kevin_zhangl 2 жил өмнө
commit
91f691c0c8
100 өөрчлөгдсөн 6720 нэмэгдсэн , 0 устгасан
  1. 15 0
      .gitignore
  2. 32 0
      LICENSE.txt
  3. 52 0
      README.md
  4. 1 0
      app/.htaccess
  5. 81 0
      app/BaseController.php
  6. 49 0
      app/ExceptionHandle.php
  7. 51 0
      app/JjjController.php
  8. 8 0
      app/Request.php
  9. 2 0
      app/admin/common.php
  10. 80 0
      app/admin/controller/Access.php
  11. 81 0
      app/admin/controller/Controller.php
  12. 17 0
      app/admin/controller/Index.php
  13. 82 0
      app/admin/controller/Message.php
  14. 30 0
      app/admin/controller/Passport.php
  15. 84 0
      app/admin/controller/Region.php
  16. 81 0
      app/admin/controller/Shop.php
  17. 25 0
      app/admin/controller/admin/User.php
  18. 62 0
      app/admin/controller/plus/Plus.php
  19. 182 0
      app/admin/model/Access.php
  20. 21 0
      app/admin/model/Setting.php
  21. 39 0
      app/admin/model/Shop.php
  22. 60 0
      app/admin/model/admin/User.php
  23. 120 0
      app/admin/model/app/App.php
  24. 73 0
      app/admin/model/page/Page.php
  25. 33 0
      app/admin/model/plus/Category.php
  26. 43 0
      app/admin/model/settings/Message.php
  27. 57 0
      app/admin/model/settings/MessageField.php
  28. 84 0
      app/admin/model/settings/Region.php
  29. 26 0
      app/admin/model/user/Grade.php
  30. 2 0
      app/api/common.php
  31. 128 0
      app/api/controller/Controller.php
  32. 74 0
      app/api/controller/Index.php
  33. 32 0
      app/api/controller/Settings.php
  34. 37 0
      app/api/controller/balance/Log.php
  35. 57 0
      app/api/controller/balance/Plan.php
  36. 37 0
      app/api/controller/coupon/Coupon.php
  37. 119 0
      app/api/controller/file/Upload.php
  38. 91 0
      app/api/controller/order/Cart.php
  39. 129 0
      app/api/controller/order/Order.php
  40. 53 0
      app/api/controller/plus/agent/Apply.php
  41. 63 0
      app/api/controller/plus/agent/Cash.php
  42. 50 0
      app/api/controller/plus/agent/Order.php
  43. 48 0
      app/api/controller/plus/agent/Qrcode.php
  44. 54 0
      app/api/controller/plus/agent/Team.php
  45. 43 0
      app/api/controller/plus/article/Article.php
  46. 25 0
      app/api/controller/plus/assemble/Bill.php
  47. 61 0
      app/api/controller/plus/assemble/Order.php
  48. 58 0
      app/api/controller/plus/assemble/Product.php
  49. 64 0
      app/api/controller/plus/bargain/Order.php
  50. 57 0
      app/api/controller/plus/bargain/Product.php
  51. 58 0
      app/api/controller/plus/bargain/Task.php
  52. 36 0
      app/api/controller/plus/invitationgift/Invitation.php
  53. 23 0
      app/api/controller/plus/live/Wx.php
  54. 56 0
      app/api/controller/plus/lottery/Lottery.php
  55. 43 0
      app/api/controller/plus/lottery/Order.php
  56. 36 0
      app/api/controller/plus/package/Order.php
  57. 68 0
      app/api/controller/plus/package/Package.php
  58. 61 0
      app/api/controller/plus/points/Order.php
  59. 37 0
      app/api/controller/plus/points/Product.php
  60. 65 0
      app/api/controller/plus/seckill/Order.php
  61. 47 0
      app/api/controller/plus/seckill/Product.php
  62. 65 0
      app/api/controller/plus/sign/Sign.php
  63. 31 0
      app/api/controller/plus/table/Table.php
  64. 27 0
      app/api/controller/points/Log.php
  65. 26 0
      app/api/controller/product/Category.php
  66. 24 0
      app/api/controller/product/Comment.php
  67. 90 0
      app/api/controller/product/Product.php
  68. 64 0
      app/api/controller/store/Order.php
  69. 33 0
      app/api/controller/store/Store.php
  70. 101 0
      app/api/controller/user/Address.php
  71. 122 0
      app/api/controller/user/Agent.php
  72. 35 0
      app/api/controller/user/Bargain.php
  73. 47 0
      app/api/controller/user/Comment.php
  74. 69 0
      app/api/controller/user/Coupon.php
  75. 50 0
      app/api/controller/user/Favorite.php
  76. 88 0
      app/api/controller/user/Index.php
  77. 51 0
      app/api/controller/user/Invitation.php
  78. 285 0
      app/api/controller/user/Order.php
  79. 120 0
      app/api/controller/user/Refund.php
  80. 70 0
      app/api/controller/user/User.php
  81. 34 0
      app/api/controller/user/Userapple.php
  82. 45 0
      app/api/controller/user/Usermp.php
  83. 174 0
      app/api/controller/user/Useropen.php
  84. 145 0
      app/api/controller/user/Userweb.php
  85. 47 0
      app/api/event/PaySuccess.php
  86. 13 0
      app/api/model/App.php
  87. 21 0
      app/api/model/file/UploadFile.php
  88. 240 0
      app/api/model/order/Cart.php
  89. 401 0
      app/api/model/order/Order.php
  90. 20 0
      app/api/model/order/OrderAddress.php
  91. 11 0
      app/api/model/order/OrderExtract.php
  92. 28 0
      app/api/model/order/OrderProduct.php
  93. 156 0
      app/api/model/order/OrderRefund.php
  94. 20 0
      app/api/model/order/OrderRefundAddress.php
  95. 13 0
      app/api/model/order/OrderRefundImage.php
  96. 269 0
      app/api/model/page/Page.php
  97. 97 0
      app/api/model/plus/agent/Apply.php
  98. 20 0
      app/api/model/plus/agent/Capital.php
  99. 83 0
      app/api/model/plus/agent/Cash.php
  100. 102 0
      app/api/model/plus/agent/Order.php

+ 15 - 0
.gitignore

@@ -0,0 +1,15 @@
+vendor
+
+public/admin
+public/h5
+public/shop
+
+runtime/admin/session
+runtime/shop/session
+runtime/cache
+runtime/logs
+
+.env
+.travis.yml
+.idea/
+sql/ekshop.zip

+ 32 - 0
LICENSE.txt

@@ -0,0 +1,32 @@
+
+ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
+版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
+All rights reserved。
+ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
+
+Apache Licence是著名的非盈利开源组织Apache采用的协议。
+该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
+允许代码修改,再作为开源或商业软件发布。需要满足
+的条件: 
+1. 需要给代码的用户一份Apache Licence ;
+2. 如果你修改了代码,需要在被修改的文件中说明;
+3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
+带有原来代码中的协议,商标,专利声明和其他原来作者规
+定需要包含的说明;
+4. 如果再发布的产品中包含一个Notice文件,则在Notice文
+件中需要带有本协议内容。你可以在Notice中增加自己的
+许可,但不可以表现为对Apache Licence构成更改。 
+具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.

+ 52 - 0
README.md

@@ -0,0 +1,52 @@
+ThinkPHP 6.0
+===============
+
+> 运行环境要求PHP7.1+。
+
+## 主要新特性
+
+* 采用`PHP7`强类型(严格模式)
+* 支持更多的`PSR`规范
+* 原生多应用支持
+* 更强大和易用的查询
+* 全新的事件系统
+* 模型事件和数据库事件统一纳入事件系统
+* 模板引擎分离出核心
+* 内部功能中间件化
+* SESSION/Cookie机制改进
+* 对Swoole以及协程支持改进
+* 对IDE更加友好
+* 统一和精简大量用法
+
+## 安装
+
+~~~
+composer create-project topthink/think tp 6.0.*-dev
+~~~
+
+如果需要更新框架使用
+~~~
+composer update topthink/framework
+~~~
+
+## 文档
+
+[完全开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content)
+
+## 参与开发
+
+请参阅 [ThinkPHP 核心框架包](https://github.com/top-think/framework)。
+
+## 版权信息
+
+ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
+
+本项目包含的第三方源码和二进制文件之版权信息另行标注。
+
+版权所有Copyright © 2006-2019 by ThinkPHP (http://thinkphp.cn)
+
+All rights reserved。
+
+ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
+
+更多细节参阅 [LICENSE.txt](LICENSE.txt)

+ 1 - 0
app/.htaccess

@@ -0,0 +1 @@
+deny from all

+ 81 - 0
app/BaseController.php

@@ -0,0 +1,81 @@
+<?php
+declare (strict_types=1);
+
+namespace app;
+
+use think\App;
+use think\Validate;
+
+/**
+ * 控制器基础类
+ */
+abstract class BaseController
+{
+    /**
+     * Request实例
+     */
+    protected $request;
+
+    /**
+     * 应用实例
+     */
+    protected $app;
+
+    /**
+     * 是否批量验证
+     */
+    protected $batchValidate = false;
+
+    /**
+     * 控制器中间件
+     */
+    protected $middleware = [];
+
+    /**
+     * 构造方法
+     */
+    public function __construct(App $app)
+    {
+        $this->app = $app;
+        $this->request = $this->app->request;
+
+        // 控制器初始化
+        $this->initialize();
+    }
+
+    // 初始化
+    protected function initialize()
+    {
+    }
+
+    /**
+     * 验证数据
+     */
+    protected function validate(array $data, $validate, array $message = [], bool $batch = false)
+    {
+        if (is_array($validate)) {
+            $v = new Validate();
+            $v->rule($validate);
+        } else {
+            if (strpos($validate, '.')) {
+                // 支持场景
+                list($validate, $scene) = explode('.', $validate);
+            }
+            $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
+            $v = new $class();
+            if (!empty($scene)) {
+                $v->scene($scene);
+            }
+        }
+
+        $v->message($message);
+
+        // 是否批量验证
+        if ($batch || $this->batchValidate) {
+            $v->batch(true);
+        }
+
+        return $v->failException(true)->check($data);
+    }
+
+}

+ 49 - 0
app/ExceptionHandle.php

@@ -0,0 +1,49 @@
+<?php
+namespace app;
+
+use think\db\exception\DataNotFoundException;
+use think\db\exception\ModelNotFoundException;
+use think\exception\Handle;
+use think\exception\HttpException;
+use think\exception\HttpResponseException;
+use think\exception\ValidateException;
+use think\Response;
+use Throwable;
+
+/**
+ * 应用异常处理类
+ */
+class ExceptionHandle extends Handle
+{
+    /**
+     * 不需要记录信息(日志)的异常类列表
+     */
+    protected $ignoreReport = [
+        HttpException::class,
+        HttpResponseException::class,
+        ModelNotFoundException::class,
+        DataNotFoundException::class,
+        ValidateException::class,
+    ];
+
+    /**
+     * 记录异常信息(包括日志或者其它方式记录)
+     */
+    public function report(Throwable $exception): void
+    {
+        // 使用内置的方式记录异常日志
+        parent::report($exception);
+    }
+
+    /**
+     * Render an exception into an HTTP response.
+     *
+     */
+    public function render($request, Throwable $e): Response
+    {
+        // 添加自定义异常处理机制
+
+        // 其他错误交给系统处理
+        return parent::render($request, $e);
+    }
+}

+ 51 - 0
app/JjjController.php

@@ -0,0 +1,51 @@
+<?php
+declare (strict_types=1);
+
+namespace app;
+
+
+/**
+ * 控制器基础类
+ */
+abstract class JjjController extends BaseController
+{
+    /**
+     * 返回封装后的 API 数据到客户端
+     */
+    protected function renderJson($code = 1, $msg = '', $data = [])
+    {
+        return compact('code', 'msg', 'data');
+    }
+
+    /**
+     * 返回操作成功json
+     */
+    protected function renderSuccess($msg = 'success', $data = [])
+    {
+        return json($this->renderJson(1, $msg, $data));
+    }
+
+    /**
+     * 返回操作失败json
+     */
+    protected function renderError($msg = 'error', $data = [], $code = 0)
+    {
+        return json($this->renderJson($code, $msg, $data));
+    }
+
+    /**
+     * 获取post数据 (数组)
+     */
+    protected function postData($key = null)
+    {
+        return $this->request->param(is_null($key) ? '' : $key . '/a');
+    }
+
+    /**
+     * 获取post数据 (数组)
+     */
+    protected function getData($key = null)
+    {
+        return $this->request->get(is_null($key) ? '' : $key);
+    }
+}

+ 8 - 0
app/Request.php

@@ -0,0 +1,8 @@
+<?php
+namespace app;
+
+// 应用请求对象类
+class Request extends \think\Request
+{
+
+}

+ 2 - 0
app/admin/common.php

@@ -0,0 +1,2 @@
+<?php
+// 应用公共文件

+ 80 - 0
app/admin/controller/Access.php

@@ -0,0 +1,80 @@
+<?php
+
+namespace app\admin\controller;
+
+
+use app\admin\model\Access as AccesscModel;
+
+/**
+ * 商家用户权限控制器
+ */
+class Access extends Controller
+{
+    /**
+     * 权限列表
+     */
+    public function index()
+    {
+        $model = new AccesscModel;
+        $list = $model->getList();
+        return $this->renderSuccess('', $list);
+    }
+
+    /**
+     * 添加权限
+     */
+    public function add()
+    {
+        $model = new AccesscModel;
+        $data = $this->postData();
+
+        if ($model->add($data)) {
+            return $this->renderSuccess('添加成功', compact('model'));
+        }
+        return $this->renderError($model->getError() ?:'添加失败');
+    }
+
+    /**
+     * 更新权限
+     */
+    public function edit()
+    {
+        $data = $this->postData();
+        // 权限详情
+        $model = AccesscModel::detail($data['access_id']);
+        // 更新记录
+        if ($model->edit($data)) {
+            return $this->renderSuccess('更新成功');
+        }
+        return $this->renderError($model->getError() ?:'更新失败');
+    }
+
+    /**
+     * 删除权限
+     */
+    public function delete($access_id)
+    {
+        $model = new  AccesscModel();
+        $num = $model->getChildCount(['parent_id' => $access_id]);
+        if ($num > 0) {
+            return $this->renderError('当前菜单下存在子权限,请先删除');
+        }
+        if ($model->remove($access_id)) {
+            return $this->renderSuccess('删除成功');
+        }
+        return $this->renderError($model->getError() ?:'删除失败');
+    }
+
+    /**
+     * 权限状态
+     */
+    public function status($access_id, $status)
+    {
+        $model = AccesscModel::detail($access_id);
+        if ($model->status($status)) {
+            return $this->renderSuccess('修改成功');
+        }
+        return $this->renderError($model->getError() ?:'修改失败');
+    }
+
+}

+ 81 - 0
app/admin/controller/Controller.php

@@ -0,0 +1,81 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\common\exception\BaseException;
+use app\JjjController;
+use think\facade\Session;
+
+/**
+ * 商户后台控制器基类
+ */
+class Controller extends JjjController
+{
+
+    // 商家登录信息
+    protected $admin;
+
+    // 当前控制器名称
+    protected $controller = '';
+
+    // 当前方法名称
+    protected $action = '';
+
+    // 当前路由uri
+    protected $routeUri = '';
+
+    // 当前路由:分组名称
+    protected $group = '';
+
+    // 登录验证白名单
+    protected $allowAllAction = [
+        // 登录页面
+        'passport/login',
+    ];
+    /**
+     * 后台初始化
+     */
+    public function initialize()
+    {
+        // 商家登录信息
+        $this->admin = Session::get('jjjshop_admin');
+        // 当前路由信息
+        $this->getRouteinfo();
+        // 验证登录
+        $this->checkLogin();
+    }
+
+    /**
+     * 解析当前路由参数 (分组名称、控制器名称、方法名)
+     */
+    protected function getRouteinfo()
+    {
+        // 控制器名称
+        $this->controller = toUnderScore(Request()->controller());
+        // 方法名称
+        $this->action = Request()->action();
+        // 控制器分组 (用于定义所属模块)
+        $groupstr = strstr($this->controller, '.', true);
+        $this->group = $groupstr !== false ? $groupstr : $this->controller;
+        // 当前uri
+        $this->routeUri = $this->controller . '/' . $this->action;
+    }
+
+    /**
+     * 验证登录状态
+     */
+    private function checkLogin()
+    {
+        // 验证当前请求是否在白名单
+        if (in_array($this->routeUri, $this->allowAllAction)) {
+            return true;
+        }
+        // 验证登录状态
+        if (!empty($this->admin) || $this->admin['is_login'] == 1) {
+            return true;
+        }
+        throw new BaseException(['code' => -1, 'msg' => 'not_login']);
+        return false;
+    }
+
+}

+ 17 - 0
app/admin/controller/Index.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\admin\controller;
+/**
+ * 后台首页
+ */
+class Index extends Controller
+{
+    /**
+     * 后台首页
+     */
+    public function index()
+    {
+        $version = get_version();
+        return $this->renderSuccess('', compact('version'));
+    }
+}

+ 82 - 0
app/admin/controller/Message.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\admin\model\settings\MessageField as MessageFieldModel;
+use app\admin\model\settings\Message as MessageModel;
+
+class Message extends Controller
+{
+    /**
+     * 列表
+     */
+    public function index()
+    {
+        $list = MessageModel::getAll();
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     * 添加
+     */
+    public function add()
+    {
+        $model = new MessageModel;
+        // 新增记录
+        if ($model->add($this->postData())) {
+            return $this->renderSuccess('添加成功');
+        }
+        return $this->renderError('添加失败');
+    }
+
+    /**
+     * 更新权限
+     */
+    public function edit()
+    {
+        // 权限详情
+        $data = $this->postData();
+        $model = MessageModel::detail($data['message_id']);
+
+        // 更新记录
+        if ($model->edit($data)) {
+            return $this->renderSuccess('更新成功');
+        }
+        return $this->renderError('更新失败');
+    }
+
+    /**
+     * 删除小程序
+     */
+    public function delete($message_id)
+    {
+        // 小程序详情
+        $model = MessageModel::detail($message_id);
+        if (!$model->setDelete()) {
+            return $this->renderError('操作失败');
+        }
+        return $this->renderSuccess('操作成功');
+    }
+
+    /**
+     * 消息字段列表
+     */
+    public function field($message_id)
+    {
+        $list = MessageFieldModel::getAll($message_id);
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     * 保存消息字段
+     */
+    public function saveField()
+    {
+        $model = new MessageFieldModel;
+        // 新增记录
+        if ($model->add($this->postData())) {
+            return $this->renderSuccess('添加成功');
+        }
+        return $this->renderError('添加失败');
+    }
+}

+ 30 - 0
app/admin/controller/Passport.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\admin\model\admin\User as UserModel;
+
+class Passport extends Controller
+{
+    /**
+     * 超管后台登录
+     */
+    public function login()
+    {
+        $model = new UserModel;
+        if ($user = $model->login($this->postData())) {
+            return $this->renderSuccess('登录成功', $user['user_name']);
+        }
+        return $this->renderError('用户名或者密码错误!');
+    }
+
+    /**
+     * 退出登录
+     */
+    public function logout()
+    {
+        session('jjjshop_admin', null);
+        return $this->renderSuccess('退出成功');
+
+    }
+}

+ 84 - 0
app/admin/controller/Region.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\admin\model\settings\Region as RegionModel;
+
+/**
+ * 地区控制器
+ */
+class Region extends Controller
+{
+    /**
+     * 物流数据
+     */
+    public function index()
+    {
+        $model = new RegionModel;
+        $list = $model->getList($this->postData());
+        $regionData = RegionModel::getCacheTree();
+        return $this->renderSuccess('',compact('list', 'regionData'));
+    }
+
+    /**
+     * 添加物流公司
+     */
+    public function add()
+    {
+        if($this->request->isGet()){
+            // 获取所有地区
+            $regionData = RegionModel::getCacheTree();
+            return $this->renderSuccess('', compact('regionData'));
+        }
+        // 新增记录
+        $model = new RegionModel;
+        if ($model->add($this->postData())) {
+            return $this->renderSuccess('添加成功');
+        }
+        return $this->renderError($model->getError() ?: '添加失败');
+    }
+
+    /**
+     * 修改
+     * @param $express_id
+     * @return \think\response\Json
+     */
+    public function edit($id)
+    {
+        $model = RegionModel::detail($id);
+        if($this->request->isGet()){
+            $regionData = RegionModel::getCacheTree();
+            if($model['level'] == 1){
+                $model['province_id'] = '';
+                $model['city_id'] = '';
+            }
+            if($model['level'] == 2){
+                $model['province_id'] = $model['pid'];
+                $model['city_id'] = '';
+            }
+            if($model['level'] == 3){
+                $model['province_id'] = RegionModel::detail($model['pid'])['pid'];
+                $model['city_id'] = $model['pid'];
+            }
+            return $this->renderSuccess('', compact('model', 'regionData'));
+        }
+        $model = RegionModel::detail($id);
+        // 更新记录
+        if ($model->edit($this->postData())) {
+            return $this->renderSuccess('更新成功');
+        }
+        return $this->renderError($model->getError() ?: '更新失败');
+    }
+
+    /**
+     * 删除记录
+     */
+    public function delete($id)
+    {
+        $model = RegionModel::detail($id);
+        if ($model->remove($id)) {
+            return $this->renderSuccess('删除成功');
+        }
+        return $this->renderError($model->getError() ?:'删除失败');
+    }
+}

+ 81 - 0
app/admin/controller/Shop.php

@@ -0,0 +1,81 @@
+<?php
+
+namespace app\admin\controller;
+
+use app\admin\model\app\App as AppModel;
+use app\admin\model\Shop as ShopModel;
+
+class Shop extends Controller
+{
+    /**
+     * 小程序列表
+     */
+    public function index()
+    {
+        $model = new AppModel;
+        $list = $list = $model->getList($this->postData());
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     * 进入商城
+     */
+    public function enter($app_id)
+    {
+        session('jjjshop_store', null);
+        $model = new ShopModel;
+        $model->login($app_id);
+        return redirect('/shop#/login?from=admin');
+    }
+
+    /**
+     * 添加应用
+     */
+    public function add()
+    {
+        $model = new AppModel;
+        // 新增记录
+        if ($model->add($this->postData())) {
+            return $this->renderSuccess('添加成功');
+        }
+        return $this->renderError($model->getError() ?: '添加失败');
+    }
+
+    /**
+     * 添加应用
+     */
+    public function edit($app_id)
+    {
+        $model = AppModel::detail($app_id);
+        // 新增记录
+        if ($model->edit($this->postData())) {
+            return $this->renderSuccess('修改成功');
+        }
+        return $this->renderError($model->getError() ?: '修改失败');
+    }
+
+    /**
+     * 删除小程序
+     */
+    public function delete($app_id)
+    {
+        // 小程序详情
+        $model = AppModel::detail($app_id);
+        if (!$model->setDelete()) {
+            return $this->renderError('操作失败');
+        }
+        return $this->renderSuccess('操作成功');
+    }
+
+    /*
+     *启用禁用
+    */
+    public function updateStatus($app_id)
+    {
+        $model = AppModel::detail($app_id);
+        if (!$model->updateStatus()) {
+            return $this->renderError('操作失败');
+        }
+        return $this->renderSuccess('操作成功');
+    }
+}

+ 25 - 0
app/admin/controller/admin/User.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace app\admin\controller\admin;
+
+use app\admin\controller\Controller;
+use app\admin\model\admin\User as AdminUserModel;
+
+/**
+ * 超管后台管理员控制器
+ */
+class User extends Controller
+{
+    /**
+     * 更新当前管理员信息
+     */
+    public function renew()
+    {
+        $session = session('jjjshop_admin');
+        $model = AdminUserModel::detail($session['user']['admin_user_id']);
+        if ($model->renew($this->postData())) {
+            return $this->renderSuccess('更新成功');
+        }
+        return $this->renderError($model->getError() ?:'更新失败');
+    }
+}

+ 62 - 0
app/admin/controller/plus/Plus.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace app\admin\controller\plus;
+
+use app\admin\controller\Controller;
+use app\admin\model\plus\Category as CategoryModel;
+use app\admin\model\Access as AccessModel;
+/**
+ * 插件控制器
+ */
+class Plus extends Controller
+{
+    /**
+     *插件列表
+     */
+    public function index()
+    {
+        $accessList = CategoryModel::getAll();
+        return $this->renderSuccess('', compact('accessList'));
+    }
+
+    /**
+     *添加插件
+     */
+    public function add()
+    {
+        if($this->request->isGet()){
+            //查找所有插件
+            $accessList = AccessModel::getAllPlus();
+            return $this->renderSuccess('', compact('accessList'));
+        }
+        $model = new AccessModel();
+        if ($model->addPlus($this->postData())) {
+            return $this->renderSuccess('添加成功');
+        }
+        return $this->renderError('添加失败');
+    }
+
+    /**
+     *删除插件
+     */
+    public function delete($plus_id)
+    {
+        $model = AccessModel::detail($plus_id);
+        if ($model->removePlus()) {
+            return $this->renderSuccess(' 删除成功');
+        }
+        return $this->renderError($model->getError()?:'删除失败');
+    }
+
+    /**
+     *删除分类
+     */
+    public function deleteCategory($plus_category_id)
+    {
+        $model = CategoryModel::detail($plus_category_id);
+        if ($model->remove()) {
+            return $this->renderSuccess(' 删除成功');
+        }
+        return $this->renderError($model->getError()?:'删除失败');
+    }
+}

+ 182 - 0
app/admin/model/Access.php

@@ -0,0 +1,182 @@
+<?php
+
+namespace app\admin\model;
+
+use app\common\model\shop\Access as AccessModel;
+
+/**
+ * Class Access
+ *  商家用户权限模型
+ * @package app\admin\model
+ */
+class Access extends AccessModel
+{
+    /**
+     * 获取权限列表
+     */
+    public function getList()
+    {
+        $all = static::getAll(-1);
+        $res = $this->recursiveMenuArray($all, 0);
+        return array_values($this->foo($res));
+
+    }
+
+    /**
+     * 新增记录
+     */
+    public function add($data)
+    {
+        // 校验路径
+        if(!$this->validate($data)){
+            return false;
+        }
+        $data['access_id'] = time();
+        $data['app_id'] = self::$app_id;
+        return $this->save($data);
+    }
+
+    /**
+     * 更新记录
+     */
+    public function edit($data)
+    {
+        if ($data['access_id'] == $data['parent_id']) {
+            $this->error = '上级菜单不允许设置为当前菜单';
+            return false;
+        }
+        // 判断上级角色是否为当前子级
+        if ($data['parent_id'] > 0) {
+            // 获取所有上级id集
+            $parentIds = $this->getTopAccessIds($data['parent_id']);
+            if (in_array($data['access_id'], $parentIds)) {
+                $this->error = '上级菜单不允许设置为当前子菜单';
+                return false;
+            }
+        }
+        // 校验路径,不限制大小写
+        if(strtolower($data['path']) !== strtolower($this['path'])){
+            if(!$this->validate($data)){
+                return false;
+            }
+        }
+
+        $data['redirect_name'] = ($data['is_route'] == 1) ? $data['redirect_name'] : '';
+        return $this->save($data);
+    }
+
+    /**
+     * 验证
+     */
+    private function validate($data){
+         $count = $this->where(['path' => $data['path']])->count();
+         if($count > 0){
+             $this->error = '路径已存在,请重新更改';
+             return false;
+         }
+         return true;
+    }
+
+    public function getChildCount($where)
+    {
+        return $this->where($where)->count();
+    }
+
+
+    /**
+     * 删除权限
+     */
+    public function remove($access_id)
+    {
+        return $this->where('access_id', '=', $access_id)->delete();
+    }
+    /**
+     * 删除插件
+     */
+    public function removePlus()
+    {
+        return $this->save([
+            'plus_category_id' => 0
+        ]);
+    }
+
+    /**
+     * 获取所有上级id集
+     */
+    public function getTopAccessIds($access_id, &$all = null)
+    {
+        static $ids = [];
+        is_null($all) && $all = $this->getAll();
+
+        foreach ($all as $item) {
+            if ($item['access_id'] == $access_id && $item['parent_id'] > 0) {
+                $ids[] = $item['parent_id'];
+                $this->getTopAccessIds($item['parent_id'], $all);
+            }
+        }
+
+        return $ids;
+    }
+
+    /**
+     * 递归获取获取分类
+     */
+    public function recursiveMenuArray($data, $pid)
+    {
+        $re_data = [];
+        foreach ($data as $key => $value) {
+            if ($value['parent_id'] == $pid) {
+                $re_data[$value['access_id']] = $value;
+                $re_data[$value['access_id']]['children'] = $this->recursiveMenuArray($data, $value['access_id']);
+            } else {
+                continue;
+            }
+        }
+        return $re_data;
+
+    }
+
+    /**
+     * 格式化递归数组下标
+     */
+    public function foo(&$ar)
+    {
+        if (!is_array($ar)) return [];
+        foreach ($ar as $k => &$v) {
+            if (is_array($v)) $this->foo($v);
+            if ($k == 'children') $v = array_values($v);
+        }
+        return $ar;
+    }
+
+    /**
+     * 更改显示状态
+     */
+    public function status($status){
+        return $this->save([
+            'is_show' => $status
+        ]);
+    }
+
+    /**
+     * 获取所有插件
+     */
+    public static function getAllPlus(){
+        $model = new static();
+        $plus = $model->where('path', '=', '/plus/plus/index')->find();
+        return $model->where('parent_id', '=', $plus['access_id'])
+            ->where('plus_category_id', '=', 0)
+            ->select();
+    }
+
+    /**
+     * 保存插件分类
+     * @param $data
+     */
+    public function addPlus($data){
+        $model = new self();
+        return $model->where('access_id', '=', $data['access_id'])->save([
+            'plus_category_id' => $data['plus_category_id']
+        ]);
+    }
+}

+ 21 - 0
app/admin/model/Setting.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace app\admin\model;
+
+use app\common\model\settings\Setting as SettingModel;
+
+class Setting extends SettingModel
+{
+    /**
+     * 新增默认配置
+     */
+    public function insertDefault($app_id, $store_name)
+    {
+        // 添加商城默认设置记录
+        $data = [];
+        foreach ($this->defaultData($store_name) as $key => $item) {
+            $data[] = array_merge($item, ['app_id' => $app_id]);
+        }
+        return $this->saveAll($data);
+    }
+}

+ 39 - 0
app/admin/model/Shop.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace app\admin\model;
+
+use app\common\exception\BaseException;
+use app\common\model\shop\User as ShopModel;
+
+class Shop extends ShopModel
+{
+    /**
+     * 新增商家用户记录
+     */
+    public function add($app_id, $data)
+    {
+        if (self::checkExist($data['user_name'])) {
+            $this->error = '商家用户名已存在';
+            return false;
+        }
+        return $this->save([
+            'user_name' => $data['user_name'],
+            'password' => salt_hash($data['password']),
+            'app_id' => $app_id,
+            'is_super' => 1
+        ]);
+    }
+
+    /**
+     * 商家用户登录
+     */
+    public function login($app_id)
+    {
+        // 验证用户名密码是否正确
+        $user = self::detail(['app_id' => $app_id], ['app']);
+        if (empty($user)) {
+            throw new BaseException(['msg' => '超级管理员用户信息不存在']);
+        }
+        $this->loginState($user);
+    }
+}

+ 60 - 0
app/admin/model/admin/User.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace app\admin\model\admin;
+
+use app\common\model\admin\User as UserModel;
+
+/**
+ * 超管后台用户模型
+ */
+class User extends UserModel
+{
+    /**
+     * 超管后台用户登录
+     */
+    public function login($data)
+    {
+        // 验证用户名密码是否正确
+        if (!$user = self::where([
+            'user_name' => $data['username'],
+            'password' => salt_hash($data['password'])
+        ])->find()
+        ) {
+            $this->error = '登录失败, 用户名或密码错误';
+            return false;
+        }
+        // 保存登录状态
+        $session = array(
+            'user' => [
+                'admin_user_id' => $user['admin_user_id'],
+                'user_name' => $user['user_name'],
+            ],
+            'is_login' => true,
+        );
+        session('jjjshop_admin', $session);
+
+        return $user;
+    }
+
+    /**
+     * 超管用户信息
+     */
+    public static function detail($admin_user_id)
+    {
+        return (new static())->find($admin_user_id);
+    }
+
+    /**
+     * 更新当前管理员信息
+     */
+    public function renew($data)
+    {
+        if ($data['pass'] !== $data['checkPass']) {
+            $this->error = '确认密码不正确';
+            return false;
+        }
+        return $this->save([
+            'password' => salt_hash($data['pass']),
+        ]);
+    }
+}

+ 120 - 0
app/admin/model/app/App.php

@@ -0,0 +1,120 @@
+<?php
+
+namespace app\admin\model\app;
+
+use app\admin\model\page\Page as PageModel;
+use app\admin\model\Shop as ShopUser;
+use app\common\model\app\App as AppModel;
+use app\admin\model\user\Grade as GradeModel;
+
+class App extends AppModel
+{
+    /**
+     * 获取小程序列表
+     */
+    public function getList($limit)
+    {
+        return $this->alias('app')->field(['app.*,user.user_name'])
+            ->join('shop_user user', 'user.app_id = app.app_id','left')
+            ->where('user.is_super', '=', 1)
+            ->where('app.is_delete', '=', 0)
+            ->order(['create_time' => 'asc'])
+            ->paginate($limit);
+    }
+
+    /**
+     * 新增记录
+     */
+    public function add($data)
+    {
+        if ($data['password'] !== $data['password_confirm']) {
+            $this->error = '确认密码不正确';
+            return false;
+        }
+        if (ShopUser::checkExist($data['user_name'])) {
+            $this->error = '商家用户名已存在';
+            return false;
+        }
+        if($data['no_expire'] == 'true'){
+            $data['expire_time'] = 0;
+        }else{
+            $data['expire_time'] = strtotime($data['expire_time']);
+        }
+        $this->startTrans();
+        try {
+            // 添加小程序记录
+            $this->save($data);
+            // 新增商家用户信息
+            $ShopUser = new ShopUser;
+            if (!$ShopUser->add($this['app_id'], $data)) {
+                $this->error = $ShopUser->error;
+                return false;
+            }
+            // 新增应用diy配置
+            (new PageModel)->insertDefault($this['app_id']);
+            // 默认等级
+            (new GradeModel)->insertDefault($this['app_id']);
+            $this->commit();
+            return true;
+        } catch (\Exception $e) {
+            $this->error = $e->getMessage();
+            $this->rollback();
+            return false;
+        }
+    }
+
+    /**
+     * 修改记录
+     */
+    public function edit($data)
+    {
+        $this->startTrans();
+        try {
+            $save_data = [
+                'app_name' => $data['app_name'],
+            ];
+            if($data['no_expire'] == 'true'){
+                $save_data['expire_time'] = 0;
+            }else{
+                $save_data['expire_time'] = strtotime($data['expire_time_text']);
+            }
+            $this->save($save_data);
+            $user_data = [
+                'user_name' => $data['user_name']
+            ];
+            if (!empty($data['password'])) {
+                $user_data['password'] = salt_hash($data['password']);
+            }
+            $shop_user = (new ShopUser())->where('app_id', '=', $this['app_id'])->where('is_super', '=', 1)->find();
+            if($shop_user['user_name'] != $data['user_name']){
+                if (ShopUser::checkExist($data['user_name'])) {
+                    $this->error = '商家用户名已存在';
+                    return false;
+                }
+            }
+            $shop_user->save($user_data);
+            $this->commit();
+            return true;
+        } catch (\Exception $e) {
+            $this->error = $e->getMessage();
+            $this->rollback();
+            return false;
+        }
+    }
+    /**
+     * 移入移出回收站
+     */
+    public function recycle($is_recycle = true)
+    {
+        return $this->save(['is_recycle' => (int)$is_recycle]);
+    }
+
+    /**
+     * 软删除
+     */
+    public function setDelete()
+    {
+        return $this->save(['is_delete' => 1]);
+    }
+
+}

+ 73 - 0
app/admin/model/page/Page.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace app\admin\model\page;
+
+use app\common\model\page\Page as PageModel;
+
+/**
+ * 微信小程序diy页面模型
+ */
+class Page extends PageModel
+{
+    /**
+     * 新增小程序首页diy默认设置
+     */
+    public function insertDefault($app_id)
+    {
+        return $this->save([
+            'page_type' => 10,
+            'page_name' => '首页',
+            'page_data' => [
+                'page' => [
+                    'type' => 'page',
+                    'name' => '页面设置',
+                    'params' => [
+                        'name' => '页面标题',
+                        'title' => '页面标题',
+                        'share_title' => '分享标题',
+                        'share_img' => self::$base_url .'image/diy/logo.png',
+                        'toplogo'=> self::$base_url .'image/diy/logo_top.png'
+                    ],
+                    'style' => [
+                        'titleTextColor' => 'black',
+                        'titleBackgroundColor' => '#ffffff',
+                    ]
+                ],
+                'items' => [
+                    /*[
+                        'type' => 'search',
+                        'name' => '搜索框',
+                        'params' => ['placeholder' => '搜索商品'],
+                        'style' => [
+                            'textAlign' => 'center',
+                            'searchStyle' => 'radius',
+                        ],
+                    ],*/
+                    [
+                        'type' => 'banner',
+                        'name' => '图片轮播',
+                        'style' => [
+                            'btnColor' => '#ffffff',
+                            'btnShape' => 'round',
+                        ],
+                        'params' => [
+                            'interval' => '2800'
+                        ],
+                        'data' => [
+                            [
+                                'imgUrl' => self::$base_url . 'assets/store/img/diy/banner/01.png',
+                                'linkUrl' => '',
+                            ],
+                            [
+                                'imgUrl' => self::$base_url . 'assets/store/img/diy/banner/01.png',
+                                'linkUrl' => '',
+                            ],
+                        ],
+                    ]
+                ],
+            ],
+            'app_id' => $app_id
+        ]);
+    }
+
+}

+ 33 - 0
app/admin/model/plus/Category.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace app\admin\model\plus;
+
+use app\common\model\plus\plus\Category as CategoryModel;
+use app\admin\model\Access as AccessModel;
+/**
+ * 插件分类模型
+ */
+class Category extends CategoryModel
+{
+    /**
+     * 获取所有插件
+     */
+    public static function getAll()
+    {
+        $model = new static();
+        $list = $model->order(['sort' => 'asc', 'create_time' => 'asc'])->select();
+        // 查询分类下的插件
+        foreach ($list as $category){
+            $category['children'] = AccessModel::getListByPlusCategoryId($category['plus_category_id']);
+        }
+        return $list;
+    }
+
+    /**
+     * 删除权限
+     */
+    public function remove()
+    {
+        return $this->delete();
+    }
+}

+ 43 - 0
app/admin/model/settings/Message.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace app\admin\model\settings;
+
+use app\common\model\settings\Message as MessageModel;
+
+class Message extends MessageModel
+{
+    /**
+     * 获取全部
+     */
+    public static function getAll()
+    {
+        $model = new static;
+        return $model->where('is_delete', '=', 0)->order(['sort' => 'asc'])->select();
+    }
+
+    /**
+     * 新增
+     */
+    public function add($data)
+    {
+        return $this->save($data);
+    }
+
+
+    /**
+     * 软删除
+     */
+    public function setDelete()
+    {
+        return $this->save(['is_delete' => 1]);
+    }
+
+    /**
+     * 更新记录
+     */
+    public function edit($data)
+    {
+        return $this->save($data);
+    }
+
+}

+ 57 - 0
app/admin/model/settings/MessageField.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace app\admin\model\settings;
+
+use app\common\model\settings\MessageField as MessageFieldModel;
+
+class MessageField extends MessageFieldModel
+{
+    /**
+     * 获取全部
+     */
+    public static function getAll($message_id)
+    {
+        $model = new static;
+        return $model->where('message_id', '=', $message_id)
+            ->where('is_delete', '=', 0)
+            ->order(['sort' => 'asc'])->select();
+    }
+
+    /**
+     * 新增
+     */
+    public function add($data)
+    {
+        $filedList = isset($data['fieldData'])?$data['fieldData']:[];
+        $this->startTrans();
+        try {
+            $save_data = [];
+            foreach ($filedList as $field){
+                // 更新小程序设置
+                if ($field['message_field_id'] > 0) {
+                    $save_data[] = $field;
+                }else {
+                    $field['message_id'] = $data['message_id'];
+                    unset($field['message_field_id']);
+                    $save_data[] = $field;
+                }
+            }
+            //保存
+            if(count($save_data) > 0){
+                $this->saveAll($save_data);
+            }
+            //删除
+            if(isset($data['deleteIds']) && count($data['deleteIds']) > 0){
+                $this->where('message_field_id', 'in', $data['deleteIds'])->update(['is_delete' => 1]);
+            }
+            //删除
+            $this->commit();
+            return true;
+        } catch (\Exception $e) {
+            $this->error = $e->getMessage();
+            $this->rollback();
+            return false;
+        }
+    }
+
+}

+ 84 - 0
app/admin/model/settings/Region.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace app\admin\model\settings;
+
+use app\common\model\settings\Region as RegionModel;
+use think\facade\Cache;
+
+/**
+ * 地区模型
+ */
+class Region extends RegionModel
+{
+    /**
+     * 获取列表
+     */
+    public function getList($params)
+    {
+        $model = $this;
+        if(isset($params['name']) && !empty($params['name'])){
+            $model = $model->where('name|shortname|merger_name', 'like', '%' . trim($params['name']) . '%');
+        }
+        if(isset($params['level']) && $params['level'] > 0){
+            $model = $model->where('level', '=', $params['level']);
+        }
+        if(isset($params['province_id']) && $params['province_id'] > 0){
+            if(isset($params['city_id']) && $params['city_id'] > 0){
+                $model = $model->where('pid', '=', $params['city_id']);
+            }else{
+                $model = $model->where('pid', '=', $params['province_id']);
+            }
+        }
+        return $model->where('is_delete', '=', 0)
+            ->order(['id' => 'asc', 'sort' => 'asc'])
+            ->paginate($params);
+    }
+
+
+    /**
+     * 添加新记录
+     */
+    public function add($data)
+    {
+        $this->deleteCache();
+        $data['pid'] = $this->getPid($data);
+        $data['app_id'] = self::$app_id;
+        return $this->save($data);
+    }
+
+    /**
+     * 编辑记录
+     */
+    public function edit($data)
+    {
+        $this->deleteCache();
+        $data['pid'] = $this->getPid($data);
+        return $this->save($data);
+    }
+
+    private function getPid($data){
+        if($data['level'] == 1){
+            return 0;
+        } else if($data['level'] == 2){
+            return $data['province_id'];
+        } else if($data['level'] == 3){
+            return $data['city_id'];
+        }
+        return false;
+    }
+
+    /**
+     * 删除记录
+     */
+    public function remove()
+    {
+        $this->deleteCache();
+        return $this->save([
+            'is_delete' => 1
+        ]);
+    }
+
+    public function deleteCache(){
+        Cache::delete('region');
+    }
+}

+ 26 - 0
app/admin/model/user/Grade.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace app\admin\model\user;
+
+use app\common\model\user\Grade as GradeModel;
+
+/**
+ * 用户会员等级模型
+ */
+class Grade extends GradeModel
+{
+    /**
+     * 新增记录
+     */
+    public function insertDefault($app_id)
+    {
+        $data = [
+            'name' => '普通会员',
+            'is_default' => 1,
+            'remark' => '新用户即为该等级',
+            'app_id' => $app_id
+        ];
+        return self::save($data);
+    }
+
+}

+ 2 - 0
app/api/common.php

@@ -0,0 +1,2 @@
+<?php
+// 应用公共文件

+ 128 - 0
app/api/controller/Controller.php

@@ -0,0 +1,128 @@
+<?php
+
+namespace app\api\controller;
+
+use app\api\model\user\User as UserModel;
+use app\api\model\App as AppModel;
+use app\common\exception\BaseException;
+use app\common\library\easywechat\AppMp;
+use app\JjjController;
+use think\facade\Env;
+use think\facade\Cache;
+
+/**
+ * API控制器基类
+ */
+class Controller extends JjjController
+{
+
+    // app_id
+    protected $app_id;
+
+    /**
+     * 后台初始化
+     */
+    public function initialize()
+    {
+        // 当前小程序id
+        $this->app_id = $this->getAppId();
+        // 验证当前小程序状态
+        $this->checkWxapp();
+    }
+
+    /**
+     * 获取当前应用ID
+     */
+    private function getAppId()
+    {
+        if (!$app_id = $this->request->param('app_id')) {
+            throw new BaseException(['msg' => '缺少必要的参数:app_id']);
+        }
+        return $app_id;
+    }
+
+    /**
+     * 验证当前小程序状态
+     */
+    private function checkWxapp()
+    {
+        $app = AppModel::detail($this->app_id);
+        if (empty($app)) {
+            throw new BaseException(['msg' => '当前应用信息不存在']);
+        }
+        if ($app['is_recycle'] || $app['is_delete']) {
+            throw new BaseException(['msg' => '当前应用已删除']);
+        }
+        if ($app['expire_time'] != 0 && $app['expire_time'] < time()) {
+            throw new BaseException(['msg' => '当前应用已过期']);
+        }
+    }
+
+    /**
+     * 获取当前用户信息
+     */
+    protected function getUser($is_force = true)
+    {
+        if (!$token = $this->request->param('token')) {
+            if ($is_force) {
+                throw new BaseException(['msg' => '缺少必要的参数:token', 'code' => -1]);
+            }
+            return false;
+        }
+        if (!$user = UserModel::getUser($token)) {
+            if ($is_force) {
+                throw new BaseException(['msg' => '没有找到用户信息', 'code' => -1]);
+            }
+            return false;
+        }
+        if ($user['is_delete'] == 1) {
+            throw new BaseException(['msg' => '没有找到用户信息', 'code' => -2]);
+            Cache::delete($token);
+        }
+        return $user;
+    }
+
+    protected function getShareParams($url, $title = '', $desc = '', $link = '', $imgUrl = '')
+    {
+        $signPackage = '';
+        $shareParams = '';
+        if (Env::get('APP_DEBUG')) {
+            return [
+                'signPackage' => $signPackage,
+                'shareParams' => $shareParams
+            ];
+        }
+        if ($url != '') {
+            $app = AppMp::getApp($this->app_id);
+            $app->jssdk->setUrl($url);
+            $signPackage = $app->jssdk->buildConfig(array('updateAppMessageShareData', 'updateTimelineShareData'), false);
+            $shareParams = [
+                'title' => $title,
+                'desc' => $desc,
+                'link' => $link,
+                'imgUrl' => $imgUrl,
+            ];
+        }
+        return [
+            'signPackage' => $signPackage,
+            'shareParams' => $shareParams
+        ];
+    }
+    protected function getScanParams($url)
+    {
+        $signPackage = '';
+        if (Env::get('APP_DEBUG')) {
+            return [
+                'signPackage' => $signPackage
+            ];
+        }
+        if ($url != '') {
+            $app = AppMp::getApp($this->app_id);
+            $app->jssdk->setUrl($url);
+            $signPackage = $app->jssdk->buildConfig(array('scanQRCode'), false);
+        }
+        return [
+            'signPackage' => $signPackage
+        ];
+    }
+}

+ 74 - 0
app/api/controller/Index.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace app\api\controller;
+
+use app\api\model\page\Page as AppPage;
+use app\api\model\settings\Setting as SettingModel;
+use app\common\enum\settings\SettingEnum;
+use app\common\model\app\AppUpdate as AppUpdateModel;
+/**
+ * 页面控制器
+ */
+class Index extends Controller
+{
+    /**
+     * 首页
+     */
+    public function index($page_id = null, $url = '')
+    {
+        // 页面元素
+        $data = AppPage::getPageData($this->getUser(false), $page_id);
+        $data['setting'] = array(
+            'collection' => SettingModel::getItem('collection'),
+            'officia' => SettingModel::getItem('officia'),
+            'homepush' => SettingModel::getItem('homepush')
+        );
+        // 扫一扫参数
+        $data['signPackage'] = $this->getScanParams($url)['signPackage'];
+        // 微信公众号分享参数
+        $data['share'] = $this->getShareParams($url, $data['page']['params']['share_title'], $data['page']['params']['share_title'], '/pages/index/index', $data['page']['params']['share_img']);
+        return $this->renderSuccess('', $data);
+    }
+
+    // 公众号客服
+    public function mpService()
+    {
+        $mp_service = SettingModel::getItem('mp_service');
+        return $this->renderSuccess('', compact('mp_service'));
+    }
+
+    // app更新
+    public function update($name, $version, $platform){
+        $result = [
+            'update' => false,
+            'wgtUrl' => '',
+            'pkgUrl' => '',
+        ];
+        try {
+            $model = AppUpdateModel::getLast();
+            // 这里简单判定下,不相等就是有更新。
+            if($model && $version != $model['version']){
+                $currentVersions = explode('.', $version);
+                $resultVersions = explode('.', $model['version']);
+
+                if ($currentVersions[0] < $resultVersions[0]) {
+                    // 说明有大版本更新
+                    $result['update'] = true;
+                    $result['pkgUrl'] = $platform == 'android'?$model['pkg_url_android']:$model['pkg_url_ios'];
+                } else {
+                    // 其它情况均认为是小版本更新
+                    $result['update'] = true;
+                    $result['wgtUrl'] = $model['wgt_url'];
+                }
+            }
+        } catch (\Exception $e) {
+
+        }
+        return $this->renderSuccess('', compact('result'));
+    }
+
+    public function nav(){
+        $vars = SettingModel::getItem(SettingEnum::TABBAR);
+        return $this->renderSuccess('', compact('vars'));
+    }
+}

+ 32 - 0
app/api/controller/Settings.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace app\api\controller;
+
+use app\api\model\settings\Setting as SettingModel;
+use app\common\model\app\AppOpen as AppOpenModel;
+use app\common\model\settings\Region as RegionModel;
+
+/**
+ * 页面控制器
+ */
+class Settings extends Controller
+{
+
+    // app分享
+    public function appShare()
+    {
+        // 分享设置
+        $appshare = SettingModel::getItem('appshare');
+        // logo
+        $logo = AppOpenModel::detail()['logo'];
+        return $this->renderSuccess('', compact('appshare', 'logo'));
+    }
+
+    /**
+     * 获取省市区
+     */
+    public function getRegion(){
+        $regionData = RegionModel::getRegionForApi();
+        return $this->renderSuccess('', compact('regionData'));
+    }
+}

+ 37 - 0
app/api/controller/balance/Log.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace app\api\controller\balance;
+
+use app\api\controller\Controller;
+use app\api\model\settings\Setting as SettingModel;
+use app\api\model\user\BalanceLog as BalanceLogModel;
+
+/**
+ * 余额账单明细
+ */
+class Log extends Controller
+{
+    /**
+     * 余额首页
+     */
+    public function index(){
+        $user = $this->getUser();
+        $list = (new BalanceLogModel)->getTop10($user['user_id']);
+        // 余额
+        $balance = $user['balance'];
+        // 充值功能是否开启
+        $balance_setting = SettingModel::getItem('balance');
+        $balance_open = intval($balance_setting['is_open']);
+        return $this->renderSuccess('', compact('list', 'balance', 'balance_open'));
+    }
+    /**
+     * 余额账单明细列表
+     */
+    public function lists($type = 'all')
+    {
+        $user = $this->getUser();
+        $list = (new BalanceLogModel)->getList($user['user_id'], $type);
+        return $this->renderSuccess('', compact('list'));
+    }
+
+}

+ 57 - 0
app/api/controller/balance/Plan.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace app\api\controller\balance;
+
+use app\api\controller\Controller;
+use app\api\model\settings\Setting as SettingModel;
+use app\api\model\user\BalancePlan as BalancePlanModel;
+use app\api\model\user\BalanceOrder as BalanceOrderModel;
+use app\api\service\pay\PayService;
+use app\common\enum\order\OrderPayTypeEnum;
+use app\common\enum\order\OrderTypeEnum;
+
+/**
+ * 充值套餐
+ */
+class Plan extends Controller
+{
+    /**
+     * 余额首页
+     */
+    public function index()
+    {
+        $params = $this->request->param();
+        $user = $this->getUser();
+        $list = (new BalancePlanModel)->getList();
+        // 设置
+        $settings = SettingModel::getItem('balance');
+        // 是否开启支付宝支付
+        $show_alipay = PayService::isAlipayOpen($params['pay_source'], $user['app_id']);
+        return $this->renderSuccess('', compact('list', 'settings', 'show_alipay'));
+    }
+
+    /**
+     * 充值套餐
+     */
+    public function submit($plan_id, $user_money)
+    {
+        $params = $this->request->param();
+        // 用户信息
+        $user = $this->getUser();
+        // 生成等级订单
+        $model = new BalanceOrderModel();
+        $order_id = $model->createOrder($user, $plan_id, $user_money);
+        if (!$order_id) {
+            return $this->renderError($model->getError() ?: '购买失败');
+        }
+        // 在线支付
+        $payment = BalanceOrderModel::onOrderPayment($user, $model, OrderPayTypeEnum::WECHAT, $params['pay_source']);
+        // 返回结算信息
+        return $this->renderSuccess(['success' => '支付成功', 'error' => '订单未支付'], [
+            'order_id' => $order_id,   // 订单id
+            'pay_type' => OrderPayTypeEnum::WECHAT,  // 支付方式
+            'payment' => $payment,               // 微信支付参数
+            'order_type' => OrderTypeEnum::BALANCE, //订单类型
+        ]);
+    }
+}

+ 37 - 0
app/api/controller/coupon/Coupon.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace app\api\controller\coupon;
+
+use app\api\controller\Controller;
+use app\api\model\plus\coupon\Coupon as CouponModel;
+use app\api\model\product\Product as ProductModel;
+
+/**
+ * 优惠券中心
+ */
+class Coupon extends Controller
+{
+    /**
+     * 优惠券列表
+     */
+    public function lists()
+    {
+        $model = new CouponModel;
+        $list = $model->getWaitList($this->getUser(false));
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    public function detail($coupon_id){
+        $model = CouponModel::detail($coupon_id);
+        if($model['apply_range'] == 20){
+            $product_ids = explode(',', $model['product_ids']);
+            $model['product'] = (new ProductModel())->getListByIdsFromApi($product_ids);
+        }
+        $product_list = [];
+        if($model['apply_range'] == 30){
+            $category_ids = json_decode($model['category_ids'], true);
+            $product_list = (new ProductModel())->getListByCatIdsFromApi($category_ids);
+        }
+        return $this->renderSuccess('', compact('model', 'product_list'));
+    }
+}

+ 119 - 0
app/api/controller/file/Upload.php

@@ -0,0 +1,119 @@
+<?php
+
+namespace app\api\controller\file;
+
+use app\api\controller\Controller;
+use app\api\model\file\UploadFile as UploadFileModel;
+use app\api\model\settings\Setting as SettingModel;
+use app\common\library\storage\Driver as StorageDriver;
+
+/**
+ * 文件库管理
+ */
+class Upload extends Controller
+{
+    protected $config;
+    protected $user;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        // 存储配置信息
+        $this->config = SettingModel::getItem('storage');
+        // 验证用户
+        $this->user = $this->getUser();
+    }
+    /**
+     * 身份证照片
+     */
+    public function idcard()
+    {
+        $post = $this->postData();            
+        if (empty($post['order_no'])) {
+            return json(['code' => 0, 'msg' => '订单号为空']);
+        }
+        if (empty($post['set'])) {
+            return json(['code' => 0, 'msg' => '正反标识为空']);
+        }    
+        if (empty($_FILES)) {
+            return json(['code' => 0, 'msg' => '请选择上传图片']);
+        }     
+        $temp = explode(".",$_FILES['iFile']["name"]);
+        $extension = end($temp);       
+        $srt  = $post['set'] == 1?'A':'b';      
+        $imageName = $post['order_no'].'_'.$srt.'.'.$extension;  
+       
+        $tempPath  = root_path('public') .'idcard/'.date('Ymd');
+         !is_dir($tempPath) && mkdir($tempPath, 0755, true);
+        $imageSrc  =  $tempPath."/". $imageName;  //图片名字             
+        if (!move_uploaded_file($_FILES['iFile']["tmp_name"],$imageSrc)) {
+            return json(['code' => 0, 'msg' => '上传失败!']);
+        }
+        $src = base_url().'idcard/'.date('Ymd').'/'.$imageName;   
+        return json(['code' => 1, 'msg' => '上传成功', 'src' => $src]);                           
+    }
+    /**
+     * 图片上传接口
+     */
+    public function image()
+    {
+        // 实例化存储驱动
+        $StorageDriver = new StorageDriver($this->config);
+        // 图片信息
+        $fileInfo = request()->file('iFile');       
+        if(!$StorageDriver->validate('iFile', $fileInfo, 'image')){
+            return json(['code' => 0, 'msg' => $StorageDriver->getError()]);
+        }
+        // 设置上传文件的信息
+        $StorageDriver->setUploadFile('iFile');
+        // 上传图片
+        $saveName = $StorageDriver->upload();
+        if ($saveName == '') {
+            return json(['code' => 0, 'msg' => '图片上传失败' . $StorageDriver->getError()]);
+        }
+        $saveName = str_replace('\\', '/', $saveName);
+        // 图片上传路径
+        $fileName = $StorageDriver->getFileName();
+
+        // 添加文件库记录
+        $uploadFile = $this->addUploadFile($fileName, $fileInfo, 'image', $saveName);
+        $data = [
+            'file_id'   => $uploadFile['file_id'],
+            'file_path' => $uploadFile['file_path'],
+        ];
+        // 图片上传成功
+        return json(['code' => 1, 'msg' => '图片上传成功', 'data' => $data]);
+    }
+
+    /**
+     * 添加文件库上传记录
+     */
+    private function addUploadFile($fileName, $fileInfo, $fileType, $savename)
+    {
+        // 存储引擎
+        $storage = $this->config['default'];
+        // 存储域名
+        $fileUrl = isset($this->config['engine'][$storage]['domain'])
+            ? $this->config['engine'][$storage]['domain'] : '';
+        // 添加文件库记录
+        $model = new UploadFileModel;
+        $data = $this->postData();
+        $model->add([
+            'storage' => $storage,
+            'file_url' => $fileUrl,
+            'file_name' => $fileName,
+            'save_name' => $savename,
+            'file_size' => $fileInfo->getSize(),
+            'file_type' => $fileType,
+            'extension' => $fileInfo->getOriginalExtension(),
+            'real_name' => $fileInfo->getOriginalName(),
+            'is_user' => 1,
+            'app_id' => $data['app_id']
+        ]);
+        return $model;
+    }
+
+}

+ 91 - 0
app/api/controller/order/Cart.php

@@ -0,0 +1,91 @@
+<?php
+
+namespace app\api\controller\order;
+
+use app\api\controller\Controller;
+use app\api\model\order\Cart as CartModel;
+use app\api\model\product\Product as ProductModel;
+
+/**
+ * 购物车控制器
+ */
+class Cart extends Controller
+{
+    private $user;
+
+    // $model
+    private $model;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        $this->user = $this->getUser();
+        $this->model = new CartModel($this->user);
+    }
+
+
+    /**
+     * 购物车列表
+     */
+    public function lists()
+    {
+        // 请求参数
+        $param = $this->request->param();
+        $cartIds = isset($param['cart_ids']) ? $param['cart_ids'] : '';
+        // 购物车商品列表
+        $productList = $this->model->getList($cartIds);
+        // 会员价
+        $product_model = new ProductModel();
+        foreach ($productList as $product){
+            $product_model->setProductGradeMoney($this->user, $product);
+        }
+        return $this->renderSuccess('', $productList);
+    }
+
+    /**
+     * 加入购物车
+     * @param int $product_id 商品id
+     * @param int $product_num 商品数量
+     * @param string $product_sku_id 商品sku索引
+     */
+    public function add()
+    {
+        $data = $this->request->param();
+        $product_id = $data['product_id'];
+        $product_num = $data['total_num'];
+        $product_sku_id = $data['product_sku_id'];
+        $model = $this->model;
+        if (!$model->add($product_id, $product_num, $product_sku_id)) {
+            return $this->renderError($model->getError() ?: '加入购物车失败');
+        }
+        // 购物车商品总数量
+        $totalNum = $model->getProductNum();
+        return $this->renderSuccess('加入购物车成功', ['cart_total_num' => $totalNum]);
+    }
+
+    /**
+     * 减少购物车商品数量
+     * @param $product_id
+     * @param $product_sku_id
+     * @return array
+     */
+    public function sub($product_id, $product_sku_id)
+    {
+        $this->model->sub($product_id, $product_sku_id);
+        return $this->renderSuccess('');
+    }
+
+    /**
+     * 删除购物车中指定商品
+     * @param $product_sku_id (支持字符串ID集)
+     * @return array
+     */
+    public function delete($product_sku_id)
+    {
+        $this->model->delete($product_sku_id);
+        return $this->renderSuccess('删除成功');
+    }
+}

+ 129 - 0
app/api/controller/order/Order.php

@@ -0,0 +1,129 @@
+<?php
+
+namespace app\api\controller\order;
+
+use app\api\model\order\Cart as CartModel;
+use app\api\model\order\Order as OrderModel;
+use app\api\service\order\settled\MasterOrderSettledService;
+use app\api\controller\Controller;
+use app\api\model\settings\Message as MessageModel;
+use app\api\service\pay\PayService;
+use app\common\enum\order\OrderTypeEnum;
+
+/**
+ * 普通订单
+ */
+class Order extends Controller
+{
+    /**
+     * 订单确认-立即购买
+     */
+    public function buy()
+    {
+        // 立即购买:获取订单商品列表
+        $params = $this->request->param();
+        // $params = array(
+        //     'delivery' =>0,
+        //     'store_id' =>'undefined',
+        //     'coupon_id' => 6,
+        //     'is_use_points' =>1,
+        //     'phone'=>null,
+        //     'linkman' =>null,
+        //     'remark' =>'',
+        //     'pay_type' => 10,
+        //     'pay_source'  =>'h5',
+        //     'product_id'  => 33,            
+        //     'product_num' => 2,
+        //     'product_sku_id' => 2,
+        // );  
+        // p($params);
+        $productList = OrderModel::getOrderProductListByNow($params);       
+        $user = $this->getUser();
+        // 实例化订单service
+        $orderService = new MasterOrderSettledService($user, $productList, $params);
+        // 获取订单信息
+        $orderInfo = $orderService->settlement();  
+         // p($orderInfo);         
+        if ($this->request->isGet()) {
+            // 如果来源是小程序, 则获取小程序订阅消息id.获取支付成功,发货通知.
+            $template_arr = MessageModel::getMessageByNameArr($params['pay_source'], ['order_pay_user', 'order_delivery_user']);
+            // 是否开启支付宝支付
+            $show_alipay = PayService::isAlipayOpen($params['pay_source'], $user['app_id']);
+            // 用户余额
+            $balance = $user['balance'];
+            return $this->renderSuccess('', compact('orderInfo', 'template_arr', 'show_alipay', 'balance'));
+        }
+        // 订单结算提交
+        if ($orderService->hasError()) {
+            return $this->renderError($orderService->getError());
+        }
+        // 创建订单
+        $order_id = $orderService->createOrder($orderInfo);
+        if(!$order_id){
+            return $this->renderError($orderService->getError() ?: '订单创建失败');
+        }
+        // 构建支付请求
+        $payment = OrderModel::onOrderPayment($user, $orderService->model, $params['pay_type'], $params['pay_source']);
+        log_write(json_encode($payment));
+        // 记录发起支付
+        log_write(sprintf('build order buy request. [buy] order_no[%s]', $order_id));
+        // 返回结算信息
+        return $this->renderSuccess(['success' => '支付成功', 'error' => '订单未支付'], [
+            'order_id' => $order_id,   // 订单id
+            'pay_type' => $params['pay_type'],  // 支付方式
+            'payment' => $payment,               // 微信支付参数
+            'order_type' => OrderTypeEnum::MASTER, //订单类型
+        ]);
+    }
+
+    /**
+     * 订单确认-立即购买
+     */
+    public function cart()
+    {
+        // 立即购买:获取订单商品列表
+        $params = $this->request->param();  
+            
+        $user = $this->getUser();
+        // 商品结算信息
+        $CartModel = new CartModel($user);
+        // 购物车商品列表
+        $productList = $CartModel->getList($params['cart_ids']);
+        // p($productList);
+        // 实例化订单service
+        $orderService = new MasterOrderSettledService($user, $productList, $params);
+        // 获取订单信息
+        $orderInfo = $orderService->settlement();       
+        if ($this->request->isGet()) {
+            // 如果来源是小程序, 则获取小程序订阅消息id.获取支付成功,发货通知.
+            $template_arr = MessageModel::getMessageByNameArr($params['pay_source'], ['order_pay_user', 'order_delivery_user']);
+            // 是否开启支付宝支付
+            $show_alipay = PayService::isAlipayOpen($params['pay_source'], $user['app_id']);
+            // 用户余额
+            $balance = $user['balance'];
+            return $this->renderSuccess('', compact('orderInfo', 'template_arr', 'show_alipay', 'balance'));
+        }
+        // 订单结算提交
+        if ($orderService->hasError()) {
+            return $this->renderError($orderService->getError());
+        }
+        // 创建订单
+        $order_id = $orderService->createOrder($orderInfo);
+        if(!$order_id){
+            return $this->renderError($orderService->getError() ?: '订单创建失败');
+        }
+        // 移出购物车中已下单的商品
+        $CartModel->clearAll($params['cart_ids']);
+        // 构建支付请求
+        $payment = OrderModel::onOrderPayment($user, $orderService->model, $params['pay_type'], $params['pay_source']);
+        // 记录发起支付
+        log_write(sprintf('build order buy request. order_no[%s]', $order_id));
+        // 返回结算信息
+        return $this->renderSuccess('', [
+            'order_id' => $orderService->model['order_id'],   // 订单id
+            'pay_type' => $params['pay_type'],  // 支付方式
+            'payment' => $payment,               // 微信支付参数
+            'order_type' => OrderTypeEnum::MASTER, //订单类型
+        ]);
+    }
+}

+ 53 - 0
app/api/controller/plus/agent/Apply.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace app\api\controller\plus\agent;
+
+use app\api\controller\Controller;
+use app\api\model\plus\agent\Apply as AgentApplyModel;
+use  app\common\model\plus\agent\Setting;
+use app\common\exception\BaseException;
+
+/**
+ * 分销商申请
+ */
+class Apply extends Controller
+{
+    // 当前用户
+    private $user;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        $this->user = $this->getUser();   // 用户信息
+    }
+
+    /**
+     * 提交分销商申请
+     */
+    public function submit()
+    {
+        $data = $this->postData();
+        if (empty($data['name']) || empty($data['mobile'])) {
+            throw new BaseException(['msg' => '用户名或者手机号为空']);
+        }
+        $model = new AgentApplyModel;
+        if ($model->submit($this->user, $data)) {
+            return $this->renderSuccess('成功');
+        }
+        return $this->renderError($model->getError() ?: '提交失败');
+    }
+
+    /*
+     *获取分销商协议
+     */
+    public function getAgreement()
+    {
+        $model = new Setting();
+        $data = $model->getItem('license');
+        return $this->renderSuccess('', compact('data'));
+    }
+
+}

+ 63 - 0
app/api/controller/plus/agent/Cash.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace app\api\controller\plus\agent;
+
+use app\api\controller\Controller;
+use app\api\model\plus\agent\Setting;
+use app\api\model\plus\agent\User as AgentUserModel;
+use app\api\model\plus\agent\Cash as CashModel;
+
+/**
+ * 分销商提现
+ */
+class Cash extends Controller
+{
+    private $user;
+
+    private $Agent;
+    private $setting;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        // 用户信息
+        $this->user = $this->getUser();
+        // 分销商用户信息
+        $this->Agent = AgentUserModel::detail($this->user['user_id']);
+        // 分销商设置
+        $this->setting = Setting::getAll();
+    }
+
+    /**
+     * 提交提现申请
+     */
+    public function submit($data)
+    {
+        $formData = json_decode(htmlspecialchars_decode($data), true);
+
+        $model = new CashModel;
+        if ($model->submit($this->Agent, $formData)) {
+            return $this->renderSuccess('申请提现成功');
+        }
+        return $this->renderError($model->getError() ?: '提交失败');
+    }
+
+    /**
+     * 分销商提现明细
+     */
+    public function lists($status = -1)
+    {
+
+        $model = new CashModel;
+        return $this->renderSuccess('', [
+            // 提现明细列表
+            'list' => $model->getList($this->user['user_id'], (int)$status,$this->postData()),
+            // 页面文字
+            'words' => $this->setting['words']['values'],
+        ]);
+    }
+
+}

+ 50 - 0
app/api/controller/plus/agent/Order.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace app\api\controller\plus\agent;
+
+use app\api\controller\Controller;
+use app\api\model\plus\agent\Setting;
+use app\api\model\plus\agent\User as AgentUserModel;
+use app\api\model\plus\agent\Order as OrderModel;
+
+/**
+ * 分销商订单
+ */
+class Order extends Controller
+{
+    // 当前用户
+    protected $user;
+    // 分销商用户信息
+    protected $Agent;
+    // 分销商设置
+    protected $setting;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        // 用户信息
+        $this->user = $this->getUser();
+        // 分销商用户信息
+        $this->Agent = AgentUserModel::detail($this->user['user_id']);
+        // 分销商设置
+        $this->setting = Setting::getAll();
+    }
+
+    /**
+     * 分销商订单列表
+     */
+    public function lists($settled = -1)
+    {
+        $model = new OrderModel;
+        return $this->renderSuccess('', [
+            // 提现明细列表
+            'list' => $model->getList($this->user['user_id'], (int)$settled),
+            // 页面文字
+            'words' => $this->setting['words']['values'],
+        ]);
+    }
+
+}

+ 48 - 0
app/api/controller/plus/agent/Qrcode.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace app\api\controller\plus\agent;
+
+use app\api\controller\Controller;
+use app\api\model\plus\agent\Setting;
+use app\api\model\plus\agent\User as AgentUserModel;
+use app\common\service\qrcode\PosterService;
+
+/**
+ * 推广二维码
+ */
+class Qrcode extends Controller
+{
+    // 当前用户
+    protected $user;
+    // 分销商
+    protected $agent;
+    // 分销设置
+    protected $setting;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        // 用户信息
+        $this->user = $this->getUser();
+        // 分销商用户信息
+        $this->agent = AgentUserModel::detail($this->user['user_id']);
+        // 分销商设置
+        $this->setting = Setting::getAll();
+    }
+
+    /**
+     * 获取推广二维码
+     */
+    public function poster($source)
+    {
+        $Qrcode = new PosterService($this->agent, $source);
+        return $this->renderSuccess('', [
+            // 二维码图片地址
+            'qrcode' => $Qrcode->getImage(),
+        ]);
+    }
+
+}

+ 54 - 0
app/api/controller/plus/agent/Team.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace app\api\controller\plus\agent;
+
+use app\api\controller\Controller;
+use app\api\model\plus\agent\Setting;
+use app\api\model\plus\agent\User as AgentUserModel;
+use app\api\model\plus\agent\Referee as RefereeModel;
+
+/**
+ * 我的团队
+ */
+class Team extends Controller
+{
+    // 用户信息
+    private $user;
+    // 分销商用户信息
+    private $Agent;
+    // 分销商设置
+    private $setting;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        // 用户信息
+        $this->user = $this->getUser();
+        // 分销商用户信息
+        $this->Agent = AgentUserModel::detail($this->user['user_id']);
+        // 分销商设置
+        $this->setting = Setting::getAll();
+    }
+
+    /**
+     * 我的团队列表
+     */
+    public function lists($level = -1)
+    {
+        $model = new RefereeModel;
+        return $this->renderSuccess('', [
+            // 分销商用户信息
+            'agent' => $this->Agent,
+            // 我的团队列表
+            'list' => $model->getList($this->user['user_id'], (int)$level),
+            // 基础设置
+            'setting' => $this->setting['basic']['values'],
+            // 页面文字
+            'words' => $this->setting['words']['values'],
+        ]);
+    }
+
+}

+ 43 - 0
app/api/controller/plus/article/Article.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace app\api\controller\plus\article;
+
+use app\api\controller\Controller;
+use app\api\model\plus\article\Article as ArticleModel;
+use app\api\model\plus\article\Category as CategoryModel;
+
+/**
+ * 文章控制器
+ */
+class Article extends Controller
+{
+    /**
+     *获取分类
+     */
+    public function category()
+    {
+        // 文章分类
+        $category = CategoryModel::getAll();
+        return $this->renderSuccess('', compact('category'));
+    }
+
+    /**
+     * 文章列表
+     */
+    public function index($category_id = 0)
+    {
+        $model = new ArticleModel;
+        $list = $model->getList($category_id, $this->postData());
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     *文章详情
+     */
+    public function detail($article_id)
+    {
+        $detail = ArticleModel::detail($article_id);
+        return $this->renderSuccess('', compact('detail'));
+    }
+
+}

+ 25 - 0
app/api/controller/plus/assemble/Bill.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace app\api\controller\plus\assemble;
+
+use app\api\controller\Controller;
+use app\api\model\plus\assemble\Bill as BillModel;
+use app\api\model\plus\assemble\Product as ProductModel;
+/**
+ * 参团详情控制器
+ */
+class Bill extends Controller
+{
+    /**
+     * 拼团商品详情
+     */
+    public function detail($assemble_bill_id, $url = '')
+    {
+        $bill = BillModel::detail($assemble_bill_id, ['activity', 'user', 'billUser.user']);
+        $product = ProductModel::detail($bill['assemble_product_id'], ['product' => ['sku', 'image.file'], 'assembleSku']);
+        // 微信公众号分享参数
+        $dif_people = $product['assemble_num'] - $bill['actual_people'];
+        $share = $this->getShareParams($url, "【仅限{$dif_people}个名额】,快来参与拼团吧", $product['product']['product_name'], '/pages/plus/assemble/fight-group-detail/fight-group-detail', $product['product']['image'][0]['file_path']);
+        return $this->renderSuccess('', compact( 'bill', 'product', 'share'));
+    }
+}

+ 61 - 0
app/api/controller/plus/assemble/Order.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace app\api\controller\plus\assemble;
+
+use app\api\model\plus\assemble\Product as ProductModel;
+use app\api\service\order\settled\AssemblelOrderSettledService;
+use app\api\controller\Controller;
+use app\api\model\settings\Message as MessageModel;
+use app\api\model\order\Order as OrderModel;
+use app\common\enum\order\OrderTypeEnum;
+use app\common\enum\settings\SettingEnum;
+use app\common\model\settings\Setting;
+
+/**
+ * 限时拼团订单
+ */
+class Order extends Controller
+{
+    /**
+     * 订单确认
+     */
+    public function buy()
+    {
+        // 限时拼团订单:获取订单商品列表
+        $params = $this->request->param();
+        $productList = ProductModel::getAssembleProduct($params);
+
+        $user = $this->getUser();
+        // 实例化订单service
+        $orderService = new AssemblelOrderSettledService($user, $productList, $params);
+        // 获取订单信息
+        $orderInfo = $orderService->settlement();
+        if ($this->request->isGet()) {
+            // 如果来源是小程序, 则获取小程序订阅消息id.获取支付成功,发货通知.
+            $template_arr = MessageModel::getMessageByNameArr($params['pay_source'], ['order_pay_user', 'order_delivery_user']);
+            // 是否开启h5支付宝支付
+            $h5_alipay = Setting::getItem(SettingEnum::H5ALIPAY)['is_open'];
+            // 用户余额
+            $balance = $user['balance'];
+            return $this->renderSuccess('', compact('orderInfo', 'template_arr', 'h5_alipay', 'balance'));
+        }
+        // 订单结算提交
+        if ($orderService->hasError()) {
+            return $this->renderError($orderService->getError());
+        }
+        // 创建订单
+        $order_id = $orderService->createOrder($orderInfo);
+        if (!$order_id) {
+            return $this->renderError($orderService->getError() ?: '订单创建失败');
+        }
+        // 构建支付请求
+        $payment = OrderModel::onOrderPayment($user, $orderService->model, $params['pay_type'], $params['pay_source']);
+        // 返回结算信息
+        return $this->renderSuccess(['success' => '支付成功', 'error' => '订单未支付'], [
+            'order_id' => $order_id,   // 订单id
+            'pay_type' => $params['pay_type'],  // 支付方式
+            'payment' => $payment,               // 微信支付参数
+            'order_type' => OrderTypeEnum::MASTER, //订单类型
+        ]);
+    }
+}

+ 58 - 0
app/api/controller/plus/assemble/Product.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace app\api\controller\plus\assemble;
+
+use app\api\controller\Controller;
+use app\api\model\plus\assemble\Product as ProductModel;
+use app\api\model\plus\assemble\Active as ActiveModel;
+use app\common\service\product\BaseProductService;
+use app\api\model\plus\assemble\Bill as BillModel;
+/**
+ * 拼团控制器
+ */
+class Product extends Controller
+{
+    /**
+     * 拼团活动
+     */
+    public function active()
+    {
+        $model = new ActiveModel();
+        $list = $model->activityList();
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     * 拼团商品
+     */
+    public function product($assemble_activity_id)
+    {
+        $detail = ActiveModel::detailWithTrans($assemble_activity_id);
+        $detail['start_time'] =strtotime($detail['start_time']);
+        $detail['end_time'] =strtotime($detail['end_time']);
+        $list = (new ProductModel())->getActivityList($assemble_activity_id);
+        return $this->renderSuccess('', compact('detail','list'));
+    }
+
+    /**
+     * 拼团商品详情
+     */
+    public function detail($assemble_product_id, $url = '')
+    {
+        $model = new ProductModel();
+        //详情
+        $detail = $model->getAssembleDetail($assemble_product_id);
+        //活动
+        $active = ActiveModel::detailWithTrans($detail['assemble_activity_id']);
+        $active['start_time'] =strtotime($active['start_time']);
+        $active['end_time'] =strtotime($active['end_time']);
+        //规格
+        $specData = BaseProductService::getSpecData($detail['product']);
+        //拼团订单
+        $model = new BillModel();
+        $bill = $model->getBill($detail['assemble_product_id'], $detail['assemble_activity_id'], $detail['assemble_num']);
+        // 微信公众号分享参数
+        $share = $this->getShareParams($url, $detail['product']['product_name'], $detail['product']['product_name'], '/pages/plus/assemble/detail/detail', $detail['product']['image'][0]['file_path']);
+        return $this->renderSuccess('', compact('detail', 'active', 'specData', 'bill', 'share'));
+    }
+}

+ 64 - 0
app/api/controller/plus/bargain/Order.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace app\api\controller\plus\bargain;
+
+use app\api\model\plus\bargain\Product as ProductModel;
+use app\api\service\order\settled\BargainOrderSettledService;
+use app\api\controller\Controller;
+use app\api\model\settings\Message as MessageModel;
+use app\api\model\order\Order as OrderModel;
+use app\common\enum\order\OrderTypeEnum;
+use app\common\enum\settings\SettingEnum;
+use app\common\model\settings\Setting;
+
+/**
+ * 限时砍价订单
+ */
+class Order extends Controller
+{
+    /**
+     * 订单确认
+     */
+    public function buy()
+    {
+        // 积分商城兑换订单:获取订单商品列表
+        $params = $this->request->param();
+        $productList = ProductModel::getBargainProduct($params);
+
+        $user = $this->getUser();
+        // 实例化订单service
+        $orderService = new BargainOrderSettledService($user, $productList, $params);
+        // 获取订单信息
+        $orderInfo = $orderService->settlement();
+        // 订单结算提交
+        if ($orderService->hasError()) {
+            return $this->renderError($orderService->getError());
+        }
+
+        if ($this->request->isGet()) {
+            // 如果来源是小程序, 则获取小程序订阅消息id.获取支付成功,发货通知.
+            $template_arr = MessageModel::getMessageByNameArr($params['pay_source'], ['order_pay_user', 'order_delivery_user']);
+            // 是否开启h5支付宝支付
+            $h5_alipay = Setting::getItem(SettingEnum::H5ALIPAY)['is_open'];
+            // 用户余额
+            $balance = $user['balance'];
+            return $this->renderSuccess('', compact('orderInfo', 'template_arr', 'h5_alipay', 'balance'));
+        }
+
+        // 创建订单
+        $order_id = $orderService->createOrder($orderInfo);
+        if (!$order_id) {
+            return $this->renderError($orderService->getError() ?: '订单创建失败');
+        }
+        // 构建支付请求
+        $payment = OrderModel::onOrderPayment($user, $orderService->model, $params['pay_type'], $params['pay_source']);
+
+        // 返回结算信息
+        return $this->renderSuccess(['success' => '支付成功', 'error' => '订单未支付'], [
+            'order_id' => $order_id,   // 订单id
+            'pay_type' => $params['pay_type'],  // 支付方式
+            'payment' => $payment,               // 微信支付参数
+            'order_type' => OrderTypeEnum::MASTER, //订单类型
+        ]);
+    }
+}

+ 57 - 0
app/api/controller/plus/bargain/Product.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace app\api\controller\plus\bargain;
+
+use app\api\controller\Controller;
+use app\api\model\settings\Setting as SettingModel;
+use app\common\service\product\BaseProductService;
+use app\api\model\plus\bargain\Active as ActiveModel;
+use app\api\model\plus\bargain\Product as ProductModel;
+/**
+ * 砍价商品控制器
+ */
+class Product extends Controller
+{
+    /**
+     * 砍价活动
+     */
+    public function active()
+    {
+        $model = new ActiveModel();
+        $list = $model->activityList();
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     * 砍价商品
+     */
+    public function product($bargain_activity_id)
+    {
+        $detail = ActiveModel::detailWithTrans($bargain_activity_id);
+        $detail['start_time'] =strtotime($detail['start_time']);
+        $detail['end_time'] =strtotime($detail['end_time']);
+        $list = (new ProductModel())->getActivityList($bargain_activity_id);
+        return $this->renderSuccess('', compact('detail','list'));
+    }
+
+    /**
+     * 砍价商品详情
+     */
+    public function detail($bargain_product_id, $url = '')
+    {
+        $model = new ProductModel();
+        //详情
+        $detail = $model->getBargainDetail($bargain_product_id);
+        //活动
+        $active = ActiveModel::detailWithTrans($detail['bargain_activity_id']);
+        $active['start_time'] =strtotime($active['start_time']);
+        $active['end_time'] =strtotime($active['end_time']);
+        //规格
+        $specData = BaseProductService::getSpecData($detail['product']);
+        // 砍价规则
+        $setting = SettingModel::getBargain();
+        // 微信公众号分享参数
+        $share = $this->getShareParams($url, $detail['product']['product_name'], $detail['product']['product_name'], '/pages/plus/assemble/detail/detail', $detail['product']['image'][0]['file_path']);
+        return $this->renderSuccess('', compact('detail', 'active', 'specData', 'setting', 'share'));
+    }
+}

+ 58 - 0
app/api/controller/plus/bargain/Task.php

@@ -0,0 +1,58 @@
+<?php
+
+namespace app\api\controller\plus\bargain;
+
+use app\api\controller\Controller;
+use app\api\model\plus\bargain\Task as TaskModel;
+
+/**
+ * 砍价任务模型
+ */
+class Task extends Controller
+{
+    /**
+     * 创建砍价任务
+     */
+    public function add($bargain_activity_id, $bargain_product_id, $bargain_product_sku_id, $product_sku_id)
+    {
+        // 用户信息
+        $user = $this->getUser();
+        // 创建砍价任务
+        $model = new TaskModel;
+        if (!$model->add($user['user_id'], $bargain_activity_id, $bargain_product_id, $bargain_product_sku_id, $product_sku_id)) {
+            return $this->renderError($model->getError() ?: '砍价任务创建失败');
+        }
+        return $this->renderSuccess('', [
+            'bargain_task_id' => $model['bargain_task_id']
+        ]);
+    }
+
+    /**
+     * 获取砍价任务详情
+     */
+    public function detail($bargain_task_id, $url = '')
+    {
+        $detail = (new TaskModel)->getTaskDetail($bargain_task_id, $this->getUser(false));
+        //分享
+        $share = $this->getShareParams($url, "发现了一个好物,快来帮我砍一刀吧", $detail['task']['product_name'], '/pages/plus/bargain/haggle/haggle', $detail['product']['product']['image'][0]['file_path']);
+        return $this->renderSuccess('', array_merge($detail, compact('share')));
+    }
+
+    /**
+     * 帮砍一刀
+     */
+    public function cut($bargain_task_id)
+    {
+        // 砍价任务详情
+        $model = TaskModel::detail($bargain_task_id);
+        // 砍一刀的金额
+        $cut_money = $model->getCutMoney();
+        // 帮砍一刀事件
+        $status = $model->helpCut($this->getUser());
+        if ($status == true) {
+            return $this->renderSuccess('砍价成功', compact('cut_money'));
+        }
+        return $this->renderError($model->getError() ?: '砍价失败');
+    }
+
+}

+ 36 - 0
app/api/controller/plus/invitationgift/Invitation.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace app\api\controller\plus\invitationgift;
+
+
+use app\api\controller\Controller;
+use app\api\model\plus\invitationgift\InvitationGift as InvitationGiftModel;
+
+/**
+ * 邀请有礼控制器
+ */
+class Invitation extends Controller
+{
+    private $user;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        $this->user = $this->getUser();   // 用户信息
+    }
+
+    /**
+     * 获取数据
+     */
+    public function getDatas($invitation_gift_id, $url = '')
+    {
+        $model = new InvitationGiftModel();
+        $data = $model->getDatas($invitation_gift_id, $this->user['user_id']);
+        // 微信公众号分享参数
+        $share = $this->getShareParams($url, $data['share_title'], $data['share_desc'], '/pages/index/index', $data['share']['file_path']);
+        return $this->renderSuccess('', compact('data', 'share'));
+    }
+}

+ 23 - 0
app/api/controller/plus/live/Wx.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace app\api\controller\plus\live;
+
+use app\api\controller\Controller;
+use app\api\model\plus\live\WxLive as WxLiveModel;
+
+/**
+ * 微信直播控制器
+ */
+class Wx extends Controller
+{
+    /**
+     * 微信直播列表
+     */
+    public function lists()
+    {
+        $model = new WxLiveModel();
+        $list = $model->getList($this->postData());
+        return $this->renderSuccess('', compact('list'));
+    }
+
+}

+ 56 - 0
app/api/controller/plus/lottery/Lottery.php

@@ -0,0 +1,56 @@
+<?php
+
+namespace app\api\controller\plus\lottery;
+
+use app\api\controller\Controller;
+use app\api\model\plus\lottery\Lottery as LotteryModel;
+use app\api\model\plus\lottery\Record as RecordModel;
+use app\shop\model\plus\lottery\LotteryPrize as LotteryPrizeModel;
+
+/**
+ * 转盘控制器
+ */
+class Lottery extends Controller
+{
+    /**
+     * 获取数据
+     * @param null $id
+     */
+    public function getLottery()
+    {
+        $model = new LotteryModel();
+        $data = $model->getDetail();
+        $data['prize'] = $data ? LotteryPrizeModel::detail($data['lottery_id']) : [];
+        //剩余抽奖次数
+        $num = $model->getNum($this->getUser());
+        $nums = $data['times'] - $num;
+        //抽奖播放数据
+        $recordModel = new RecordModel();
+        $recordList = $recordModel->getLimitList(60);
+        $data['user_points'] = $this->getUser()['points'];
+        return $this->renderSuccess('', compact('data', 'nums', 'recordList'));
+    }
+
+    /*
+     * 转盘记录列表
+     */
+    public function record()
+    {
+        $model = new RecordModel();
+        $list = $model->getList($this->postData(), $this->getUser());
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /*
+     * 开始抽奖
+     */
+    public function draw()
+    {
+        $model = new LotteryModel();
+        $result = $model->getdraw($this->getUser());
+        if ($result) {
+            return $this->renderSuccess('', compact('result'));
+        }
+        return $this->renderError($model->getError() ?: '抽奖失败');
+    }
+}

+ 43 - 0
app/api/controller/plus/lottery/Order.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace app\api\controller\plus\lottery;
+
+use app\api\controller\Controller;
+use app\api\model\plus\lottery\Order as OrderModel;
+use app\api\model\product\Product as ProductModel;
+use app\api\model\plus\lottery\Record as RecordModel;
+
+/**
+ *
+ * 转盘商品订单控制器
+ *
+ */
+class Order extends Controller
+{
+    /**
+     * 记录详情
+     */
+    public function buy($record_id)
+    {
+        $detail = RecordModel::detail($record_id);
+        $params = $this->request->param();
+        $user = $this->getUser();
+        $model = new OrderModel();
+        if ($this->request->isGet()) {
+            if ($detail['prize_type'] != 3) {
+                return $this->renderError('礼品类型错误');
+            }
+            if ($detail['status'] == 1) {
+                return $this->renderError('礼品已兑换');
+            }
+            $data = $model->getOrderData($params, $user);
+            $data['product'] = (new ProductModel)->getProduct([$detail['award_id']]);
+            return $this->renderSuccess('', compact('data'));
+        }
+        if ($model->addOrder($params, $this->getUser())) {
+            return $this->renderSuccess('兑换成功');
+        }
+        return $this->renderError($model->getError() ?: '兑换失败');
+
+    }
+}

+ 36 - 0
app/api/controller/plus/package/Order.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace app\api\controller\plus\package;
+
+use app\api\controller\Controller;
+use app\api\model\plus\giftpackage\Order as OrderModel;
+
+/**
+ *
+ * 礼包购订单控制器
+ *
+ */
+class Order extends Controller
+{
+    /**
+     * 购买记录
+     */
+    public function orderlist()
+    {   
+        // 用户信息
+        $user = $this->getUser();
+        $data = $this->postData();
+        $model = new OrderModel();
+        $list = $model->getList($user,$data);
+        return $this->renderSuccess('', compact('list'));
+    }
+    /**
+     * 记录详情
+     */
+    public function orderdetail($order_no)
+    {   
+        $model = new OrderModel();
+        $detail = $model->orderDetail($order_no);
+        return $this->renderSuccess('', compact('detail'));
+    }
+}

+ 68 - 0
app/api/controller/plus/package/Package.php

@@ -0,0 +1,68 @@
+<?php
+
+namespace app\api\controller\plus\package;
+
+
+use app\api\controller\Controller;
+use app\api\model\plus\giftpackage\GiftPackage as GiftPackageModel;
+use app\api\model\plus\giftpackage\Order as OrderModel;
+use app\api\service\pay\PayService;
+use app\common\enum\order\OrderTypeEnum;
+
+/**
+ * 礼包购控制器
+ */
+class Package extends Controller
+{
+    /**
+     * 获取数据
+     */
+    public function index($package_id)
+    {   
+        // 用户信息
+        $user = $this->getUser(false);
+        $params = $this->request->param();
+        $model = new GiftPackageModel();
+        $data = $model->getGiftPackage($package_id,$params,$user);
+        if (!$data) {
+            return $this->renderError($model->getError() ?: '活动不存在');
+        }
+        return $this->renderSuccess('', compact('data'));
+    }
+
+    /**
+     * 礼包购
+     */
+    public function buy($package_id)
+    {
+        // 用户信息
+        $user = $this->getUser();
+        $params = $this->request->param();
+        if($this->request->isGet()){
+            $model = new GiftPackageModel();
+            $data = $model->checkGiftPackage($package_id,$params,$user);
+            // 是否开启支付宝支付
+            $show_alipay = PayService::isAlipayOpen($params['pay_source'], $user['app_id']);
+            if($data){
+               return $this->renderSuccess('', compact('data', 'show_alipay'));
+           }else{
+                return $this->renderError($model->getError() ?: '购买失败');
+           }
+        }
+        // 生成礼品订单
+        $model = new OrderModel;
+        // 创建订单
+        if (!$model->createOrder($user, $package_id, $params)) {
+            return $this->renderError($model->getError() ?: '订单创建失败');
+        }
+        // 构建支付请求
+        $payment = OrderModel::onOrderPayment($user, $model, $params['pay_type'], $params['pay_source']);
+        // 返回结算信息
+        return $this->renderSuccess(['success' => '支付成功', 'error' => '订单未支付'], [
+            'order_id' => $model['order_id'],   // 订单id
+            'pay_type' => $params['pay_type'],  // 支付方式,仅支持微信
+            'payment' => $payment,               // 微信支付参数
+            'order_type' => OrderTypeEnum::GIFT, //订单类型
+        ]);
+    }
+}

+ 61 - 0
app/api/controller/plus/points/Order.php

@@ -0,0 +1,61 @@
+<?php
+
+namespace app\api\controller\plus\points;
+
+use app\api\model\plus\points\Product as ProductModel;
+use app\api\service\order\settled\PointsOrderSettledService;
+use app\api\controller\Controller;
+use app\api\model\settings\Message as MessageModel;
+use app\api\model\order\Order as OrderModel;
+use app\common\enum\order\OrderTypeEnum;
+use app\common\enum\settings\SettingEnum;
+use app\common\model\settings\Setting;
+
+/**
+ * 积分商城兑换订单
+ */
+class Order extends Controller
+{
+    /**
+     * 订单确认
+     */
+    public function buy()
+    {
+        // 积分商城兑换订单:获取订单商品列表
+        $params = $this->request->param();
+        $productList = ProductModel::getPointsProduct($params);
+        $user = $this->getUser();
+        // 实例化订单service
+        $orderService = new PointsOrderSettledService($user, $productList, $params);
+        // 获取订单信息
+        $orderInfo = $orderService->settlement();
+
+        if ($this->request->isGet()) {
+            // 如果来源是小程序, 则获取小程序订阅消息id.获取支付成功,发货通知.
+            $template_arr = MessageModel::getMessageByNameArr($params['pay_source'], ['order_pay_user', 'order_delivery_user']);
+            // 是否开启h5支付宝支付
+            $h5_alipay = Setting::getItem(SettingEnum::H5ALIPAY)['is_open'];
+            // 用户余额
+            $balance = $user['balance'];
+            return $this->renderSuccess('', compact('orderInfo', 'template_arr', 'h5_alipay', 'balance'));
+        }
+        // 订单结算提交
+        if ($orderService->hasError()) {
+            return $this->renderError($orderService->getError());
+        }
+        // 创建订单
+        $order_id = $orderService->createOrder($orderInfo);
+        if(!$order_id){
+            return $this->renderError($orderService->getError() ?: '订单创建失败');
+        }
+        // 构建支付请求
+        $payment = OrderModel::onOrderPayment($user, $orderService->model, $params['pay_type'], $params['pay_source']);
+        // 返回结算信息
+        return $this->renderSuccess(['success' => '支付成功', 'error' => '订单未支付'], [
+            'order_id' => $order_id,   // 订单id
+            'pay_type' => $params['pay_type'],  // 支付方式
+            'payment' => $payment,               // 微信支付参数
+            'order_type' => OrderTypeEnum::MASTER, //订单类型
+        ]);
+    }
+}

+ 37 - 0
app/api/controller/plus/points/Product.php

@@ -0,0 +1,37 @@
+<?php
+
+namespace app\api\controller\plus\points;
+
+use app\api\controller\Controller;
+use app\api\model\plus\points\Product as ProductModel;
+use app\common\service\product\BaseProductService;
+
+/**
+ * 积分商城控制器
+ */
+class Product extends Controller
+{
+    /**
+     *积分商品列表
+     */
+    public function index()
+    {
+        $model = new ProductModel();
+        $list = $model->getList($this->request->param());
+        $points = $this->getUser()['points'];
+        return $this->renderSuccess('', compact('list', 'points'));
+    }
+
+    /**
+     *积分商品列表
+     */
+    public function detail($point_product_id, $url = '')
+    {
+        $detail = (new ProductModel())->getPointDetail($point_product_id);
+        //规格
+        $specData = BaseProductService::getSpecData($detail['product']);
+        // 微信公众号分享参数
+        $share = $this->getShareParams($url, $detail['product']['product_name'], $detail['product']['product_name'], '/pages/plus/assemble/detail/detail', $detail['product']['image'][0]['file_path']);
+        return $this->renderSuccess('', compact('detail', 'specData', 'share'));
+    }
+}

+ 65 - 0
app/api/controller/plus/seckill/Order.php

@@ -0,0 +1,65 @@
+<?php
+
+namespace app\api\controller\plus\seckill;
+
+use app\api\model\plus\seckill\Product as ProductModel;
+use app\api\service\order\settled\SeckillOrderSettledService;
+use app\api\controller\Controller;
+use app\api\model\settings\Message as MessageModel;
+use app\api\model\order\Order as OrderModel;
+use app\common\enum\order\OrderTypeEnum;
+use app\common\enum\settings\SettingEnum;
+use app\common\model\settings\Setting;
+
+
+/**
+ * 限时秒杀订单
+ */
+class Order extends Controller
+{
+    /**
+     * 订单确认
+     */
+    public function buy()
+    {
+        // 限时秒杀订单:获取订单商品列表
+        $params = $this->request->param();
+        $productList = ProductModel::getSeckillProduct($params);
+
+        $user = $this->getUser();
+        // 实例化订单service
+        $orderService = new SeckillOrderSettledService($user, $productList, $params);
+        // 获取订单信息
+        $orderInfo = $orderService->settlement();
+        if ($this->request->isGet()) {
+            // 如果来源是小程序, 则获取小程序订阅消息id.获取支付成功,发货通知.
+            $template_arr = MessageModel::getMessageByNameArr($params['pay_source'], ['order_pay_user', 'order_delivery_user']);
+            // 是否开启h5支付宝支付
+            $h5_alipay = Setting::getItem(SettingEnum::H5ALIPAY)['is_open'];
+            // 用户余额
+            $balance = $user['balance'];
+            return $this->renderSuccess('', compact('orderInfo', 'template_arr', 'h5_alipay', 'balance'));
+        }
+
+        // 订单结算提交
+        if ($orderService->hasError()) {
+            return $this->renderError($orderService->getError());
+        }
+
+        // 创建订单
+        $order_id = $orderService->createOrder($orderInfo);
+        if (!$order_id) {
+            return $this->renderError($orderService->getError() ?: '订单创建失败');
+        }
+
+        // 构建支付请求
+        $payment = OrderModel::onOrderPayment($user, $orderService->model, $params['pay_type'], $params['pay_source']);
+        // 返回结算信息
+        return $this->renderSuccess(['success' => '支付成功', 'error' => '订单未支付'], [
+            'order_id' => $order_id,   // 订单id
+            'pay_type' => $params['pay_type'],  // 支付方式
+            'payment' => $payment,               // 微信支付参数
+            'order_type' => OrderTypeEnum::MASTER, //订单类型
+        ]);
+    }
+}

+ 47 - 0
app/api/controller/plus/seckill/Product.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace app\api\controller\plus\seckill;
+
+use app\api\controller\Controller;
+use app\api\model\plus\seckill\Product as ProductModel;
+use app\api\model\plus\seckill\Active as ActiveModel;
+use app\common\service\product\BaseProductService;
+
+/**
+ * 秒杀产品控制器
+ */
+class Product extends Controller
+{
+    /**
+     * 秒杀活动
+     */
+    public function active()
+    {
+        $model = new ActiveModel();
+        $list = $model->activityList();
+        return $this->renderSuccess('', compact('list'));
+    }
+    /**
+     * 秒杀商品
+     */
+    public function product($seckill_activity_id)
+    {
+        $detail = ActiveModel::detailWithTrans($seckill_activity_id);
+        $list = (new ProductModel())->getActivityList($seckill_activity_id);
+        return $this->renderSuccess('', compact('detail','list'));
+    }
+    /**
+     * 秒杀商品详情
+     */
+    public function detail($seckill_product_id, $url = '')
+    {
+        $model = new ProductModel();
+        $detail = $model->getSeckillDetail($seckill_product_id);
+        $active = ActiveModel::detailWithTrans($detail['seckill_activity_id']);
+        $specData = BaseProductService::getSpecData($detail['product']);
+        // 微信公众号分享参数
+        $share = $this->getShareParams($url, $detail['product']['product_name'], $detail['product']['product_name'], '/pages/plus/seckill/detail/detail', $detail['product']['image'][0]['file_path']);
+        return $this->renderSuccess('', compact('detail', 'active', 'specData', 'share'));
+    }
+
+}

+ 65 - 0
app/api/controller/plus/sign/Sign.php

@@ -0,0 +1,65 @@
+<?php
+
+namespace app\api\controller\plus\sign;
+
+use app\api\controller\Controller;
+use app\api\model\settings\Setting as SettingModel;
+use app\api\model\plus\sign\Sign as SignModel;
+
+/**
+ * 用户签到控制器
+ */
+class Sign extends Controller
+{
+    /**
+     * 添加用户签到
+     */
+    public function add()
+    {
+        $model = new SignModel();
+        $msg = $model->add($this->getUser());
+        if ($msg != '') {
+            return $this->renderSuccess('', compact('msg'));
+        }
+        return $this->renderError($model->getError() ?: '签到失败,请重试');
+    }
+
+    /**
+     * 签到页面
+     */
+    public function index()
+    {
+        $user = $this->getUser();   // 用户信息
+        $model = new SignModel();
+        $list = $model->getListByUserId($user['user_id']);
+
+        //获取签到配置
+        $sign_conf = SettingModel::getItem('sign');
+        $day_arr = [];
+        if (isset($sign_conf['reward_data'])) {
+            $day_arr = array_column($sign_conf['reward_data'], 'day');
+        }
+        $arr = [];
+        $point = [];
+        foreach ($day_arr as $key => $val) {
+            if ($day_arr[$key] - $list[1] > 0) {
+                array_push($arr, $val - $list[1]);
+                $point[$val - $list[1]] = isset($sign_conf['reward_data'][$key]['point'])?$sign_conf['reward_data'][$key]['point']:0;
+            }
+        }
+        return $this->renderSuccess('', compact('list', 'arr', 'point'));
+
+    }
+
+    /**
+     * 获取签到规则
+     */
+    public function getSign()
+    {
+        // 获取签到配置
+        $sign_conf = SettingModel::getItem('sign');
+        $detail = $sign_conf['content'];
+        return $this->renderSuccess('', compact('detail'));
+    }
+
+}

+ 31 - 0
app/api/controller/plus/table/Table.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace app\api\controller\plus\table;
+
+use app\api\controller\Controller;
+use app\api\model\plus\table\Table as TableModel;
+use app\common\model\settings\Region as RegionModel;
+
+/**
+ * 表单填写控制器
+ */
+class Table extends Controller
+{
+    /**
+     * 添加用户签到
+     */
+    public function add($table_id)
+    {
+        $user = $this->getUser();
+        $model = TableModel::detail($table_id);
+        if($this->request->isGet()){
+            $regionData = RegionModel::getRegionForApi();
+            return $this->renderSuccess('', compact('model', 'regionData'));
+        }
+        if ($model->add($user, $this->postData())) {
+            return $this->renderSuccess('');
+        }
+        return $this->renderError($model->getError() ?: '提交失败');
+    }
+
+}

+ 27 - 0
app/api/controller/points/Log.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace app\api\controller\points;
+
+use app\api\controller\Controller;
+use app\api\model\user\PointsLog as PointsLogModel;
+use app\api\model\settings\Setting as SettingModel;
+
+/**
+ * 积分明细控制器
+ */
+class Log extends Controller
+{
+    /**
+     * 积分明细列表
+     */
+    public function index()
+    {
+        $user = $this->getUser();
+        $points = $user['points'];
+        $list = (new PointsLogModel)->getList($user['user_id'], $this->postData());
+        //积分商城是否开放
+        $is_open = SettingModel::getItem('pointsmall')['is_open'];
+        return $this->renderSuccess('', compact('list', 'points', 'is_open'));
+    }
+
+}

+ 26 - 0
app/api/controller/product/Category.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace app\api\controller\product;
+
+use app\api\model\product\Category as CategoryModel;
+use app\api\controller\Controller;
+use app\common\model\page\PageCategory as PageCategoryModel;
+
+/**
+ * 商品分类控制器
+ */
+class Category extends Controller
+{
+    /**
+     * 分类页面
+     */
+    public function index()
+    {
+        // 分类模板
+        $template = PageCategoryModel::detail();
+        // 商品分类列表
+        $list = array_values(CategoryModel::getCacheTree());
+        return $this->renderSuccess('', compact('template','list'));
+    }
+
+}

+ 24 - 0
app/api/controller/product/Comment.php

@@ -0,0 +1,24 @@
+<?php
+
+namespace app\api\controller\product;
+
+use app\api\controller\Controller;
+use app\api\model\product\Comment as CommentModel;
+
+/**
+ * 商品评价控制器
+ */
+class Comment extends Controller
+{
+    /**
+     * 商品评价列表
+     */
+    public function lists($product_id, $scoreType = -1)
+    {
+        $model = new CommentModel;
+        $list = $model->getProductCommentList($product_id, $scoreType, $this->postData());
+        $total = $model->getTotal($product_id);
+        return $this->renderSuccess('', compact('list', 'total'));
+    }
+
+}

+ 90 - 0
app/api/controller/product/Product.php

@@ -0,0 +1,90 @@
+<?php
+
+namespace app\api\controller\product;
+
+use app\api\model\product\Product as ProductModel;
+use app\api\model\order\Cart as CartModel;
+use app\api\controller\Controller;
+use app\api\model\settings\Setting as SettingModel;
+use app\api\service\common\RecommendService;
+use app\common\service\qrcode\ProductService;
+use app\common\model\user\Favorite as FavoriteModel;
+/**
+ * 商品控制器
+ */
+class Product extends Controller
+{
+    /**
+     * 商品列表
+     */
+    public function lists()
+    {
+        // 整理请求的参数
+        $param = array_merge($this->postData(), [
+            'product_status' => 10
+        ]);
+
+        // 获取列表数据
+        $model = new ProductModel;
+        $list = $model->getList($param, $this->getUser(false));
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     * 推荐产品
+     */
+    public function recommendProduct($location)
+    {
+        $recommend = SettingModel::getItem('recommend');
+        $model = new ProductModel;
+        $is_recommend = RecommendService::checkRecommend($recommend, $location);
+        $list = [];
+        if($is_recommend){
+            $list = $model->getRecommendProduct($recommend);
+        }
+        return $this->renderSuccess('', compact('list', 'recommend', 'is_recommend'));
+    }
+
+    /**
+     * 获取商品详情
+     */
+    public function detail($product_id, $url = '')
+    {
+        // 用户信息
+        $user = $this->getUser(false);
+        // 商品详情
+        $model = new ProductModel;
+        $product = $model->getDetails($product_id, $this->getUser(false));
+        if ($product === false) {
+            return $this->renderError($model->getError() ?: '商品信息不存在');
+        }
+        // 多规格商品sku信息
+        $specData = $product['spec_type'] == 20 ? $model->getManySpecData($product['spec_rel'], $product['sku']) : null;
+
+        return $this->renderSuccess('', [
+            // 商品详情
+            'detail' => $product,
+            // 购物车商品总数量
+            'cart_total_num' => $user ? (new CartModel($user))->getProductNum() : 0,
+            // 多规格商品sku信息
+            'specData' => $specData,
+            // 是否收藏
+            'is_fav' => $user ? FavoriteModel::isFav($product_id, $user['user_id']) : false,
+            // 微信公众号分享参数
+            'share' => $this->getShareParams($url, $product['product_name'], $product['product_name'], '/pages/product/detail/detail', $product['image'][0]['file_path']),
+        ]);
+    }
+
+    /**
+     * 生成商品海报
+     */
+    public function poster($product_id, $source)
+    {
+        // 商品详情
+        $detail = ProductModel::detail($product_id);
+        $Qrcode = new ProductService($detail, $this->getUser(false), $source);
+        return $this->renderSuccess('', [
+            'qrcode' => $Qrcode->getImage(),
+        ]);
+    }
+}

+ 64 - 0
app/api/controller/store/Order.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace app\api\controller\store;
+
+use app\api\controller\Controller;
+use app\api\model\settings\Setting as SettingModel;
+use app\api\model\store\Clerk as ClerkModel;
+use app\api\model\order\Order as OrderModel;
+
+/**
+ * 自提订单管理
+ */
+class Order extends Controller
+{
+    private $user;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        $this->user = $this->getUser();   // 用户信息
+    }
+
+    /**
+     * 核销订单详情
+     */
+    public function detail($order_no)
+    {
+        // 订单详情
+        $model = OrderModel::detailByNo($order_no);
+        // 验证是否为该门店的核销员
+        $clerkModel = ClerkModel::detail(['user_id' => $this->user['user_id']]);
+        return $this->renderSuccess('', [
+            'order' => $model,  // 订单详情
+            'clerkModel' => $clerkModel,
+            'setting' => [
+                // 积分名称
+                'points_name' => SettingModel::getPointsName(),
+            ],
+        ]);
+    }
+
+    /**
+     * 确认核销
+     */
+    public function extract($order_id)
+    {
+        // 订单详情
+        $order = OrderModel::detail($order_id);
+        // 验证是否为该门店的核销员
+        $ClerkModel = ClerkModel::detail(['user_id' => $this->user['user_id']]);
+        if (!$ClerkModel->checkUser($order['extract_store_id'])) {
+            return $this->renderError($ClerkModel->getError());
+        }
+        // 确认核销
+        if ($order->verificationOrder($ClerkModel['clerk_id'])) {
+            return $this->renderSuccess('订单核销成功', []);
+        }
+        return $this->renderError($order->getError() ?:'核销失败');
+    }
+
+}

+ 33 - 0
app/api/controller/store/Store.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace app\api\controller\store;
+
+use app\api\controller\Controller;
+use app\api\model\store\Store as StoreModel;
+
+
+/**
+ * 门店列表
+ */
+class Store extends Controller
+{
+    /**
+     * 门店列表
+     */
+    public function lists($longitude = '', $latitude = '')
+    {
+        $model = new StoreModel;
+        $list = $model->getList(true, $longitude, $latitude);
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     * 门店详情
+     */
+    public function detail($store_id)
+    {
+        $detail = StoreModel::detail($store_id);
+        return $this->renderSuccess('', compact('detail'));
+    }
+
+}

+ 101 - 0
app/api/controller/user/Address.php

@@ -0,0 +1,101 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\model\user\UserAddress;
+use app\api\controller\Controller;
+use app\common\model\settings\Region as RegionModel;
+
+/**
+ * 收货地址控制器
+ */
+class Address extends Controller
+{
+    /**
+     * 收货地址列表
+     */
+    public function lists()
+    {
+        $user = $this->getUser();
+        $model = new UserAddress;
+        $list = $model->getList($user['user_id']);
+        return $this->renderSuccess('', [
+            'list' => $list,
+            'default_id' => $user['address_id'],
+        ]);
+    }
+
+    /**
+     * 添加收货地址
+     */
+    public function add()
+    {
+        $data = $this->request->post();
+        if ($data['phone'] == '') {
+            return $this->renderError('手机号不正确');
+        }
+        if ($data['name'] == '') {
+            return $this->renderError('收货人不能为空');
+        }
+        if ($data['detail'] == '') {
+            return $this->renderError('收货地址不能为空');
+        }
+        $model = new UserAddress;
+        if ($model->add($this->getUser(), $data)) {
+            return $this->renderSuccess('添加成功');
+        }
+        return $this->renderError('添加失败');
+    }
+
+    /**
+     * 收货地址详情
+     */
+    public function detail($address_id)
+    {
+        $user = $this->getUser();
+        $detail = UserAddress::detail($user['user_id'], $address_id);
+        $region = array_values($detail['region']);
+        $regionData = RegionModel::getRegionForApi();
+        return $this->renderSuccess('', compact('detail', 'region', 'regionData'));
+    }
+
+    /**
+     * 编辑收货地址
+     */
+    public function edit($address_id)
+    {
+        $user = $this->getUser();
+        $model = UserAddress::detail($user['user_id'], $address_id);
+        if ($model->edit($this->request->post())) {
+            return $this->renderSuccess('更新成功');
+        }
+        return $this->renderError('更新失败');
+    }
+
+    /**
+     * 设为默认地址
+     */
+    public function setDefault($address_id)
+    {
+        $user = $this->getUser();
+        $model = UserAddress::detail($user['user_id'], $address_id);
+        if ($model->setDefault($user)) {
+            return $this->renderSuccess('设置成功');
+        }
+        return $this->renderError('设置失败');
+    }
+
+    /**
+     * 删除收货地址
+     */
+    public function delete($address_id)
+    {
+        $user = $this->getUser();
+        $model = UserAddress::detail($user['user_id'], $address_id);
+        if ($model->remove($user)) {
+            return $this->renderSuccess('删除成功');
+        }
+        return $this->renderError('删除失败');
+    }
+
+}

+ 122 - 0
app/api/controller/user/Agent.php

@@ -0,0 +1,122 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\plus\agent\Referee;
+use app\api\model\plus\agent\Setting;
+use app\api\model\plus\agent\User as AgentUserModel;
+use app\api\model\plus\agent\Apply as AgentApplyModel;
+use app\api\model\settings\Message as MessageModel;
+
+/**
+ * 分销中心
+ */
+class Agent extends Controller
+{
+    // 用户
+    private $user;
+    // 分销商
+    private $agent;
+    // 分销设置
+    private $setting;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        // 用户信息
+        $this->user = $this->getUser();
+        // 分销商用户信息
+        $this->agent = AgentUserModel::detail($this->user['user_id']);
+        // 分销商设置
+        $this->setting = Setting::getAll();
+    }
+
+    /**
+     * 分销商中心
+     */
+    public function center()
+    {
+        return $this->renderSuccess('', [
+            // 当前是否为分销商
+            'is_agent' => $this->isAgentUser(),
+            // 当前是否在申请中
+            'is_applying' => AgentApplyModel::isApplying($this->user['user_id']),
+            // 当前用户信息
+            'user' => $this->user,
+            // 分销商用户信息
+            'agent' => $this->agent,
+            // 背景图
+            'background' => $this->setting['background']['values']['index'],
+            // 页面文字
+            'words' => $this->setting['words']['values'],
+        ]);
+    }
+
+    /**
+     * 分销商申请状态
+     */
+    public function apply($referee_id = null, $platform= '')
+    {
+        // 推荐人昵称
+        $referee_name = '平台';
+        // 如果之前有关联分销商,则继续关联之前的分销商
+        $has_referee_id = Referee::getRefereeUserId($this->user['user_id'], 1);
+        if($has_referee_id > 0){
+            $referee_id = $has_referee_id;
+        }
+        if ($referee_id > 0 && ($referee = AgentUserModel::detail($referee_id))) {
+            $referee_name = $referee['user']['nickName'];
+        }
+
+        return $this->renderSuccess('', [
+            // 当前是否为分销商
+            'is_agent' => $this->isAgentUser(),
+            // 当前是否在申请中
+            'is_applying' => AgentApplyModel::isApplying($this->user['user_id']),
+            // 推荐人昵称
+            'referee_name' => $referee_name,
+            // 背景图
+            'background' => $this->setting['background']['values']['apply'],
+            // 页面文字
+            'words' => $this->setting['words']['values'],
+            // 申请协议
+            'license' => $this->setting['license']['values']['license'],
+            // 如果来源是小程序, 则获取小程序订阅消息id.获取售后通知.
+            'template_arr' => MessageModel::getMessageByNameArr($platform, ['agent_apply_user']),
+        ]);
+    }
+
+    /**
+     * 分销商提现信息
+     */
+    public function cash($platform = '')
+    {
+        // 如果来源是小程序, 则获取小程序订阅消息id.获取售后通知.
+        $template_arr = MessageModel::getMessageByNameArr($platform, ['agent_cash_user']);
+        return $this->renderSuccess('', [
+            // 分销商用户信息
+            'agent' => $this->agent,
+            // 结算设置
+            'settlement' => $this->setting['settlement']['values'],
+            // 背景图
+            'background' => $this->setting['background']['values']['cash_apply'],
+            // 页面文字
+            'words' => $this->setting['words']['values'],
+            // 小程序消息
+            'template_arr' => $template_arr
+        ]);
+    }
+
+    /**
+     * 当前用户是否为分销商
+     */
+    private function isAgentUser()
+    {
+        return !!$this->agent && !$this->agent['is_delete'];
+    }
+
+}

+ 35 - 0
app/api/controller/user/Bargain.php

@@ -0,0 +1,35 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\plus\bargain\Task;
+
+/**
+ * 个人砍价控制器
+ */
+class Bargain extends Controller
+{
+    // 当前用户
+    private $user;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        $this->user = $this->getUser();   // 用户信息
+
+    }
+
+    /**
+     *个人砍价列表
+     */
+    public function lists()
+    {
+        $model = new Task();
+        $list = $model->getList($this->user['user_id'], $this->postData());
+        return $this->renderSuccess('', compact('list'));
+    }
+}

+ 47 - 0
app/api/controller/user/Comment.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\order\Order as OrderModel;
+use app\api\model\order\OrderProduct as OrderProductModel;
+use app\api\model\product\Comment as CommentModel;
+
+/**
+ * 订单评价管理
+ */
+class Comment extends Controller
+{
+    /**
+     * 待评价订单商品列表
+     */
+    public function order($order_id)
+    {
+        // 用户信息
+        $user = $this->getUser();
+        // 订单信息
+        $order = OrderModel::getUserOrderDetail($order_id, $user['user_id']);
+        // 验证订单是否已完成
+        $model = new CommentModel;
+        if (!$model->checkOrderAllowComment($order)) {
+            return $this->renderError($model->getError());
+        }
+        // 待评价商品列表
+        /* @var \think\Collection $productList */
+        $OrderProductModel = new OrderProductModel;
+        $productList = $OrderProductModel->getNotCommentProductList($order_id);
+        if ($productList->isEmpty()) {
+            return $this->renderError('该订单没有可评价的商品');
+        }
+        // 提交商品评价
+        if ($this->request->isPost()) {
+            $formData = $this->request->post('formData', '', null);
+            if ($model->addForOrder($order, $productList, $formData)) {
+                return $this->renderSuccess('评价发表成功');
+            }
+            return $this->renderError($model->getError() ?: '评价发表失败');
+        }
+        return $this->renderSuccess('', compact('productList'));
+    }
+
+}

+ 69 - 0
app/api/controller/user/Coupon.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\plus\coupon\UserCoupon as UserCouponModel;
+
+/**
+ * 用户优惠券
+ */
+class Coupon extends Controller
+{
+    // 当前用户
+    private $user;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        $this->user = $this->getUser();
+    }
+
+    /**
+     * 优惠券列表
+     */
+    public function lists($data_type = 'all')
+    {
+        $is_use = false;
+        $is_expire = false;
+        switch ($data_type) {
+            case 'not_use':
+                $is_use = false;
+                break;
+            case 'is_use':
+                $is_use = true;
+                break;
+            case 'is_expire':
+                $is_expire = true;
+                break;
+        }
+        $list = (new UserCouponModel())->getPageList($this->user['user_id'], $is_use, $is_expire, $this->postData());
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     * 领取优惠券
+     */
+    public function receive($coupon_id)
+    {
+        $model = new UserCouponModel();
+        if ($model->receive($this->user, $coupon_id)) {
+            return $this->renderSuccess([], '领取成功');
+        }
+        return $this->renderError($model->getError() ?: '添加失败');
+    }
+
+    /**
+     * 批量领取优惠券
+     */
+    public function receiveList($coupon_ids)
+    {
+        if ((new UserCouponModel())->receiveList($this->user, $coupon_ids)) {
+            return $this->renderSuccess('领取成功', '');
+        }
+        return $this->renderError('领取失败');
+    }
+}

+ 50 - 0
app/api/controller/user/Favorite.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\user\Favorite as FavoriteModel;
+/**
+ * 我的收藏商品和关注店铺
+ */
+class Favorite extends Controller
+{
+    protected $user;
+     /**
+     * 构造方法
+     */
+    public function initialize()
+    {   
+        parent::initialize();
+        $this->user = $this->getUser();
+    }
+
+    /**
+     * 取消或者收藏
+     */
+    public function fav($product_id){
+        $user_id = $this->user['user_id'];
+        $model = FavoriteModel::detail($product_id, $user_id);
+        if($model){
+            if($model->cancelFav()){
+                return $this->renderSuccess('操作成功');
+            }
+        }else{
+            // 新增
+            $model = new FavoriteModel();
+            if($model->addFav($product_id, $user_id)){
+                return $this->renderSuccess('收藏成功');
+            }
+        }
+        return $this->renderSuccess($model->getError()?:'操作失败');
+    }
+
+    /**
+     * 我的收藏
+     */
+    public function list(){
+        $favorite_model = new FavoriteModel;
+        $list = $favorite_model->getList($this->user['user_id'],$this->postData());
+        return $this->renderSuccess('',compact('list'));
+    }
+}

+ 88 - 0
app/api/controller/user/Index.php

@@ -0,0 +1,88 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\plus\agent\Setting;
+use app\api\model\user\User as UserModel;
+use app\api\model\order\Order as OrderModel;
+use app\api\model\settings\Setting as SettingModel;
+use app\api\model\plus\coupon\UserCoupon as UserCouponModel;
+use app\common\enum\settings\GetPhoneTypeEnum;
+use think\facade\Cache;
+use app\api\model\plus\invitationgift\InvitationGift as InvitationGiftModel;
+
+/**
+ * 个人中心主页
+ */
+class Index extends Controller
+{
+    /**
+     * 获取当前用户信息
+     */
+    public function detail($source = 'wx')
+    {
+        // 当前用户信息
+        $user = $this->getUser();
+        $coupon_model = new UserCouponModel();
+        $coupon = $coupon_model->getCount($user['user_id']);
+        // 订单总数
+        $model = new OrderModel;
+
+        // 分销商基本设置
+        $setting = Setting::getItem('basic');
+        // 是否开启分销功能
+        $agent_open = $setting['is_open'];
+        $invitation = InvitationGiftModel::getShow();
+        return $this->renderSuccess('', [
+            'coupon' => $coupon,
+            'userInfo' => $user,
+            'orderCount' => [
+                'payment' => $model->getCount($user, 'payment'),
+                'delivery' => $model->getCount($user, 'delivery'),
+                'received' => $model->getCount($user, 'received'),
+                'comment' => $model->getCount($user, 'comment'),
+            ],
+            'setting' => [
+                'is_show_personal_points' => SettingModel::getIsShowPersonalPoints(),
+                'points_name' => SettingModel::getPointsName(),
+                'agent_open' => $agent_open
+            ],
+            'sign' => SettingModel::getItem('sign'),
+            'getPhone' => $this->isGetPhone(),
+            'menus' => UserModel::getMenus($source, $user['user_id']),   // 个人中心菜单列表
+            'invitation' => $invitation
+        ]);
+    }
+
+    /**
+     * 当前用户设置
+     */
+    public function setting()
+    {
+        // 当前用户信息
+        $user = $this->getUser();
+
+        return $this->renderSuccess('', [
+            'userInfo' => $user
+        ]);
+    }
+
+    private function isGetPhone()
+    {
+        $user = $this->getUser();
+        if ($user['mobile'] != '') {
+            return false;
+        }
+        $settings = SettingModel::getItem('getPhone');
+        if (in_array(GetPhoneTypeEnum::USER, $settings['area_type'])) {
+            // 缓存时间
+            $key = 'get_phone_' . $user['user_id'];
+            if (!$data = Cache::get($key)) {
+                $settings['send_day'] > 0 && Cache::set($key, '1', 86400 * $settings['send_day']);
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 51 - 0
app/api/controller/user/Invitation.php

@@ -0,0 +1,51 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\plus\invitationgift\Partake;
+use app\api\model\plus\invitationgift\InvitationReward;
+use app\api\model\user\User as UserModel;
+
+/**
+ * 用户邀请有礼控制器
+ */
+class Invitation extends Controller
+{
+    private $model;
+
+    private $user;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        $this->user = $this->getUser();
+        $this->model = new Partake;
+    }
+
+    /**
+     *领奖
+     */
+    public function getPrize($invitation_reward_id, $invitation_gift_id)
+    {
+        $count = (new UserModel())->getCountInv($this->user['user_id']);
+        $reward = InvitationReward::detail($invitation_reward_id);
+        if (empty($reward)) {
+            return $this->renderError('奖项不存在', '');
+        }
+        if ($count < $reward['invitation_num']) {
+            return $this->renderError('未达邀请到人数', '');
+        }
+        if ($this->model->checkReward($invitation_reward_id, $invitation_gift_id, $this->user['user_id'])) {
+            return $this->renderError('已经领过该奖品', '');
+        }
+        if ($this->model->getPrize($invitation_reward_id, $invitation_gift_id, $this->user['user_id'], $reward)) {
+            return $this->renderSuccess('领取成功', '');
+        }
+        return $this->renderError('领取失败', '');
+    }
+
+}

+ 285 - 0
app/api/controller/user/Order.php

@@ -0,0 +1,285 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\order\Order as OrderModel;
+use app\api\model\settings\Setting as SettingModel;
+use app\common\enum\order\OrderPayTypeEnum;
+use app\common\enum\settings\SettingEnum;
+use app\common\model\settings\Setting;
+use app\common\service\qrcode\ExtractService;
+use app\shop\model\order\Deliver;
+use app\shop\model\settings\Express;
+use app\common\model\order\OrderAddress;
+use app\api\model\user\UserAddress;
+use think\facade\Validate;
+
+/**
+ * 我的订单
+ */
+class Order extends Controller
+{
+    // user
+    private $user;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        $this->user = $this->getUser();   // 用户信息
+
+    }
+
+    /**
+     * 修改收货地址
+     */
+    public function addressedit()
+    {
+        $data =  $this->postData();
+        if (empty($data['order_id'])) {
+            return $this->renderError('订单id为空');
+        }
+        if (empty($data['address_id'])) {
+            return $this->renderError('收货地址为空');
+        }      
+        $order = OrderModel::getUserOrderDetail($data['order_id'], $this->user['user_id']);
+        if ($order['delivery_status']['value'] == 20) {
+           return $this->renderError('该订单已发货,不允许修改');
+        }       
+        $useradd  =(new UserAddress)->find($data['address_id']);
+        if ($useradd['user_id'] !=  $this->user['user_id']) {
+            return $this->renderError('收货地址信息错误');
+        }
+        $vall = [
+            'name'       => $useradd['name'],
+            'phone'      => $useradd['phone'],
+            'detail'     => $useradd['detail'],
+            'province_id'=> $useradd['province_id'],
+            'city_id'    => $useradd['city_id'],
+            'region_id'  => $useradd['region_id'],                
+        ];     
+        (new OrderAddress)->where('order_id',$order['order_id'])->update($vall);
+        $this->user->where('user_id',$this->user['user_id'])->update(['address_id'=>$data['address_id']]);
+        return $this->renderSuccess('修改成功');
+    }
+    /**
+     * 是否有未上传信息订单
+     */
+    public function borderorder()
+    {
+        $where  = [
+            ['user_id','=',$this->user['user_id']],
+            ['is_border','=',20],
+            ['order_status','in',"10,30"],
+            ['pay_status','=',20],
+            ['real_name','=',null],            
+        ];
+        $order_id = (new OrderModel)->where($where)->value('order_id');
+        if (empty($order_id)) {
+            $data = [];
+        }else{
+            $data = ['order_id'=>$order_id];
+        }
+        return $this->renderSuccess('查询成功',$data);      
+    }
+    /**
+     * 跨境信息上传
+     */
+    public function crossborder()
+    {
+        $data =  $this->postData();
+        // $data = [
+        //     'order_id'   => 1,
+        //     'real_name'  => '葛云龙',
+        //     'idcard'     => '23018419910505303X',
+        //     'card_front' => 'http://192.168.18.9:8009/uploads/20220408/3759c7b39b77fc40575172e864fc4489.jpg',
+        //     'card_back'  => 'http://192.168.18.9:8009/uploads/20220407/7ea9db666a9a95dd1f54e2a42e0ac3ed.png',
+        // ];
+        if (empty($data['order_id'])) {
+            return $this->renderError('订单id为空');
+        }
+        if (empty($data['real_name'])) {
+            return $this->renderError('请填写收货人真实姓名');
+        }
+        $order = OrderModel::getUserOrderDetail($data['order_id'], $this->user['user_id']); 
+        if (empty($order)) {
+            return $this->renderError('订单信息错误');           
+        }
+        if (!empty($order['card_front'])) {
+            return $this->renderError('该订单信息已上传');           
+        }               
+        if ($order['address']['name'] != $data['real_name']) {
+            return $this->renderError('收货人姓名信息错误');
+        }
+        if (empty($data['idcard'])) {
+            return $this->renderError('请填写身份证号码');
+        }
+        $regIdCard = "/^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/";
+        if (!Validate::regex($data['idcard'],$regIdCard)){         
+            return $this->renderError('身份证号格式错误');
+            return false;           
+        }
+        if (empty($data['card_front'])) {
+            return $this->renderError('请上传身份证正面照');
+        }
+        if (empty($data['card_back'])) {
+            return $this->renderError('请上传身份证反面照');
+        }        
+        $vall = [          
+            'real_name'  => $data['real_name'],
+            'idcard'     => $data['idcard'],
+            'card_front' => $data['card_front'],
+            'card_back'  => $data['card_back'],
+        ];
+        if ((new OrderModel)->where('order_id',$order['order_id'])->update($vall)) {
+            return $this->renderSuccess('信息上传成功');
+        }
+        return $this->renderError('网络错误,请稍后再试');   
+    }
+
+
+
+    /**
+     * 我的订单列表
+     */
+    public function lists($dataType)
+    {
+        $data = $this->postData();
+        $model = new OrderModel;
+        $list = $model->getList($this->user['user_id'], $dataType, $data);
+        $h5_alipay = Setting::getItem(SettingEnum::H5ALIPAY)['is_open'];
+        return $this->renderSuccess('', compact('list', 'h5_alipay'));
+    }
+
+    /**
+     * 订单详情信息
+     */
+    public function detail($order_id)
+    {
+        // 订单详情
+        $model = OrderModel::getUserOrderDetail($order_id, $this->user['user_id']);
+        // 剩余支付时间
+        if($model['pay_status']['value'] == 10 && $model['order_status']['value'] != 20 && $model['pay_end_time'] != 0){
+            $model['pay_end_time'] = $this->formatPayEndTime($model['pay_end_time'] - time());
+        }else{
+            $model['pay_end_time'] = '';
+        }
+        // 该订单是否允许申请售后
+        $model['isAllowRefund'] = $model->isAllowRefund();
+        $h5_alipay = Setting::getItem(SettingEnum::H5ALIPAY)['is_open'];
+        return $this->renderSuccess('', [
+            'order' => $model,  // 订单详情
+            'setting' => [
+                // 积分名称
+                'points_name' => SettingModel::getPointsName(),
+            ],
+            'h5_alipay' => $h5_alipay
+        ]);
+    }
+
+    /**
+     * 获取物流信息
+     */
+    public function express($order_id)
+    {
+        // 订单信息
+        $order = OrderModel::getUserOrderDetail($order_id, $this->user['user_id']);
+        if (!$order['express_no']) {
+            return $this->renderError('没有物流信息');
+        }
+        // 获取物流信息
+        $model = $order['express'];
+        $express = $model->dynamic($model['express_name'], $model['express_code'], $order['express_no']);
+        if ($express === false) {
+            return $this->renderError($model->getError());
+        }
+        return $this->renderSuccess('', compact('express'));
+    }
+
+    /**
+     * 取消订单
+     */
+    public function cancel($order_id)
+    {
+        $model = OrderModel::getUserOrderDetail($order_id, $this->user['user_id']);
+        if ($model->cancel($this->user)) {
+            return $this->renderSuccess('订单取消成功');
+        }
+        return $this->renderError($model->getError()?:'订单取消失败');
+    }
+
+    /**
+     * 确认收货
+     */
+    public function receipt($order_id)
+    {
+        $model = OrderModel::getUserOrderDetail($order_id, $this->user['user_id']);
+        if ($model->receipt()) {
+            return $this->renderSuccess('收货成功');
+        }
+        return $this->renderError($model->getError()?:'收货失败');
+    }
+
+    /**
+     * 立即支付
+     */
+    public function pay($order_id, $payType = OrderPayTypeEnum::WECHAT, $pay_source = 'wx')
+    {
+        // 获取订单详情
+        $model = OrderModel::getUserOrderDetail($order_id, $this->user['user_id']);
+        // 订单支付事件
+        if (!$model->onPay($payType, $pay_source)) {
+            return $this->renderError($model->getError() ?: '订单支付失败');
+        }
+        // 构建微信支付请求
+        $payment = $model->onOrderPayment($this->user, $model, $payType, $pay_source);
+        // 支付状态提醒
+        return $this->renderSuccess('', [
+            'order_id' => $model['order_id'],   // 订单id
+            'pay_type' => $payType,             // 支付方式
+            'payment' => $payment               // 微信支付参数
+        ]);
+    }
+
+    /**
+     * 获取订单核销二维码
+     */
+    public function qrcode($order_id, $source)
+    {
+        // 订单详情
+        $order = OrderModel::getUserOrderDetail($order_id, $this->user['user_id']);
+        // 判断是否为待核销订单
+        if (!$order->checkExtractOrder($order)) {
+            return $this->renderError($order->getError());
+        }
+        $Qrcode = new ExtractService(
+            $this->app_id,
+            $this->user,
+            $order_id,
+            $source,
+            $order['order_no']
+        );
+        return $this->renderSuccess('',[
+            'qrcode' => $Qrcode->getImage(),
+        ]);
+    }
+
+    private function formatPayEndTime($leftTime){
+        if($leftTime <= 0){
+            return '';
+        }
+
+        $str = '';
+        $day = floor($leftTime/86400);
+        $hour = floor(($leftTime - $day * 86400)/3600);
+        $min = floor((($leftTime - $day * 86400) - $hour * 3600)/60);
+
+        if ($day > 0) $str .= $day . '天';
+        if ($hour > 0) $str .= $hour . '小时';
+        if ($min > 0) $str .= $min . '分钟';
+        return $str;
+    }
+}

+ 120 - 0
app/api/controller/user/Refund.php

@@ -0,0 +1,120 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\settings\Express as ExpressModel;
+use app\api\model\order\OrderProduct as OrderProductModel;
+use app\api\model\order\OrderRefund as OrderRefundModel;
+use app\api\model\settings\Message as MessageModel;
+
+/**
+ * 订单售后服务
+ */
+class Refund extends Controller
+{
+    // $user
+    private $user;
+
+    /**
+     * 构造方法
+     */
+    public function initialize()
+    {
+        parent::initialize();
+        $this->user = $this->getUser();   // 用户信息
+    }
+
+    /**
+     * 用户售后单列表
+     */
+    public function lists($state = -1)
+    {
+        $model = new OrderRefundModel;
+        $list = $model->getList($this->user['user_id'], $state, $this->postData());
+        return $this->renderSuccess('', compact('list'));
+    }
+
+    /**
+     * 申请售后
+     */
+    public function apply($order_product_id, $platform = 'wx')
+    {
+        // 订单商品详情
+        $detail = OrderProductModel::detail($order_product_id);
+        $refund = $detail->toArray();
+//        if (isset($product['refund']) && !empty($detail['refund'])) {
+        if (isset($refund['last_refund'][0]) && $refund['last_refund'][0]['is_agree']['value'] != 20) {
+            return $this->renderError('当前商品已申请售后');
+        }
+
+        if ($this->request->isGet()) {
+            // 如果来源是小程序, 则获取小程序订阅消息id.获取售后通知.
+            $template_arr = MessageModel::getMessageByNameArr($platform, ['order_refund_user']);
+            return $this->renderSuccess('', compact('detail', 'template_arr'));
+        }
+        // 新增售后单记录
+        $model = new OrderRefundModel;
+        if ($model->apply($this->user, $detail, $this->request->post())) {
+            return $this->renderSuccess('提交成功');
+        }
+        return $this->renderError($model->getError() ?: '提交失败');
+    }
+
+    /**
+     * 售后单详情
+     */
+    public function detail($order_refund_id, $platform = '')
+    {
+        // 售后单详情
+        $detail = OrderRefundModel::detail([
+            'user_id' => $this->user['user_id'],
+            'order_refund_id' => $order_refund_id
+        ]);
+        if (empty($detail)) {
+            return $this->renderError('售后单不存在');
+        }
+        // 物流公司列表
+        $model = new ExpressModel();
+        $expressList = $model->getAll();
+        // 如果来源是小程序, 则获取小程序订阅消息id.获取售后通知.
+        $template_arr = MessageModel::getMessageByNameArr($platform, ['order_refund_user']);
+        return $this->renderSuccess('', compact('detail', 'expressList', 'template_arr'));
+    }
+
+    /**
+     * 用户发货
+     */
+    public function delivery($order_refund_id)
+    {
+        // 售后单详情
+        $model = OrderRefundModel::detail([
+            'user_id' => $this->user['user_id'],
+            'order_refund_id' => $order_refund_id
+        ]);
+        if ($model->delivery($this->postData())) {
+            return $this->renderSuccess('操作成功');
+        }
+        return $this->renderError($model->getError() ?: '提交失败');
+    }
+
+    /**
+     * 获取物流信息
+     */
+    public function express($order_refund_id)
+    {
+        // 订单信息
+        $model = OrderRefundModel::detail($order_refund_id);
+        if (!$model['send_express_no']) {
+            return $this->renderError('没有物流信息');
+        }
+        // 获取物流信息
+        $model = $model['sendexpress'];
+        $express = $model->dynamic($model['express_name'], $model['express_code'], $model['send_express_no']);
+        if ($express === false) {
+            return $this->renderError($model->getError());
+        }
+        return $this->renderSuccess('', compact('express'));
+    }
+
+}

+ 70 - 0
app/api/controller/user/User.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\model\user\User as UserModel;
+use app\api\controller\Controller;
+use app\common\library\easywechat\AppWx;
+
+/**
+ * 用户管理模型
+ */
+class User extends Controller
+{
+    /**
+     * 用户自动登录,默认微信小程序
+     */
+    public function login()
+    {
+        $model = new UserModel;
+        $user_id = $model->login($this->request->post());
+        return $this->renderSuccess('', [
+            'user_id' => $user_id,
+            'token' => $model->getToken()
+        ]);
+    }
+
+    /**
+     * 当前用户详情
+     */
+    public function detail()
+    {
+        // 当前用户信息
+        $userInfo = $this->getUser();
+        return $this->renderSuccess('', compact('userInfo'));
+    }
+
+    public function getSession($code)
+    {
+        // 微信登录 获取session_key
+        $app = AppWx::getApp();
+        $session_key = AppWx::sessionKey($app, $code)['session_key'];
+        return $this->renderSuccess('', compact('session_key'));
+    }
+
+    /**
+     * 绑定手机号
+     */
+    public function bindMobile()
+    {
+        $model = $this->getUser();
+        $mobile = $model->bindMobile($this->request->post());
+        if ($mobile) {
+            return $this->renderSuccess('', compact('mobile'));
+        }
+        return $this->renderError('绑定失败');
+    }
+
+    /**
+     * 修改用户信息
+     */
+    public function updateInfo()
+    {
+        // 当前用户信息
+        $model = $this->getUser();
+        if ($model->edit($this->request->post())) {
+            return $this->renderSuccess('修改成功');
+        }
+        return $this->renderError($model->getError() ?: '修改失败');
+    }
+}

+ 34 - 0
app/api/controller/user/Userapple.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\model\user\Userapple as UserappleModel;
+use app\api\controller\Controller;
+use app\common\model\settings\Setting;
+
+/**
+ * 用户管理模型
+ */
+class Userapple extends Controller
+{
+    /**
+     * 用户自动登录,默认微信小程序
+     */
+    public function login()
+    {
+        $model = new UserappleModel;
+        $user_id = $model->login($this->request->post());
+        return $this->renderSuccess('',[
+            'user_id' => $user_id,
+            'token' => $model->getToken()
+        ]);
+    }
+
+    public function policy(){
+        $config = Setting::getItem('store');
+        return $this->renderSuccess('',[
+            'service' => $config['policy']['service'],
+            'privacy' => $config['policy']['privacy'],
+        ]);
+    }
+}

+ 45 - 0
app/api/controller/user/Usermp.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\user\UserMp as UserMpModel;
+use app\common\library\easywechat\AppMp;
+
+/**
+ * 公众号用户管理
+ */
+class Usermp extends Controller
+{
+
+    /**
+     * 用户自动登录
+     */
+    public function login($referee_id = '')
+    {
+        $app = AppMp::getApp($this->app_id);
+        $redirect_uri = base_url()."index.php/api/user.usermp/login_callback?app_id={$this->app_id}&referee_id={$referee_id}";
+        $app->oauth->scopes(['snsapi_userinfo'])->redirect($redirect_uri)->send();
+    }
+
+    /**
+     * 用户自动登录
+     */
+    public function login_callback()
+    {
+        $app   = AppMp::getApp($this->app_id);
+        $oauth = $app->oauth;
+        // 获取 OAuth 授权结果用户信息
+        $userInfo = $oauth->user();
+        // 保存数据库
+        $model = new UserMpModel;
+        $referee_id = $this->request->param('referee_id');
+        $data  = $model->login($userInfo, $referee_id);
+        $signA ='';
+        foreach ($data as $key => $val) {
+            $signA .= $key."=".urlencode($val)."&";      
+        }      
+        return redirect(base_url().'h5/pages/login/weblogin?app_id='.$this->app_id.'&'.$signA);              
+        // return redirect(base_url().'h5/pages/login/mplogin?app_id='.$this->app_id.'&token='.$model->getToken().'&user_id='.$user_id);
+    }
+}

+ 174 - 0
app/api/controller/user/Useropen.php

@@ -0,0 +1,174 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\order\Order as OrderModel;
+use app\api\model\settings\Setting as SettingModel;
+use app\api\model\user\UserOpen as UserOpenModel;
+use app\api\model\user\UserMp as UserMpModel;
+use app\common\enum\order\OrderPayTypeEnum;
+use app\common\library\easywechat\AppMp;
+use app\common\model\app\AppOpen as AppOpenModel;
+use app\common\model\user\Sms as SmsModel;
+
+/**
+ * app用户管理
+ */
+class Useropen extends Controller
+{
+    /**
+     * 用户自动登录
+     */
+    public function login($code, $referee_id = 0)
+    {
+        $wxConfig = AppOpenModel::getAppOpenCache($this->app_id);
+        $appId = $wxConfig['openapp_id'];
+        $appSecret = $wxConfig['openapp_secret'];
+        $token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appId . '&secret=' . $appSecret . '&code=' . $code . '&grant_type=authorization_code';
+        $stream_opts = [
+            "ssl" => [
+                "verify_peer" => false,
+                "verify_peer_name" => false,
+            ]
+        ];
+        //获取token,为了获取access_token 如果没有就弹出错误
+        $token = json_decode(file_get_contents($token_url, false, stream_context_create($stream_opts)));
+        if (isset($token->errcode)) {
+            return $this->renderError($token->errmsg);
+        }
+        $access_token_url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=' . $appId . '&grant_type=refresh_token&refresh_token=' . $token->refresh_token;
+        //获取access_token ,为了获取微信的个人信息,如果没有就弹出错误
+        $access_token = json_decode(file_get_contents($access_token_url, false, stream_context_create($stream_opts)));
+        if (isset($access_token->errcode)) {
+            return $this->renderError($access_token->errmsg);
+        }
+        $user_info_url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $access_token->access_token . '&openid=' . $access_token->openid . '&lang=zh_CN';
+        //获取用户信息
+        $user_info = json_decode(file_get_contents($user_info_url, false, stream_context_create($stream_opts)));
+        if (isset($user_info->errcode)) {
+            log_write($user_info->errcode);
+            log_write($user_info->errmsg);
+            return $this->renderError($user_info->errmsg);
+        }
+        $model = new UserOpenModel;
+        $user_id = $model->login((array)$user_info, $referee_id);
+        return $this->renderSuccess('', [
+            'user_id' => $user_id,
+            'token' => $model->getToken()
+        ]);
+    }
+
+    public function payWx($order_id)
+    {
+        $user = $this->getUser();
+        // 订单详情
+        $model = OrderModel::getUserOrderDetail($order_id, $user['user_id']);
+        // 构建支付请求
+        $payment = OrderModel::onOrderPayment($user, [$model], OrderPayTypeEnum::WECHAT, 'payApp');
+
+        return $this->renderSuccess('', [
+            'order' => $model,  // 订单详情
+            'payment' => $payment
+        ]);
+    }
+
+    public function invite($referee_id = '')
+    {
+        $app = AppMp::getApp($this->app_id);
+        $redirect_uri = base_url() . "index.php/api/user.useropen/invite_callback?app_id={$this->app_id}&referee_id={$referee_id}";
+        $app->oauth->scopes(['snsapi_userinfo'])->redirect($redirect_uri)->send();
+    }
+
+    /**
+     * 用户自动登录
+     */
+    public function invite_callback()
+    {
+        $app = AppMp::getApp($this->app_id);
+        $oauth = $app->oauth;
+        // 获取 OAuth 授权结果用户信息
+        $userInfo = $oauth->user();
+        // 绑定关系,保存数据库
+        $model = new UserMpModel;
+        $referee_id = $this->request->param('referee_id');
+        $model->login($userInfo, $referee_id);
+        //跳转到app下载页
+        $appshare = SettingModel::getItem('appshare');
+        $down_url = $appshare['down_url'];
+        return redirect($down_url);
+    }
+
+    /**
+     * 手机号码登录
+     */
+    public function phonelogin()
+    {
+        $data = $this->request->post();
+        $model = new UserOpenModel;
+        $user_id = $model->phoneLogin($data);
+        if ($user_id) {
+            return $this->renderSuccess('', [
+                'user_id' => $user_id,
+                'token' => $model->getToken()
+            ]);
+        }
+        return $this->renderError($model->getError() ?: '登录失败');
+    }
+
+    /**
+     * 短信登录
+     */
+    public function smslogin()
+    {
+        $data = $this->request->post();
+        $model = new UserOpenModel;
+        $user_id = $model->smslogin($data);
+        if ($user_id) {
+            return $this->renderSuccess('', [
+                'user_id' => $user_id,
+                'token' => $model->getToken()
+            ]);
+        }
+        return $this->renderError($model->getError() ?: '登录失败');
+    }
+
+    /**
+     * 忘记密码
+     */
+    public function resetpassword()
+    {
+        $data = $this->request->post();
+        $model = new UserOpenModel;
+        if ($model->resetpassword($data)) {
+            return $this->renderSuccess('设置成功');
+        }
+        return $this->renderError($model->getError() ?: '设置失败');
+    }
+
+    /**
+     * 手机号码注册
+     */
+    public function register()
+    {
+        $data = $this->request->post();
+        $model = new UserOpenModel;
+        if ($model->phoneRegister($data)) {
+            return $this->renderSuccess('注册成功');
+        }
+        return $this->renderError($model->getError() ?: '注册失败');
+
+    }
+
+    /**
+     * 发送短信
+     */
+    public function sendCode($mobile, $type)
+    {
+        $model = new SmsModel();
+        if ($model->send($mobile, $type)) {
+            return $this->renderSuccess();
+        }
+        return $this->renderError($model->getError() ?: '发送失败');
+    }
+}

+ 145 - 0
app/api/controller/user/Userweb.php

@@ -0,0 +1,145 @@
+<?php
+
+namespace app\api\controller\user;
+
+use app\api\controller\Controller;
+use app\api\model\order\Order as OrderModel;
+use app\api\model\user\BalanceOrder as BalanceOrderModel;
+use app\common\enum\order\OrderPayTypeEnum;
+use app\common\enum\order\OrderTypeEnum;
+use app\common\model\user\Sms as SmsModel;
+use app\api\model\user\UserWeb as UserModel;
+use app\api\model\user\User as UserloginModel;
+use app\api\model\plus\giftpackage\Order as GiftOrderModel;
+/**
+ * h5 web用户管理
+ */
+class Userweb extends Controller
+{
+
+    /**
+     * 小程序获取openid
+     */
+    public function login()
+    {
+        $model   = new UserloginModel;
+        $session = $model->login($this->request->post()); 
+        return $this->renderSuccess('',['openid' => $session['openid']]);
+    }
+     /**
+     * 小程序账号密码登陆
+     */
+    public function accountlogin()
+    {     
+        $model   = new UserloginModel;
+        $user_id = $model->accountlogin($this->request->post());
+        if ($user_id) {
+            return $this->renderSuccess('', [
+                'user_id' => $user_id,
+                'token'   => $model->getToken()
+            ]);
+        }
+        return $this->renderError($model->getError() ?: '登录失败');
+    }
+    
+
+
+    /**
+     * 用户自动登录,默认微信小程序
+     */
+    // public function login()
+    // {
+    //     $model   = new UserModel;
+    //     $user_id = $model->login($this->request->post());
+
+    //     if($user_id == 0){
+    //         return $this->renderError($model->getError() ?:'登录失败');
+    //     }
+    //     return $this->renderSuccess('',[
+    //         'user_id' => $user_id,
+    //         'token'   => $model->getToken()
+    //     ]);
+    // }
+
+    /**
+     * 短信登录
+     */
+    public function sendCode($mobile)
+    {
+        $model = new SmsModel();
+        if($model->send($mobile)){
+            return $this->renderSuccess();
+        }
+        return $this->renderError($model->getError() ?:'发送失败');
+    }
+
+
+    public function payH5($order_id, $order_type = OrderTypeEnum::MASTER){
+        $user = $this->getUser();
+        if ($order_type == 'undefined') {
+            $order_type = OrderTypeEnum::MASTER;
+        }
+        if($order_type == OrderTypeEnum::MASTER){
+            // 订单详情
+            $model = OrderModel::getUserOrderDetail($order_id, $user['user_id']);
+            // 构建支付请求
+            $payment = OrderModel::onOrderPayment($user, $model, OrderPayTypeEnum::WECHAT, 'payH5');
+            $return_Url = urlencode(base_url()."h5/pages/order/myorder/myorder");
+        }else if($order_type == OrderTypeEnum::GIFT){
+            // 订单详情
+            $model = GiftOrderModel::getUserOrderDetail($order_id, $user['user_id']);
+            // 构建支付请求
+            $payment = GiftOrderModel::onOrderPayment($user, $model, OrderPayTypeEnum::WECHAT, 'payH5');
+            $return_Url = urlencode(base_url()."h5/pages/user/index/index");
+        }else if($order_type == OrderTypeEnum::BALANCE){
+            // 订单详情
+            $model = BalanceOrderModel::getUserOrderDetail($order_id, $user['user_id']);
+            // 构建支付请求
+            $payment = BalanceOrderModel::onOrderPayment($user, $model, OrderPayTypeEnum::WECHAT, 'payH5');
+            $return_Url = urlencode(base_url()."h5/pages/user/my-wallet/my-wallet");
+        }
+
+        return $this->renderSuccess('',[
+            'order' => $model,  // 订单详情
+            'mweb_url' => $payment['mweb_url'],
+            'return_Url' => $return_Url
+        ]);
+    }
+
+    public function bindMobile(){
+        $model = new UserModel;
+        if($model->bindMobile($this->getUser(), $this->request->post())){
+            return $this->renderSuccess('绑定成功');
+        }
+        return $this->renderError($model->getError() ?:'绑定失败');
+    }
+
+    /**
+     * h5下支付宝支付
+     */
+    public function alipayH5($order_id, $order_type = OrderTypeEnum::MASTER){
+        $user = $this->getUser();
+        $payment = [];
+        if($order_type == OrderTypeEnum::MASTER){
+            // 订单详情
+            $model = OrderModel::getUserOrderDetail($order_id, $user['user_id']);
+            // 构建支付请求
+            $payment = OrderModel::onOrderPayment($user, $model, OrderPayTypeEnum::ALIPAY, 'payH5');
+        }else if($order_type == OrderTypeEnum::GIFT){
+            // 订单详情
+            $model = GiftOrderModel::getUserOrderDetail($order_id, $user['user_id']);
+            // 构建支付请求
+            $payment = GiftOrderModel::onOrderPayment($user, $model, OrderPayTypeEnum::ALIPAY, 'payH5');
+        }else if($order_type == OrderTypeEnum::BALANCE){
+            // 订单详情
+            $model = BalanceOrderModel::getUserOrderDetail($order_id, $user['user_id']);
+            // 构建支付请求
+            $payment = BalanceOrderModel::onOrderPayment($user, $model, OrderPayTypeEnum::ALIPAY, 'payH5');
+        }
+
+
+        return $this->renderSuccess('',[
+            'payment' => $payment,
+        ]);
+    }
+}

+ 47 - 0
app/api/event/PaySuccess.php

@@ -0,0 +1,47 @@
+<?php
+
+
+namespace app\api\event;
+
+use app\common\enum\order\OrderTypeEnum;
+use app\common\service\message\MessageService;
+use app\api\model\order\Order;
+use app\api\service\order\paysuccess\source\PaySourceSuccessFactory;
+
+class PaySuccess
+{
+    public $order;
+    public $appId;
+    public $orderType;
+
+
+    public function handle(Order $order)
+    {
+        $this->order = $order;
+        $this->appId = $order['app_id'];
+        $this->orderType = OrderTypeEnum::MASTER;
+        // 订单公共业务
+        $this->onCommonEvent();
+        // 订单来源回调业务
+        $this->onSourceCallback();
+        return true;
+    }
+
+    /**
+     * 订单公共业务
+     */
+    private function onCommonEvent()
+    {
+        // 发送消息通知
+        (new MessageService)->payment($this->order, $this->orderType);
+    }
+
+    /**
+     * 订单来源回调业务
+     */
+    private function onSourceCallback()
+    {
+        $model = PaySourceSuccessFactory::getFactory($this->order['order_source']);
+        return $model->onPaySuccess($this->order);
+    }
+}

+ 13 - 0
app/api/model/App.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace app\api\model;
+
+use app\common\model\app\App as AppModel;
+
+/**
+ * 应用模型
+ */
+class App extends AppModel
+{
+
+}

+ 21 - 0
app/api/model/file/UploadFile.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace app\api\model\file;
+
+use app\common\model\file\UploadFile as UploadFileModel;
+
+/**
+ * 文件库模型
+ */
+class UploadFile extends UploadFileModel
+{
+    /**
+     * 隐藏字段
+     * @var array
+     */
+    protected $hidden = [
+        'app_id',
+        'create_time',
+    ];
+
+}

+ 240 - 0
app/api/model/order/Cart.php

@@ -0,0 +1,240 @@
+<?php
+
+namespace app\api\model\order;
+
+use think\facade\Cache;
+use app\api\model\product\Product as ProductModel;
+
+use app\common\library\helper;
+
+/**
+ * 购物车管理
+ */
+class Cart
+{
+    // 错误信息
+    public $error = '';
+    //用户
+    private $user;
+    // 用户id
+    private $user_id;
+    // 购物车列表
+    private static $cart = [];
+    // $clear 是否清空购物车
+    private $clear = false;
+
+    /**
+     * 构造方法
+     */
+    public function __construct($user)
+    {   
+        $this->user = $user;
+        $this->user_id = $user['user_id'];
+        static::$cart = Cache::get('cart_' . $this->user_id) ?: [];
+    }
+
+    /**
+     * 购物车列表 (含商品信息)
+     */
+    public function getList($cartIds = null)
+    {
+        // 获取购物车商品列表
+        return $this->getOrderProductList($cartIds);
+    }
+
+    /**
+     * 获取购物车列表
+     */
+    public function getCartList($cartIds = null)
+    {
+        if (empty($cartIds)) return static::$cart;
+        $cartList = [];
+        $indexArr = (strpos($cartIds, ',') !== false) ? explode(',', $cartIds) : [$cartIds];
+        foreach ($indexArr as $index) {
+            isset(static::$cart[$index]) && $cartList[$index] = static::$cart[$index];
+        }
+        return $cartList;
+    }
+
+    /**
+     * 获取购物车中的商品列表
+     */
+    public function getOrderProductList($cartIds)
+    {
+        // 购物车商品列表
+        $productList = [];
+        // 获取购物车列表
+        $cartList = $this->getCartList($cartIds);
+        if (empty($cartList)) {
+            $this->setError('当前购物车没有商品');
+            return $productList;
+        }
+        // 购物车中所有商品id集
+        $productIds = array_unique(helper::getArrayColumn($cartList, 'product_id'));
+
+        // 获取并格式化商品数据
+        $sourceData = (new ProductModel)->getListByIds($productIds);
+
+        $sourceData = helper::arrayColumn2Key($sourceData, 'product_id');
+           // p($cartList);
+        // 格式化购物车数据列表
+        foreach ($cartList as $key => $item) {
+            // 判断商品不存在则自动删除
+            if (!isset($sourceData[$item['product_id']])) {
+                $this->delete($key);
+                continue;
+            }
+            // 商品信息
+            $product = clone $sourceData[$item['product_id']];
+            // 判断商品是否已删除
+            if ($product['is_delete']) {
+                $this->delete($key);
+                continue;
+            }                   
+            // 商品sku信息
+            $product['product_sku'] = ProductModel::getProductSku($product, $item['product_sku_id']);
+            $product['product_sku_id'] = $item['product_sku_id'];
+            $product['spec_sku_id'] = $product['product_sku']['spec_sku_id'];
+         
+            // 商品pv 
+            $product['pv'] = $product['product_sku']['pv'];
+            // 商品总pv 
+            $product['total_pv']    = bcmul($product['pv'], $item['product_num']);
+            // 商品sku不存在则自动删除
+            if (empty($product['product_sku'])) {
+                $this->delete($key);
+                continue;
+            }
+            // 商品单价
+            $product['product_price'] = $product['product_sku']['product_price'];
+            // 购买数量
+            $product['total_num'] = $item['product_num'];
+            // 商品总价
+            $product['total_price'] = bcmul($product['product_price'], $item['product_num'], 2);
+
+            $productList[] = $product->hidden(['category', 'content', 'image']);
+        }
+        return $productList;
+    }
+
+    /**
+     * 加入购物车
+     */
+    public function add($productId, $productNum, $productSkuId)
+    {
+        // 购物车商品索引
+        $index = "{$productId}_{$productSkuId}";
+        // 加入购物车后的商品数量
+        $cartProductNum = $productNum + (isset(static::$cart[$index]) ? static::$cart[$index]['product_num'] : 0);
+        // 获取商品信息
+        $product = ProductModel::detail($productId);
+        // 验证商品能否加入
+        if (!$this->checkProduct($product, $productSkuId, $cartProductNum)) {
+            return false;
+        }
+        // 记录到购物车列表
+        static::$cart[$index] = [
+            'product_id' => $productId,
+            'product_num' => $cartProductNum,
+            'product_sku_id' => $productSkuId,
+            'create_time' => time()
+        ];
+        return true;
+    }
+
+    /**
+     * 验证商品是否可以购买
+     */
+    private function checkProduct($product, $productSkuId, $cartProductNum)
+    {
+        // 判断商品是否下架
+        if (!$product || $product['is_delete'] || $product['product_status']['value'] != 10) {
+            $this->setError('很抱歉,商品信息不存在或已下架');
+            return false;
+        }
+        // 商品sku信息
+        $product['product_sku'] = ProductModel::getProductSku($product, $productSkuId);
+        // 判断商品库存
+        if ($cartProductNum > $product['product_sku']['stock_num']) {
+            $this->setError('很抱歉,商品库存不足');
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 减少购物车中某商品数量
+     */
+    public function sub($productId, $productSkuId)
+    {
+        $index = "{$productId}_{$productSkuId}";
+        static::$cart[$index]['product_num'] > 1 && static::$cart[$index]['product_num']--;
+    }
+
+    /**
+     * 删除购物车中指定商品
+     * @param string $cartIds (支持字符串ID集)
+     */
+    public function delete($cartIds)
+    {
+        $indexArr = array_filter(trim(strpos($cartIds, ','), ',') !== false ? explode(',', $cartIds) : [$cartIds]);
+        foreach ($indexArr as $index) {
+            if (isset(static::$cart[$index])) unset(static::$cart[$index]);
+        }
+    }
+
+    /**
+     * 获取当前用户购物车商品总数量(含件数)
+     */
+    public function getTotalNum()
+    {
+        return helper::getArrayColumnSum(static::$cart, 'product_num');
+    }
+
+    /**
+     * 获取当前用户购物车商品总数量(不含件数)
+     */
+    public function getProductNum()
+    {
+        return count(static::$cart);
+    }
+
+    /**
+     * 析构方法
+     * 将cart数据保存到缓存文件
+     */
+    public function __destruct()
+    {
+        $this->clear !== true && Cache::set('cart_' . $this->user_id, static::$cart, 86400 * 15);
+    }
+
+    /**
+     * 清空当前用户购物车
+     */
+    public function clearAll($cartIds = null)
+    {
+        if (empty($cartIds)) {
+            $this->clear = true;
+            Cache::delete('cart_' . $this->user_id);
+        } else {
+            $this->delete($cartIds);
+        }
+    }
+
+    /**
+     * 设置错误信息
+     */
+    private function setError($error)
+    {
+        empty($this->error) && $this->error = $error;
+    }
+
+    /**
+     * 获取错误信息
+     */
+    public function getError()
+    {
+        return $this->error;
+    }
+
+}

+ 401 - 0
app/api/model/order/Order.php

@@ -0,0 +1,401 @@
+<?php
+
+namespace app\api\model\order;
+
+use app\api\model\product\Product as ProductModel;
+use app\api\service\order\paysuccess\type\MasterPaySuccessService;
+use app\api\service\order\PaymentService;
+use app\api\model\settings\Setting as SettingModel;
+use app\common\enum\order\OrderPayTypeEnum;
+use app\common\enum\order\OrderSourceEnum;
+use app\common\enum\order\OrderTypeEnum;
+use app\common\enum\order\OrderPayStatusEnum;
+use app\common\enum\order\OrderStatusEnum;
+use app\common\exception\BaseException;
+use app\common\service\order\OrderCompleteService;
+use app\common\enum\settings\DeliveryTypeEnum;
+use app\common\library\helper;
+use app\common\model\order\Order as OrderModel;
+use app\api\service\order\checkpay\CheckPayFactory;
+use app\common\service\product\factory\ProductFactory;
+use app\common\model\plus\coupon\UserCoupon as UserCouponModel;
+/**
+ * 普通订单模型
+ */
+class Order extends OrderModel
+{
+    /**
+     * 隐藏字段
+     * @var array
+     */
+    protected $hidden = [
+        'app_id',
+        'update_time'
+    ];
+
+    /**
+     * 订单支付事件
+     */
+    public function onPay($payType, $pay_source)
+    {
+        // 判断订单状态
+        $checkPay = CheckPayFactory::getFactory($this['order_source']);
+
+        if (!$checkPay->checkOrderStatus($this)) {
+            $this->error = $checkPay->getError();
+            return false;
+        }
+
+        // 余额支付
+        if ($payType == OrderPayTypeEnum::BALANCE) {
+            $data['attach'] = '{"pay_source":"' . $pay_source . '"}';
+            return $this->onPaymentByBalance($this['order_no'], $data);
+        }
+        return true;
+    }
+
+    /**
+     * 用户中心订单列表
+     */
+    public function getList($user_id, $type, $params)
+    {
+        // 筛选条件
+        $filter = [];
+        // 订单数据类型
+        switch ($type) {
+            case 'all':
+                break;
+            case 'payment';//待付款
+                $filter['pay_status'] = OrderPayStatusEnum::PENDING;//付款状态(10未付款)
+                $filter['order_status'] = 10;//订单状态10=>进行中
+                break;
+            case 'delivery';//代发货
+                $filter['pay_status'] = OrderPayStatusEnum::SUCCESS;//已付款
+                $filter['delivery_status'] = 10;//未发货
+                $filter['order_status'] = 10;//订单状态10=>进行中
+                break;
+            case 'received';//待收货
+                $filter['pay_status'] = OrderPayStatusEnum::SUCCESS;
+                $filter['delivery_status'] = 20;//已发货
+                $filter['receipt_status'] = 10;//未收货
+                $filter['order_status'] = 10;//订单状态10=>进行中
+                break;
+            case 'comment';//待评价
+                $filter['is_comment'] = 0;//未评价
+                $filter['order_status'] = 30;//订单状态30=>已完成
+                break;
+        }
+        return $this->with(['product.image'])
+            ->where('user_id', '=', $user_id)
+            ->where($filter)
+            ->where('is_delete', '=', 0)
+            ->order(['create_time' => 'desc'])
+            ->paginate($params);
+    }
+
+    /**
+     * 确认收货
+     */
+    public function receipt()
+    {
+        // 验证订单是否合法
+        // 条件1: 订单必须已发货
+        // 条件2: 订单必须未收货
+        if ($this['delivery_status']['value'] != 20 || $this['receipt_status']['value'] != 10) {
+            $this->error = '该订单不合法';
+            return false;
+        }
+        return $this->transaction(function () {
+            // 更新订单状态
+            $status = $this->save([
+                'receipt_status' => 20,
+                'receipt_time' => time(),
+                'order_status' => 30
+            ]);
+            // 执行订单完成后的操作
+            $OrderCompleteService = new OrderCompleteService(OrderTypeEnum::MASTER);
+            $OrderCompleteService->complete([$this], static::$app_id);
+            return $status;
+        });
+    }
+
+    /**
+     * 立即购买:获取订单商品列表
+     */
+    public static function getOrderProductListByNow($params)
+    {
+        // 商品详情
+        $product = ProductModel::detail($params['product_id']);
+        // 商品sku信息
+        $product['product_sku'] = ProductModel::getProductSku($product, $params['product_sku_id']);
+        $product['total_pv']    = helper::bcmul($product['pv'], $params['product_num']);
+       
+        // 商品列表
+        $productList = [$product->hidden(['category', 'content', 'image', 'sku'])];
+        foreach ($productList as &$item) {                    
+            // 商品单价
+            $item['product_price'] = $item['product_sku']['product_price'];
+            // 商品购买数量
+            $item['total_num']   = $params['product_num'];
+            $item['spec_sku_id'] = $item['product_sku']['spec_sku_id'];
+            $item['pv']          = $item['product_sku']['pv'];      
+            $item['total_pv']      = helper::bcmul($item['pv'], $params['product_num']);
+            // 商品购买总金额
+            $item['total_price'] = helper::bcmul($item['product_price'], $params['product_num']);
+        }
+       
+        return $productList;
+    }
+
+    /**
+     * 获取订单总数
+     */
+    public function getCount($user, $type = 'all')
+    {
+        if ($user === false) {
+            return false;
+        }
+        // 筛选条件
+        $filter = [];
+        // 订单数据类型
+        switch ($type) {
+            case 'all':
+                break;
+            case 'payment';
+                $filter['pay_status'] = OrderPayStatusEnum::PENDING;
+                break;
+            case 'delivery';
+                $filter['pay_status'] = OrderPayStatusEnum::SUCCESS;
+                $filter['delivery_status'] = 10;
+                $filter['order_status'] = 10;
+                break;    
+            case 'received';
+                $filter['pay_status'] = OrderPayStatusEnum::SUCCESS;
+                $filter['delivery_status'] = 20;
+                $filter['receipt_status'] = 10;
+                break;
+            case 'comment';
+                $filter['order_status'] = 30;
+                $filter['is_comment'] = 0;
+                break;
+        }
+        return $this->where('user_id', '=', $user['user_id'])
+            ->where('order_status', '<>', 20)
+            ->where($filter)
+            ->where('is_delete', '=', 0)
+            ->count();
+    }
+
+    /**
+     * 取消订单
+     */
+    public function cancel($user)
+    {
+        if ($this['delivery_status']['value'] == 20) {
+            $this->error = '已发货订单不可取消';
+            return false;
+        }
+        //进行中的拼团订单不能取消
+        if($this['order_source'] == OrderSourceEnum::ASSEMBLE){
+            if($this['assemble_status'] == 10){
+                $this->error = '订单正在拼团,到期后如果订单未拼团成功将自动退款';
+                return false;
+            }
+        }
+        // 订单取消事件
+        return $this->transaction(function () use ($user) {
+            // 订单是否已支付
+            $isPay = $this['pay_status']['value'] == OrderPayStatusEnum::SUCCESS;
+            // 未付款的订单
+            if ($isPay == false) {
+                //主商品退回库存
+                ProductFactory::getFactory($this['order_source'])->backProductStock($this['product'], $isPay);
+                // 回退用户优惠券
+                $this['coupon_id'] > 0 && UserCouponModel::setIsUse($this['coupon_id'], false);
+                // 回退用户积分
+                $describe = "订单取消:{$this['order_no']}";
+                $this['points_num'] > 0 && $user->setIncPoints($this['points_num'], $describe);
+            }
+            // 更新订单状态
+            return $this->save(['order_status' => $isPay ? OrderStatusEnum::APPLY_CANCEL : OrderStatusEnum::CANCELLED]);
+        });
+    }
+
+    /**
+     * 订单详情
+     */
+    public static function getUserOrderDetail($order_id, $user_id)
+    {
+        $model = new static();
+        $order = $model->where(['order_id' => $order_id, 'user_id' => $user_id])->with(['product' => ['image', 'refund','last_refund'], 'address', 'express', 'extractStore'])->find();
+        if (empty($order)) {
+            throw new BaseException(['msg' => '订单不存在']);
+        }
+        return $order;
+    }
+
+    /**
+     * 余额支付标记订单已支付
+     */
+    public function onPaymentByBalance($orderNo, $data)
+    {
+        // 获取订单详情
+        $PaySuccess = new MasterPaySuccessService($orderNo);
+        // 发起余额支付
+        $status = $PaySuccess->onPaySuccess(OrderPayTypeEnum::BALANCE, $data);
+        if (!$status) {
+            $this->error = $PaySuccess->getError();
+        }
+        return $status;
+    }
+
+    /**
+     * 构建微信支付请求
+     */
+    protected static function onPaymentByWechat($user, $order, $pay_source)
+    {
+        return PaymentService::wechat(
+            $user,
+            $order['order_id'],
+            $order['order_no'],
+            $order['pay_price'],
+            OrderTypeEnum::MASTER,
+            $pay_source
+        );
+    }
+
+    /**
+     * 待支付订单详情
+     */
+    public static function getPayDetail($orderNo, $pay_status)
+    {
+        $model = new static();
+        $model = $model->where('order_no', '=', $orderNo)->where('is_delete', '=', 0);
+        if($pay_status > 0){
+            $model = $model->where('pay_status', '=', 10);
+        }
+        return $model->with(['product', 'user'])->find();
+    }
+
+    /**
+     * 构建支付请求的参数
+     */
+    public static function onOrderPayment($user, $order, $payType, $pay_source)
+    {
+        //如果来源是h5,首次不处理,payH5再处理
+        if($pay_source == 'h5'){
+            return [];
+        }
+        if ($payType == OrderPayTypeEnum::WECHAT) {
+            return self::onPaymentByWechat($user, $order, $pay_source);
+        }
+        if ($payType == OrderPayTypeEnum::ALIPAY) {
+            return self::onPaymentByAlipay($user, $order, $pay_source);
+        }
+        return [];
+    }
+
+    /**
+     * 判断当前订单是否允许核销
+     */
+    public function checkExtractOrder($order)
+    {
+        if (
+            $order['pay_status']['value'] == OrderPayStatusEnum::SUCCESS
+            && $order['delivery_type']['value'] == DeliveryTypeEnum::EXTRACT
+            && $order['delivery_status']['value'] == 10
+        ) {
+            return true;
+        }
+        $this->setError('该订单不能被核销');
+        return false;
+    }
+
+    /**
+     * 当前订单是否允许申请售后
+     */
+    public function isAllowRefund()
+    {
+        // 必须是已发货的订单
+        if ($this['delivery_status']['value'] != 20) {
+            return false;
+        }
+        // 允许申请售后期限(天)
+        $refundDays = SettingModel::getItem('trade')['order']['refund_days'];
+        // 不允许售后
+        if ($refundDays == 0) {
+            return false;
+        }
+        // 当前时间超出允许申请售后期限
+        if (
+            $this['receipt_status']['value'] == 20
+            && time() > ($this['receipt_time'] + ((int)$refundDays * 86400))
+        ) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 获取活动订单
+     * 已付款,未取消
+     */
+    public static function getPlusOrderNum($user_id, $product_id, $order_source)
+    {
+        $model = new static();
+        return $model->alias('order')->where('order.user_id', '=', $user_id)
+            ->join('order_product', 'order_product.order_id = order.order_id', 'left')
+            ->where('order_product.product_source_id', '=', $product_id)
+            ->where('order.pay_status', '=', 20)
+            ->where('order.order_source', '=', $order_source)
+            ->where('order.order_status', '<>', 20)
+            ->count();
+    }
+
+    /**
+     * 构建支付宝请求
+     */
+    protected static function onPaymentByAlipay($user, $order, $pay_source)
+    {
+        return PaymentService::alipay(
+            $user,
+            $order['order_id'],
+            $order['order_no'],
+            $order['pay_price'],
+            OrderTypeEnum::MASTER,
+            $pay_source
+        );
+    }
+
+    /**
+     * 主订单购买的数量
+     * 未取消的订单
+     */
+    public static function getHasBuyOrderNum($user_id, $product_id)
+    {
+        $model = new static();
+        return $model->alias('order')->where('order.user_id', '=', $user_id)
+            ->join('order_product', 'order_product.order_id = order.order_id', 'left')
+            ->where('order_product.product_id', '=', $product_id)
+            ->where('order.order_source', '=', OrderSourceEnum::MASTER)
+            ->where('order.pay_status', '<>', 10)
+            ->sum('total_num');
+    }
+
+    /**
+     * 设置错误信息
+     */
+    protected function setError($error)
+    {
+        empty($this->error) && $this->error = $error;
+    }
+
+    /**
+     * 是否存在错误
+     */
+    public function hasError()
+    {
+        return !empty($this->error);
+    }
+
+}

+ 20 - 0
app/api/model/order/OrderAddress.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace app\api\model\order;
+
+use app\common\model\order\OrderAddress as OrderAddressModel;
+
+/**
+ * 订单地址模型
+ */
+class OrderAddress extends OrderAddressModel
+{
+    /**
+     * 隐藏字段
+     */
+    protected $hidden = [
+        'app_id',
+        'create_time',
+    ];
+
+}

+ 11 - 0
app/api/model/order/OrderExtract.php

@@ -0,0 +1,11 @@
+<?php
+
+namespace app\api\model\order;
+use app\common\model\order\OrderExtract as OrderExtractModel;
+/**
+ * 自提订单联系方式记录模型
+ */
+class OrderExtract extends OrderExtractModel
+{
+    
+}

+ 28 - 0
app/api/model/order/OrderProduct.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace app\api\model\order;
+
+use app\common\model\order\OrderProduct as OrderProductModel;
+
+/**
+ * 商品订单模型
+ */
+class OrderProduct extends OrderProductModel
+{
+    /**
+     * 隐藏字段
+     */
+    protected $hidden = [
+        'content',
+        'app_id',
+        'create_time',
+    ];
+
+    /**
+     * 获取未评价的商品
+     */
+    public function getNotCommentProductList($order_id)
+    {
+        return $this->where(['order_id' => $order_id, 'is_comment' => 0])->with(['orderM', 'image'])->select();
+    }
+}

+ 156 - 0
app/api/model/order/OrderRefund.php

@@ -0,0 +1,156 @@
+<?php
+
+namespace app\api\model\order;
+
+use app\common\model\order\OrderRefund as OrderRefundModel;
+
+/**
+ * 售后单模型
+ */
+class OrderRefund extends OrderRefundModel
+{
+    /**
+     * 隐藏字段
+     * @var array
+     */
+    protected $hidden = [
+        'app_id',
+        'update_time'
+    ];
+
+    /**
+     * 追加字段
+     * @var array
+     */
+    protected $append = [
+        'state_text',   // 售后单状态文字描述
+    ];
+
+    /**
+     * 售后单状态文字描述
+     */
+    public function getStateTextAttr($value, $data)
+    {
+        // 已完成
+        if ($data['status'] == 20) {
+            $text = [10 => '已同意退货并已退款', 20 => '已同意换货并已收货', '30' => '仅退款并已退款'];
+            return $text[$data['type']];
+        }
+        // 已取消
+        if ($data['status'] == 30) {
+            return '已取消';
+        }
+        // 已拒绝
+        if ($data['status'] == 10) {
+//            return $data['type'] == 10 ? '已拒绝退货退款' : '已拒绝换货';
+//            售后类型(10退货退款 20换货 30退款)
+            $map = [10=>'已拒绝退货退款',20=>'已拒绝换货',30=>'已拒绝退款'];
+            return $map[$data['type']] ?? '已拒绝';
+        }
+        // 进行中
+        if ($data['status'] == 0) {
+            if ($data['is_agree'] == 0) {
+                return '等待审核中';
+            }
+            if ($data['type'] == 10) {
+                return $data['is_user_send'] ? '已发货,待平台确认' : '已同意退货,请及时发货';
+            }
+            if ($data['type'] == 20) {
+                return $data['is_user_send'] ? '已发货,待平台确认' : '已同意换货,请及时发货';
+            }
+        }
+        return $value;
+    }
+
+    /**
+     * 获取用户售后单列表
+     */
+    public function getList($user_id, $state, $limit)
+    {
+        $model = $this;
+        $state > -1 && $model = $this->where('status', '=', $state);
+
+        return $model->with(['order_master', 'orderproduct.image'])
+            ->where('user_id', '=', $user_id)
+            ->order(['create_time' => 'desc'])
+            ->paginate($limit);
+    }
+
+    /**
+     * 用户发货
+     */
+    public function delivery($data)
+    {
+        if ($this['is_agree']['value'] != 10 || $this['is_user_send'] != 0) {
+            $this->error = '当前售后单不合法,不允许该操作';
+            return false;
+        }
+        if ($data['express_id'] <= 0) {
+            $this->error = '请选择物流公司';
+            return false;
+        }
+        if (empty($data['express_no'])) {
+            $this->error = '请填写物流单号';
+            return false;
+        }
+        return $this->save([
+            'is_user_send' => 1,
+            'send_time' => time(),
+            'express_id' => (int)$data['express_id'],
+            'express_no' => $data['express_no'],
+        ]);
+    }
+
+    /**
+     * 新增售后单记录
+     */
+    public function apply($user, $product, $data)
+    {
+        $this->startTrans();
+        try {
+            // 新增售后单记录
+            $this->save([
+                'order_product_id' => $data['order_product_id'],
+                'order_id' => $product['order_id'],
+                'user_id' => $user['user_id'],
+                'type' => $data['type'],
+                'apply_desc' => $data['content'],
+                'is_agree' => 0,
+                'status' => 0,
+                'app_id' => self::$app_id,
+            ]);
+            // 记录凭证图片关系
+            if (isset($data['images']) && !empty($data['images'])) {
+                $this->saveImages($this['order_refund_id'], $data['images']);
+            }
+            $this->commit();
+            return true;
+        } catch (\Exception $e) {
+            $this->error = $e->getMessage();
+            $this->rollback();
+            return false;
+        }
+    }
+
+    /**
+     * 记录售后单图片
+     */
+    private function saveImages($order_refund_id, $images)
+    {
+        $images_ids = [];
+        foreach (json_decode($images, true) as $val) {
+            $images_ids[] = $val['file_id'];
+        }
+        // 生成评价图片数据
+        $data = [];
+        foreach ($images_ids as $image_id) {
+            $data[] = [
+                'order_refund_id' => $order_refund_id,
+                'image_id' => $image_id,
+                'app_id' => self::$app_id
+            ];
+        }
+        return !empty($data) && (new OrderRefundImage)->saveAll($data);
+    }
+
+}

+ 20 - 0
app/api/model/order/OrderRefundAddress.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace app\api\model\order;
+
+use app\common\model\order\OrderRefundAddress as OrderRefundAddressModel;
+
+/**
+ * 售后单退货地址模型
+ */
+class OrderRefundAddress extends OrderRefundAddressModel
+{
+    /**
+     * 隐藏字段
+     */
+    protected $hidden = [
+        'app_id',
+        'create_time'
+    ];
+
+}

+ 13 - 0
app/api/model/order/OrderRefundImage.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace app\api\model\order;
+
+use app\common\model\order\OrderRefundImage as OrderRefundImageModel;
+
+/**
+ * 售后单图片模型
+ */
+class OrderRefundImage extends OrderRefundImageModel
+{
+
+}

+ 269 - 0
app/api/model/page/Page.php

@@ -0,0 +1,269 @@
+<?php
+
+namespace app\api\model\page;
+
+use app\api\model\plus\live\WxLive;
+use app\api\model\product\Product as ProductModel;
+use app\api\model\plus\article\Article;
+use app\api\model\store\Store as StoreModel;
+use app\common\model\page\Page as PageModel;
+use app\api\model\plus\coupon\Coupon;
+use app\api\model\plus\seckill\Product as SeckillProductModel;
+use app\api\model\plus\seckill\Active as SeckillActiveModel;
+use app\api\model\plus\assemble\Product as AssembleProductModel;
+use app\api\model\plus\assemble\Active as AssembleActiveModel;
+use app\api\model\plus\bargain\Product as BargainProductModel;
+use app\api\model\plus\bargain\Active as BargainActiveModel;
+/**
+ * 首页模型
+ */
+class Page extends PageModel
+{
+    /**
+     * 隐藏字段
+     */
+    protected $hidden = [
+        'app_id',
+        'create_time',
+        'update_time'
+    ];
+
+    /**
+     * DIY页面详情
+     */
+    public static function getPageData($user, $page_id = null)
+    {
+        // 页面详情
+        $detail = $page_id > 0 ? parent::detail($page_id) : parent::getHomePage();
+
+        // 页面diy元素
+        $items = $detail['page_data']['items'];
+        // 页面顶部导航
+        isset($detail['page_data']['page']) && $items['page'] = $detail['page_data']['page'];
+        // 获取动态数据
+        $model = new self;
+       
+        foreach ($items as $key => $item) { 
+            
+            unset($items[$key]['defaultData']);
+            if ($item['type'] === 'window') {
+                $items[$key]['data'] = array_values($item['data']);
+            } else if ($item['type'] === 'product') {
+                $items[$key]['data'] = $model->getProductList($user, $item);
+            } else if ($item['type'] === 'coupon') {
+                $items[$key]['data'] = $model->getCouponList($user, $item);
+            } else if ($item['type'] === 'article') {
+                $items[$key]['data'] = $model->getArticleList($item);
+            } else if ($item['type'] === 'special') {
+                $items[$key]['data'] = $model->getSpecialList($item);
+            } else if ($item['type'] === 'store') {
+                $items[$key]['data'] = $model->getStoreList($item);
+            } else if ($item['type'] === 'seckillProduct') {
+                // 如果没有活动,则不显示
+                $item_data = $model->getSeckillList($item);
+                if(empty($item_data)){
+                    unset($items[$key]);
+                }else{
+                    $items[$key]['data'] = $item_data;
+                }
+            } else if ($item['type'] === 'assembleProduct') {
+                // 如果没有活动,则不显示
+                $item_data = $model->getAssembleList($item);
+                if(empty($item_data)){
+                    unset($items[$key]);
+                }else{
+                    $items[$key]['data'] = $item_data;
+                }
+            } else if ($item['type'] === 'bargainProduct') {
+                // 如果没有活动,则不显示
+                $item_data = $model->getBargainList($item);
+                if(empty($item_data)){
+                    unset($items[$key]);
+                }else{
+                    $items[$key]['data'] = $item_data;
+                }
+            } else if ($item['type'] === 'wxlive') {
+                $items[$key]['data'] = $model->getWxLiveList($item);
+            }else if ($item['type'] === 'banner') {
+                          
+                $items[$key]['data'] = $model->getBannerList($item);
+            }
+        }
+        return ['page' => $items['page'], 'items' => $items];
+    }
+     /**
+     * 商品组件:获取商品列表
+     */
+    private function getBannerList($item)
+    {
+        if(!empty($item['data'])){
+            $data = [];
+            foreach ($item['data'] as $key => $val) { 
+                if(!empty($val['name']) && empty($val['linkUrl'])){
+                    $val['linkUrl'] = $val['name'];
+                }
+                $data[] = $val;
+            }
+            return $data;   
+        }else{
+            return [];   
+        }
+        
+    }
+
+    /**
+     * 商品组件:获取商品列表
+     */
+    private function getProductList($user, $item)
+    {
+        // 获取商品数据
+        $model = new ProductModel;
+        if ($item['params']['source'] === 'choice') {
+            // 数据来源:手动
+            $productIds = array_column($item['data'], 'product_id');
+            $productList = $model->getListByIdsFromApi($productIds, $user);
+        } else {
+            // 数据来源:自动
+            $productList = $model->getList([
+                'type' => 'sell',
+                'category_id' => $item['params']['auto']['category'],
+                'sortType' => $item['params']['auto']['productSort'],
+                'list_rows' => $item['params']['auto']['showNum']
+            ], $user);
+        }
+        if ($productList->isEmpty()) return [];
+        // 格式化商品列表
+        $data = [];
+        foreach ($productList as $product) {
+            $show_sku = ProductModel::getShowSku($product);
+            $data[] = [
+                'product_id' => $product['product_id'],
+                'product_name' => $product['product_name'],
+                'selling_point' => $product['selling_point'],
+                'image' => $product['image'][0]['file_path'],
+                'product_image' => $product['image'][0]['file_path'],
+                'product_price' => $show_sku['product_price'],
+                'line_price' => $show_sku['line_price'],
+                'product_sales' => $product['product_sales'],
+            ];
+        }
+        return $data;
+    }
+
+    /**
+     * 优惠券组件:获取优惠券列表
+     */
+    private function getCouponList($user, $item)
+    {
+        // 获取优惠券数据
+        return (new Coupon)->getList($user, $item['params']['limit'], true);
+    }
+
+    /**
+     * 文章组件:获取文章列表
+     */
+    private function getArticleList($item)
+    {
+        // 获取文章数据
+        $model = new Article;
+        $articleList = $model->getList($item['params']['auto']['category'], $item['params']['auto']['showNum']);
+        return $articleList->isEmpty() ? [] : $articleList->toArray()['data'];
+    }
+
+    /**
+     * 头条快报:获取头条列表
+     */
+    private function getSpecialList($item)
+    {
+        // 获取头条数据
+        $model = new Article;
+        $articleList = $model->getList($item['params']['auto']['category'], $item['params']['auto']['showNum']);
+        return $articleList->isEmpty() ? [] : $articleList->toArray()['data'];
+    }
+
+    /**
+     * 线下门店组件:获取门店列表
+     */
+    private function getStoreList($item)
+    {
+        // 获取商品数据
+        $model = new StoreModel;
+        if ($item['params']['source'] === 'choice') {
+            // 数据来源:手动
+            $storeIds = array_column($item['data'], 'store_id');
+            $storeList = $model->getListByIds($storeIds);
+        } else {
+            // 数据来源:自动
+            $storeList = $model->getList(null, false, false, $item['params']['auto']['showNum']);
+        }
+        if ($storeList->isEmpty()) return [];
+        // 格式化商品列表
+        $data = [];
+        foreach ($storeList as $store) {
+            $data[] = [
+                'store_id' => $store['store_id'],
+                'store_name' => $store['store_name'],
+                'logo_image' => $store['logo']['file_path'],
+                'phone' => $store['phone'],
+                'region' => $store['region'],
+                'address' => $store['address'],
+            ];
+        }
+        return $data;
+    }
+
+    /**
+     * 获取限时秒杀
+     */
+    private function getSeckillList($item)
+    {
+        // 获取秒杀数据
+        $seckill = SeckillActiveModel::getActive();
+        if($seckill){
+            $product_model = new SeckillProductModel;
+            $seckill['product_list'] = $product_model->getProductList($seckill['seckill_activity_id'], $item['params']['showNum']);
+        }
+        return $seckill;
+    }
+
+    /**
+     * 获取限时拼团
+     */
+    private function getAssembleList($item)
+    {
+        // 获取拼团数据
+        $assemble = AssembleActiveModel::getActive();
+        if($assemble){
+            $assemble->visible(['assemble_activity_id','title', 'start_time', 'end_time']);
+            $product_model = new AssembleProductModel;
+            $assemble['product_list'] = $product_model->getProductList($assemble['assemble_activity_id'], $item['params']['showNum']);
+        }
+        return $assemble;
+    }
+
+    /**
+     * 获取限时砍价
+     */
+    private function getBargainList($item)
+    {
+        // 获取拼团数据
+        $bargain = BargainActiveModel::getActive();
+        if($bargain){
+            $bargain->visible(['bargain_activity_id','title', 'start_time', 'end_time']);
+            $product_model = new BargainProductModel;
+            $bargain['product_list'] = $product_model->getProductList($bargain['bargain_activity_id'], $item['params']['showNum']);
+        }
+        return $bargain;
+    }
+
+    /**
+     * 微信直播
+     */
+    private function getWxLiveList($item)
+    {
+        // 获取头条数据
+        $model = new WxLive();
+        $liveList = $model->getList($item['params']['showNum']);
+        return $liveList->isEmpty() ? [] : $liveList->toArray()['data'];
+    }
+}

+ 97 - 0
app/api/model/plus/agent/Apply.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace app\api\model\plus\agent;
+
+use app\api\model\plus\agent\Referee as RefereeModel;
+use app\common\model\plus\agent\Apply as ApplyModel;
+
+/**
+ * 分销商申请模型
+ */
+class Apply extends ApplyModel
+{
+    /**
+     * 隐藏字段
+     * @var array
+     */
+    protected $hidden = [
+        'create_time',
+        'update_time',
+    ];
+
+    /**
+     * 是否为分销商申请中
+     */
+    public static function isApplying($user_id)
+    {
+        $detail = self::detail(['user_id' => $user_id]);
+        return $detail ? ((int)$detail['apply_status']['value'] === 10) : false;
+    }
+
+    /**
+     * 提交申请
+     */
+    public function submit($user, $data)
+    {
+        // 成为分销商条件
+        $config = Setting::getItem('condition');
+        // 如果之前有关联分销商,则继续关联之前的分销商
+        $has_referee_id = Referee::getRefereeUserId($user['user_id'], 1);
+        if($has_referee_id > 0){
+            $referee_id = $has_referee_id;
+        }else{
+            $referee_id = $data['referee_id'] > 0 ?$data['referee_id']:0;
+        }
+        // 数据整理
+        $data = [
+            'user_id' => $user['user_id'],
+            'real_name' => trim($data['name']),
+            'mobile' => trim($data['mobile']),
+            'referee_id' => $referee_id,
+            'apply_type' => $config['become'],
+            'apply_time' => time(),
+            'app_id' => self::$app_id,
+        ];
+        if ($config['become'] == 10) {
+            $data['apply_status'] = 10;
+        } elseif ($config['become'] == 20) {
+            $data['apply_status'] = 20;
+        }
+        return $this->add($user, $data);
+    }
+
+    /**
+     * 更新分销商申请信息
+     */
+    private function add($user, $data)
+    {
+        // 实例化模型
+        $model = self::detail(['user_id' => $user['user_id']]) ?: $this;
+        // 更新记录
+        $this->startTrans();
+        try {
+            // 保存申请信息
+            $model->save($data);
+            // 无需审核,自动通过
+            if ($data['apply_type'] == 20) {
+                // 新增分销商用户记录
+                User::add($user['user_id'], [
+                    'real_name' => $data['real_name'],
+                    'mobile' => $data['mobile'],
+                    'referee_id' => $data['referee_id']
+                ]);
+            }
+            // 记录推荐人关系
+            if ($data['referee_id'] > 0) {
+                RefereeModel::createRelation($user['user_id'], $data['referee_id']);
+            }
+            $this->commit();
+            return true;
+        } catch (\Exception $e) {
+            $this->error = $e->getMessage();
+            $this->rollback();
+            return false;
+        }
+    }
+
+}

+ 20 - 0
app/api/model/plus/agent/Capital.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace app\api\model\plus\agent;
+
+use app\common\model\plus\agent\Capital as CapitalModel;
+
+/**
+ * 分销商资金明细模型
+ */
+class Capital extends CapitalModel
+{
+    /**
+     * 隐藏字段
+     */
+    protected $hidden = [
+        'create_time',
+        'update_time',
+    ];
+
+}

+ 83 - 0
app/api/model/plus/agent/Cash.php

@@ -0,0 +1,83 @@
+<?php
+
+namespace app\api\model\plus\agent;
+
+use app\common\exception\BaseException;
+use app\common\model\plus\agent\Cash as CashModel;
+
+/**
+ * 分销商提现明细模型
+ */
+class Cash extends CashModel
+{
+    /**
+     * 隐藏字段
+     */
+    protected $hidden = [
+        'update_time',
+    ];
+
+    /**
+     * 获取分销商提现明细
+     */
+    public function getList($user_id, $apply_status = -1,$limit=15)
+    {
+        $model = $this;
+        $apply_status > -1 && $model = $model->where('apply_status', '=', $apply_status);
+        return $model->where('user_id', '=', $user_id)->order(['create_time' => 'desc'])
+            ->paginate($limit);
+    }
+
+    /**
+     * 提交申请
+     */
+    public function submit($agent, $data)
+    {
+        // 数据验证
+        $this->validation($agent, $data);
+        // 新增申请记录
+        $this->save(array_merge($data, [
+            'user_id' => $agent['user_id'],
+            'apply_status' => 10,
+            'app_id' => self::$app_id,
+        ]));
+        // 冻结用户资金
+        $agent->freezeMoney($data['money']);
+        return true;
+    }
+
+    /**
+     * 数据验证
+     */
+    private function validation($agent, $data)
+    {
+        // 结算设置
+        $settlement = Setting::getItem('settlement');
+        // 最低提现佣金
+        if ($data['money'] <= 0) {
+            throw new BaseException(['msg' => '提现金额不正确']);
+        }
+        if ($agent['money'] <= 0) {
+            throw new BaseException(['msg' => '当前用户没有可提现佣金']);
+        }
+        if ($data['money'] > $agent['money']) {
+            throw new BaseException(['msg' => '提现金额不能大于可提现佣金']);
+        }
+        if ($data['money'] < $settlement['min_money']) {
+            throw new BaseException(['msg' => '最低提现金额为' . $settlement['min_money']]);
+        }
+        if (!in_array($data['pay_type'], $settlement['pay_type'])) {
+            throw new BaseException(['msg' => '提现方式不正确']);
+        }
+        if ($data['pay_type'] == '20') {
+            if (empty($data['alipay_name']) || empty($data['alipay_account'])) {
+                throw new BaseException(['msg' => '请补全提现信息']);
+            }
+        } elseif ($data['pay_type'] == '30') {
+            if (empty($data['bank_name']) || empty($data['bank_account']) || empty($data['bank_card'])) {
+                throw new BaseException(['msg' => '请补全提现信息']);
+            }
+        }
+    }
+
+}

+ 102 - 0
app/api/model/plus/agent/Order.php

@@ -0,0 +1,102 @@
+<?php
+
+namespace app\api\model\plus\agent;
+
+use app\common\model\plus\agent\Order as OrderModel;
+use app\common\service\order\OrderService;
+use app\common\enum\order\OrderTypeEnum;
+
+/**
+ * 分销商订单模型
+ */
+class Order extends OrderModel
+{
+    /**
+     * 隐藏字段
+     */
+    protected $hidden = [
+        'update_time',
+    ];
+
+    /**
+     * 获取分销商订单列表
+     */
+    public function getList($user_id, $is_settled = -1)
+    {
+        $model = $this;
+        $is_settled > -1 && $model = $model->where('is_settled', '=', !!$is_settled);
+        $data = $model->with(['user'])
+            ->where('first_user_id|second_user_id|third_user_id', '=', $user_id)
+            ->order(['create_time' => 'desc'])
+            ->paginate(15);
+        if ($data->isEmpty()) {
+            return $data;
+        }
+        // 整理订单信息
+        $with = ['product' => ['image', 'refund'], 'address', 'user'];
+        return OrderService::getOrderList($data, 'order_master', $with);
+    }
+
+    /**
+     * 创建分销商订单记录
+     */
+    public static function createOrder($order, $order_type = OrderTypeEnum::MASTER)
+    {
+        // 分销订单模型
+        $model = new self;
+        // 分销商基本设置
+        $setting = Setting::getItem('basic', $order['app_id']);
+        // 是否开启分销功能
+        if (!$setting['is_open']) {
+            return false;
+        }
+        // 获取当前买家的所有上级分销商用户id
+        $agentUser = $model->getAgentUserId($order['user_id'], $setting['level'], $setting['self_buy']);
+        // 非分销订单
+        if (!$agentUser['first_user_id']) {
+            return false;
+        }
+        // 计算订单分销佣金
+        $capital = $model->getCapitalByOrder($order, 'create');
+        if(!$capital['is_record']){
+            return false;
+        }
+        // 保存分销订单记录
+        return $model->save([
+            'user_id' => $order['user_id'],
+            'order_id' => $order['order_id'],
+            'order_type' => $order_type,
+            'order_price' => $capital['orderPrice'],
+            'first_money' => $agentUser['first_user_id'] > 0?max($capital['first_money'], 0):0,
+            'second_money' => $agentUser['second_user_id'] > 0?max($capital['second_money'], 0):0,
+            'third_money' => $agentUser['third_user_id'] > 0?max($capital['third_money'], 0):0,
+            'first_user_id' => $agentUser['first_user_id'],
+            'second_user_id' => $agentUser['second_user_id'],
+            'third_user_id' => $agentUser['third_user_id'],
+            'is_settled' => 0,
+            'app_id' => $order['app_id']
+        ]);
+    }
+
+    /**
+     * 获取当前买家的所有上级分销商用户id
+     */
+    private function getAgentUserId($user_id, $level, $self_buy)
+    {
+        $agentUser = [
+            'first_user_id' => $level >= 1 ? Referee::getRefereeUserId($user_id, 1, true) : 0,
+            'second_user_id' => $level >= 2 ? Referee::getRefereeUserId($user_id, 2, true) : 0,
+            'third_user_id' => $level == 3 ? Referee::getRefereeUserId($user_id, 3, true) : 0
+        ];
+        // 分销商自购
+        if ($self_buy && User::isAgentUser($user_id)) {
+            return [
+                'first_user_id' => $user_id,
+                'second_user_id' => $agentUser['first_user_id'],
+                'third_user_id' => $agentUser['second_user_id'],
+            ];
+        }
+        return $agentUser;
+    }
+
+}

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно