Kirin 3 years ago
parent
commit
80169d6661
100 changed files with 11245 additions and 0 deletions
  1. 1 0
      .example.env
  2. 9 0
      .gitignore
  3. 42 0
      .travis.yml
  4. 2 0
      .version
  5. 32 0
      LICENSE.txt
  6. 1 0
      app/.htaccess
  7. 32 0
      app/AppService.php
  8. 86 0
      app/ExceptionHandle.php
  9. 113 0
      app/Request.php
  10. 56 0
      app/command/ClearCacheAttachment.php
  11. 52 0
      app/command/ClearMerchantData.php
  12. 57 0
      app/command/FormatMenuPath.php
  13. 119 0
      app/command/VersionUpdate.php
  14. 115 0
      app/command/updateMenu.php
  15. 67 0
      app/command/updateSpu.php
  16. 884 0
      app/common.php
  17. 281 0
      app/common/dao/BaseDao.php
  18. 143 0
      app/common/dao/article/ArticleCategoryDao.php
  19. 32 0
      app/common/dao/article/ArticleContentDao.php
  20. 175 0
      app/common/dao/article/ArticleDao.php
  21. 60 0
      app/common/dao/store/ExcelDao.php
  22. 119 0
      app/common/dao/store/StoreAttrTemplateDao.php
  23. 68 0
      app/common/dao/store/StoreBrandCategoryDao.php
  24. 62 0
      app/common/dao/store/StoreBrandDao.php
  25. 67 0
      app/common/dao/store/StoreCategoryDao.php
  26. 143 0
      app/common/dao/store/StoreSeckillActiveDao.php
  27. 112 0
      app/common/dao/store/StoreSeckillTimeDao.php
  28. 133 0
      app/common/dao/store/broadcast/BroadcastGoodsDao.php
  29. 156 0
      app/common/dao/store/broadcast/BroadcastRoomDao.php
  30. 65 0
      app/common/dao/store/broadcast/BroadcastRoomGoodsDao.php
  31. 270 0
      app/common/dao/store/coupon/StoreCouponDao.php
  32. 55 0
      app/common/dao/store/coupon/StoreCouponIssueUserDao.php
  33. 77 0
      app/common/dao/store/coupon/StoreCouponProductDao.php
  34. 43 0
      app/common/dao/store/coupon/StoreCouponSendDao.php
  35. 106 0
      app/common/dao/store/coupon/StoreCouponUserDao.php
  36. 57 0
      app/common/dao/store/order/MerchantReconciliationDao.php
  37. 34 0
      app/common/dao/store/order/MerchantReconciliationOrderDao.php
  38. 62 0
      app/common/dao/store/order/PresellOrderDao.php
  39. 142 0
      app/common/dao/store/order/StoreCartDao.php
  40. 95 0
      app/common/dao/store/order/StoreGroupOrderDao.php
  41. 33 0
      app/common/dao/store/order/StoreImportDao.php
  42. 33 0
      app/common/dao/store/order/StoreImportDeliveryDao.php
  43. 711 0
      app/common/dao/store/order/StoreOrderDao.php
  44. 132 0
      app/common/dao/store/order/StoreOrderProductDao.php
  45. 100 0
      app/common/dao/store/order/StoreOrderReceiptDao.php
  46. 58 0
      app/common/dao/store/order/StoreOrderStatusDao.php
  47. 155 0
      app/common/dao/store/order/StoreRefundOrderDao.php
  48. 37 0
      app/common/dao/store/order/StoreRefundProductDao.php
  49. 32 0
      app/common/dao/store/order/StoreRefundStatusDao.php
  50. 144 0
      app/common/dao/store/product/ProductAssistDao.php
  51. 77 0
      app/common/dao/store/product/ProductAssistSetDao.php
  52. 45 0
      app/common/dao/store/product/ProductAssistSkuDao.php
  53. 33 0
      app/common/dao/store/product/ProductAssistUserDao.php
  54. 47 0
      app/common/dao/store/product/ProductAttrDao.php
  55. 260 0
      app/common/dao/store/product/ProductAttrValueDao.php
  56. 47 0
      app/common/dao/store/product/ProductCateDao.php
  57. 36 0
      app/common/dao/store/product/ProductContentDao.php
  58. 37 0
      app/common/dao/store/product/ProductCopyDao.php
  59. 595 0
      app/common/dao/store/product/ProductDao.php
  60. 53 0
      app/common/dao/store/product/ProductGroupBuyingDao.php
  61. 146 0
      app/common/dao/store/product/ProductGroupDao.php
  62. 38 0
      app/common/dao/store/product/ProductGroupSkuDao.php
  63. 41 0
      app/common/dao/store/product/ProductGroupUserDao.php
  64. 176 0
      app/common/dao/store/product/ProductPresellDao.php
  65. 85 0
      app/common/dao/store/product/ProductPresellSkuDao.php
  66. 174 0
      app/common/dao/store/product/ProductReplyDao.php
  67. 142 0
      app/common/dao/store/product/SpuDao.php
  68. 171 0
      app/common/dao/store/service/StoreServiceDao.php
  69. 182 0
      app/common/dao/store/service/StoreServiceLogDao.php
  70. 30 0
      app/common/dao/store/shipping/CityDao.php
  71. 65 0
      app/common/dao/store/shipping/ExpressDao.php
  72. 94 0
      app/common/dao/store/shipping/ShippingTemplateDao.php
  73. 72 0
      app/common/dao/store/shipping/ShippingTemplateFreeDao.php
  74. 72 0
      app/common/dao/store/shipping/ShippingTemplateRegionDao.php
  75. 60 0
      app/common/dao/store/shipping/ShippingTemplateUndeliveryDao.php
  76. 66 0
      app/common/dao/system/CacheDao.php
  77. 117 0
      app/common/dao/system/admin/AdminDao.php
  78. 60 0
      app/common/dao/system/admin/LogDao.php
  79. 183 0
      app/common/dao/system/attachment/AttachmentCategoryDao.php
  80. 120 0
      app/common/dao/system/attachment/AttachmentDao.php
  81. 162 0
      app/common/dao/system/config/SystemConfigClassifyDao.php
  82. 111 0
      app/common/dao/system/config/SystemConfigDao.php
  83. 113 0
      app/common/dao/system/config/SystemConfigValueDao.php
  84. 69 0
      app/common/dao/system/financial/FinancialDao.php
  85. 114 0
      app/common/dao/system/groupData/GroupDao.php
  86. 172 0
      app/common/dao/system/groupData/GroupDataDao.php
  87. 328 0
      app/common/dao/system/menu/MenuDao.php
  88. 101 0
      app/common/dao/system/menu/RoleDao.php
  89. 88 0
      app/common/dao/system/merchant/FinancialRecordDao.php
  90. 218 0
      app/common/dao/system/merchant/MerchantAdminDao.php
  91. 77 0
      app/common/dao/system/merchant/MerchantCategoryDao.php
  92. 245 0
      app/common/dao/system/merchant/MerchantDao.php
  93. 49 0
      app/common/dao/system/merchant/MerchantIntentionDao.php
  94. 36 0
      app/common/dao/system/notice/SystemNoticeDao.php
  95. 81 0
      app/common/dao/system/notice/SystemNoticeLogDao.php
  96. 89 0
      app/common/dao/system/sms/SmsRecordDao.php
  97. 42 0
      app/common/dao/user/FeedbackCateoryDao.php
  98. 80 0
      app/common/dao/user/FeedbackDao.php
  99. 38 0
      app/common/dao/user/LabelRuleDao.php
  100. 48 0
      app/common/dao/user/UserAddressDao.php

+ 1 - 0
.example.env

@@ -0,0 +1 @@
+APP_DEBUG = false

[APP]
DEFAULT_TIMEZONE = Asia/Shanghai

[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = crmeb_merchant
USERNAME = root
PASSWORD = root
HOSTPORT = 3306
CHARSET = utf8
DEBUG = true
PREFIX = eb_

[LANG]
default_lang = zh-cn

[REDIS]
HOSTNAME = 127.0.0.1
PORT = 6379
PASSWORD =
SELECT = 0

+ 9 - 0
.gitignore

@@ -0,0 +1,9 @@
+/.idea
+/.vscode
+*.log
+.env
+.phpstorm.meta.php
+.constant
+install/install.lock
+public/phpExcel/*
+app/controller/api/Test.php

+ 42 - 0
.travis.yml

@@ -0,0 +1,42 @@
+sudo: false
+
+language: php
+
+branches:
+  only:
+    - stable
+
+cache:
+  directories:
+    - $HOME/.composer/cache
+
+before_install:
+  - composer self-update
+
+install:
+  - composer install --no-dev --no-interaction --ignore-platform-reqs
+  - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .
+  - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0"
+  - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0"
+  - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0"
+  - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0"
+  - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0"
+  - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0"
+  - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0"
+  - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0"
+  - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0"
+  - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .
+
+script:
+  - php think unit
+
+deploy:
+  provider: releases
+  api_key:
+    secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=
+  file:
+    - ThinkPHP_Core.zip
+    - ThinkPHP_Full.zip
+  skip_cleanup: true
+  on:
+    tags: true

+ 2 - 0
.version

@@ -0,0 +1,2 @@
+version=CRMEB-MERCHANT-v1.4.0
+version_code=10

+ 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.

+ 1 - 0
app/.htaccess

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

+ 32 - 0
app/AppService.php

@@ -0,0 +1,32 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+declare (strict_types = 1);
+
+namespace app;
+
+use think\Service;
+
+/**
+ * 应用服务类
+ */
+class AppService extends Service
+{
+    public function register()
+    {
+        // 服务注册
+    }
+
+    public function boot()
+    {
+        // 服务启动
+    }
+}

+ 86 - 0
app/ExceptionHandle.php

@@ -0,0 +1,86 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app;
+
+use think\db\exception\DataNotFoundException;
+use think\db\exception\ModelNotFoundException;
+use think\db\exception\PDOException;
+use think\exception\ErrorException;
+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
+{
+    /**
+     * 不需要记录信息(日志)的异常类列表
+     * @var array
+     */
+    protected $ignoreReport = [
+        HttpException::class,
+        HttpResponseException::class,
+        ModelNotFoundException::class,
+        DataNotFoundException::class,
+        ValidateException::class,
+    ];
+
+    /**
+     * 记录异常信息(包括日志或者其它方式记录)
+     *
+     * @access public
+     * @param Throwable $exception
+     * @return void
+     */
+    public function report(Throwable $exception): void
+    {
+        // 使用内置的方式记录异常日志
+        parent::report($exception);
+    }
+
+    /**
+     * Render an exception into an HTTP response.
+     *
+     * @access public
+     * @param \think\Request $request
+     * @param Throwable $e
+     * @return Response
+     */
+    public function render($request, Throwable $e): Response
+    {
+        // 添加自定义异常处理机制
+        $this->report($e);
+        // 其他错误交给系统处理
+        if ($e instanceof ValidateException)
+            return app('json')->fail($e->getMessage());
+        else if ($e instanceof DataNotFoundException)
+            return app('json')->fail(isDebug() ? $e->getMessage() : '数据不存在');
+        else if ($e instanceof ModelNotFoundException)
+            return app('json')->fail(isDebug() ? $e->getMessage() : '数据不存在');
+        else if ($e instanceof PDOException)
+            return app('json')->fail(isDebug() ? $e->getMessage() : '数据库操作失败', isDebug() ? $e->getData() : []);
+        else if ($e instanceof ErrorException)
+            return app('json')->fail(isDebug() ? $e->getMessage() : '系统错误', isDebug() ? $e->getData() : []);
+        else if ($e instanceof \PDOException)
+            return app('json')->fail(isDebug() ? $e->getMessage() : '数据库连接失败');
+        else if ($e instanceof \EasyWeChat\Core\Exceptions\HttpException)
+            return app('json')->fail($e->getMessage());
+
+        return parent::render($request, $e);
+    }
+}

+ 113 - 0
app/Request.php

@@ -0,0 +1,113 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app;
+
+use crmeb\traits\Macro;
+
+class Request extends \think\Request
+{
+    use Macro;
+
+    protected $cache = [];
+
+    public function __construct()
+    {
+        parent::__construct();
+        $this->filter[] = function ($val) {
+            return is_string($val) ? trim($val) : $val;
+        };
+    }
+
+    public function ip(): string
+    {
+        return $this->header('remote-host') ?? parent::ip();
+    }
+
+    /**
+     * @param $db
+     * @param $key
+     * @return bool
+     * @author xaboy
+     * @day 2020/10/22
+     */
+    public function hasCache($db, $key)
+    {
+        return isset($this->cache[$db][$key]);
+    }
+
+    /**
+     * @param $db
+     * @param $key
+     * @return array|mixed|string
+     * @author xaboy
+     * @day 2020/10/22
+     */
+    public function getCache($db, $key)
+    {
+        if (is_array($key)) {
+            $data = [];
+            foreach ($key as $v) {
+                $data[$v] = $this->getCache($db, $v);
+            }
+            return $data;
+        }
+        return $this->cache[$db][$key] ?? '';
+    }
+
+    /**
+     * @param $db
+     * @param $key
+     * @param null $value
+     * @author xaboy
+     * @day 2020/10/22
+     */
+    public function setCache($db, $key, $value = null)
+    {
+        if (!isset($this->cache[$db])) $this->cache[$db] = [];
+        if (is_array($key)) {
+            foreach ($key as $k => $v) {
+                $this->setCache($db, $k, $v);
+            }
+            return;
+        }
+        $this->cache[$db][$key] = $value;
+    }
+
+    public function clearCache()
+    {
+        $this->cache = [];
+    }
+
+    public function params(array $names, $filter = '')
+    {
+        $data = [];
+        $flag = false;
+        if ($filter === true) {
+            $filter = '';
+            $flag = true;
+        }
+        foreach ($names as $name) {
+            if (!is_array($name))
+                $data[$name] = $this->param($name, '', $filter);
+            else
+                $data[$name[0]] = $this->param($name[0], $name[1], $filter);
+        }
+
+        return $flag ? array_values($data) : $data;
+    }
+
+    public function merId()
+    {
+        return intval($this->hasMacro('merchantId') ? $this->merchantId() : 0);
+    }
+}

+ 56 - 0
app/command/ClearCacheAttachment.php

@@ -0,0 +1,56 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+declare (strict_types=1);
+
+namespace app\command;
+
+use app\common\repositories\system\attachment\AttachmentRepository;
+use app\common\repositories\system\auth\MenuRepository;
+use think\console\Command;
+use think\console\Input;
+use think\console\Output;
+
+/**
+ * Class FormatMenuPath
+ * @package app\command
+ * @author xaboy
+ * @day 2020/8/26
+ */
+class ClearCacheAttachment extends Command
+{
+    /**
+     * @author xaboy
+     * @day 2020/9/21
+     */
+    protected function configure()
+    {
+        // 指令配置
+        $this->setName('clear:attachment')
+            ->setDescription('clear cache attachment');
+    }
+
+
+    /**
+     * @param Input $input
+     * @param Output $output
+     * @return int|void|null
+     * @author xaboy
+     * @day 2020/9/21
+     */
+    protected function execute(Input $input, Output $output)
+    {
+        $output->writeln('开始清理');
+        app()->make(AttachmentRepository::class)->clearCache();
+        $output->writeln('开始完毕');
+    }
+
+}

+ 52 - 0
app/command/ClearMerchantData.php

@@ -0,0 +1,52 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\command;
+
+
+use think\console\Command;
+use think\console\Input;
+use think\console\input\Option;
+use think\console\Output;
+use think\db\PDOConnection;
+use think\Exception;
+use think\facade\Db;
+use think\Model;
+
+class ClearMerchantData extends Command
+{
+    protected function configure()
+    {
+        // 指令配置
+        $this->setName('clear:merchant')
+            ->setDescription('清空数据(除系统配置以外的所有数据)');
+    }
+
+    protected function execute(Input $input, Output $output)
+    {
+        $flag = $output->confirm($input, '清空数据前务必做好数据库的备份,防止数据被误删 !!!', false);
+        if (!$flag) return;
+        $tables = Db::query('SHOW TABLES FROM ' . env('database.database', ''));
+        $pre = env('database.prefix', '');
+        $bakTables = [$pre . 'express', $pre . 'system_admin', $pre . 'system_city', $pre . 'system_config', $pre . 'system_config_classify', $pre . 'system_config_value', $pre . 'system_group', $pre . 'system_group_data', $pre . 'system_menu', $pre . 'system_role', $pre . 'template_message'];
+
+        foreach ($tables as $table) {
+            $name = array_values($table)[0];
+            if (!in_array($name, $bakTables)) {
+                Db::table($name)->delete(true);
+            }
+        }
+
+        $output->info('删除成功');
+    }
+
+}

+ 57 - 0
app/command/FormatMenuPath.php

@@ -0,0 +1,57 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+declare (strict_types=1);
+
+namespace app\command;
+
+use app\common\repositories\system\auth\MenuRepository;
+use think\console\Command;
+use think\console\Input;
+use think\console\Output;
+
+/**
+ * Class FormatMenuPath
+ * @package app\command
+ * @author xaboy
+ * @day 2020/8/26
+ */
+class FormatMenuPath extends Command
+{
+    /**
+     * @author xaboy
+     * @day 2020/8/26
+     */
+    protected function configure()
+    {
+        // 指令配置
+        $this->setName('menu:format')
+            ->setDescription('the format menu command');
+    }
+
+
+    /**
+     * @param Input $input
+     * @param Output $output
+     * @return int|void|null
+     * @author xaboy
+     * @day 2020/8/26
+     */
+    protected function execute(Input $input, Output $output)
+    {
+        $output->writeln('开启修复');
+        $menuRepository = app()->make(MenuRepository::class);
+        $menuRepository->formatPath(0);
+        $menuRepository->formatPath(1);
+        $output->writeln('执行成功');
+    }
+
+}

+ 119 - 0
app/command/VersionUpdate.php

@@ -0,0 +1,119 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\command;
+
+
+use think\console\Command;
+use think\console\Input;
+use think\console\input\Option;
+use think\console\Output;
+use think\Exception;
+use think\facade\Db;
+
+class VersionUpdate extends Command
+{
+    protected function configure()
+    {
+        $this->setName('version:update')
+            ->setDescription('crmeb_merchant 版本更新命令')
+            ->addOption('package', 'p', Option::VALUE_REQUIRED, '指定更新包的路径');
+    }
+
+    protected function execute(Input $input, Output $output)
+    {
+        $flag = $output->confirm($input, '更新之前请务必做好数据库和代码的备份,防止数据或代码在更新中被覆盖 !!!', false);
+        if (!$flag) return;
+        $flag = $output->confirm($input, '请确保swoole服务和队列服务已关闭,防止意外报错', false);
+        if (!$flag) return;
+
+        $version = str_replace('CRMEB-MERCHANT-v', '', get_crmeb_version('no'));
+        ini_set('memory_limit', '-1');
+        set_time_limit(0);
+
+        $packagePath = $input->getOption('package') ?: 'auto_update.zip';
+        $updateFilePath = app()->getRootPath() . ltrim($packagePath, '/= ');
+        $updatePath = dirname($updateFilePath);
+        $unzipPath = $updatePath . '/_update_runtime_' . str_replace('.', '_', $version);
+        if (!is_file($updateFilePath)) {
+            $output->warning($updateFilePath . ' 更新包不存在');
+            return;
+        }
+        $zip = new \ZipArchive();
+        if ($zip->open($updateFilePath) === true) {
+            $zip->extractTo($unzipPath);
+            $zip->close();
+        } else {
+            $output->warning($updateFilePath . ' 更新包打开失败');
+            return;
+        }
+
+        $unlink = function () use ($unzipPath) {
+            @unlink($unzipPath . '/update.sql');
+            @unlink($unzipPath . '/update.zip');
+            @unlink($unzipPath . '/.env');
+            @rmdir($unzipPath);
+        };
+
+        if (!is_file($unzipPath . '/.env')) {
+            $output->warning('文件不完整');
+            $unlink();
+            return;
+        }
+
+        $env = parse_ini_file($unzipPath . '/.env', true) ?: [];
+        if (($env['NAME'] ?? '') !== 'CRMEB-MERCHANT' || ((($env['TYPE'] ?? '') === 'MODEL' && ($env['VERSION'] ?? '') !== $version) || (($env['OLD_VERSION'] ?? '') && ($env['OLD_VERSION'] ?? '') !== $version))) {
+            $output->warning('版本号对比失败,请检查当前版本号(.version/更新包)是否被修改');
+            $unlink();
+            return;
+        }
+
+        if (is_file($unzipPath . '/update.sql')) {
+            $str = preg_replace('/--.*/i', '', file_get_contents($unzipPath . '/update.sql'));
+            $str = preg_replace('/\/\*.*\*\/(\;)?/i', '', $str);
+            $sqlList = explode(";\n", $str);
+        } else {
+            $sqlList = [];
+        }
+
+        $output->info('开始更新');
+        try {
+            Db::transaction(function () use ($output, $unzipPath, $sqlList) {
+                foreach ($sqlList as $sql) {
+                    $sql = trim($sql, " \xEF\xBB\xBF\r\n");
+                    if (!$sql) continue;
+                    Db::query($sql . ';');
+                }
+                if (count($sqlList)) {
+                    $output->info('数据库更新成功');
+                }
+                $zip = new \ZipArchive();
+                if ($zip->open($unzipPath . '/update.zip') === true) {
+                    $zip->extractTo(app()->getRootPath());
+                    $zip->close();
+                } else {
+                    throw new Exception('更新文件覆盖失败');
+                }
+            });
+        } catch (\Throwable $e) {
+            $output->warning('更新失败:' . $e->getMessage());
+            $unlink();
+            return;
+        }
+
+        $unlink();
+        $output->info('版本更新成功, 请重启swoole服务和队列服务');
+
+        update_crmeb_compiled();
+    }
+
+}

+ 115 - 0
app/command/updateMenu.php

@@ -0,0 +1,115 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+declare (strict_types=1);
+
+namespace app\command;
+
+use Swoole\Coroutine\MySQL\Exception;
+use think\console\Command;
+use think\console\Input;
+use think\console\input\Argument;
+use think\console\input\Option;
+use think\console\Output;
+use think\event\RouteLoaded;
+use think\facade\Route;
+use app\common\repositories\system\auth\MenuRepository;
+
+class updateMenu extends Command
+{
+    protected function configure()
+    {
+        // 指令配置
+        $this->setName('menu')
+            ->setDescription('the menu command');
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/15
+     * @param Input $input
+     * @param Output $output
+     * @return int|void|null
+     */
+    protected function execute(Input $input, Output $output)
+    {
+        $output->writeln('开始执行');
+        $output->writeln('---------------->');
+        $count = $this->routeList();
+        $output->writeln('<----------------');
+        $output->writeln('执行成功,合计'.$count.'条');
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/15
+     * @param string|null $dir
+     * @return mixed
+     */
+    public function routeList(string $dir = null)
+    {
+        $this->app->route->setTestMode(true);
+        $this->app->route->clear();
+        $path = $this->app->getRootPath() . 'route' . DIRECTORY_SEPARATOR;
+        include $path . 'admin.php';
+        include $path . 'merchant.php';
+//        $files = is_dir($path) ? scandir($path) : [];
+//        foreach ($files as $file) {
+//            if (strpos($file, '.php')) {
+//                include $path . $file;
+//            }
+//        }
+        //触发路由载入完成事件
+        $this->app->event->trigger(RouteLoaded::class);
+        $routeList = $this->app->route->getRuleList();
+        $rows = [];
+        $name = [];
+        foreach ($routeList as $k => $item) {
+            if (!(strpos($item['name'], '/') !== false) && !(strpos($item['name'], '@') !== false) && is_string($item['route'])) {
+                $rule = Route::getRule($item['rule']);
+                $group = ($rule[$item['route']])->getParent();
+                $groupRoute = $this->getGroupTree($group);
+                $groupName = !empty($group->getName()) ? $group->getName() : 'route';
+                if (in_array($item['name'], $name))
+                    throw new Exception( "< " . $item['name'] . ' >路由名重复');
+                $name[] = $item['name'];
+                $rows[$groupRoute][$groupName][] = $item['name'];
+            }
+        }
+        return app()->make(MenuRepository::class)->commandCreate($rows);
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/15
+     * @param $group
+     * @return mixed
+     */
+    protected function getGroupTree($group)
+    {
+        $name = $group->getName();
+        if (in_array($name, ['sys','mer'])) {
+            return $name;
+        } else {
+            return $this->getGroupTree($group->getParent());
+        }
+    }
+}

+ 67 - 0
app/command/updateSpu.php

@@ -0,0 +1,67 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+declare (strict_types=1);
+
+namespace app\command;
+
+use app\common\repositories\store\product\SpuRepository;
+use think\console\Command;
+use think\console\Input;
+use think\console\Output;
+use think\console\input\Option;
+
+class updateSpu extends Command
+{
+    protected function configure()
+    {
+        // 指令配置
+        $this->setName('spu')
+            ->addOption('productType', null, Option::VALUE_REQUIRED, 'product type :0,1,2,3')
+            ->setDescription('the update spu command');
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/15
+     * @param Input $input
+     * @param Output $output
+     * @return int|void|null
+     */
+    protected function execute(Input $input, Output $output)
+    {
+        $prodcutType = [];
+        if ($input->hasOption('productType')){
+            $tyep = $input->getOption('productType');
+            if(in_array($tyep,[0,1,2,3,4])) $prodcutType = [$tyep];
+        }
+
+
+        $output->writeln('开始执行');
+        $this->checkAndUpdateSpu($prodcutType);
+        $output->writeln('执行完成');
+    }
+
+    public function checkAndUpdateSpu($prodcutType)
+    {
+        app()->make(SpuRepository::class)->updateSpu($prodcutType);
+    }
+}

+ 884 - 0
app/common.php

@@ -0,0 +1,884 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+// 应用公共文件
+
+use app\common\repositories\system\config\ConfigValueRepository;
+use app\common\repositories\system\groupData\GroupDataRepository;
+use crmeb\services\UploadService;
+use Swoole\Lock;
+use think\db\BaseQuery;
+
+if (!function_exists('go')) {
+    function go(): bool
+    {
+        return \Swoole\Coroutine::create(...func_get_args());
+    }
+}
+
+if (!function_exists('isDebug')) {
+    function isDebug(): bool
+    {
+        return !!env('APP_DEBUG');
+    }
+}
+
+if (!function_exists('formToData')) {
+    function formToData($form): array
+    {
+        $rule = $form->formRule();
+        $action = $form->getAction();
+        $method = $form->getMethod();
+        $title = $form->getTitle();
+        $config = (object)$form->formConfig();
+        return compact('rule', 'action', 'method', 'title', 'config');
+    }
+}
+
+if (!function_exists('getDistance')) {
+
+    function getDistance($lat1, $lng1, $lat2, $lng2)
+    {
+        //将角度转为狐度
+        $radLat1 = deg2rad($lat1);//deg2rad()函数将角度转换为弧度
+        $radLat2 = deg2rad($lat2);
+        $radLng1 = deg2rad($lng1);
+        $radLng2 = deg2rad($lng2);
+        $a = $radLat1 - $radLat2;
+        $b = $radLng1 - $radLng2;
+        $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6371;
+        return round($s, 1);
+    }
+}
+
+/**
+ * 无线级分类处理
+ *
+ * @param array $data 数据源
+ * @param string $idName 主键
+ * @param string $fieldName 父级字段
+ * @param string $childrenKey 子级字段名
+ * @return array
+ * @author 张先生
+ * @date 2020-03-27
+ */
+if (!function_exists('formatCategory')) {
+    function formatCategory(array $data, string $idName = "id", string $fieldName = 'pid', $childrenKey = 'children')
+    {
+        $items = [];
+        foreach ($data as $item) {
+            $items[$item[$idName]] = $item;
+        }
+        $result = array();
+        foreach ($items as $item) {
+            if (isset($items[$item[$fieldName]])) {
+                $items[$item[$fieldName]][$childrenKey][] = &$items[$item[$idName]];
+            } else if($item[$fieldName] == 0){
+                $result[] = &$items[$item[$idName]];
+            }
+        }
+        return $result;
+    }
+}
+
+if (!function_exists('formatTreeList')) {
+    function formatTreeList(&$options, $name, $pidName = 'pid', $pid = 0, $level = 0, &$data = []): array
+    {
+        $_options = $options;
+        foreach ($_options as $k => $option) {
+            if ($option[$pidName] == $pid) {
+                $data[] = ['value' => $k, 'label' => str_repeat('|---', $level + 1) . $option[$name]];
+                unset($options[$k]);
+                formatTreeList($options, $name, $pidName, $k, $level + 1, $data);
+            }
+        }
+        return $data;
+    }
+}
+
+if (!function_exists('formatTree')) {
+    function formatTree(&$options, $name, $pidName = 'pid', $pid = 0, $level = 0, $data = []): array
+    {
+        $_options = $options;
+        foreach ($_options as $k => $option) {
+            if ($option[$pidName] == $pid) {
+                $value = ['id' => $k, 'title' => $option[$name]];
+                unset($options[$k]);
+                $value['children'] = formatTree($options, $name, $pidName, $k, $level + 1);
+                $data[] = $value;
+            }
+        }
+        return $data;
+    }
+}
+
+if (!function_exists('formatCascaderData')) {
+    function formatCascaderData(&$options, $name, $baseLevel = 0, $pidName = 'pid', $pid = 0, $level = 0, $data = []): array
+    {
+        $_options = $options;
+        foreach ($_options as $k => $option) {
+            if ($option[$pidName] == $pid) {
+                $value = ['value' => $k, 'label' => $option[$name]];
+                unset($options[$k]);
+                $value['children'] = formatCascaderData($options, $name, $baseLevel, $pidName, $k, $level + 1);
+                if (!count($value['children'])) unset($value['children']);
+                $data[] = $value;
+            }
+        }
+        return $data;
+    }
+}
+
+/**
+ * @function toMap 数组重新组装
+ * @param array $data 数据
+ * @param string $field key
+ * @param string $value value default null
+ * @return array
+ * @author 张先生
+ * @date 2020-04-01
+ */
+if (!function_exists('toMap')) {
+    function toMap(array $data, $field = 'id', $value = '')
+    {
+        $result = array();
+
+        if (empty($data)) {
+            return $result;
+        }
+
+        //开始处理数据
+        foreach ($data as $item) {
+            $val = $item;
+            if (!empty($value)) {
+                $val = $item[$value];
+            }
+            $result[$item[$field]] = $val;
+        }
+
+        return $result;
+    }
+}
+
+/**
+ * @function getUniqueListByArray 从数组中获取某个字段的值,重新拼装成新的一维数组
+ * @param array $data 数据
+ * @param string $field key
+ * @return array
+ * @author 张先生
+ * @date 2020-04-01
+ */
+if (!function_exists('getUniqueListByArray')) {
+    function getUniqueListByArray(array $data, $field = 'id')
+    {
+        return array_unique(array_values(array_column($data, $field)));
+    }
+}
+
+
+if (!function_exists('isPhone')) {
+    function isPhone($test)
+    {
+        return !preg_match("/^1[3456789]{1}\d{9}$/", $test);
+    }
+}
+
+if (!function_exists('getMonth')) {
+    /**
+     * 获取本季度 time
+     * @param int|string $time
+     * @param $ceil
+     * @return array
+     */
+    function getMonth($time = '', $ceil = 0)
+    {
+        if ($ceil != 0)
+            $season = ceil(date('n') / 3) - $ceil;
+        else
+            $season = ceil(date('n') / 3);
+        $firstday = date('Y-m-01', mktime(0, 0, 0, ($season - 1) * 3 + 1, 1, date('Y')));
+        $lastday = date('Y-m-t', mktime(0, 0, 0, $season * 3, 1, date('Y')));
+        return array($firstday, $lastday);
+    }
+}
+
+
+if (!function_exists('getModelTime')) {
+    /**
+     * @param BaseQuery $model
+     * @param string $section
+     * @param string $prefix
+     * @param string $field
+     * @return mixed
+     * @author xaboy
+     * @day 2020-04-29
+     */
+    function getModelTime(BaseQuery $model, string $section, $prefix = 'create_time', $field = '-')
+    {
+        if (!isset($section)) return $model;
+        switch ($section) {
+            case 'today':
+                $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('today')), date('Y-m-d H:i:s', strtotime('tomorrow -1second'))]);
+                break;
+            case 'week':
+                $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('this week 00:00:00')), date('Y-m-d H:i:s', strtotime('next week 00:00:00 -1second'))]);
+                break;
+            case 'month':
+                $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('first Day of this month 00:00:00')), date('Y-m-d H:i:s', strtotime('first Day of next month 00:00:00 -1second'))]);
+                break;
+            case 'year':
+                $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('this year 1/1')), date('Y-m-d H:i:s', strtotime('next year 1/1 -1second'))]);
+                break;
+            case 'yesterday':
+                $model->whereBetween($prefix, [date('Y-m-d H:i:s', strtotime('yesterday')), date('Y-m-d H:i:s', strtotime('today -1second'))]);
+                break;
+            case 'quarter':
+                list($startTime, $endTime) = getMonth();
+                $model = $model->where($prefix, '>', $startTime);
+                $model = $model->where($prefix, '<', $endTime);
+                break;
+            case 'lately7':
+                $model = $model->where($prefix, 'between', [date('Y-m-d', strtotime("-7 day")), date('Y-m-d H:i:s')]);
+                break;
+            case 'lately30':
+                $model = $model->where($prefix, 'between', [date('Y-m-d', strtotime("-30 day")), date('Y-m-d H:i:s')]);
+                break;
+            default:
+                if (strstr($section, $field) !== false) {
+                    list($startTime, $endTime) = explode($field, $section);
+                    if (strlen($startTime) == 4) {
+                        $model->whereBetweenTime($prefix, date('Y-m-d H:i:s', strtotime($section)), date('Y-m-d H:i:s', strtotime($section . ' +1day -1second')));
+                    } else {
+                        if ($startTime == $endTime) {
+                            $model = $model->whereBetweenTime($prefix, date('Y-m-d 0:0:0', strtotime($startTime)), date('Y-m-d 23:59:59', strtotime($endTime)));
+                        } else {
+                            $model = $model->whereBetweenTime($prefix, date('Y-m-d H:i:s', strtotime($startTime)), date('Y-m-d H:i:s', strtotime($endTime . ' +1day -1second')));
+                        }
+                    }
+                }
+                break;
+        }
+        return $model;
+    }
+}
+
+
+if (!function_exists('systemConfig')) {
+    /**
+     * 获取系统配置
+     *
+     * @param string|string[] $key
+     * @return mixed
+     * @author xaboy
+     * @day 2020-05-08
+     */
+    function systemConfig($key)
+    {
+        return merchantConfig(0, $key);
+    }
+}
+
+if (!function_exists('getDatesBetweenTwoDays')) {
+    function getDatesBetweenTwoDays($startDate, $endDate)
+    {
+        $dates = [];
+        if (strtotime($startDate) > strtotime($endDate)) {
+            //如果开始日期大于结束日期,直接return 防止下面的循环出现死循环
+            return $dates;
+        } elseif ($startDate == $endDate) {
+            //开始日期与结束日期是同一天时
+            array_push($dates, date('m-d', strtotime($startDate)));
+            return $dates;
+        } else {
+            array_push($dates, date('m-d', strtotime($startDate)));
+            $currentDate = $startDate;
+            do {
+                $nextDate = date('Y-m-d', strtotime($currentDate . ' +1 days'));
+                array_push($dates, date('m-d', strtotime($currentDate . ' +1 days')));
+                $currentDate = $nextDate;
+            } while ($endDate != $currentDate);
+            return $dates;
+        }
+    }
+}
+
+if (!function_exists('getStartModelTime')) {
+    function getStartModelTime(string $section)
+    {
+        switch ($section) {
+            case 'today':
+            case 'yesterday':
+                return date('Y-m-d', strtotime($section));
+            case 'week':
+                return date('Y-m-d', strtotime('this week'));
+            case 'month':
+                return date('Y-m-d', strtotime('first Day of this month'));
+            case 'year':
+                return date('Y-m-d', strtotime('this year 1/1'));
+            case 'quarter':
+                list($startTime, $endTime) = getMonth();
+                return $startTime;
+            case 'lately7':
+                return date('Y-m-d', strtotime("-7 day"));
+            case 'lately30':
+                return date('Y-m-d', strtotime("-30 day"));
+            default:
+                if (strstr($section, '-') !== false) {
+                    list($startTime, $endTime) = explode('-', $section);
+                    return date('Y-m-d H:i:s', strtotime($startTime));
+                }
+                return date('Y-m-d H:i:s');
+        }
+    }
+}
+
+if (!function_exists('merchantConfig')) {
+    /**
+     * 获取商户配置
+     *
+     * @param int $merId
+     * @param string|string[] $key
+     * @return mixed
+     * @author xaboy
+     * @day 2020-05-08
+     */
+    function merchantConfig(int $merId, $key)
+    {
+        $request = request();
+        $make = app()->make(ConfigValueRepository::class);
+        if (is_array($key)) {
+            $_key = [];
+            $cacheData = [];
+            foreach ($key as $v) {
+                if ($request->hasCache($merId, $v)) {
+                    $cacheData[$v] = $request->getCache($merId, $v);
+                } else {
+                    $_key[] = $v;
+                }
+            }
+            if (!count($_key)) return $cacheData;
+            $data = $make->more($_key, $merId);
+            $request->setCache($merId, $data);
+            $data += $cacheData;
+        } else {
+            if ($request->hasCache($merId, $key)) {
+                $data = $request->getCache($merId, $key);
+            } else {
+                $data = $make->get($key, $merId);
+                $request->setCache($merId, $key, $data);
+            }
+        }
+        return $data;
+    }
+}
+
+if (!function_exists('systemGroupData')) {
+    /**
+     * 获取总后台组合数据配置
+     *
+     * @param string $key
+     * @param int|null $page
+     * @param int|null $limit
+     * @return array
+     * @author xaboy
+     * @day 2020/5/27
+     */
+    function systemGroupData(string $key, ?int $page = null, ?int $limit = 10)
+    {
+        $make = app()->make(GroupDataRepository::class);
+        return $make->groupData($key, 0, $page, $limit);
+    }
+}
+
+if (!function_exists('merchantGroupData')) {
+    /**
+     * 获取商户后台组合数据配置
+     *
+     * @param int $merId
+     * @param string $key
+     * @param int|null $page
+     * @param int|null $limit
+     * @return array
+     * @author xaboy
+     * @day 2020/5/27
+     */
+    function merchantGroupData(int $merId, string $key, ?int $page = null, ?int $limit = 10)
+    {
+        $make = app()->make(GroupDataRepository::class);
+        return $make->groupData($key, $merId, $page, $limit);
+    }
+}
+
+if (!function_exists('filter_emoji')) {
+
+    // 过滤掉emoji表情
+    function filter_emoji($str)
+    {
+        $str = preg_replace_callback(    //执行一个正则表达式搜索并且使用一个回调进行替换
+            '/./u',
+            function (array $match) {
+                return strlen($match[0]) >= 4 ? '' : $match[0];
+            },
+            $str);
+        return $str;
+    }
+}
+
+if (!function_exists('setHttpType')) {
+
+    /**
+     * TODO 修改 https 和 http 移动到common
+     * @param $url $url 域名
+     * @param int $type 0 返回https 1 返回 http
+     * @return string
+     */
+    function setHttpType($url, $type = 0)
+    {
+        $domainTop = substr($url, 0, 5);
+        if ($type) {
+            if ($domainTop == 'https') $url = 'http' . substr($url, 5, strlen($url));
+        } else {
+            if ($domainTop != 'https') $url = 'https:' . substr($url, 5, strlen($url));
+        }
+        return $url;
+    }
+}
+
+if (!function_exists('remoteImage')) {
+
+    /**
+     * TODO 获取小程序二维码是否生成
+     * @param $url
+     * @return array
+     */
+    function remoteImage($url)
+    {
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_URL, $url);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+        $result = curl_exec($curl);
+        $result = json_decode($result, true);
+        if (is_array($result)) return ['status' => false, 'msg' => $result['errcode'] . '---' . $result['errmsg']];
+        return ['status' => true];
+    }
+}
+
+if (!function_exists('image_to_base64')) {
+    /**
+     * 获取图片转为base64
+     * @param string $avatar
+     * @return bool|string
+     */
+    function image_to_base64($avatar = '', $timeout = 9)
+    {
+        try {
+            $url = parse_url($avatar);
+            $url = $url['host'];
+            $header = [
+                'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0',
+                'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
+                'Accept-Encoding: gzip, deflate, br',
+                'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
+                'Host:' . $url
+            ];
+            $dir = pathinfo($url);
+            $host = $dir['dirname'];
+            $refer = $host . '/';
+            $curl = curl_init();
+            curl_setopt($curl, CURLOPT_REFERER, $refer);
+            curl_setopt($curl, CURLOPT_URL, $avatar);
+            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
+            curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
+            curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
+            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
+            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+            $data = curl_exec($curl);
+            $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+            curl_close($curl);
+            if ($code == 200) {
+                return "data:image/jpeg;base64," . base64_encode($data);
+            } else {
+                return false;
+            }
+        } catch (Exception $e) {
+            return false;
+        }
+    }
+}
+
+
+if (!function_exists('put_image')) {
+    /**
+     * 获取图片转为base64
+     * @param string $avatar
+     * @return bool|string
+     */
+    function put_image($url, $filename = '')
+    {
+
+        if ($url == '') {
+            return false;
+        }
+        try {
+            if ($filename == '') {
+
+                $ext = pathinfo($url);
+                if ($ext['extension'] != "jpg" && $ext['extension'] != "png" && $ext['extension'] != "jpeg") {
+                    return false;
+                }
+                $filename = time() . "." . $ext['extension'];
+            }
+
+            //文件保存路径
+            ob_start();
+            readfile($url);
+            $img = ob_get_contents();
+            ob_end_clean();
+            $path = 'public/uploads/qrcode';
+            $fp2 = fopen($path . '/' . $filename, 'a');
+            fwrite($fp2, $img);
+            fclose($fp2);
+            return $path . '/' . $filename;
+        } catch (Exception $e) {
+            return false;
+        }
+    }
+}
+
+if (!function_exists('path_to_url')) {
+    /**
+     * 路径转url路径
+     * @param $path
+     * @return string
+     */
+    function path_to_url($path)
+    {
+        return trim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '.');
+    }
+}
+
+if (!function_exists('tidy_url')) {
+    /**
+     * 路径转url路径
+     * @param $url
+     * @param int $http
+     * @param string $site
+     * @return string
+     */
+    function tidy_url($url, $http = null, $site = null)
+    {
+        if (!$site) {
+            $site = systemConfig('site_url');
+        }
+        $url = path_to_url($url);
+        if (strpos($url, 'http') === false)
+            $url = rtrim($site, '/') . '/' . ltrim($url, '/');
+
+        if (is_null($http)) {
+            $http = (parse_url($site)['scheme'] ?? '') == 'https' ? 0 : 1;
+        }
+        $url = set_http_type($url, $http);
+        return $url;
+    }
+}
+
+
+if (!function_exists('curl_file_exist')) {
+    /**
+     * CURL 检测远程文件是否在
+     * @param $url
+     * @return bool
+     */
+    function curl_file_exist($url)
+    {
+        $ch = curl_init();
+        try {
+            curl_setopt($ch, CURLOPT_URL, $url);
+            curl_setopt($ch, CURLOPT_HEADER, 1);
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
+            $contents = curl_exec($ch);
+            if (preg_match("/404/", $contents)) return false;
+            if (preg_match("/403/", $contents)) return false;
+            return true;
+        } catch (Exception $e) {
+            return false;
+        }
+    }
+}
+
+
+if (!function_exists('set_http_type')) {
+    /**
+     * 修改 https 和 http
+     * @param $url $url 域名
+     * @param int $type 0 返回https 1 返回 http
+     * @return string
+     */
+    function set_http_type($url, $type = 0)
+    {
+        $domainTop = substr($url, 0, 5);
+        if ($type) {
+            if ($domainTop == 'https') $url = 'http' . substr($url, 5, strlen($url));
+        } else {
+            if ($domainTop != 'https') $url = 'https:' . substr($url, 5, strlen($url));
+        }
+        return $url;
+    }
+
+}
+
+if (!function_exists('setSharePoster')) {
+    /**
+     * TODO 生成分享二维码图片
+     * @param array $config
+     * @param $path
+     * @return array|bool|string
+     * @throws Exception
+     */
+    function setSharePoster($config, $path)
+    {
+        $imageDefault = array(
+            'left' => 0,
+            'top' => 0,
+            'right' => 0,
+            'bottom' => 0,
+            'width' => 100,
+            'height' => 100,
+            'opacity' => 100
+        );
+        $textDefault = array(
+            'text' => '',
+            'left' => 0,
+            'top' => 0,
+            'fontSize' => 32,       //字号
+            'fontColor' => '255,255,255', //字体颜色
+            'angle' => 0,
+        );
+        $background = $config['background'];//海报最底层得背景
+        if (substr($background, 0, 1) === '/') {
+            $background = substr($background, 1);
+        }
+        $backgroundInfo = getimagesize($background);
+        $background = imagecreatefromstring(file_get_contents($background));
+        $backgroundWidth = $backgroundInfo[0];  //背景宽度
+        $backgroundHeight = $backgroundInfo[1];  //背景高度
+        $imageRes = imageCreatetruecolor($backgroundWidth, $backgroundHeight);
+        $color = imagecolorallocate($imageRes, 0, 0, 0);
+        imagefill($imageRes, 0, 0, $color);
+        imagecopyresampled($imageRes, $background, 0, 0, 0, 0, imagesx($background), imagesy($background), imagesx($background), imagesy($background));
+        if (!empty($config['image'])) {
+            foreach ($config['image'] as $key => $val) {
+                $val = array_merge($imageDefault, $val);
+                $info = getimagesize($val['url']);
+                $function = 'imagecreatefrom' . image_type_to_extension($info[2], false);
+                if ($val['stream']) {
+                    $info = getimagesizefromstring($val['url']);
+                    $function = 'imagecreatefromstring';
+                }
+                $res = $function($val['url']);
+                $resWidth = $info[0];
+                $resHeight = $info[1];
+                $canvas = imagecreatetruecolor($val['width'], $val['height']);
+                imagefill($canvas, 0, 0, $color);
+                imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'], $resWidth, $resHeight);
+                $val['left'] = $val['left'] < 0 ? $backgroundWidth - abs($val['left']) - $val['width'] : $val['left'];
+                $val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) - $val['height'] : $val['top'];
+                imagecopymerge($imageRes, $canvas, $val['left'], $val['top'], $val['right'], $val['bottom'], $val['width'], $val['height'], $val['opacity']);//左,上,右,下,宽度,高度,透明度
+            }
+        }
+        if (isset($config['text']) && !empty($config['text'])) {
+            foreach ($config['text'] as $key => $val) {
+                $val = array_merge($textDefault, $val);
+                list($R, $G, $B) = explode(',', $val['fontColor']);
+                $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
+                $val['left'] = $val['left'] < 0 ? $backgroundWidth - abs($val['left']) : $val['left'];
+                $val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) : $val['top'];
+                imagettftext($imageRes, $val['fontSize'], $val['angle'], $val['left'], $val['top'], $fontColor, $val['fontPath'], $val['text']);
+            }
+        }
+        ob_start();
+        imagejpeg($imageRes);
+        imagedestroy($imageRes);
+        $res = ob_get_contents();
+        ob_end_clean();
+        $key = substr(md5(rand(0, 9999)), 0, 5) . date('YmdHis') . rand(0, 999999) . '.jpg';
+        $uploadType = (int)systemConfig('upload_type') ?: 1;
+        $upload = UploadService::create($uploadType);
+        $res = $upload->to($path)->validate()->stream($res, $key);
+        if ($res === false) {
+            return $upload->getError();
+        } else {
+            $info = $upload->getUploadInfo();
+            $info['image_type'] = $uploadType;
+            return $info;
+        }
+    }
+
+}
+
+if (!function_exists('getTimes')) {
+    function getTimes()
+    {
+        $dates = [];
+        for ($i = 0; $i <= 24; $i++) {
+            for ($j = 0; $j < 60; $j++) {
+                $dates[] = sprintf('%02.d', $i) . ':' . sprintf('%02.d', $j);
+            }
+        }
+        return $dates;
+    }
+}
+
+if (!function_exists('monday')) {
+    /**
+     * 获取周一
+     *
+     * @param null $time
+     * @return false|string
+     * @author xaboy
+     * @day 2020/6/22
+     */
+    function monday($time = null)
+    {
+        return date('Y-m-d', strtotime('Sunday -6 day', $time ?: time()));
+    }
+}
+
+if (!function_exists('orderLock')) {
+    /**
+     * @param string $name
+     * @return Lock
+     * @author xaboy
+     * @day 2020/8/25
+     */
+    function makeLock($name = 'default'): Lock
+    {
+        return $GLOBALS['_swoole_order_lock'][$name];
+    }
+}
+
+if (!function_exists('get_crmeb_version')) {
+    /**
+     * 获取CRMEB系统版本号
+     * @param string $default
+     * @return string
+     */
+    function get_crmeb_version($default = 'v1.0.0')
+    {
+        try {
+            $version = parse_ini_file(app()->getRootPath() . '.version');
+            return $version['version'] ?? $default;
+        } catch (Throwable $e) {
+            return $default;
+        }
+    }
+}
+
+if (!function_exists('update_crmeb_compiled')) {
+    /**
+     * 获取CRMEB系统版本号
+     * @param string $default
+     * @return string
+     */
+    function update_crmeb_compiled($default = 'v1.0.0')
+    {
+        $compiled = [
+            '7.1' => 'compiled71',
+            '7.2' => 'compiled72',
+            '7.3' => 'compiled73',
+        ];
+
+        $phpv = @phpversion();
+        $phpvs = substr($phpv, 0, 3);
+        $key = $compiled[$phpvs] ?? '';
+        if (!$key)
+            return false;
+        $root = app()->getRootPath();
+        $compiledPath = $root . 'install/compiled';
+        $file = $root . 'install/compiled/' . $key . '.zip';
+        $toPath = $root . 'crmeb/basic';
+        $toConfigPath = $root . 'config/crmeb.php';
+        try {
+            if (is_file($file)) {
+                $zip = new ZipArchive();
+                if ($zip->open($file) === true) {
+                    $zip->extractTo($compiledPath . '/');
+                    $zip->close();
+                }
+                if (is_dir($compiledPath . '/basic')) {
+                    if (is_dir($toPath) || mkdir($toPath, 0777) || is_dir($toPath)) {
+                        foreach (glob($compiledPath . '/basic/*') as $item) {
+                            @rename($item, $toPath . '/' . pathinfo($item, PATHINFO_BASENAME));
+                        }
+                    }
+                    @rmdir($compiledPath . '/basic');
+                }
+                if (is_file($compiledPath . '/crmeb.php')) {
+                    @rename($compiledPath . '/crmeb.php', $toConfigPath);
+                }
+            }
+        } catch (\Exception $exception) {
+            return false;
+        }
+        return true;
+    }
+}
+
+if (!function_exists('attr_format')) {
+    /**
+     * 格式化属性
+     * @param $arr
+     * @return array
+     */
+    function attr_format($arr)
+    {
+        $data = [];
+        $res = [];
+        $count = count($arr);
+        if ($count > 1) {
+            for ($i = 0; $i < $count - 1; $i++) {
+                if ($i == 0) $data = $arr[$i]['detail'];
+                //替代变量1
+                $rep1 = [];
+                foreach ($data as $v) {
+                    foreach ($arr[$i + 1]['detail'] as $g) {
+                        //替代变量2
+                        $rep2 = ($i != 0 ? '' : $arr[$i]['value'] . '_$_') . $v . '-$-' . $arr[$i + 1]['value'] . '_$_' . $g;
+                        $tmp[] = $rep2;
+                        if ($i == $count - 2) {
+                            foreach (explode('-$-', $rep2) as $k => $h) {
+                                //替代变量3
+                                $rep3 = explode('_$_', $h);
+                                //替代变量4
+                                $rep4['detail'][$rep3[0]] = isset($rep3[1]) ? $rep3[1] : '';
+                            }
+                            if($count == count($rep4['detail']))
+                                $res[] = $rep4;
+                        }
+                    }
+                }
+                $data = isset($tmp) ? $tmp : [];
+            }
+        } else {
+            $dataArr = [];
+            foreach ($arr as $k => $v) {
+                foreach ($v['detail'] as $kk => $vv) {
+                    $dataArr[$kk] = $v['value'] . '_' . $vv;
+                    $res[$kk]['detail'][$v['value']] = $vv;
+                }
+            }
+            $data[] = implode('-', $dataArr);
+        }
+        return [$data, $res];
+    }
+}

+ 281 - 0
app/common/dao/BaseDao.php

@@ -0,0 +1,281 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao;
+
+
+use app\common\model\BaseModel;
+use think\Collection;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+/**
+ * Class BaseDao
+ * @package app\common\dao
+ * @author xaboy
+ * @day 2020-03-30
+ */
+abstract class BaseDao
+{
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    abstract protected function getModel(): string;
+
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    public function getPk()
+    {
+        return ($this->getModel())::tablePk();
+    }
+
+    /**
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function exists(int $id)
+    {
+        return $this->fieldExists($this->getPk(), $id);
+    }
+
+
+    /**
+     * @param $field
+     * @param $value
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    public function fieldExists($field, $value, ?int $except = null): bool
+    {
+        $query = ($this->getModel())::getDB()->where($field, $value);
+        if (!is_null($except)) $query->where($this->getPk(), '<>', $except);
+        return $query->count() > 0;
+    }
+
+    /**
+     * @param array $data
+     * @return self|Model
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function create(array $data)
+    {
+        return ($this->getModel())::create($data);
+    }
+
+
+    /**
+     * @param int $id
+     * @param array $data
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function update(int $id, array $data)
+    {
+        return ($this->getModel())::getDB()->where($this->getPk(), $id)->update($data);
+    }
+
+    /**
+     * @param array $ids
+     * @param array $data
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/6/8
+     */
+    public function updates(array $ids, array $data)
+    {
+        return ($this->getModel())::getDB()->whereIn($this->getPk(), $ids)->update($data);
+    }
+
+
+    /**
+     * @param int $id
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function delete(int $id)
+    {
+        return ($this->getModel())::getDB()->where($this->getPk(), $id)->delete();
+    }
+
+
+    /**
+     * @param int $id
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function get($id)
+    {
+        return ($this->getModel())::getInstance()->find($id);
+    }
+
+    /**
+     * @param array $where
+     * @param string $field
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/1
+     */
+    public function getWhere(array $where, string $field = '*', array $with = [])
+    {
+        return ($this->getModel())::getInstance()->where($where)->when($with, function ($query) use ($with) {
+            $query->with($with);
+        })->field($field)->find();
+    }
+
+    /**
+     * @param array $where
+     * @param string $field
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/1
+     */
+    public function selectWhere(array $where, string $field = '*')
+    {
+        return ($this->getModel())::getInstance()->where($where)->field($field)->select();
+    }
+
+    /**
+     * @param int $id
+     * @param array $with
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function getWith(int $id, $with = [])
+    {
+        return ($this->getModel())::getInstance()->with($with)->find($id);
+    }
+
+
+    /**
+     * @param array $data
+     * @return int
+     * @author xaboy
+     * @day 2020/6/8
+     */
+    public function insertAll(array $data)
+    {
+        return ($this->getModel())::getDB()->insertAll($data);
+    }
+
+    /**
+     * TODO 通过条件判断是否存在
+     * @param array $where
+     * @author Qinii
+     * @day 2020-06-13
+     */
+    public function getWhereCount(array $where)
+    {
+        return ($this->getModel()::getDB())->where($where)->count();
+    }
+
+    public function existsWhere($where)
+    {
+        return ($this->getModel())::getDB()->where($where)->count() > 0;
+    }
+
+    /**
+     * TODO 查询,如果不存在就创建
+     * @Author:Qinii
+     * @Date: 2020/9/8
+     * @param array $where
+     * @return array|Model|null
+     */
+    public function findOrCreate(array $where)
+    {
+       $res = ($this->getModel()::getDB())->where($where)->find();
+       if(!$res)$res = $this->getModel()::create($where);
+       return $res;
+    }
+
+    /**
+     * TODO 搜索
+     * @param $where
+     * @return BaseModel
+     * @author Qinii
+     * @day 2020-10-16
+     */
+    public function getSearch(array $where)
+    {
+        foreach ($where as $key => $item) {
+            if ($item !== '') {
+                $keyArray[] = $key;
+                $whereArr[$key] = $item;
+            }
+        }
+        if(empty($keyArray)){
+            return ($this->getModel())::getDB();
+        }else{
+            return ($this->getModel())::withSearch($keyArray, $whereArr);
+        }
+    }
+
+    /**
+     * TODO 自增
+     * @param array $id
+     * @param string $field
+     * @param int $num
+     * @return mixed
+     * @author Qinii
+     * @day 1/11/21
+     */
+    public function incField(int $id, string $field , $num = 1)
+    {
+        return ($this->getModel()::getDB())->where($this->getPk(),$id)->inc($field,$num)->update();
+    }
+
+    /**
+     * TODO 自减
+     * @param array $id
+     * @param string $field
+     * @param int $num
+     * @return mixed
+     * @author Qinii
+     * @day 1/11/21
+     */
+    public function decField(int $id, string $field , $num = 1)
+    {
+        return ($this->getModel()::getDB())->where($this->getPk(),$id)->dec($field,$num)->update();
+    }
+}

+ 143 - 0
app/common/dao/article/ArticleCategoryDao.php

@@ -0,0 +1,143 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\article;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\article\ArticleCategory;
+use app\common\model\BaseModel;
+use think\Collection;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+/**
+ * Class ArticleCategoryDao
+ * @package app\common\dao\article
+ * @author xaboy
+ * @day 2020-04-20
+ */
+class ArticleCategoryDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return ArticleCategory::class;
+    }
+
+    /**
+     * @param int $mer_id
+     * @return array
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function getAllOptions($mer_id = 0)
+    {
+        return ArticleCategory::getDB()->where('mer_id', $mer_id)->order('sort DESC')->column('pid,title', $this->getPk());
+    }
+
+    /**
+     * @param int $mer_id
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function getAll($mer_id = 0,$status = null)
+    {
+        return ArticleCategory::getDB()->where('mer_id', $mer_id)->when($status,function($query)use($status){
+            $query->where('status',$status);
+        })->order('sort DESC')->select();
+    }
+
+    /**
+     * @param array $where
+     * @return \think\db\BaseQuery
+     * @author xaboy
+     * @day 2020/9/18
+     */
+    public function search(array $where)
+    {
+        return ArticleCategory::getDB()->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) {
+            $query->where('status', $where['status']);
+        })->when(isset($where['pid']) && $where['pid'] !== '', function ($query) use ($where) {
+            $query->where('pid', $where['pid']);
+        })->order('sort DESC, article_category_id DESC');
+    }
+
+    /**
+     * @param int $merId
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function merFieldExists(int $merId, $field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->where('mer_id', $merId)->where($field, $value)->count() > 0;
+    }
+
+    /**
+     * @param int $merId
+     * @param int $id
+     * @param null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function merExists(int $merId, int $id, $except = null)
+    {
+        return $this->merFieldExists($merId, $this->getPk(), $id, $except);
+    }
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function get( $id, $merId = 0)
+    {
+        return ($this->getModel())::getDB()->where('mer_id', 0)->find($id);
+    }
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function delete(int $id, $merId = 0)
+    {
+        return ($this->getModel())::getDB()->where($this->getPk(), $id)->where('mer_id', $merId)->delete();
+    }
+}

+ 32 - 0
app/common/dao/article/ArticleContentDao.php

@@ -0,0 +1,32 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\article;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+
+class ArticleContentDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return ArticleContentDao::class;
+    }
+}

+ 175 - 0
app/common/dao/article/ArticleDao.php

@@ -0,0 +1,175 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\article;
+
+use think\Collection;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\facade\Db;
+use app\common\dao\BaseDao;
+use app\common\model\article\Article;
+use app\common\model\BaseModel;
+use think\Model;
+
+class ArticleDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return Article::class;
+    }
+
+    /**
+     * @param int $mer_id
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     */
+    public function getAll($mer_id = 0)
+    {
+        return Article::getDB()->with('content')->where('mer_id', $mer_id)->select();
+    }
+
+    /**
+     * 搜索列表
+     * @param $merId
+     * @param array $where
+     * @return BaseQuery
+     * @author Qinii
+     */
+    public function search($merId,array $where)
+    {
+        $query = Article::getDB();
+        if (isset($where['cid']) && $where['cid'] !== '') $query->where('cid', (int)$where['cid']);
+        if (isset($where['title']) && $where['title'] !== '') $query->whereLike('title', "%{$where['title']}%");
+        if (isset($where['status']) && $where['status'] !== '') $query->where('status', $where['status']);
+        if (isset($where['wechat_news_id']) && $where['wechat_news_id'] !== '') $query->where('wechat_news_id', $where['wechat_news_id']);
+        $query->with(['content','articleCategory']);
+        return $query->where('mer_id',$merId)->order('sort DESC,create_time DESC');
+    }
+
+
+
+    /**
+     * 根据 字段名查询
+     * @param int $merId
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     * @author Qinii
+     */
+    public function merFieldExists(int $merId, $field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->where('mer_id', $merId)->where('wechat_news_id',0)->where($field, $value)->count() > 0;
+    }
+
+    /**
+     * 查询一条
+     * @param int $merId
+     * @param int $id
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author Qinii
+     *
+     */
+    public function get( $id, int $merId = 0)
+    {
+        return ($this->getModel())::getDB()->where('mer_id', $merId)->where('wechat_news_id',0)->with(['content','articleCategory'])->find($id);
+    }
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function delete(int $id, int $merId = 0)
+    {
+        $result = ($this->getModel())::getDB()->where('mer_id', $merId)
+            ->where($this->getPk(),$id)
+            ->with('content')
+            ->find();
+        return $result->together(['content'])->delete();
+    }
+
+
+    /**
+     * 关联添加
+     * @param array $data
+     * @return BaseDao|Model|void
+     * @author Qinii
+     */
+    public function create(array $data)
+    {
+        Db::transaction(function()use($data){
+            $content = $data['content'];
+            unset($data['content']);
+            $article = $this->getModel()::create($data);
+            $article->content()->save(['content' => $content]);
+        });
+    }
+
+    /**
+     * 关联更新
+     * @param int $id
+     * @param array $data
+     * @return int|void
+     * @author Qinii
+     */
+    public function update(int $id, array $data)
+    {
+        Db::transaction(function()use($id,$data){
+            $content = $data['content'];
+            unset($data['content']);
+
+            $this->getModel()::where($this->getPk(),$id)->update($data);
+
+            $article = $this->getModel()::find($id);
+            $article->content->content = $content;
+            $article->together(['content'])->save();
+        });
+    }
+
+    /**
+     * 根据字段获取 主键值
+     * @param int $vale
+     * @param null $field
+     * @return array
+     * @author Qinii
+     */
+    public function getKey(int $vale,$field = null)
+    {
+        return ($this->getModel())::getDB()->where($field,$vale)->column($this->getPk());
+    }
+
+    public function wechatNewIdByData($id)
+    {
+        return ($this->getModel())::getDB()->where('wechat_news_id', $id)->select();
+    }
+}

+ 60 - 0
app/common/dao/store/ExcelDao.php

@@ -0,0 +1,60 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store;
+
+use app\common\model\store\Excel;
+use app\common\dao\BaseDao;
+
+class ExcelDao extends BaseDao
+{
+
+    /**
+     * TODO
+     * @return string
+     * @author Qinii
+     * @day 2020-07-30
+     */
+    protected function getModel(): string
+    {
+        return Excel::class;
+    }
+
+
+    public function search(array $where)
+    {
+        $query = $this->getModel()::getDB()
+            ->when(isset($where['type']) && $where['type'] !== '',function($query) use($where){
+                $query->where('type',$where['type']);
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '',function($query) use($where){
+                $query->where('mer_id',$where['mer_id']);
+            })
+            ->when(isset($where['admin_id']) && $where['admin_id'] !== '',function($query) use($where){
+                $query->where('admin_id',$where['admin_id']);
+            });
+        $query->order('create_time DESC');
+        return $query;
+    }
+
+    /**
+     * TODO 获取小于某个时间的文件
+     * @param $time
+     * @return mixed
+     * @author Qinii
+     * @day 2020-08-15
+     */
+    public function getDelByTime($time)
+    {
+        return $this->getModel()::getDB()->whereTime('create_time','<',$time)->column('path','excel_id');
+    }
+}

+ 119 - 0
app/common/dao/store/StoreAttrTemplateDao.php

@@ -0,0 +1,119 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\StoreAttrTemplate;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+/**
+ * Class StoreAttrTemplateDao
+ * @package app\common\dao\store
+ * @author xaboy
+ * @day 2020-05-06
+ */
+class StoreAttrTemplateDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return StoreAttrTemplate::class;
+    }
+
+    /**
+     * @param $merId
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-05-06
+     */
+    public function search($merId, array $where = [])
+    {
+        return StoreAttrTemplate::getDB()->where('mer_id', $merId)->order('attr_template_id DESC');
+    }
+
+    /**
+     * @param int $merId
+     * @param int $id
+     * @param null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function merExists(int $merId, int $id, $except = null)
+    {
+        return $this->merFieldExists($merId, $this->getPk(), $id, $except);
+    }
+
+    /**
+     * @param int $merId
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function merFieldExists(int $merId, $field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->where('mer_id', $merId)->where($field, $value)->count() > 0;
+    }
+
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function get( $id, $merId = 0)
+    {
+        return ($this->getModel())::getDB()->where('mer_id', $merId)->find($id);
+    }
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function delete(int $id, $merId = 0)
+    {
+        return ($this->getModel())::getDB()->where($this->getPk(), $id)->where('mer_id', $merId)->delete();
+    }
+
+    public function getList($merId)
+    {
+        return ($this->getModel())::getDB()->where('mer_id',$merId)->field('attr_template_id,template_name,template_value')->select();
+    }
+}

+ 68 - 0
app/common/dao/store/StoreBrandCategoryDao.php

@@ -0,0 +1,68 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\StoreBrandCategory as model;
+use crmeb\traits\CategoresDao;
+
+class StoreBrandCategoryDao extends BaseDao
+{
+
+    use CategoresDao;
+
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+    public function getMaxLevel()
+    {
+        return 2;
+    }
+
+    public function getAll($mer_id = 0,$status = null)
+    {
+        return $this->getModel()::getDB()->when(($status !== null),function($query)use($status){
+            $query->where($this->getStatus(),$status);
+        })->order('sort DESC')->select();
+    }
+
+    public function merFieldExists(int $merId, $field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()
+                ->when($except, function ($query, $except) use ($field) {
+                    $query->where($field, '<>', $except);
+                })
+                ->where($field, $value)->count() > 0;
+    }
+
+    public function getAllByField( $field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()
+                ->when($except, function ($query, $except) use ($field) {
+                    $query->where($field, '<>', $except);
+                })
+                ->where($field, $value);
+    }
+
+    /**
+     * @return array
+     * @author xaboy
+     * @day 2020/7/22
+     */
+    public function options()
+    {
+        return model::getDB()->where('is_show', 1)->column('pid,cate_name', 'store_brand_category_id');
+    }
+
+}

+ 62 - 0
app/common/dao/store/StoreBrandDao.php

@@ -0,0 +1,62 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\StoreBrand as model;
+use crmeb\traits\CategoresDao;
+
+class StoreBrandDao extends BaseDao
+{
+
+    use CategoresDao;
+
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+
+    public function getAll()
+    {
+        $query = $this->getModel()::hasWhere('brandCategory',function($query){
+                $query->where('is_show',1);
+            });
+        $query->where('StoreBrand.is_show',1);
+        return $query->order('StoreBrand.sort DESC')->select();
+    }
+
+
+    public function merFieldExists($field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()
+                ->when($except, function ($query, $except) use ($field) {
+                    $query->where($field, '<>', $except);
+                })
+                ->where($field, $value)->count() > 0;
+    }
+
+    public function search(array $where)
+    {
+        $query = $this->getModel()::getDB()->order('sort DESC');
+        if(isset($where['brand_category_id']) && $where['brand_category_id'])
+            $query->where('brand_category_id',$where['brand_category_id']);
+        if(isset($where['brand_name']) && $where['brand_name'])
+            $query->where('brand_name','like','%'.$where['brand_name'].'%');
+        if((isset($where['ids']) && $where['ids']))
+            $query->where($this->getPk(),'in',$where['ids']);
+        return $query->order('create_time desc');
+
+    }
+
+}

+ 67 - 0
app/common/dao/store/StoreCategoryDao.php

@@ -0,0 +1,67 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\StoreCategory as model;
+use crmeb\traits\CategoresDao;
+
+class StoreCategoryDao extends BaseDao
+{
+
+    use CategoresDao;
+
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    public function findChildrenId($id)
+    {
+        return model::getDB()->whereLike('path', '%/'. $id . '/%')->column('store_category_id');
+    }
+
+
+    public function fieldExistsList(?int $merId,$field,$value,$except = null)
+    {
+        return ($this->getModel()::getDB())->when($except ,function($query)use($field,$except){
+            $query->where($field,'<>',$except);
+        })->when(($merId !== null) ,function($query)use($merId){
+            $query->where('mer_id',$merId);
+        })->where($field,$value);
+
+    }
+
+    public function getTwoLevel($merId = 0)
+    {
+        $pid = model::getDB()->where('pid', 0)->where('is_show',1)->where('mer_id', $merId)->column('store_category_id');
+        return model::getDB()->whereIn('pid', $pid)->where('is_show', 1)->where('mer_id', $merId)->order('sort DESC')->column('store_category_id,cate_name,pid');
+    }
+
+    public function children($pid, $merId = 0)
+    {
+        return model::getDB()->where('pid', $pid)->where('mer_id', $merId)->where('is_show', 1)->order('sort DESC')->column('store_category_id,cate_name,pic');
+    }
+
+    public function allChildren($id)
+    {
+        $path = model::getDB()->where('store_category_id', $id)->where('mer_id', 0)->value('path');
+        return model::getDB()->whereLike('path', "$path%")->where('mer_id', 0)->order('sort DESC')->column('store_category_id');
+    }
+
+    public function getMaxLevel($merId = null)
+    {
+        if($merId) return 2;
+        return 3;
+    }
+}

+ 143 - 0
app/common/dao/store/StoreSeckillActiveDao.php

@@ -0,0 +1,143 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store;
+
+use app\common\model\store\StoreSeckillActive;
+use app\common\dao\BaseDao;
+use app\common\repositories\store\product\SpuRepository;
+
+class StoreSeckillActiveDao extends BaseDao
+{
+
+    /**
+     * TODO
+     * @return string
+     * @author Qinii
+     * @day 2020-07-30
+     */
+    protected function getModel(): string
+    {
+        return StoreSeckillActive::class;
+    }
+
+
+    /**
+     * TODO 搜索
+     * @param array $where
+     * @return mixed
+     * @author Qinii
+     * @day 2020-08-05
+     */
+    public function search(array $where)
+    {
+        $query = $this->getModel()::getDB()
+            ->when(isset($where['status']) && $where['status'] !== '',function($query) use($where){
+                $query->where('status',$where['status']);
+            })
+            ->when(isset($where['start_day']) && $where['start_day'] !== '',function($query) use($where){
+                $query->whereTime('start_day','<=',$where['start_day']);
+            })
+            ->when(isset($where['end_day']) && $where['end_day'] !== '',function($query) use($where){
+                $query->whereTime('end_day','>',$where['end_day']);
+            })
+            ->when(isset($where['start_time']) && $where['start_time'] !== '',function($query) use($where){
+                $query->whereTime('start_time','<=',$where['start_time']);
+            })
+            ->when(isset($where['end_time']) && $where['end_time'] !== '',function($query) use($where){
+                $query ->whereTime('end_time','>',$where['end_time']);
+            })
+            ->when(isset($where['product_id']) && $where['product_id'] !== '',function($query) use($where){
+                $query->where('product_id',$where['product_id']);
+            })
+            ->when(isset($where['day']) && $where['day'] !== '',function($query) use($where){
+                $query->whereTime('start_day','<=',$where['day'])->whereTime('end_day','>',$where['day']);
+            })
+            ->when(isset($where['time']) && $where['time'] !== '',function($query) use($where){
+                $query->whereTime('start_time','<=',$where['time'])->whereTime('end_time','>',$where['time']);
+            });
+
+        $query->order('start_time DESC');
+        return $query;
+    }
+
+
+    /**
+     * TODO
+     * @param int $productId
+     * @param array $data
+     * @return mixed
+     * @author Qinii
+     * @day 2020-08-11
+     */
+    public function updateByProduct(int $productId,array $data)
+    {
+        return $this->getModel()::getDB()->where('product_id',$productId)->update($data);
+    }
+
+    /**
+     * TODO
+     * @author Qinii
+     * @day 2020-08-11
+     */
+    public function valActiveStatus()
+    {
+        $day = date('Y-m-d',time());
+        $_h = date('H',time());
+        $id = $this->getModel()::getDB()->where('status',1)
+            ->whereTime('end_day','<=',$day)
+            ->whereTime('end_time','<',$_h)
+            ->column('seckill_active_id');
+        if($id) {
+            $this->getModel()::getDB()->where('seckill_active_id', 'in', $id)->update(['status' => -1]);
+            $where = [
+                'product_type' => 1,
+                'activity_ids' => $id
+            ];
+            app()->make(SpuRepository::class)->getSearch($where)->update(['status' => 0]);
+        }
+    }
+
+    /**
+     * TODO 不同状态商品
+     * @param $status
+     * @return mixed
+     * @author Qinii
+     * @day 2020-08-19
+     */
+    public function getStatus($status)
+    {
+        $day = date('Y-m-d',time());
+        $_h = date('H',time());
+        $query = $this->getModel()::getDB();
+        if($status == 1) //未开始
+            $query->where('status','<>',-1)->where(function($query)use ($day,$_h){
+                $query->whereTime('start_day','>',$day)->whereOr(function($query)use($day,$_h){
+                    $query->whereTime('start_day','<=',$day)->where('start_time','>',$_h);
+                });
+            });
+
+        if($status == 2)//进行中
+            $query->where('status',1)
+                ->whereTime('start_day','<=',$day)->whereTime('end_day','>',$day)
+                ->where('start_time','<=',$_h)->where('end_time','>',$_h);
+
+        if($status == 3) //结束
+            $query->where('status',-1)->whereOr(function($query)use($day,$_h){
+                $query->whereTime('end_day','<',$day)
+                    ->whereOr(function($query)use($day,$_h){
+                        $query->whereTime('start_day','<=',$day)->whereTime('end_day','>=',$day)->where('end_time','<=',$_h);
+                });
+            });
+        return $query;
+    }
+}

+ 112 - 0
app/common/dao/store/StoreSeckillTimeDao.php

@@ -0,0 +1,112 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store;
+
+use app\common\model\store\StoreSeckillTime;
+use app\common\dao\BaseDao;
+
+class StoreSeckillTimeDao extends BaseDao
+{
+
+    /**
+     * TODO
+     * @return string
+     * @author Qinii
+     * @day 2020-07-30
+     */
+    protected function getModel(): string
+    {
+        return StoreSeckillTime::class;
+    }
+
+    public function getTime($status)
+    {
+        foreach (StoreSeckillTime::ISTIME as $k => $item){
+            if($status && $k !== 24){
+                $time [] = ['value' => $k,  'label' => $item];
+            }
+            if(!$status && $k !== 0){
+                $time [] = ['value' => $k,  'label' => $item];
+            }
+        }
+        return $time;
+    }
+
+
+    public function search(array $where)
+    {
+        $query = $this->getModel()::getDB()
+            ->when(isset($where['status']) && $where['status'] !== '',function($query) use($where){
+                $query->where('status',$where['status']);
+            })
+            ->when(isset($where['title']) && $where['title'] !== '',function($query) use($where){
+                $query->where('title','like','%'.$where['title'].'%');
+            })
+            ->when(isset($where['start_time']) && $where['start_time'] !== '',function($query) use($where){
+                $query->whereTime('start_time','<=',intval($where['start_time']));
+            })
+            ->when(isset($where['end_time']) && $where['end_time'] !== '',function($query) use($where){
+                $query->whereTime('end_time','>=',intval($where['end_time']));
+            });
+        $query->order('start_time ASC');
+        return $query;
+    }
+
+    /**
+     * TODO 开始时间 在别的时间段中
+     * @param $time
+     * @return mixed
+     * @author Qinii
+     * @day 2020-07-31
+     */
+    public function valStartTime($time,$id)
+    {
+        return $this->getModel()::getDB()
+            ->when($id,function ($query)use($id){
+                $query->where($this->getPk(),'<>',$id);
+            })->where('start_time','<=',$time)->where('end_time','>',$time)->count();
+    }
+
+    /**
+     * TODO 结束时间在别的时间段中
+     * @param $time
+     * @param $id
+     * @return mixed
+     * @author Qinii
+     * @day 2020-07-31
+     */
+    public function valEndTime($time,$id)
+    {
+        return $this->getModel()::getDB()
+            ->when($id,function ($query)use($id){
+                $query->where($this->getPk(),'<>',$id);
+            })->where('start_time','<',$time)->where('end_time','>=',$time)->count();
+    }
+
+    /**
+     * TODO 时间段包含了别的时间段
+     * @param array $data
+     * @param $id
+     * @return mixed
+     * @author Qinii
+     * @day 2020-07-31
+     */
+    public function valAllTime(array $data,$id)
+    {
+        return $this->getModel()::getDB()
+            ->when($id,function ($query)use($id){
+                $query->where($this->getPk(),'<>',$id);
+            })->where('start_time','>',$data['start_time'])->where('end_time','<=',$data['end_time'])->count();
+    }
+
+}

+ 133 - 0
app/common/dao/store/broadcast/BroadcastGoodsDao.php

@@ -0,0 +1,133 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\broadcast;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\store\broadcast\BroadcastGoods;
+use app\common\repositories\system\merchant\MerchantRepository;
+use think\db\BaseQuery;
+use think\db\exception\DbException;
+
+/**
+ * Class BroadcastGoodsDao
+ * @package app\common\dao\store\broadcast
+ * @author xaboy
+ * @day 2020/7/29
+ */
+class BroadcastGoodsDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/7/29
+     */
+    protected function getModel(): string
+    {
+        return BroadcastGoods::class;
+    }
+
+    /**
+     * @param int $id
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/7/30
+     */
+    public function delete(int $id)
+    {
+        return $this->update($id, ['is_del' => 1]);
+    }
+
+    /**
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020/7/30
+     */
+    public function exists(int $id)
+    {
+        return $this->existsWhere(['broadcast_goods_id' => $id, 'is_del' => 0]);
+    }
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @return bool
+     * @author xaboy
+     * @day 2020/7/30
+     */
+    public function merExists(int $id, int $merId)
+    {
+        return $this->existsWhere(['broadcast_goods_id' => $id, 'is_del' => 0, 'is_mer_del' => 0, 'mer_id' => $merId]);
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/7/30
+     */
+    public function search(array $where)
+    {
+        if (isset($where['is_trader']) && $where['is_trader'] !== '') {
+            $query = BroadcastGoods::hasWhere('merchant', function ($query) use ($where) {
+                $query->where('is_trader', $where['is_trader']);
+            });
+        } else {
+            $query = BroadcastGoods::getDB()->alias('BroadcastGoods');
+        }
+        $query->when(isset($where['mer_id']), function ($query) use ($where) {
+            $query->where('BroadcastGoods.mer_id', $where['mer_id']);
+        })->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+            $query->whereLike('goods_id|mark|name|broadcast_goods_id', "%{$where['keyword']}%");
+        })->when(isset($where['valid']) && $where['valid'] !== '', function ($query) use ($where) {
+            $query->where('BroadcastGoods.is_show', 1);
+        })->when(isset($where['mer_valid']) && $where['mer_valid'] !== '', function ($query) use ($where) {
+            $query->where('BroadcastGoods.is_show', 1)->where('BroadcastGoods.is_mer_show', 1);
+        })->when(isset($where['broadcast_goods_id']) && $where['broadcast_goods_id'] !== '', function ($query) use ($where) {
+            $query->where('BroadcastGoods.broadcast_goods_id', $where['broadcast_goods_id']);
+        })->when(isset($where['status_tag']) && $where['status_tag'] !== '', function ($query) use ($where) {
+            if ($where['status_tag'] == 1) {
+                $query->where('BroadcastGoods.status', 2);
+            } else if ($where['status_tag'] == -1) {
+                $query->where('BroadcastGoods.status', -1);
+            } else if ($where['status_tag'] == 0) {
+                $query->whereIn('BroadcastGoods.status', [0, 1]);
+            }
+        })->where('BroadcastGoods.is_del', 0)->where('BroadcastGoods.is_mer_del', 0);
+        return $query;
+    }
+
+    public function goodsStatusAll()
+    {
+        return BroadcastGoods::getDB()->where('goods_id', '>', 0)->whereIn('audit_status', [0, 1])->column('audit_status', 'goods_id');
+    }
+
+    public function updateGoods($goods_id, $data)
+    {
+        return BroadcastGoods::getDB()->where('goods_id', $goods_id)->update($data);
+    }
+
+    public function goodsList($merId, array $ids)
+    {
+        return BroadcastGoods::getDB()->whereIn('broadcast_goods_id', $ids)->where('mer_id', $merId)->where('is_show', 1)->where('is_mer_show', 1)->where('is_del', 0)->where('status', 2)->select();
+    }
+
+    public function merDelete(int $id)
+    {
+        return $this->update($id, ['is_mer_del' => 1]);
+    }
+}

+ 156 - 0
app/common/dao/store/broadcast/BroadcastRoomDao.php

@@ -0,0 +1,156 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\broadcast;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\store\broadcast\BroadcastRoom;
+use app\common\repositories\system\merchant\MerchantRepository;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+/**
+ * Class BroadcastRoomDao
+ * @package app\common\dao\store\broadcast
+ * @author xaboy
+ * @day 2020/7/29
+ */
+class BroadcastRoomDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/7/29
+     */
+    protected function getModel(): string
+    {
+        return BroadcastRoom::class;
+    }
+
+    /**
+     * @param int $id
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/7/30
+     */
+    public function delete(int $id)
+    {
+        return $this->update($id, ['is_del' => 1]);
+    }
+
+    /**
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020/7/30
+     */
+    public function exists(int $id)
+    {
+        return $this->existsWhere(['broadcast_room_id' => $id, 'is_del' => 0]);
+    }
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @return bool
+     * @author xaboy
+     * @day 2020/7/30
+     */
+    public function merExists(int $id, int $merId)
+    {
+        return $this->existsWhere(['broadcast_room_id' => $id, 'is_del' => 0, 'is_mer_del' => 0, 'mer_id' => $merId]);
+    }
+
+    public function merDelete(int $id)
+    {
+        return $this->update($id, ['is_mer_del' => 1]);
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/7/30
+     */
+    public function search(array $where)
+    {
+        if(isset($where['is_trader']) && $where['is_trader'] !== ''){
+            $query = BroadcastRoom::hasWhere('merchant',function($query)use($where){
+                $query->where('is_trader',$where['is_trader']);
+            });
+        }else{
+            $query = BroadcastRoom::getDB()->alias('BroadcastRoom');
+        }
+        $query->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+            $query->whereLike('room_id|name|anchor_name|anchor_wechat|broadcast_room_id', "%{$where['keyword']}%");
+        })->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+            $query->where('BroadcastRoom.mer_id', $where['mer_id']);
+        })->when(isset($where['live_status']) && $where['live_status'] !== '', function ($query) use ($where) {
+            $query->where('BroadcastRoom.live_status', $where['live_status']);
+        })->when(isset($where['star']) && $where['star'] !== '', function ($query) use ($where) {
+            $query->where('BroadcastRoom.star', $where['star']);
+        })->when(isset($where['show_tag']) && $where['show_tag'] !== '', function ($query) use ($where) {
+            $query->where('is_show', 1)->where('is_mer_show', 1)->where('status', 2);
+        })->when(isset($where['hot']) && $where['hot'] !== '', function ($query) use ($where) {
+            $query->order('live_status ASC,star DESC,sort DESC');
+        })->when(isset($where['broadcast_room_id']) && $where['broadcast_room_id'] !== '', function ($query) use ($where) {
+            $query->where('BroadcastRoom.broadcast_room_id', $where['broadcast_room_id']);
+        })->when(isset($where['status_tag']) && $where['status_tag'] !== '', function ($query) use ($where) {
+            if ($where['status_tag'] == 1) {
+                $query->where('BroadcastRoom.status', 2);
+            } else if ($where['status_tag'] == -1) {
+                $query->where('BroadcastRoom.status', -1);
+            } else if ($where['status_tag'] == 0) {
+                $query->whereIn('BroadcastRoom.status', [0, 1]);
+            }
+        })->when(isset($where['show_type']) && $where['show_type'] !== '', function ($query) use ($where) {
+            if ($where['show_type'] == 3) {
+                $query->where('BroadcastRoom.is_mer_show', 1)->where('BroadcastRoom.is_show', 1);
+            } else if ($where['show_type'] == 2) {
+                $query->where('BroadcastRoom.is_mer_show', 0)->where('BroadcastRoom.is_show', 1);
+            } else if ($where['show_type'] == 1) {
+                $query->where('BroadcastRoom.is_mer_show', 1)->where('BroadcastRoom.is_show', 0);
+            } else if ($where['show_type'] == 0) {
+                $query->where('BroadcastRoom.is_mer_show', 0)->where('BroadcastRoom.is_show', 0);
+            }
+        })->where('BroadcastRoom.is_del', 0)->where('BroadcastRoom.is_mer_del', 0);
+
+        return $query;
+    }
+
+    /**
+     * @param $roomId
+     * @param $merId
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/7/31
+     */
+    public function validRoom($roomId, $merId)
+    {
+        return BroadcastRoom::getDB()->where('broadcast_room_id', $roomId)->where('mer_id', $merId)->where('status', 2)->where('is_show', 1)->find();
+    }
+
+    public function getRooms(array $roomIds)
+    {
+        return BroadcastRoom::getDB()->whereIn('room_id', $roomIds)->column('live_status,broadcast_room_id', 'room_id');
+    }
+}

+ 65 - 0
app/common/dao/store/broadcast/BroadcastRoomGoodsDao.php

@@ -0,0 +1,65 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\broadcast;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\broadcast\BroadcastRoomGoods;
+use app\common\repositories\store\order\StoreCartRepository;
+
+class BroadcastRoomGoodsDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return BroadcastRoomGoods::class;
+    }
+
+    public function clear($id)
+    {
+        return BroadcastRoomGoods::getDB()->where('broadcast_room_id', $id)->delete();
+    }
+
+    public function goodsId($id)
+    {
+        return BroadcastRoomGoods::getDB()->where('broadcast_room_id', $id)->column('broadcast_goods_id');
+    }
+
+    public function rmGoods($goodsId, $roomId)
+    {
+        return BroadcastRoomGoods::getDB()->where('broadcast_room_id', $roomId)->where('broadcast_goods_id', $goodsId)->delete();
+    }
+
+    public function getGoodsList($roomId, $page, $limit)
+    {
+        $query = BroadcastRoomGoods::getDB()->where('broadcast_room_id', $roomId);
+        $count = $query->count();
+        $list = $query->page($page, $limit)->with('goods.product')->select()->toArray();
+        $list = array_column($list, 'goods');
+        $ids = array_column($list, 'broadcast_goods_id');
+        if (count($ids)) {
+            $sourcePayInfo = app()->make(StoreCartRepository::class)->getSourcePayInfo(1, $ids);
+            $data = [];
+            foreach ($sourcePayInfo as $item) {
+                $data[$item['source_id']] = $item;
+            }
+            foreach ($list as $k => $goods) {
+                $list[$k]['pay_num'] = $data[$goods['broadcast_goods_id']]['pay_num'] ?? 0;
+                $list[$k]['pay_price'] = $data[$goods['broadcast_goods_id']]['pay_price'] ?? 0;
+            }
+        }
+        return compact('list', 'count');
+    }
+}

+ 270 - 0
app/common/dao/store/coupon/StoreCouponDao.php

@@ -0,0 +1,270 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\coupon;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\coupon\StoreCoupon;
+use app\common\repositories\system\merchant\MerchantRepository;
+use think\Collection;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+/**
+ * Class StoreCouponIssueDao
+ * @package app\common\dao\store\coupon
+ * @author xaboy
+ * @day 2020-05-14
+ */
+class StoreCouponDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return StoreCoupon::class;
+    }
+
+    /**
+     * @param int $merId
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-05-14
+     */
+    public function search(?int $merId, array $where)
+    {
+        if(isset($where['is_trader']) && $where['is_trader'] !== ''){
+            $query = StoreCoupon::hasWhere('merchant',function($query)use($where){
+                $query->where('is_trader',$where['is_trader']);
+            });
+        }else{
+            $query = StoreCoupon::getDB()->alias('StoreCoupon');
+        }
+        $query->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) {
+            $query->where('StoreCoupon.status', (int)$where['status']);
+        })->when(isset($where['coupon_name']) && $where['coupon_name'] !== '', function ($query) use ($where) {
+            $query->whereLike('title', "%{$where['coupon_name']}%");
+        })->when(isset($where['send_type']) && $where['send_type'] !== '', function ($query) use ($where) {
+            $query->where('send_type', (int)$where['send_type']);
+        })->when(isset($where['type']) && $where['type'] !== '', function ($query) use ($where) {
+            $query->where('type', (int)$where['type']);
+        })->when($merId !== null, function ($query) use ($merId) {
+            $query->where('StoreCoupon.mer_id', $merId);
+        });
+        return $query->where('StoreCoupon.is_del', 0)->order(($merId ? 'StoreCoupon.sort DESC,' : '') . 'coupon_id DESC');
+    }
+
+    /**
+     * @param int|null $type
+     * @param int $send_type
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/6/18
+     */
+    public function validCouponQuery(int $type = null, $send_type = 0)
+    {
+        $query = StoreCoupon::getDB()->where('status', 1)->where('send_type', $send_type)->where('is_del', 0)->order('sort DESC,coupon_id DESC')->when(!is_null($type), function ($query) use ($type) {
+            $query->where('type', $type);
+        });
+        $query->where(function (BaseQuery $query) {
+            $query->where('is_limited', 0)->whereOr(function (BaseQuery $query) {
+                $query->where('is_limited', 1)->where('remain_count', '>', 0);
+            });
+        })->where(function (BaseQuery $query) {
+            $query->where('is_timeout', 0)->whereOr(function (BaseQuery $query) {
+                $time = date('Y-m-d H:i:s');
+                $query->where('is_timeout', 1)->where('start_time', '<', $time)->where('end_time', '>', $time);
+            });
+        })->where(function (BaseQuery $query) {
+            $query->where('coupon_type', 0)->whereOr(function (BaseQuery $query) {
+                $query->where('coupon_type', 1)->where('use_end_time', '>', date('Y-m-d H:i:s'));
+            });
+        });
+        return $query;
+    }
+
+    /**
+     * @param $id
+     * @param $uid
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/19
+     */
+    public function validCoupon($id, $uid)
+    {
+        return $this->validCouponQuery()->when($uid, function (BaseQuery $query, $uid) {
+            $query->with(['issue' => function (BaseQuery $query) use ($uid) {
+                $query->where('uid', $uid);
+            }]);
+        })->where('coupon_id', $id)->find();
+    }
+
+    /**
+     * @param $merId
+     * @param null $uid
+     * @return Collection
+     * @throws DbException
+     * @throws DataNotFoundException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/1
+     */
+    public function validMerCoupon($merId, $uid = null, $type = 0)
+    {
+        return $this->validCouponQuery($type)->when($uid, function (BaseQuery $query, $uid) {
+            $query->with(['issue' => function (BaseQuery $query) use ($uid) {
+                $query->where('uid', $uid);
+            }]);
+        })->where('mer_id', $merId)->select();
+    }
+
+    /**
+     * @param $merId
+     * @param null $uid
+     * @return int
+     * @author xaboy
+     * @day 2020/6/19
+     */
+    public function validMerCouponExists($merId, $uid = null)
+    {
+        return $this->validCouponQuery(0)->when($uid, function (BaseQuery $query, $uid) {
+            $query->with(['issue' => function (BaseQuery $query) use ($uid) {
+                $query->where('uid', $uid);
+            }]);
+        })->where('mer_id', $merId)->count();
+    }
+
+    /**
+     * @param array $couponIds
+     * @param null $uid
+     * @return Collection
+     * @throws DbException
+     * @throws DataNotFoundException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/1
+     */
+    public function validProductCoupon(array $couponIds, $uid = null)
+    {
+        return $this->validCouponQuery(1)->when($uid, function (BaseQuery $query, $uid) {
+            $query->with(['issue' => function (BaseQuery $query) use ($uid) {
+                $query->where('uid', $uid);
+            }]);
+        })->whereIn('coupon_id', $couponIds)->select();
+    }
+
+    /**
+     * @param array $couponIds
+     * @param null $uid
+     * @return int
+     * @author Qinii
+     */
+    public function validProductCouponExists(array $couponIds, $uid = null)
+    {
+        return $this->validCouponQuery(1)->when($uid, function (BaseQuery $query, $uid) {
+            $query->with(['issue' => function (BaseQuery $query) use ($uid) {
+                $query->where('uid', $uid);
+            }]);
+        })->whereIn('coupon_id', $couponIds)->count();
+    }
+
+    /**
+     * @param int $id
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-05-13
+     */
+    public function delete(int $id)
+    {
+        return StoreCoupon::getDB()->where($this->getPk(), $id)->update(['is_del' => 1]);
+    }
+
+    /**
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020-05-13
+     */
+    public function exists(int $id)
+    {
+        return StoreCoupon::getDB()->where($this->getPk(), $id)->where('is_del', 0)->count($this->getPk()) > 0;
+    }
+
+    /**
+     * @param int $merId
+     * @param int $id
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-05-13
+     */
+    public function merDelete(int $merId, int $id)
+    {
+        return StoreCoupon::getDB()->where($this->getPk(), $id)->where('mer_id', $merId)->update(['is_del' => 1]);
+    }
+
+    /**
+     * @param int $merId
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020-05-13
+     */
+    public function merExists(int $merId, int $id)
+    {
+        return StoreCoupon::getDB()->where($this->getPk(), $id)->where('mer_id', $merId)->where('is_del', 0)->count($this->getPk()) > 0;
+    }
+
+    /**
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/18
+     */
+    public function newPeopleCoupon()
+    {
+        return $this->validCouponQuery(null, 2)->select();
+    }
+
+    /**
+     * @param array|null $ids
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/19
+     */
+    public function getGiveCoupon(array $ids = null)
+    {
+        return $this->validCouponQuery(null, 3)->when($ids, function ($query, $ids) {
+            $query->whereIn('coupon_id', $ids);
+        })->select();
+    }
+}

+ 55 - 0
app/common/dao/store/coupon/StoreCouponIssueUserDao.php

@@ -0,0 +1,55 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\coupon;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\coupon\StoreCouponIssueUser;
+use think\db\BaseQuery;
+
+/**
+ * Class StoreCouponIssueUserDao
+ * @package app\common\dao\store\coupon
+ * @author xaboy
+ * @day 2020/6/2
+ */
+class StoreCouponIssueUserDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/6/2
+     */
+    protected function getModel(): string
+    {
+        return StoreCouponIssueUser::class;
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/6/2
+     */
+    public function search(array $where)
+    {
+        return StoreCouponIssueUser::getDB()->when(isset($where['coupon_id']) && $where['coupon_id'] != '', function ($query) use ($where) {
+            $query->where('coupon_id', $where['coupon_id']);
+        })->when(isset($where['uid']) && $where['uid'] != '', function ($query) use ($where) {
+            $query->where('uid', $where['uid']);
+        })->order('create_time');
+    }
+}

+ 77 - 0
app/common/dao/store/coupon/StoreCouponProductDao.php

@@ -0,0 +1,77 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\coupon;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\coupon\StoreCouponProduct;
+use think\Collection;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+
+/**
+ * Class StoreCouponProductDao
+ * @package app\common\dao\store\coupon
+ * @author xaboy
+ * @day 2020-05-13
+ */
+class StoreCouponProductDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return StoreCouponProduct::class;
+    }
+
+    /**
+     * @param array $data
+     * @return int
+     * @author xaboy
+     * @day 2020-05-13
+     */
+    public function insertAll(array $data)
+    {
+        return StoreCouponProduct::getDB()->insertAll($data);
+    }
+
+    /**
+     * @param $couponId
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-05-13
+     */
+    public function clear($couponId)
+    {
+        return StoreCouponProduct::getDB()->where('coupon_id', $couponId)->delete();
+    }
+
+    /**
+     * @param $productId
+     * @return array
+     * @author xaboy
+     * @day 2020/6/1
+     */
+    public function productByCouponId($productId)
+    {
+        return StoreCouponProduct::getDB()->whereIn('product_id', $productId)->column('coupon_id');
+    }
+}

+ 43 - 0
app/common/dao/store/coupon/StoreCouponSendDao.php

@@ -0,0 +1,43 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\coupon;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\coupon\StoreCouponSend;
+
+class StoreCouponSendDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return StoreCouponSend::class;
+    }
+
+    public function search(array $where)
+    {
+        return StoreCouponSend::getDB()->alias('A')->leftJoin('StoreCoupon B', 'B.coupon_id = A.coupon_id')
+            ->when(isset($where['coupon_name']) && $where['coupon_name'] !== '', function ($query) use ($where) {
+                $query->whereLike('B.title', "%{$where['coupon_name']}%");
+            })->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+                getModelTime($query, $where['date'], 'A.create_time');
+            })->when(isset($where['coupon_type']) && $where['coupon_type'] !== '', function ($query) use ($where) {
+                $query->where('B.type', $where['coupon_type']);
+            })->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) {
+                $query->where('A.status', $where['status']);
+            })->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+                $query->where('A.mer_id', $where['mer_id']);
+            });
+    }
+}

+ 106 - 0
app/common/dao/store/coupon/StoreCouponUserDao.php

@@ -0,0 +1,106 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\coupon;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\coupon\StoreCouponUser;
+
+/**
+ * Class StoreCouponUserDao
+ * @package app\common\dao\store\coupon
+ * @author xaboy
+ * @day 2020-05-14
+ */
+class StoreCouponUserDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return StoreCouponUser::class;
+    }
+
+    public function search(array $where)
+    {
+        return StoreCouponUser::when(isset($where['username']) && $where['username'] !== '', function ($query) use ($where) {
+            $query->hasWhere('user', [['nickname', 'LIKE', "%{$where['username']}%"]]);
+        })->alias('StoreCouponUser')->when(isset($where['coupon']) && $where['coupon'] !== '', function ($query) use ($where) {
+            $query->whereLike('StoreCouponUser.coupon_title', "%{$where['coupon']}%");
+        })->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) {
+            $query->where('StoreCouponUser.status', $where['status']);
+        })->when(isset($where['uid']) && $where['uid'] !== '', function ($query) use ($where) {
+            $query->where('StoreCouponUser.uid', $where['uid']);
+        })->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+            $query->where('StoreCouponUser.mer_id', $where['mer_id']);
+        })->when(isset($where['coupon_id']) && $where['coupon_id'] !== '', function ($query) use ($where) {
+            $query->where('StoreCouponUser.coupon_id', $where['coupon_id']);
+        })->when(isset($where['coupon']) && $where['coupon'] !== '', function ($query) use ($where) {
+            $query->whereLike('StoreCouponUser.coupon_title|StoreCouponUser.coupon_id', "%{$where['coupon']}%");
+        })->when(isset($where['type']) && $where['type'] !== '', function ($query) use ($where) {
+            $query->where('StoreCouponUser.type', $where['type']);
+        })->when(isset($where['send_id']) && $where['send_id'] !== '', function ($query) use ($where) {
+            $query->where('StoreCouponUser.send_id', $where['send_id'])->where('StoreCouponUser.type', 'send');
+        })->when(isset($where['statusTag']) && $where['statusTag'] !== '', function ($query) use ($where) {
+            if ($where['statusTag'] == 1) {
+                $query->where('StoreCouponUser.status', 0);
+            } else {
+                $query->whereIn('StoreCouponUser.status', [1, 2])->where('StoreCouponUser.create_time', '>', date('Y-m-d H:i:s', strtotime('-60 day')));
+            }
+        })->order('StoreCouponUser.coupon_user_id DESC');
+    }
+
+    public function validIntersection($merId, $uid, array $ids): array
+    {
+        $time = date('Y-m-d H:i:s');
+        return StoreCouponUser::getDB()->whereIn('coupon_user_id', $ids)->where('start_time', '<', $time)->where('end_time', '>', $time)
+            ->where('is_fail', 0)->where('status', 0)->where('mer_id', $merId)->where('uid', $uid)->column('coupon_user_id');
+    }
+
+    public function validQuery()
+    {
+        $time = date('Y-m-d H:i:s');
+        return StoreCouponUser::getDB()->where('start_time', '<', $time)->where('end_time', '>', $time)->where('is_fail', 0)->where('status', 0);
+    }
+
+    public function failCoupon()
+    {
+        $time = date('Y-m-d H:i:s');
+        return StoreCouponUser::getDB()->where('end_time', '<', $time)->where('is_fail', 0)->where('status', 0)->update(['status' => 2]);
+    }
+
+    public function userTotal($uid)
+    {
+        return $this->validQuery()->where('uid', $uid)->count();
+    }
+
+    public function usedNum($couponId)
+    {
+        return StoreCouponUser::getDB()->where('coupon_id', $couponId)->where('status', 1)->count();
+    }
+
+    public function sendNum($couponId, $sendId = null, $status = null)
+    {
+        return StoreCouponUser::getDB()->where('coupon_id', $couponId)->when($sendId, function ($query, $sendId) {
+            $query->where('type', 'send')->where('send_id', $sendId);
+        })->when(isset($status), function ($query) use ($status) {
+            $query->where('status', $status);
+        })->count();
+    }
+}

+ 57 - 0
app/common/dao/store/order/MerchantReconciliationDao.php

@@ -0,0 +1,57 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\order;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\order\MerchantReconciliation as model;
+use app\common\repositories\system\admin\AdminRepository;
+use app\common\repositories\system\merchant\MerchantRepository;
+
+class MerchantReconciliationDao extends BaseDao
+{
+   public function getModel(): string
+   {
+       return model::class;
+   }
+
+   public function search(array $where)
+   {
+       $query = ($this->getModel()::getDB())
+           ->when(isset($where['mer_id']) && $where['mer_id'] != '' ,function($query)use($where){
+               $query->where('mer_id',$where['mer_id']);
+           })->when(isset($where['status']) && $where['status'] != '' ,function($query)use($where){
+               $query->where('status',$where['status']);
+           })->when(isset($where['is_accounts']) && $where['is_accounts'] != '' ,function($query)use($where){
+               $query->where('is_accounts',$where['is_accounts']);
+           })->when(isset($where['date']) && $where['date'] != '' ,function($query)use($where){
+               getModelTime($query,$where['date']);
+           })->when(isset($where['reconciliation_id']) && $where['reconciliation_id'] != '' ,function($query)use($where){
+               $query->where('reconciliation_id',$where['reconciliation_id']);
+           })
+           ->when(isset($where['keyword']) && $where['keyword'] !== '',function($query)use($where){
+               $make = app()->make(AdminRepository::class);
+               $admin_id = $make->getSearch(['real_name' => $where['keyword']],null,false)->column('admin_id');
+               $query->where(function($query) use($admin_id,$where){
+                   if(isset($where['mer_id'])){
+                        $query->where('admin_id','in',$admin_id);
+                   }else {
+                       $mer_make = app()->make(MerchantRepository::class);
+                       $mer_id = $mer_make->getSearch(['keyword' => $where['keyword']])->column('mer_id');
+                       $query->where('admin_id','in',$admin_id)->whereOr('mer_id','in',$mer_id);
+                   }
+               });
+           });
+       return $query->order('create_time DESC,status DESC');
+   }
+
+}

+ 34 - 0
app/common/dao/store/order/MerchantReconciliationOrderDao.php

@@ -0,0 +1,34 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\order;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\order\MerchantReconciliationOrder as model;
+
+class MerchantReconciliationOrderDao extends BaseDao
+{
+   public function getModel(): string
+   {
+       return model::class;
+   }
+
+
+   public function search($where)
+   {
+       return ($this->getModel()::getDB())->when(isset($where['reconciliation_id']) && $where['reconciliation_id'] !== '',function ($query)use ($where){
+        $query->where('reconciliation_id',$where['reconciliation_id']);
+       })->when(isset($where['type']) && $where['type'] !== '',function ($query)use ($where){
+           $query->where('type',$where['type']);
+       });
+   }
+}

+ 62 - 0
app/common/dao/store/order/PresellOrderDao.php

@@ -0,0 +1,62 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\order\PresellOrder;
+
+class PresellOrderDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return PresellOrder::class;
+    }
+
+    public function search(array $where)
+    {
+        return PresellOrder::getDB()->when(isset($where['pay_type']) && $where['pay_type'] !== '', function ($query) use ($where) {
+            $query->whereIn('pay_type', $where['pay_type']);
+        })->when(isset($where['paid']) && $where['paid'] !== '', function ($query) use ($where) {
+            $query->where('paid', $where['paid']);
+        })->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+            $query->where('mer_id', $where['mer_id']);
+        });
+    }
+
+    public function userOrder($uid, $orderId)
+    {
+        return PresellOrder::getDB()->where('uid', $uid)->where('order_id', $orderId)->find();
+    }
+
+    /**
+     * @param $time
+     * @return array
+     * @author xaboy
+     * @day 2020/11/3
+     */
+    public function getTimeOutIds($time)
+    {
+        return PresellOrder::getDB()->where('status', 1)->where('paid', 0)
+            ->where('final_end_time', '<', $time)->column('presell_order_id');
+    }
+
+    public function sendSmsIds($date)
+    {
+        return PresellOrder::getDB()->where('status', 1)->where('paid', 0)
+            ->whereLike('final_start_time', $date . '%')->column('order_id');
+    }
+}

+ 142 - 0
app/common/dao/store/order/StoreCartDao.php

@@ -0,0 +1,142 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\order\StoreCart;
+use think\Collection;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\model\Relation;
+
+class StoreCartDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return StoreCart::class;
+    }
+
+    public function test()
+    {
+        return StoreCart::getDB()->with(['product' => function (Relation $query) {
+            $query->where('store_name', '儿童节礼物');
+        }])->select();
+    }
+
+    /**
+     * @param array $ids
+     * @param $uid
+     * @param int|null $merId
+     * @return array
+     * @author xaboy
+     * @day 2020/6/5
+     */
+    public function validIntersection(array $ids, $uid, int $merId = null): array
+    {
+        return StoreCart::getDB()->whereIn('cart_id', $ids)
+            ->when($merId, function ($query, $merId) {
+                $query->where('mer_id', $merId);
+            })
+            ->where('is_del', 0)->where('is_fail', 0)->where('is_pay', 0)->where('uid', $uid)->column('cart_id');
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/6/1
+     * @param int $uid
+     * @return mixed
+     */
+    public function getAll(int $uid)
+    {
+        $query = ($this->getModel())::where(['uid' => $uid, 'is_del' => 0, 'is_new' => 0, 'is_pay' => 0])
+            ->with([
+                'product' => function ($query) {
+                    $query->field('product_id,image,store_name,is_show,status,is_del,unit_name,price,mer_status,is_used,product_type');
+                },
+                'productAttr' => function ($query) {
+                    $query->field('product_id,stock,price,unique,sku,image');
+                },
+                'merchant' => function ($query) {
+                    $query->field('mer_id,mer_name,mer_state,mer_avatar,is_trader');
+                }
+            ])->select();
+
+        return $query;
+    }
+
+    public function cartIbByData(array $ids, int $uid, ?int $cityId, bool $confirm = true)
+    {
+        return StoreCart::getDb()->where('uid', $uid)->with(['product' => function (Relation $query) use ($cityId) {
+            $query->field('product_id,image,store_name,is_show,status,is_del,unit_name,price,mer_status,temp_id,give_coupon_ids,is_gift_bag,is_used,product_type,old_product_id');
+            if ($cityId) {
+                $query->with(['temp' => ['region' => function (Relation $query) use ($cityId) {
+                    $query->where(function ($query) use ($cityId) {
+                        $query->whereLike('city_id', "%/{$cityId}/%")->whereOr('city_id', '0');
+                    })->order('shipping_template_region_id DESC')->withLimit(1);
+                }, 'undelives' => function ($query) use ($cityId) {
+                    $query->whereLike('city_id', "%/{$cityId}/%");
+                }, 'free' => function (Relation $query) use ($cityId) {
+                    $query->whereLike('city_id', "%/{$cityId}/%")->order('shipping_template_free_id DESC')->withLimit(1);
+                }]]);
+            }
+        }, 'productAttr' => function (Relation $query) use ($confirm) {
+            $query->field('image,extension_one,extension_two,product_id,stock,price,unique,sku,volume,weight,ot_price ' . ($confirm ? '' : ',cost'))
+                ->append(['bc_extension_one', 'bc_extension_two']);
+        }, 'merchant' => function (Relation $query) use ($uid) {
+            $query->field('mer_id,mer_name,mer_state,mer_avatar')->with(['coupon' => function ($query) use ($uid) {
+                $query->where('uid', $uid);
+            }]);
+        }])->whereIn('cart_id', $ids)->order('product_type DESC,cart_id DESC')->select();
+    }
+
+    /**
+     * @param array $cartIds
+     * @param int $uid
+     * @author Qinii
+     */
+    public function batchDelete(array $cartIds, int $uid)
+    {
+        return ($this->getModel()::getDB())->where('uid', $uid)->whereIn('cart_id', $cartIds)->delete();
+    }
+
+    /**
+     * @param int $uid
+     * @return mixed
+     * @author Qinii
+     */
+    public function getCartCount(int $uid)
+    {
+        $data = ($this->getModel()::getDB())->where(['uid' => $uid, 'is_del' => 0, 'is_new' => 0, 'is_pay' => 0])->field('SUM(cart_num) as count')->select();
+        $data[0]['count'] = $data[0]['count'] ? $data[0]['count'] : 0;
+        return $data;
+    }
+
+    /**
+     * @param $source
+     * @param array|null $ids
+     * @author xaboy
+     * @day 2020/8/31
+     */
+    public function getSourcePayInfo($source, ?array $ids = null)
+    {
+        return StoreCart::getDB()->alias('A')->where('A.source', $source)->where('A.is_pay', 1)->when($ids, function ($query, $ids) {
+            $query->whereIn('A.source_id', $ids);
+        })->leftJoin('StoreOrderProduct B', 'A.cart_id = B.cart_id')
+            ->field('sum(B.product_num) as pay_num,sum(B.product_price) as pay_price,A.source_id')->group('A.source_id')->select();
+    }
+}

+ 95 - 0
app/common/dao/store/order/StoreGroupOrderDao.php

@@ -0,0 +1,95 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\store\order\StoreGroupOrder;
+
+/**
+ * Class StoreGroupOrderDao
+ * @package app\common\dao\store\order
+ * @author xaboy
+ * @day 2020/6/9
+ */
+class StoreGroupOrderDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    protected function getModel(): string
+    {
+        return StoreGroupOrder::class;
+    }
+
+    /**
+     * @param null $uid
+     * @return int
+     * @author xaboy
+     * @day 2020/6/11
+     */
+    public function orderNumber($uid = null)
+    {
+        return StoreGroupOrder::when($uid, function ($query, $uid) {
+            $query->where('uid', $uid);
+        })->where('is_del', 0)->where('paid', 0)->count();
+    }
+
+    /**
+     * @param array $where
+     * @return \think\db\BaseQuery
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    public function search(array $where)
+    {
+        return StoreGroupOrder::getDB()->when(isset($where['paid']) && $where['paid'] !== '', function ($query) use ($where) {
+            $query->where('paid', $where['paid']);
+        })->when(isset($where['uid']) && $where['uid'] !== '', function ($query) use ($where) {
+            $query->where('uid', $where['uid']);
+        })->order('create_time DESC')->when(isset($where['is_del']) && $where['is_del'] !== '', function ($query) use ($where) {
+            $query->where('is_del', $where['is_del']);
+        }, function ($query) {
+            $query->where('is_del', 0);
+        });
+    }
+
+    /**
+     * @param $time
+     * @param bool $is_remind
+     * @return array
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    public function getTimeOutIds($time, $is_remind = false)
+    {
+        return StoreGroupOrder::getDB()->where('is_del', 0)->where('paid', 0)
+            ->when($is_remind, function ($query) {
+                $query->where('is_remind', 0);
+            })->where('create_time', '<=', $time)->column('group_order_id');
+    }
+
+    public function isRemind($id)
+    {
+        return StoreGroupOrder::getDB()->where('group_order_id', $id)->update(['is_remind' => 1]);
+    }
+
+    public function totalNowMoney($uid)
+    {
+        return StoreGroupOrder::getDB()->where('pay_type', 0)->where('uid', $uid)->sum('pay_price') ?: 0;
+    }
+}

+ 33 - 0
app/common/dao/store/order/StoreImportDao.php

@@ -0,0 +1,33 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\store\order\StoreImport;
+
+class StoreImportDao extends BaseDao
+{
+
+    /**
+     * TODO
+     * @return string
+     * @author Qinii
+     * @day 3/16/21
+     */
+    protected function getModel(): string
+    {
+        return StoreImport::class;
+    }
+}

+ 33 - 0
app/common/dao/store/order/StoreImportDeliveryDao.php

@@ -0,0 +1,33 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\store\order\StoreImportDelivery;
+
+class StoreImportDeliveryDao extends BaseDao
+{
+
+    /**
+     * TODO
+     * @return string
+     * @author Qinii
+     * @day 3/16/21
+     */
+    protected function getModel(): string
+    {
+        return StoreImportDelivery::class;
+    }
+}

+ 711 - 0
app/common/dao/store/order/StoreOrderDao.php

@@ -0,0 +1,711 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\order\StoreOrder;
+use app\common\model\store\order\StoreOrderProduct;
+use app\common\model\store\order\StoreOrderStatus;
+use app\common\model\user\User;
+use app\common\repositories\store\order\StoreImportDeliveryRepository;
+use app\common\repositories\store\order\StoreImportRepository;
+use app\common\repositories\store\order\StoreOrderStatusRepository;
+use app\common\repositories\store\product\ProductAssistSetRepository;
+use app\common\repositories\store\product\ProductGroupBuyingRepository;
+use app\common\repositories\store\product\ProductGroupRepository;
+use app\common\repositories\system\merchant\MerchantRepository;
+use crmeb\services\SpreadsheetExcelService;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\facade\Db;
+use think\Model;
+
+/**
+ * Class StoreOrderDao
+ * @package app\common\dao\store\order
+ * @author xaboy
+ * @day 2020/6/8
+ */
+class StoreOrderDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/6/8
+     */
+    protected function getModel(): string
+    {
+        return StoreOrder::class;
+    }
+
+    /**
+     * @param array $where
+     * @param int $sysDel
+     * @return BaseQuery
+     * @author xaboyCRMEB
+     * @day 2020/6/16
+     */
+    public function search(array $where, $sysDel = 0)
+    {
+        if (isset($where['is_trader']) && $where['is_trader'] !== '') {
+            $query = StoreOrder::hasWhere('merchant', function ($query) use ($where) {
+                $query->where('is_trader', $where['is_trader']);
+            });
+        } else {
+            $query = StoreOrder::getDB()->alias('StoreOrder');
+        }
+        $query->when(($sysDel !== null), function ($query) use ($sysDel) {
+            $query->where('is_system_del', $sysDel);
+        })
+            ->when(isset($where['order_type']) && $where['order_type'] >= 0 && $where['order_type'] !== '', function ($query) use ($where) {
+                $query->where('order_type', $where['order_type']);
+            })
+            ->when(isset($where['activity_type']) && $where['activity_type'] != '', function ($query) use ($where) {
+                $query->where('activity_type', $where['activity_type']);
+            })
+            ->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) {
+                if ($where['status'] == -2)
+                    $query->where('paid', 1)->whereNotIn('status', [10, 11]);
+                else if ($where['status'] == 0)
+                    $query->whereIn('StoreOrder.status', [0, 9]);
+                else if ($where['status'] == 10)
+                    $query->whereIn('StoreOrder.status', [10, 11]);
+                else
+                    $query->where('StoreOrder.status', $where['status']);
+            })
+            ->when(isset($where['uid']) && $where['uid'] !== '', function ($query) use ($where) {
+                $query->where('uid', $where['uid']);
+            })
+            ->when(isset($where['pay_type']) && $where['pay_type'] !== '', function ($query) use ($where) {
+                $query->where('pay_type', $where['pay_type']);
+            })
+            ->when(isset($where['order_ids']) && $where['order_ids'] !== '', function ($query) use ($where) {
+                $query->whereIn('order_id', $where['order_ids']);
+            })
+            ->when(isset($where['order_id']) && $where['order_id'] !== '', function ($query) use ($where) {
+                $query->where('order_id', $where['order_id']);
+            })
+            ->when(isset($where['take_order']) && $where['take_order'] != '', function ($query) use ($where) {
+                $query->where('order_type', 1)->whereNotNull('verify_time');
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+                $query->where('StoreOrder.mer_id', $where['mer_id']);
+            })
+            ->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+                getModelTime($query, $where['date'], 'StoreOrder.create_time');
+            })
+            ->when(isset($where['verify_date']) && $where['verify_date'] !== '', function ($query) use ($where) {
+                getModelTime($query, $where['verify_date'], 'verify_time');
+            })
+            ->when(isset($where['order_sn']) && $where['order_sn'] !== '', function ($query) use ($where) {
+                $query->where('order_sn', 'like', '%' . $where['order_sn'] . '%');
+            })
+            ->when(isset($where['paid']) && $where['paid'] !== '', function ($query) use ($where) {
+                $query->where('paid', $where['paid']);
+            })
+            ->when(isset($where['is_del']) && $where['is_del'] !== '', function ($query) use ($where) {
+                $query->where('StoreOrder.is_del', $where['is_del']);
+            })
+            ->when(isset($where['service_id']) && $where['service_id'] !== '', function ($query) use ($where) {
+                $query->where('service_id', $where['service_id']);
+            })
+            ->when(isset($where['username']) && $where['username'] !== '', function ($query) use ($where) {
+                $uid = User::where('nickname', 'like', "%{$where['username']}%")
+                    ->whereOr('phone', 'like', "%{$where['username']}%")
+                    ->column('uid');
+                $query->where('uid', 'in', $uid);
+            })
+            ->when(isset($where['keywords']) && $where['keywords'] !== '', function ($query) use ($where) {
+                $query->where(function ($query) use ($where) {
+                    $query->whereLike('real_name|user_phone|order_sn', "%" . $where['keywords'] . "%");
+                });
+            })
+            ->when(isset($where['reconciliation_type']) && $where['reconciliation_type'] !== '', function ($query) use ($where) {
+                $query->when($where['reconciliation_type'], function ($query) use ($where) {
+                    $query->where('reconciliation_id', '<>', 0);
+                }, function ($query) use ($where) {
+                    $query->where('reconciliation_id', 0);
+                });
+            })->order('StoreOrder.create_time DESC');
+
+        return $query;
+    }
+
+    public function groupBuyingStatus(array $orderIds, $status)
+    {
+        if (!count($orderIds)) return 0;
+        $make = app()->make(StoreOrderStatusRepository::class);
+        foreach ($orderIds as $id){
+            $make->status($id,'group_success','拼团成功');
+        }
+        return StoreOrder::getDB()->whereIn('order_id', $orderIds)->update(compact('status'));
+    }
+
+    /**
+     * @param $id
+     * @param $uid
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/11
+     */
+    public function userOrder($id, $uid)
+    {
+        return StoreOrder::getDB()->where('order_id', $id)->where('uid', $uid)->where('is_del', 0)->where('paid', 1)->where('is_system_del', 0)->find();
+    }
+
+    /**
+     * @param array $where
+     * @param $ids
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/6/26
+     */
+    public function usersOrderQuery(array $where, $ids)
+    {
+        return StoreOrder::getDB()->whereIn('uid', $ids)->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+            getModelTime($query, $where['date'], 'pay_time');
+        })->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+            $query->where('order_id|order_sn', $where['keyword']);
+        })->where('paid', 1)->order('pay_time DESC');
+    }
+
+    /**
+     * @param $field
+     * @param $value
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020/6/11
+     */
+    public function fieldExists($field, $value, ?int $except = null): bool
+    {
+        return ($this->getModel()::getDB())->when($except, function ($query) use ($field, $except) {
+                $query->where($field, '<>', $except);
+            })->where($field, $value)->count() > 0;
+    }
+
+    /**
+     * @param $id
+     * @return mixed
+     * @author xaboy
+     * @day 2020/6/12
+     */
+    public function getMerId($id)
+    {
+        return StoreOrder::getDB()->where('order_id', $id)->value('mer_id');
+    }
+
+    /**
+     * @param array $where
+     * @return bool
+     * @author Qinii
+     * @day 2020-06-12
+     */
+    public function merFieldExists(array $where)
+    {
+        return ($this->getModel()::getDB())->where($where)->count() > 0;
+    }
+
+    /**
+     * TODO
+     * @param $reconciliation_id
+     * @return mixed
+     * @author Qinii
+     * @day 2020-06-15
+     */
+    public function reconciliationUpdate($reconciliation_id)
+    {
+        return ($this->getModel()::getDB())->whereIn('reconciliation_id', $reconciliation_id)->update(['reconciliation_id' => 0]);
+    }
+
+    public function dayOrderNum($day, $merId = null)
+    {
+        return StoreOrder::getDB()->where('paid', 1)->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->when($day, function ($query, $day) {
+            getModelTime($query, $day, 'pay_time');
+        })->count();
+    }
+
+    public function dayOrderPrice($day, $merId = null)
+    {
+        return getModelTime(StoreOrder::getDB()->where('paid', 1)->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        }), $day, 'pay_time')->sum('pay_price');
+    }
+
+    public function dateOrderPrice($date, $merId = null)
+    {
+        return StoreOrder::getDB()->where('paid', 1)->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->when($date, function ($query, $date) {
+            getModelTime($query, $date, 'pay_time');
+        })->sum('pay_price');
+    }
+
+    public function dateOrderNum($date, $merId = null)
+    {
+        return StoreOrder::getDB()->where('paid', 1)->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->when($date, function ($query, $date) {
+            getModelTime($query, $date, 'pay_time');
+        })->count();
+    }
+
+    public function dayOrderUserNum($day, $merId = null)
+    {
+        return StoreOrder::getDB()->where('paid', 1)->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->when($day, function ($query, $day) {
+            getModelTime($query, $day, 'pay_time');
+        })->group('uid')->count();
+    }
+
+    public function orderUserNum($date, $paid = null, $merId = null)
+    {
+        return StoreOrder::getDB()->when($paid, function ($query, $paid) {
+            $query->where('paid', $paid);
+        })->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->when($date, function ($query, $date) use ($paid) {
+            if (!$paid) {
+                getModelTime($query, $date);
+//                $query->where(function ($query) use ($date) {
+//                    $query->where(function ($query) use ($date) {
+//                        $query->where('paid', 1);
+//                        getModelTime($query, $date, 'pay_time');
+//                    })->whereOr(function ($query) use ($date) {
+//                        $query->where('paid', 0);
+//                        getModelTime($query, $date);
+//                    });
+//                });
+            } else
+                getModelTime($query, $date, 'pay_time');
+        })->group('uid')->count();
+    }
+
+    public function orderUserGroup($date, $paid = null, $merId = null)
+    {
+        return StoreOrder::getDB()->when($paid, function ($query, $paid) {
+            $query->where('paid', $paid);
+        })->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->when($date, function ($query, $date) {
+            getModelTime($query, $date, 'pay_time');
+        })->group('uid')->field(Db::raw('uid,sum(pay_price) as pay_price,count(order_id) as total'))->select();
+    }
+
+    public function oldUserNum(array $ids, $merId = null)
+    {
+        return StoreOrder::getDB()->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->whereIn('uid', $ids)->where('paid', 1)->group('uid')->count();
+    }
+
+    public function oldUserIds(array $ids, $merId = null)
+    {
+        return StoreOrder::getDB()->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->whereIn('uid', $ids)->where('paid', 1)->group('uid')->column('uid');
+    }
+
+    public function orderPrice($date, $paid = null, $merId = null)
+    {
+        return StoreOrder::getDB()->when($paid, function ($query, $paid) {
+            $query->where('paid', $paid);
+        })->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->when($date, function ($query, $date) use ($paid) {
+            if (!$paid) {
+                $query->where(function ($query) use ($date) {
+                    $query->where(function ($query) use ($date) {
+                        $query->where('paid', 1);
+                        getModelTime($query, $date, 'pay_time');
+                    })->whereOr(function ($query) use ($date) {
+                        $query->where('paid', 0);
+                        getModelTime($query, $date);
+                    });
+                });
+            } else
+                getModelTime($query, $date, 'pay_time');
+        })->sum('pay_price');
+    }
+
+    public function orderGroupNum($date, $merId = null)
+    {
+        return StoreOrder::getDB()->field(Db::raw('sum(pay_price) as pay_price,count(*) as total,count(distinct uid) as user,from_unixtime(unix_timestamp(pay_time),\'%m-%d\') as `day`'))
+            ->where('paid', 1)->when($date, function ($query, $date) {
+                getModelTime($query, $date, 'pay_time');
+            })->when($merId, function ($query, $merId) {
+                $query->where('mer_id', $merId);
+            })->order('day ASC')->group('day')->select();
+    }
+
+    public function orderGroupNumPage($where, $page, $limit, $merId = null)
+    {
+        return StoreOrder::getDB()->when(isset($where['dateRange']), function ($query) use ($where) {
+            getModelTime($query, date('Y/m/d 00:00:00', $where['dateRange']['start']) . '-' . date('Y/m/d 00:00:00', $where['dateRange']['stop']), 'pay_time');
+        })->field(Db::raw('sum(pay_price) as pay_price,count(*) as total,count(distinct uid) as user,from_unixtime(unix_timestamp(pay_time),\'%m-%d\') as `day`'))
+            ->where('paid', 1)->when($merId, function ($query, $merId) {
+                $query->where('mer_id', $merId);
+            })->order('day DESC')->page($page, $limit)->group('day')->select();
+    }
+
+    public function dayOrderPriceGroup($date, $merId = null)
+    {
+        return StoreOrder::getDB()->field(Db::raw('sum(pay_price) as price, from_unixtime(unix_timestamp(pay_time),\'%H:%i\') as time'))
+            ->where('paid', 1)->when($date, function ($query, $date) {
+                getModelTime($query, $date, 'pay_time');
+            })->when($merId, function ($query, $merId) {
+                $query->where('mer_id', $merId);
+            })->group('time')->select();
+    }
+
+    public function dayOrderNumGroup($date, $merId = null)
+    {
+        return StoreOrder::getDB()->field(Db::raw('count(*) as total, from_unixtime(unix_timestamp(pay_time),\'%H:%i\') as time'))
+            ->where('paid', 1)->when($date, function ($query, $date) {
+                getModelTime($query, $date, 'pay_time');
+            })->when($merId, function ($query, $merId) {
+                $query->where('mer_id', $merId);
+            })->group('time')->select();
+    }
+
+    public function dayOrderUserGroup($date, $merId = null)
+    {
+        return StoreOrder::getDB()->field(Db::raw('count(DISTINCT uid) as total, from_unixtime(unix_timestamp(pay_time),\'%H:%i\') as time'))
+            ->where('paid', 1)->when($date, function ($query, $date) {
+                getModelTime($query, $date, 'pay_time');
+            })->when($merId, function ($query, $merId) {
+                $query->where('mer_id', $merId);
+            })->group('time')->select();
+    }
+
+    /**
+     * 获取当前时间到指定时间的支付金额 管理员
+     * @param string $start 开始时间
+     * @param string $stop 结束时间
+     * @return mixed
+     */
+    public function chartTimePrice($start, $stop, $merId = null)
+    {
+        return StoreOrder::getDB()->where('paid', 1)
+            ->where('pay_time', '>=', $start)
+            ->where('pay_time', '<', $stop)
+            ->when($merId, function ($query, $merId) {
+                $query->where('mer_id', $merId);
+            })
+            ->field('sum(pay_price) as num,FROM_UNIXTIME(unix_timestamp(pay_time), \'%Y-%m-%d\') as time')
+            ->group('time')
+            ->order('pay_time ASC')->select()->toArray();
+    }
+
+    /**
+     * @param $date
+     * @param null $merId
+     * @return mixed
+     */
+    public function chartTimeNum($date, $merId = null)
+    {
+        return StoreOrder::getDB()->where('paid', 1)->when($date, function ($query) use ($date) {
+            getModelTime($query, $date, 'pay_time');
+        })->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->field('count(order_id) as num,FROM_UNIXTIME(unix_timestamp(pay_time), \'%Y-%m-%d\') as time')
+            ->group('time')
+            ->order('pay_time ASC')->select()->toArray();
+    }
+
+    /**
+     * @param $end
+     * @return mixed
+     * @author xaboy
+     * @day 2020/9/16
+     */
+    public function getFinishTimeoutIds($end)
+    {
+        return StoreOrderStatus::getDB()->alias('A')->leftJoin('StoreOrder B', 'A.order_id = B.order_id')
+            ->where('A.change_type', 'take')
+            ->where('A.change_time', '<', $end)->where('B.paid', 1)->where('B.status', 2)
+            ->column('A.order_id');
+    }
+
+
+    /**
+     * TODO 参与人数
+     * @param array $data
+     * @param int|null $uid
+     * @return BaseQuery
+     * @author Qinii
+     * @day 2020-11-11
+     */
+    public function getTattendCount(array $data,?int $uid)
+    {
+        $query = StoreOrder::hasWhere('orderProduct',function($query)use($data,$uid){
+            $query->when(isset($data['activity_id']),function ($query)use($data){
+                    $query->where('activity_id',$data['activity_id']);
+                })
+                ->when(isset($data['product_sku']),function ($query)use($data){
+                    $query->where('product_sku',$data['product_sku']);
+                })
+                ->when(isset($data['product_id']),function ($query)use($data){
+                    $query->where('product_id',$data['product_id']);
+                })
+                ->when(isset($data['exsits_id']),function ($query)use ($data){
+                    switch ($data['product_type']){
+                        case 3:
+                            $make = app()->make(ProductAssistSetRepository::class);
+                            $id = 'product_assist_id';
+                            break;
+                        case 4:
+                            $make = app()->make(ProductGroupBuyingRepository::class);
+                            $id = 'product_group_id';
+                            break;
+                    }
+                    $where = [$id => $data['exsits_id']];
+                    $activity_id = $make->getSearch($where)->column($make->getPk());
+                    if($activity_id) {
+                        $id = array_unique($activity_id);
+                        $query->where('activity_id','in',$id);
+                    }else{
+                        $query->where('activity_id','<',0);
+                    }
+                })
+                ->where('product_type',$data['product_type']);
+            if($uid) $query->where('uid',$uid);
+        });
+        $query->where('activity_type',$data['product_type']);
+        switch($data['product_type'])
+        {
+            case 0:
+                $query->where(function($query){
+                    $query->where('paid',1);
+                })->whereOr(function($query){
+                    $query->where('paid',0)->where('is_del',0);
+                });
+                break;
+            case 1: //秒杀
+                $query->where(function($query){
+                    $query->where(function($query){
+                        $query->where('paid',1);
+                    })->whereOr(function($query){
+                        $query->where('paid',0)->where('is_del',0);
+                    });
+                })->when(isset($data['day']), function ($query) use ($data) {
+                    $query->whereDay('StoreOrder.create_time', $data['day']);
+                });
+                break;
+            case 2: //预售
+
+                /**
+                 * 第一阶段参与人数:所有人
+                 * 第二阶段参与人数:支付了第一阶段
+                 */
+                //第二阶段
+                if($data['type'] == 1){
+                    $query->where(function($query){
+                        $query->where('paid',1)->whereOr(function($query){
+                            $query->where('paid',0)->where('is_del',0);
+                        });
+                    });
+                }
+                if($data['type'] == 2) $query->where('paid',1)->where('status','in',[0,1,2,3,-1]);
+                break;
+            case 3: //助力
+                $query->where(function($query){
+                    $query->where('paid',1)->whereOr(function($query){
+                        $query->where('paid',0)->where('is_del',0);
+                    });
+                });
+                break;
+            case 4: //
+                $query->where(function($query){
+                    $query->where('paid',1)->whereOr(function($query){
+                        $query->where('paid',0)->where('is_del',0);
+                    })
+                    ->where('status','>',-1);
+                });
+                break;
+        }
+        return $query;
+    }
+
+    /**
+     *  未使用
+     * TODO 成功支付人数
+     * @param int $productType
+     * @param int $activityId
+     * @param int|null $uid
+     * @param int|null $status
+     * @author Qinii
+     * @day 2020-10-30
+     */
+    public function getTattendSuccessCount($data,?int $uid)
+    {
+        $query = StoreOrder::hasWhere('orderProduct',function($query)use($data,$uid){
+            $query->when(isset($data['activity_id']),function ($query)use($data){
+                    $query->where('activity_id',$data['activity_id']);
+                })
+                ->when(isset($data['product_sku']),function ($query)use($data){
+                    $query->where('product_sku',$data['product_sku']);
+                })
+                ->when(isset($data['product_id']),function ($query)use($data){
+                    $query->where('product_id',$data['product_id']);
+                })
+                ->when(isset($data['exsits_id']),function ($query)use ($data){
+                    switch ($data['product_type']){
+                        case 3:
+                            $make = app()->make(ProductAssistSetRepository::class);
+                            $id = 'product_assist_id';
+                            break;
+                        case 4:
+                            $make = app()->make(ProductGroupBuyingRepository::class);
+                            $id = 'product_group_id';
+                            break;
+                    }
+                    $where = [$id => $data['exsits_id']];
+                    $activity_id = $make->getSearch($where)->column($make->getPk());
+                    if($activity_id) {
+                        $id = array_unique($activity_id);
+                        $query->where('activity_id','in',$id);
+                    }else{
+                        $query->where('activity_id','<',0);
+                    }
+                })
+                ->where('product_type',$data['product_type']);
+            if($uid) $query->where('uid',$uid);
+        });
+        $query->where('activity_type',$data['product_type'])->where('paid',1);
+
+        switch($data['product_type'])
+        {
+            case 1: //秒杀
+                $query->where(function($query){
+                    $query->where(function($query){
+                        $query->where('paid',1);
+                    });
+                })->when(isset($data['day']), function ($query) use ($data) {
+                    $query->whereDay('StoreOrder.create_time', $data['day']);
+                });
+                break;
+            case 2: //预售
+                if($data['type'] == 1){    //第一阶段
+                    $query->where('status','in',[0,1,2,3,10]);
+                } else {        //第二阶段
+                    $query->where('status','in',[0,1,2,3]);
+                }
+                break;
+            case 3: //助力
+                break;
+            case 4:
+                break;
+        }
+        return $query;
+    }
+
+
+    /**
+     * TODO 获取退款单数量
+     * @param $where
+     * @return mixed
+     * @author Qinii
+     * @day 1/4/21
+     */
+    public function getSeckillRefundCount($where,$type = 1)
+    {
+        $query = StoreOrderProduct::getDB()->alias('P')->join('StoreRefundOrder R','P.order_id = R.order_id');
+        $query->join('StoreOrder O','O.order_id = P.order_id');
+        $query
+            ->when(isset($where['activity_id']),function ($query)use($where){
+                $query->where('P.activity_id',$where['activity_id']);
+            })
+            ->when(isset($where['product_sku']),function ($query)use($where){
+                $query->where('P.product_sku',$where['product_sku']);
+            })
+            ->when(isset($where['day']), function ($query) use ($where) {
+                $query->whereDay('P.create_time', $where['day']);
+            })
+            ->when($type == 1, function ($query) use ($where) {
+                $query->where('O.verify_time',null)->where('O.delivery_type',null);
+            },function ($query){
+                $query ->where('R.refund_type',2);
+            })
+            ->where('P.product_type',1)->where('R.status',3);
+        return $query->count();
+    }
+
+    /**
+     * TODO 导入发货信息
+     * @param array $data
+     * @param $merId
+     * @author Qinii
+     * @day 3/16/21
+     */
+    public function setWhereDeliveryStatus(array $arrary,$merId)
+    {
+        //读取excel
+        $data = SpreadsheetExcelService::instance()->_import($arrary['path'],$arrary['sql'],$arrary['where'],4);
+        if(!$data) return ;
+        $import_id = $arrary['import_id'];
+        Db::transaction(function() use ($data,$merId,$import_id){
+            $result = [];
+            $num = 0;
+            $count = 0;
+            $status = 0;
+            foreach ($data as $datum){
+                $value = [];
+                $ret = [];
+                if($datum['where']){
+                    $count = $count +1;
+                    if(empty($datum['value']['delivery_id'])){
+                        $mark = '发货单号为空';
+                    }else{
+                        $ret = $this->getModel()::getDB()->where('status',0)->where('paid',1)->where('order_type',0)->where('mer_id',$merId)->where($datum['where'])->find();
+                        $mark = '数据有误或已发货';
+                    }
+                    if($ret){
+                        try{
+                            $value = array_merge($datum['value'],['status' => 1]);
+                            $value['delivery_type'] = 1;
+                            $this->getModel()::getDB()->where($datum['where'])->update($value);
+                            $status = 1;
+                            $mark = '';
+                            $num = $num + 1;
+                        }catch (\Exception $exception){
+                            $mark = '数据库操作失败';
+                        }
+                    }
+                    $datum['where']['mark'] = $mark;
+                    $datum['where']['mer_id'] = $merId;
+                    $datum['where']['status'] = $status;
+                    $datum['where']['import_id'] = $import_id;
+                    $result[] = array_merge($datum['where'],$datum['value']);
+                }
+            }
+            // 记录入库操作
+            if(!empty($result)) app()->make(StoreImportDeliveryRepository::class)->insertAll($result);
+            $_status = ($count == $num) ? 1 : (($num < 1) ? -1 : 10 );
+            app()->make(StoreImportRepository::class)->update($import_id,['count'=> $count,'success' => $num,'status' => $_status]);
+        });
+        if(file_exists($arrary['path'])) unlink($arrary['path']);
+    }
+}

+ 132 - 0
app/common/dao/store/order/StoreOrderProductDao.php

@@ -0,0 +1,132 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\order\StoreOrderProduct;
+use think\facade\Db;
+use think\model\Relation;
+
+/**
+ * Class StoreOrderProductDao
+ * @package app\common\dao\store\order
+ * @author xaboy
+ * @day 2020/6/10
+ */
+class StoreOrderProductDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/6/10
+     */
+    protected function getModel(): string
+    {
+        return StoreOrderProduct::class;
+    }
+
+    /**
+     * @param $id
+     * @param $uid
+     * @return array|\think\Model|null
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/10
+     */
+    public function userOrderProduct($id, $uid)
+    {
+        return StoreOrderProduct::getDB()->where('uid', $uid)->where('order_product_id', $id)->with(['orderInfo' => function (Relation $query) {
+            $query->field('order_id,mer_id')->where('status', 2);
+        }])->find();
+    }
+
+    /**
+     * @param $orderId
+     * @return int
+     * @author xaboy
+     * @day 2020/6/12
+     */
+    public function noReplyProductCount($orderId)
+    {
+        return StoreOrderProduct::getDB()->where('order_id', $orderId)->where('is_reply', 0)
+            ->count();
+    }
+
+    /**
+     * @param array $ids
+     * @param $uid
+     * @param null $orderId
+     * @return \think\Collection
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/12
+     */
+    public function userRefundProducts(array $ids, $uid, $orderId = null)
+    {
+        return StoreOrderProduct::getDB()->whereIn('order_product_id', $ids)->when($orderId, function ($query, $orderId) {
+            return $query->where('order_id', $orderId);
+        })->where('uid', $uid)->where('refund_num', '>', 0)->select();
+    }
+
+    public function orderProductGroup($date, $merId = null, $limit = 7)
+    {
+        return StoreOrderProduct::getDB()->alias('A')->leftJoin('StoreOrder B', 'A.order_id = B.order_id')
+            ->field(Db::raw('sum(A.product_num) as total,A.product_id,cart_info'))
+            ->withAttr('cart_info', function ($val) {
+                return json_decode($val, true);
+            })->when($date, function ($query, $date) {
+                getModelTime($query, $date, 'B.pay_time');
+            })->when($merId, function ($query, $merId) {
+                $query->where('B.mer_id', $merId);
+            })->where('B.paid', 1)->group('A.product_id')->limit($limit)->order('total DESC')->select();
+    }
+
+    public function dateProductNum($date)
+    {
+        return StoreOrderProduct::getDB()->alias('A')->leftJoin('StoreOrder B', 'A.order_id = B.order_id')->when($date, function ($query, $date) {
+            getModelTime($query, $date, 'B.pay_time');
+        })->where('B.paid',1)->sum('A.product_num');
+    }
+
+    /**
+     * TODO 用户购买活动商品数量
+     * @param int $activityId
+     * @param int $uid
+     * @param int $orderType
+     * @return int
+     * @author Qinii
+     * @day 2020-10-23
+     */
+    public function getUserPayCount(int $activityId,int $uid,int $productType)
+    {
+        $query = StoreOrderProduct::hasWhere('orderInfo',function($query){
+            //  已支付/未支付
+            $query->where('is_del',0)->whereOr(function($query){
+                $query->where('paid',1)->where('is_del',1);
+            });
+        });
+        $query->where('uid',$uid)->where('product_type',$productType)->where('activity_id',$activityId);
+        $count = $query->count();
+        return $count;
+    }
+
+
+}

+ 100 - 0
app/common/dao/store/order/StoreOrderReceiptDao.php

@@ -0,0 +1,100 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\order;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\order\StoreOrderReceipt;
+use app\common\model\user\User;
+
+class StoreOrderReceiptDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return StoreOrderReceipt::class;
+    }
+
+    public function search(array $where)
+    {
+        if((isset($where['order_type']) && $where['order_type'] !== '') || (isset($where['keyword']) && $where['keyword'] !== '')){
+            $query = StoreOrderReceipt::hasWhere('storeOrder',function($query)use($where){
+                switch ($where['order_type'])
+                {
+                    case 1:
+                        $query->where('StoreOrder.paid',0)->where('StoreOrder.is_del',0);
+                        break;    // 未支付
+                    case 2:
+                        $query->where('StoreOrder.paid',1)->where('StoreOrder.status',0)->where('StoreOrder.is_del',0);
+                        break;  // 待发货
+                    case 3:
+                        $query->where('StoreOrder.status',1)->where('StoreOrder.is_del',0);
+                        break;  // 待收货
+                    case 4:
+                        $query->where('StoreOrder.status',2)->where('StoreOrder.is_del',0);
+                        break;  // 待评价
+                    case 5:
+                        $query->where('StoreOrder.status',3)->where('StoreOrder.is_del',0);
+                        break;  // 交易完成
+                    case 6:
+                        $query->where('StoreOrder.status',-1)->where('StoreOrder.is_del',0);
+                        break; // 已退款
+                    case 7:
+                        $query->where('StoreOrder.is_del',1);
+                        break;  // 已删除
+                    case 8:
+                        $query->where('StoreOrder.is_del', 0);
+                        break;  //全部
+                    default:
+                        $query->where(true);
+                        break;         //全部
+                }
+                $query->when(isset($where['keyword']) && $where['keyword'] !== '' ,function($query)use($where){
+                    $query->whereLike("order_sn|real_name|user_phone","%{$where['keyword']}%");
+                });
+            });
+        }else{
+            $query = StoreOrderReceipt::alias('StoreOrderReceipt');
+        }
+        $query->when(isset($where['status']) && $where['status'] !== '' ,function($query)use($where){
+                $query->where('StoreOrderReceipt.status',$where['status']);
+            })
+            ->when(isset($where['date']) && $where['date'] !== '' ,function($query)use($where){
+                getModelTime($query,$where['date'],'StoreOrderReceipt.create_time');
+            })
+            ->when(isset($where['receipt_sn']) && $where['receipt_sn'] !== '' ,function($query)use($where){
+                $query->where('StoreOrderReceipt.receipt_sn',$where['receipt_sn']);
+            })
+            ->when(isset($where['username']) && $where['username'] !== '' ,function($query)use($where){
+                $uid = User::whereLike('nickname|phone',"%{$where['username']}%")->column('uid');
+                $query->where('StoreOrderReceipt.uid','in',$uid);
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '' ,function($query)use($where){
+                $query->where('StoreOrderReceipt.mer_id',$where['mer_id']);
+            })
+            ->when(isset($where['uid']) && $where['uid'] !== '' ,function($query)use($where){
+                $query->where('StoreOrderReceipt.uid',$where['uid']);
+            })
+        ;
+        return $query->order('StoreOrderReceipt.create_time DESC');
+    }
+
+    public function updateBySn(string $receipt_sn,$data)
+    {
+        return $this->getModel()::getDB()->where('receipt_sn',$receipt_sn)->update($data);
+    }
+
+
+    public function deleteByOrderId($id)
+    {
+        return $this->getModel()::getDB()->where('order_id',$id)->delete();
+    }
+}

+ 58 - 0
app/common/dao/store/order/StoreOrderStatusDao.php

@@ -0,0 +1,58 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\order\StoreOrderStatus;
+
+/**
+ * Class StoreOrderStatusDao
+ * @package app\common\dao\store\order
+ * @author xaboy
+ * @day 2020/6/12
+ */
+class StoreOrderStatusDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/6/12
+     */
+    protected function getModel(): string
+    {
+        return StoreOrderStatus::class;
+    }
+
+    /**
+     * @param $id
+     * @return mixed
+     * @author xaboy
+     * @day 2020/6/12
+     */
+    public function search($id)
+    {
+        return $query = ($this->getModel()::getDB())->where('order_id', $id);
+    }
+
+    public function getTimeoutDeliveryOrder($end)
+    {
+        return StoreOrderStatus::getDB()->alias('A')->leftJoin('StoreOrder B', 'A.order_id = B.order_id')
+            ->whereIn('A.change_type', ['delivery_0', 'delivery_1', 'delivery_2'])
+            ->where('A.change_time', '<', $end)->where('B.paid', 1)->where('B.status', 1)
+            ->column('A.order_id');
+    }
+}

+ 155 - 0
app/common/dao/store/order/StoreRefundOrderDao.php

@@ -0,0 +1,155 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\order\StoreOrder;
+use app\common\model\store\order\StoreRefundOrder;
+use app\common\repositories\system\merchant\MerchantRepository;
+use think\db\BaseQuery;
+use think\db\exception\DbException;
+
+class StoreRefundOrderDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return StoreRefundOrder::class;
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/6/12
+     */
+    public function search(array $where)
+    {
+        if(isset($where['is_trader']) && $where['is_trader'] !== ''){
+            $query = StoreRefundOrder::hasWhere('merchant',function($query)use($where){
+                $query->where('is_trader',$where['is_trader']);
+            });
+        }else{
+            $query = (StoreRefundOrder::getDB())->alias('StoreRefundOrder');
+        }
+        $query->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+            $query->where('StoreRefundOrder.mer_id', $where['mer_id']);
+        })->when(isset($where['order_sn']) && $where['order_sn'] !== '', function ($query) use ($where) {
+            $ids = StoreOrder::where('order_sn','like','%'.$where['order_sn'].'%')->column('order_id');
+            $query->where('order_id','in',$ids);
+        })->when(isset($where['refund_order_sn']) && $where['refund_order_sn'] !== '', function ($query) use ($where) {
+            $query->where('refund_order_sn', 'like', '%' . $where['refund_order_sn'] . '%');
+        })->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) {
+            $query->where('StoreRefundOrder.status', $where['status']);
+        })->when(isset($where['uid']) && $where['uid'] !== '', function ($query) use ($where) {
+            $query->where('uid', $where['uid']);
+        })->when(isset($where['id']) && $where['id'] !== '', function ($query) use ($where) {
+            $query->where('refund_order_id', $where['id']);
+        })->when(isset($where['is_del']) && $where['is_del'] !== '', function ($query) use ($where) {
+            $query->where('StoreRefundOrder.is_del', $where['is_del']);
+        })->when(isset($where['type']) && $where['type'] == 1, function ($query) {
+            $query->whereIn('StoreRefundOrder.status', [0, 1, 2]);
+        })->when(isset($where['type']) && $where['type'] == 2, function ($query) {
+            $query->whereIn('status', [-1, 3]);
+        })->when(isset($where['refund_type']) && $where['refund_type'] !== '',function($query)use($where){
+            $query->where('refund_type',$where['refund_type']);
+        })->when(isset($where['reconciliation_type']) && $where['reconciliation_type'] !== '' ,function($query)use($where){
+            $query->when($where['reconciliation_type'],
+                function($query)use($where){$query->where('reconciliation_id','<>',0);},
+                function($query)use($where){$query->where('reconciliation_id',0);}
+                );
+        })->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+            getModelTime($query,$where['date'],'StoreRefundOrder.create_time');
+        })->when(isset($where['order_id']) && $where['order_id'] !== '', function ($query) use ($where) {
+            $query->where('order_id', $where['order_id']);
+        })->order('StoreRefundOrder.create_time DESC');
+        return $query;
+    }
+
+    /**
+     * @param $id
+     * @return mixed
+     * @author Qinii
+     * @day 2020-06-12
+     */
+    public function getOne($id)
+    {
+        return $this->getModel()::where($this->getPk(),$id)->with(['refundProduct.product','user' => function($query){
+            $query->field('uid,nickname,phone');
+        }])->find();
+    }
+
+    /**
+     * @param $where
+     * @return bool
+     * @author Qinii
+     * @day 2020-06-12
+     */
+    public function getFieldExists($where)
+    {
+        return (($this->getModel()::getDB())->where($where)->count()) > 0;
+    }
+
+    /**
+     * @param $uid
+     * @param $id
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/6/12
+     */
+    public function userDel($uid, $id)
+    {
+        return StoreRefundOrder::getDB()->where('uid', $uid)->where('refund_order_id', $id)->where('status', 3)->update(['is_del' => 1, 'status_time' => date('Y-m-d H:i:s')]);
+    }
+
+    /**
+     * TODO超过期限退款申请
+     * @param $time
+     * @return mixed
+     * @author Qinii
+     * @day 2020-06-13
+     */
+    public function getTimeOutIds($time)
+    {
+        return ($this->getModel()::getDB())->where('status_time','<=',$time)
+            ->where(function($query){
+                $query->where(function($query){
+                    $query->where('refund_type',1)->where('status',0);
+                })->whereOr(function($query){
+                    $query->where('refund_type',2)->where('status',2);
+                });
+            })->column('refund_order_id');
+    }
+
+    /**
+     * TODO
+     * @param $reconciliation_id
+     * @return mixed
+     * @author Qinii
+     * @day 2020-06-15
+     */
+    public function reconciliationUpdate($reconciliation_id)
+    {
+        return ($this->getModel()::getDB())->whereIn('reconciliation_id',$reconciliation_id)->update(['reconciliation_id' => 0]);
+    }
+
+    public function refundPirceByOrder(array $orderIds)
+    {
+        return $this->getModel()::getDB()->whereIn('order_id',$orderIds)->where('status',3)->sum('refund_price');
+    }
+
+}

+ 37 - 0
app/common/dao/store/order/StoreRefundProductDao.php

@@ -0,0 +1,37 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\store\order\StoreRefundProduct;
+
+class StoreRefundProductDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return StoreRefundProduct::class;
+    }
+
+    public function search(array $where)
+    {
+        $query = $this->getModel()::getDB()
+            ->when(isset($where['order_id']) && $where['order_id'] !== '',function($query)use($where){
+                $query->where('order_id',$where['order_id']);
+            });
+
+        return $query->order('create_time');
+    }
+}

+ 32 - 0
app/common/dao/store/order/StoreRefundStatusDao.php

@@ -0,0 +1,32 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\order;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\store\order\StoreRefundStatus;
+
+class StoreRefundStatusDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return StoreRefundStatus::class;
+    }
+
+    public function search($id)
+    {
+        return $query = StoreRefundStatus::getDB()->where('refund_order_id', $id);
+    }
+}

+ 144 - 0
app/common/dao/store/product/ProductAssistDao.php

@@ -0,0 +1,144 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductAssist;
+use app\common\repositories\store\product\SpuRepository;
+use app\common\repositories\system\merchant\MerchantRepository;
+
+class ProductAssistDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return ProductAssist::class;
+    }
+
+    public function search(array $where)
+    {
+        $query = ProductAssist::hasWhere('product',function($query)use($where){
+            $query->when(isset($where['product_show']) && $where['product_show'] !== '',function($query)use($where){
+                    $query->where('is_del',0)->where('mer_status',1)->where('product_type',3);
+                })
+                ->where('status',1);
+        });
+
+        $query->when(isset($where['product_assist_id']) && $where['product_assist_id'] !== '',function($query)use($where){
+                $query->where('product_assist_id',$where['product_assist_id']);
+            })
+            ->when(isset($where['keyword']) && $where['keyword'] !== '',function($query)use($where){
+                $query->whereLike('ProductAssist.store_name|ProductAssist.product_id',"%{$where['keyword']}%");
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '',function($query)use($where){
+                $query->where('ProductAssist.mer_id',$where['mer_id']);
+            })
+            ->when(isset($where['type']) && $where['type'] !== '',function($query)use($where){
+                switch ($where['type']){
+                    case 0: //未开始
+                        $query->whereTime('start_time','>',time());
+                        break;
+                    case 1: //进行中
+                        $query->whereTime('start_time','<=',time())->whereTime('end_time','>',time())
+                        ->where('ProductAssist.product_status',1)->where('ProductAssist.status',1)->where('ProductAssist.is_show',1);
+                        break;
+                    case 2: //已结束
+                        $query->where(function($query){
+                            $query->where('action_status',-1)->whereOr('end_time','<= TIME',time());
+                        });
+                        break;
+                }
+            })
+            ->when(isset($where['status']) && $where['status'] !== '',function($query)use($where){
+                $query->where('ProductAssist.status',$where['status']);
+            })
+            ->when(isset($where['is_show']) && $where['is_show'] !== '',function($query)use($where){
+                $query->where('ProductAssist.is_show',$where['is_show']);
+            })
+            ->when(isset($where['mer_name']) && $where['mer_name'] !== '',function($query)use($where){
+                $make = app()->make(MerchantRepository::class);
+                $mer_id = $make->search(['keyword' => $where['mer_name']])->column('mer_id');
+                $query->whereIn('ProductAssist.mer_id',$mer_id);
+            })
+            ->when(isset($where['product_status']) && $where['product_status'] !== '',function($query)use($where){
+                if($where['product_status'] == -1){
+                    $query->where('ProductAssist.product_status','in',[-1,-2]);
+                }else{
+                    $query->where('ProductAssist.product_status',$where['product_status']);
+                }
+            })
+            ->when(isset($where['is_trader']) && $where['is_trader'] !== '',function($query)use($where){
+                $make = app()->make(MerchantRepository::class);
+                $mer_id = $make->search(['is_trader' => $where['is_trader']])->column('mer_id');
+                $query->whereIn('ProductAssist.mer_id',$mer_id);
+            })
+            ->when(isset($where['us_status']) && $where['us_status'] !== '',function($query)use($where){
+                if($where['us_status'] == 0) {
+                    $query->where('ProductAssist.is_show',0)->where('ProductAssist.status',1)->where('ProductAssist.product_status',1);
+                }
+                if($where['us_status'] == 1) {
+                    $query->where('ProductAssist.is_show',1)->where('ProductAssist.status',1)->where('ProductAssist.product_status',1);
+                }
+                if($where['us_status'] == -1) {
+                    $query->where(function($query){
+                        $query->where('ProductAssist.status',0)->whereOr('ProductAssist.product_status','<>',1);
+                    });
+                }
+            })
+            ->when(isset($where['star']),function($query)use($where){
+                $query->Join('StoreSpu U', 'Product.product_id = U.product_id')->where('U.product_type', 3);
+                $query->when($where['star'] !== '', function ($query) use ($where) {
+                    $query->where('U.star', $where['star']);
+                });
+                $query->order('U.star DESC,U.rank DESC,ProductAssist.create_time DESC');
+            });
+        $query->where('ProductAssist.is_del',0);
+        return $query;
+    }
+
+    /**
+     * TODO 移动端展示 条件
+     * @return array
+     * @author Qinii
+     * @day 2020-10-19
+     */
+    public function assistShow()
+    {
+        return [
+            'product_show' => 1,
+            'product_status' => 1,
+            'status' => 1,
+            'is_show' => 1,
+            'type' => 1
+        ];
+    }
+
+    /**
+     * TODO
+     * @author Qinii
+     * @day 1/27/21
+     */
+    public function valActiveStatus()
+    {
+        $query = $this->getModel()::getDB()->whereTime('end_time','<=',time())->where('action_status',1);
+        $id = $query->column($this->getPk());
+        if($id) {
+            $this->getModel()::getDB()->where($this->getPk(),'in',$id)->update(['action_status' => -1]);
+            $where = [
+                'product_type' => 3,
+                'activity_ids' => $id
+            ];
+            app()->make(SpuRepository::class)->getSearch($where)->update(['status' => 0]);
+        }
+    }
+}
+

+ 77 - 0
app/common/dao/store/product/ProductAssistSetDao.php

@@ -0,0 +1,77 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductAssistSet;
+use app\common\model\system\merchant\Merchant;
+use app\common\repositories\system\merchant\MerchantRepository;
+use think\Exception;
+
+class ProductAssistSetDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return ProductAssistSet::class;
+    }
+
+
+    public function search(array $where)
+    {
+        $query = $this->getSearch($where)
+            ->when(isset($where['date']) && $where['date'] !== '',function($query) use($where){
+                getModelTime($query,$where['date']);
+            })->where('is_del',0);
+        return $query->order('create_time DESC');
+    }
+
+    public function incNum(int $type,int $id,int $inc = 1)
+    {
+        try{
+            $query = $this->getModel()::where($this->getPk(),$id);
+            if($type == 1) $query->inc('share_num',$inc)->update();
+            if($type == 2) $query->inc('view_num',$inc)->update();
+        }catch (Exception $exception){
+
+        }
+
+    }
+
+    public function userCount()
+    {
+        $count = $this->getModel()::getDB()->count("*");
+        $res = $this->getModel()::getDB()->order('create_time DESC')->with(['user' => function($query){
+            $query->field('uid,avatar avatar_img');
+        }])->limit(10)->group('uid')->select()->toArray();
+
+        $list = [];
+        foreach ($res as $item){
+            if($item['user']['avatar_img']){
+                $list[] = $item['user'];
+            }
+        }
+        return compact('count','list');
+    }
+
+    /**
+     * TODO 更新状态
+     * @param int $id
+     * @author Qinii
+     * @day 2020-11-25
+     */
+    public function changStatus(int $id)
+    {
+        $this->getModel()::getDB()->where($this->getPk(),$id)->update(['status' => 20]);
+    }
+}
+

+ 45 - 0
app/common/dao/store/product/ProductAssistSkuDao.php

@@ -0,0 +1,45 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductAssistSku;
+use think\facade\Db;
+
+class ProductAssistSkuDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return ProductAssistSku::class;
+    }
+
+    public function clear($id)
+    {
+        $this->getModel()::getDB()->where('product_assist_id',$id)->delete();
+    }
+
+    public function descStock(int $product_assist_id, string $unique, int $desc)
+    {
+        return $this->getModel()::getDB()->where('product_assist_id', $product_assist_id)->where('unique', $unique)->update([
+            'stock' => Db::raw('stock-' . $desc)
+        ]);
+    }
+
+    public function incStock(int $product_assist_id, string $unique, int $desc)
+    {
+        return $this->getModel()::getDB()->where('product_assist_id', $product_assist_id)->where('unique', $unique)->update([
+            'stock' => Db::raw('stock+' . $desc)
+        ]);
+    }
+}
+

+ 33 - 0
app/common/dao/store/product/ProductAssistUserDao.php

@@ -0,0 +1,33 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductAssistUser;
+
+class ProductAssistUserDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return ProductAssistUser::class;
+    }
+
+
+    public function userCount(int $limit = 3)
+    {
+        $count = $this->getModel()::getDB()->count("*");
+        $list = $this->getModel()::getDB()->limit(3)->order('create_time DESC')->select();
+        return compact('count','list');
+    }
+}
+

+ 47 - 0
app/common/dao/store/product/ProductAttrDao.php

@@ -0,0 +1,47 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductAttr as model;
+
+class ProductAttrDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/9
+     * @param int $productId
+     * @return mixed
+     */
+    public function clearAttr(int $productId)
+    {
+        return ($this->getModel())::where('product_id',$productId)->delete();
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/13
+     * @param array $data
+     * @return mixed
+     */
+    public function insert(array $data)
+    {
+        return ($this->getModel()::getDB())->insertAll($data);
+    }
+
+}

+ 260 - 0
app/common/dao/store/product/ProductAttrValueDao.php

@@ -0,0 +1,260 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductAttrValue as model;
+use think\db\exception\DbException;
+use think\facade\Db;
+
+/**
+ * Class ProductAttrValueDao
+ * @package app\common\dao\store\product
+ * @author xaboy
+ * @day 2020/6/9
+ */
+class ProductAttrValueDao extends BaseDao
+{
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/9
+     * @param int $productId
+     * @return mixed
+     */
+    public function clearAttr(int $productId)
+    {
+        return ($this->getModel())::where('product_id', $productId)->delete();
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/9
+     * @param int $merId
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return mixed
+     */
+    public function getFieldColumnt($key, $value, $field, $except = null)
+    {
+        return ($this->getModel()::getDB())->when($except, function ($query, $except) use ($field) {
+            $query->where($field, '<>', $except);
+        })->where($key, $value)->column($field);
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/11
+     * @param $key
+     * @param $value
+     * @param $field
+     * @param null $except
+     * @return mixed
+     */
+    public function getFieldSum($key, $value, $field, $except = null)
+    {
+        return ($this->getModel()::getDB())->when($except, function ($query, $except) use ($field) {
+            $query->where($field, '<>', $except);
+        })->where($key, $value)->sum($field);
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/11
+     * @param array $data
+     * @return mixed
+     */
+    public function insert(array $data)
+    {
+        return ($this->getModel()::getDB())->insertAll($data);
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/11
+     * @param int|null $merId
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     */
+    public function merFieldExists(?int $merId, $field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->when($merId, function ($query, $merId) {
+                $query->where('mer_id', $merId);
+            })->where($field, $value)->count() > 0;
+    }
+
+    /**
+     * @param $id
+     * @return mixed
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    public function getSku($id)
+    {
+        return ($this->getModel())::where('product_id', $id);
+    }
+
+    /**
+     * @param int|null $merId
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return mixed
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    public function getFieldExists(?int $merId, $field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+            $query->where($field, '<>', $except);
+        })->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->where($field, $value);
+    }
+
+    /**
+     * @param int $productId
+     * @param string $unique
+     * @param int $desc
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/6/8
+     */
+    public function descStock(int $productId, string $unique, int $desc)
+    {
+        return model::getDB()->where('product_id', $productId)->where('unique', $unique)->update([
+            'stock' => Db::raw('stock-' . $desc),
+            'sales' => Db::raw('sales+' . $desc)
+        ]);
+    }
+
+    /**
+     * @param int $productId
+     * @param string $sku
+     * @param int $desc
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/6/8
+     */
+    public function descSkuStock(int $productId, string $sku, int $desc)
+    {
+        return model::getDB()->where('product_id', $productId)->where('sku', $sku)->update([
+            'stock' => Db::raw('stock-' . $desc),
+            'sales' => Db::raw('sales+' . $desc)
+        ]);
+    }
+
+    /**
+     * @param int $productId
+     * @param string $unique
+     * @param int $inc
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/6/8
+     */
+    public function incStock(int $productId, string $unique, int $inc)
+    {
+        model::getDB()->where('product_id', $productId)->where('unique', $unique)->inc('stock', $inc)->update();
+        model::getDB()->where('product_id', $productId)->where('unique', $unique)->where('sales', '>=', $inc)->dec('sales', $inc)->update();
+    }
+
+    /**
+     * @param int $productId
+     * @param string $sku
+     * @param int $inc
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/6/8
+     */
+    public function incSkuStock(int $productId, string $sku, int $inc)
+    {
+        model::getDB()->where('product_id', $productId)->where('sku', $sku)->inc('stock', $inc)->update();
+        model::getDB()->where('product_id', $productId)->where('sku', $sku)->where('sales', '>', $inc)->dec('sales', $inc)->update();
+    }
+
+    /**
+     * @param int $productId
+     * @param string $unique
+     * @return bool
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    public function attrExists(int $productId, string $unique): bool
+    {
+        return model::getDB()->where('product_id', $productId)->where('unique', $unique)->count() > 0;
+    }
+
+    /**
+     * @param int $productId
+     * @param string $sku
+     * @return bool
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    public function skuExists(int $productId, string $sku): bool
+    {
+        return model::getDB()->where('product_id', $productId)->where('sku', $sku)->count() > 0;
+    }
+
+    /**
+     * TODO 商品佣金是否大于设置佣金比例
+     * @param $productId
+     * @return bool
+     * @author Qinii
+     * @day 2020-06-25
+     */
+    public function checkExtensionById($productId)
+    {
+        $extension_one_rate = systemConfig('extension_one_rate');
+        $extension_two_rate = systemConfig('extension_two_rate');
+
+        $count = ($this->getModel()::getDb())->where(function($query)use($productId,$extension_one_rate){
+            $query->where('product_id',$productId)->whereRaw('price * '.$extension_one_rate.' > extension_one');
+        })->whereOr(function($query)use($productId,$extension_two_rate){
+            $query->where('product_id',$productId)->whereRaw('price * '.$extension_two_rate.' > extension_two');
+        })->count();
+        return $count ? false : true;
+    }
+
+    public function search(array $where)
+    {
+        $query = ($this->getModel()::getDb())
+            ->when(isset($where['product_id']) && $where['product_id'] !== '',function($query)use($where){
+                $query->where('product_id',$where['product_id']);
+            })
+            ->when(isset($where['sku']) && $where['sku'] !== '',function($query)use($where){
+                $query->where('sku',$where['sku']);
+            })
+            ->when(isset($where['unique']) && $where['unique'] !== '',function($query)use($where){
+                $query->where('unique',$where['unique']);
+            });
+        return $query;
+    }
+}

+ 47 - 0
app/common/dao/store/product/ProductCateDao.php

@@ -0,0 +1,47 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductCate as model;
+
+class ProductCateDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/9
+     * @param int $productId
+     * @return mixed
+     */
+    public function clearAttr(int $productId)
+    {
+        return ($this->getModel())::where('product_id',$productId)->delete();
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/13
+     * @param array $data
+     * @return mixed
+     */
+    public function insert(array $data)
+    {
+        return ($this->getModel()::getDB())->insertAll($data);
+    }
+
+}

+ 36 - 0
app/common/dao/store/product/ProductContentDao.php

@@ -0,0 +1,36 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductContent as model;
+
+class ProductContentDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/9
+     * @param int $productId
+     * @return mixed
+     */
+    public function clearAttr(int $productId)
+    {
+        return ($this->getModel())::where('product_id',$productId)->delete();
+    }
+
+}

+ 37 - 0
app/common/dao/store/product/ProductCopyDao.php

@@ -0,0 +1,37 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductCopy as model;
+
+class ProductCopyDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    public function search(array $where)
+    {
+        return $this->getModel()::getDB()
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '',function($query)use($where){
+                $query->where('mer_id',$where['mer_id']);
+            })
+            ->when(isset($where['type']) && $where['type'] !== '',function($query)use($where){
+                $query->where('type',$where['type']);
+            })
+            ->order('create_time DESC');
+    }
+
+}

+ 595 - 0
app/common/dao/store/product/ProductDao.php

@@ -0,0 +1,595 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\Product as model;
+use app\common\repositories\store\product\SpuRepository;
+use app\common\repositories\store\StoreCategoryRepository;
+use think\db\BaseQuery;
+use think\db\exception\DbException;
+use think\facade\Db;
+
+class ProductDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/9
+     * @param int $id
+     * @param array $data
+     */
+    public function createAttr(int $id, array $data)
+    {
+        ($this->getModel()::withTrashed()->find($id))->attr()->saveAll($data);
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/9
+     * @param int $id
+     * @param array $data
+     */
+    public function createAttrValue(int $id, array $data)
+    {
+        ($this->getModel()::withTrashed()->find($id))->attrValue()->saveAll($data);
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/9
+     * @param int $id
+     * @param array $data
+     */
+    public function createContent(int $id, array $data)
+    {
+        ($this->getModel()::withTrashed()->find($id))->content()->save($data);
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/9
+     * @param int $merId
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     */
+    public function merFieldExists(?int $merId, $field, $value, $except = null)
+    {
+        return model::withTrashed()->when($except, function ($query, $except) use ($field) {
+            $query->where($field, '<>', $except);
+        })->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->where($field, $value)->count() > 0;
+    }
+
+    public function apiFieldExists(int $merId, $field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+            $query->where($field, '<>', $except);
+        })->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->where(['status' => 1])->where($field, $value)->count() > 0;
+    }
+
+    /**
+     * @param int $merId
+     * @param int $productId
+     * @return bool
+     * @author Qinii
+     */
+    public function getDeleteExists(int $merId, int $productId)
+    {
+        return ($this->getModel())::onlyTrashed()->where('mer_id', $merId)->where($this->getPk(), $productId)->count() > 0;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/11
+     * @param int $merId
+     * @param array $where
+     * @return mixed
+     */
+    public function search(?int $merId, array $where)
+    {
+        $keyArray = $whereArr = [];
+        unset($where['type'],$where['us_status']);
+        foreach ($where as $key => $item) {
+            if ($item !== '' && $key != 'soft') {
+                $keyArray[] = $key;
+                $whereArr[$key] = $item;
+            }
+        }
+        $query = isset($where['soft']) ? model::onlyTrashed()->alias('Product') : model::alias('Product');
+        if (isset($where['is_trader']) && $where['is_trader'] !== '') {
+            $query->hasWhere('merchant', function ($query) use ($where) {
+                $query->where('is_trader', $where['is_trader']);
+            });
+        }
+        $query->withSearch($keyArray, $whereArr)
+            ->when(($merId !== null), function ($query) use ($merId) {
+                $query->where('Product.mer_id', $merId);
+            })
+            ->when(isset($where['hot_type']) && $where['hot_type'] !== '', function ($query) use ($where) {
+                if ($where['hot_type'] == 'new')
+                    $query->where('is_new', 1);
+                else if ($where['hot_type'] == 'hot')
+                    $query->where('is_hot', 1);
+                else if ($where['hot_type'] == 'best')
+                    $query->where('is_best', 1);
+                else if ($where['hot_type'] == 'good')
+                    $query->where('is_benefit', 1);
+            })
+            ->when(isset($where['pid']) && $where['pid'] !== '', function ($query) use ($where) {
+                $storeCategoryRepository = app()->make(StoreCategoryRepository::class);
+                $ids = array_merge($storeCategoryRepository->findChildrenId((int)$where['pid']), [(int)$where['pid']]);
+                if (count($ids)) $query->whereIn('cate_id', $ids);
+            })
+            ->when(isset($where['us_status']) && $where['us_status'] !== '', function ($query) use ($where) {
+                if ($where['us_status'] == 0) {
+                    $query->where('Product.is_show', 0)->where('Product.is_used', 1)->where('Product.status',1);
+                }
+                if ($where['us_status'] == 1) {
+                    $query->where('Product.is_show', 1)->where('Product.is_used', 1)->where('Product.status',1);
+                }
+                if ($where['us_status'] == -1) {
+                    $query->where(function($query){
+                        $query->where('Product.is_used',0)->whereOr('Product.status','<>',1);
+                    });
+                }
+            })
+            ->when(isset($where['order']), function ($query) use ($where, $merId) {
+                $query->when(
+                    in_array($where['order'], ['is_new', 'price_asc', 'price_desc', 'rate', 'sales']),
+                    function ($query) use ($where) {
+                        if ($where['order'] == 'price_asc') {
+                            $where['order'] = 'price ASC';
+                        } else if ($where['order'] == 'price_desc') {
+                            $where['order'] = 'price DESC';
+                        } else {
+                            $where['order'] = $where['order'] . ' DESC';
+                        }
+                        $query->order($where['order'] . ',rank DESC ,create_time DESC ');
+                    },
+                    function ($query) use ($merId) {
+                        if ($merId) $query->order('Product.sort DESC ,Product.create_time DESC');
+                    }
+                );
+            })
+            ->when(isset($where['star']),function($query)use($where){
+                $query->Join('StoreSpu U', 'Product.product_id = U.product_id')->where('U.product_type', $where['product_type'] ?? 0);
+                $query->when($where['star'] !== '', function ($query) use ($where) {
+                    $query->where('U.star', $where['star']);
+                });
+                $query->order('U.star DESC,U.rank DESC,Product.create_time DESC');
+            });
+        return $query;
+    }
+
+    /**
+     * TODO
+     * @param array $where
+     * @return BaseQuery
+     * @author Qinii
+     * @day 2020-08-04
+     */
+    public function seckillSearch(array $where)
+    {
+        $query = model::hasWhere('seckillActive', function ($query) use ($where) {
+            $query->where('status', 1);
+            $query->whereTime('start_day', '<=', $where['day'])->whereTime('end_day', '>=', $where['day']);
+            $query->where('start_time', '<=', $where['start_time'])
+                ->where('end_time', '>', $where['start_time'])
+                ->where('end_time', '<=', $where['end_time']);
+        });
+        $query->where([
+            'Product.is_show'       => 1,
+            'Product.status'        => 1,
+            'Product.is_used'       => 1,
+            'Product.mer_status'    => 1,
+            'Product.product_type'  => 1,
+            'Product.is_gift_bag'   => 0,
+        ])
+        ->when(isset($where['star']),function($query)use($where){
+            $query->Join('StoreSpu U', 'Product.product_id = U.product_id')->where('U.product_type', 1);
+            $query->when($where['star'] !== '', function ($query) use ($where) {
+                $query->where('U.star', $where['star']);
+            });
+            $query->order('U.star DESC,U.rank DESC');
+        });
+        return $query;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/18
+     * @param int $id
+     * @param bool $soft
+     * @return int|mixed
+     */
+    public function delete(int $id, $soft = false)
+    {
+        if ($soft) {
+            return (($this->getModel())::onlyTrashed()->find($id))->force()->delete();
+        } else {
+            return $this->getModel()::where($this->getPk(), $id)->update(['is_del' => 1]);
+        }
+        app()->make(SpuRepository::class)->where('product_id', $id)->where('product_type', 1)->update(['is_del' => 1, 'status' => 0]);
+    }
+
+    /**
+     * TODO
+     * @param $id
+     * @return mixed
+     * @author Qinii
+     * @day 2020-07-03
+     */
+    public function restore($id)
+    {
+        $res = ($this->getModel())::onlyTrashed()->find($id);
+        app()->make(SpuRepository::class)->delProduct($id, 0);
+        return $res->restore();
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/18
+     * @param int $id
+     * @param array $status
+     * @return mixed
+     */
+    public function switchStatus(int $id, array $status)
+    {
+        return ($this->getModel()::getDB())->where($this->getPk(), $id)->update($status);
+    }
+
+    /**
+     * @param int $merId
+     * @param array $productIds
+     * @return array
+     * @author xaboy
+     * @day 2020/5/26
+     */
+    public function productIdByImage(int $merId, array $productIds)
+    {
+        return model::getDB()->where('mer_id', $merId)->whereIn('product_id', $productIds)->column('product_id,image');
+    }
+
+    /**
+     * @param array $ids
+     * @return array
+     * @author xaboy
+     * @day 2020/5/30
+     */
+    public function intersectionKey(array $ids): array
+    {
+        return model::getDB()->whereIn('product_id', $ids)->column('product_id');
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/30
+     * @param $id
+     * @return mixed
+     */
+    public function productIdByMerId($id)
+    {
+        return model::getDB()->where('product_id', $id)->value('mer_id');
+    }
+
+
+    /**
+     * @param int $productId
+     * @param int $desc
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/6/8
+     */
+    public function descStock(int $productId, int $desc)
+    {
+        return model::getDB()->where('product_id', $productId)->update([
+            'stock' => Db::raw('stock-' . $desc),
+            'sales' => Db::raw('sales+' . $desc)
+        ]);
+    }
+
+    /**
+     * @param int $productId
+     * @param int $inc
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/6/8
+     */
+    public function incStock(int $productId, int $inc)
+    {
+        model::getDB()->where('product_id', $productId)->inc('stock', $inc)->update();
+        model::getDB()->where('product_id', $productId)->where('sales', '>=', $inc)->dec('sales', $inc)->update();
+    }
+
+    public function visitProductGroup($date, $merId = null, $limit = 7)
+    {
+        return model::getDB()->alias('A')->leftJoin('UserRelation B', 'A.product_id = B.type_id')
+            ->field(Db::raw('count(B.type_id) as total,A.product_id,A.store_name,A.image'))
+            ->when($date, function ($query, $date) {
+                getModelTime($query, $date, 'B.create_time');
+            })->when($merId, function ($query, $merId) {
+                $query->where('A.mer_id', $merId);
+            })->where('B.type', 1)->group('A.product_id')->limit($limit)->order('total DESC')->select();
+    }
+
+    public function cartProductGroup($date, $merId = null, $limit = 7)
+    {
+        return model::getDB()->alias('A')->leftJoin('StoreCart B', 'A.product_id = B.product_id')
+            ->field(Db::raw('sum(B.cart_num) as total,A.product_id,A.store_name,A.image'))
+            ->when($date, function ($query, $date) {
+                getModelTime($query, $date, 'B.create_time');
+            })->when($merId, function ($query, $merId) {
+                $query->where('A.mer_id', $merId);
+            })->where('B.product_type', 0)->where('B.is_pay', 0)->where('B.is_del', 0)
+            ->where('B.is_new', 0)->where('B.is_fail', 0)->group('A.product_id')->limit($limit)->order('total DESC')->select();
+    }
+
+    public function changeMerchantProduct($merId, $data)
+    {
+        ($this->getModel()::getDB())->where('mer_id', $merId)->update($data);
+    }
+
+    /**
+     * TODO
+     * @param int $productId
+     * @author Qinii
+     * @day 2020-07-09
+     */
+    public function incCareCount(int $productId)
+    {
+        ($this->getModel()::getDB())->where($this->getPk(), $productId)->inc('care_count', 1)->update();
+    }
+
+    /**
+     * TODO
+     * @param int $productId
+     * @author Qinii
+     * @day 2020-07-09
+     */
+    public function decCareCount(int $productId)
+    {
+        ($this->getModel()::getDB())->where($this->getPk(), $productId)->where('care_count', '>', 0)->dec('care_count', 1)->update();
+    }
+
+    /**
+     * TODO api展示的商品条件
+     * @return array
+     * @author Qinii
+     * @day 2020-08-18
+     */
+    public function productShow()
+    {
+        return [
+            'is_show'       => 1,
+            'status'        => 1,
+            'is_used'       => 1,
+            'product_type'  => 0,
+            'mer_status'    => 1,
+            'is_gift_bag'   => 0,
+        ];
+    }
+
+    /**
+     * TODO api展示的礼包商品条件
+     * @return array
+     * @author Qinii
+     * @day 2020-08-18
+     */
+    public function bagShow()
+    {
+        return [
+            'is_show'       => 1,
+            'status'        => 1,
+            'is_used'       => 1,
+            'mer_status'    => 1,
+            'product_type'  => 0,
+            'is_gift_bag'   => 1,
+        ];
+    }
+
+    /**
+     * TODO api展示的秒杀商品条件
+     * @return array
+     * @author Qinii
+     * @day 2020-08-18
+     */
+    public function seckillShow()
+    {
+        return [
+            'is_show'       => 1,
+            'status'        => 1,
+            'is_used'       => 1,
+            'mer_status'    => 1,
+            'product_type'  => 1,
+            'is_gift_bag'   => 0,
+        ];
+    }
+
+    public function getProductTypeById(int $productId, ?int $exsistType)
+    {
+        $product_type = $this->getModel()::getDB()
+            ->when($exsistType, function ($query) use ($exsistType) {
+                $query->where('product_type', $exsistType);
+            })
+            ->where($this->getPk(), $productId)->where('is_del', 0)->value('product_type');
+        return $product_type == 0 ?  true : false;
+    }
+
+    public function getFailProduct(int $productId)
+    {
+        return $this->getModel()::withTrashed()->field('product_id,image,store_name,is_show,status,is_del,unit_name,price,mer_status,is_used')->find($productId);
+    }
+
+    public function geTrashedtProduct(int $id)
+    {
+        return model::withTrashed()->where($this->getPk(),$id);
+    }
+
+
+    /**
+     * TODO 获取各种有效时间内的活动
+     * @param int $productType
+     * @return array
+     * @author Qinii
+     * @day 2/1/21
+     */
+    public function activitSearch(int $productType)
+    {
+        $query = model::getDB()->alias('P')
+            ->where('P.is_del', 0)
+            ->where('P.mer_status', 1)
+            ->where('P.product_type', $productType);
+        switch ($productType) {
+            case 0:
+                // $query->where('P.is_show',1)
+                //     ->where('P.is_used',1)
+                //     ->field('product_id,product_type,mer_id,store_name,keyword,price,rank,sort,image,status,temp_id');
+                break;
+            case 1:
+                $query->join('StoreSeckillActive S', 'S.product_id = P.product_id')
+                ->field('P.*,S.status,S.seckill_active_id,S.end_time');
+                break;
+            case 2:
+                $query->join('StoreProductPresell R', 'R.product_id = P.product_id')
+                ->where('R.is_del',0)
+                ->field('P.*,R.product_presell_id,R.store_name,R.price,R.status,R.is_show,R.product_status,R.action_status');
+                break;
+            case 3:
+                $query->join('StoreProductAssist A', 'A.product_id = P.product_id')
+                    ->where('A.is_del',0)
+                    ->field('P.*,A.product_assist_id,A.store_name,A.status,A.is_show,A.product_status,A.action_status');
+                break;
+            case 4:
+                $query->join('StoreProductGroup G', 'G.product_id = P.product_id')
+                    ->where('G.is_del',0)
+                    ->field('P.*,G.product_group_id,G.price,G.status,G.is_show,G.product_status,G.action_status');
+                break;
+            default:
+                break;
+        }
+        $data = $query->select()->toArray();
+        $ret = $this->commandChangeProductStatus($data);
+        return $ret;
+    }
+
+
+    public function commandChangeProductStatus($data)
+    {
+        $ret = [];
+
+        foreach ($data as $item) {
+            $status = 0;
+            switch ($item['product_type']) {
+                case 0:
+                    if ($item['is_show'] && $item['is_used']) $status = 1;
+                    $ret[] = [
+                        'activity_id' => 0,
+                        'product_id' => $item['product_id'],
+                        'mer_id' => $item['mer_id'],
+                        'keyword' => $item['keyword'],
+                        'price' => $item['price'],
+                        'rank' => $item['rank'],
+                        'sort' => $item['sort'],
+                        'image' => $item['image'],
+                        'status' => $status,
+                        'temp_id' => $item['temp_id'],
+                        'store_name' => $item['store_name'],
+                        'product_type' => $item['product_type'],
+                    ];
+                    break;
+                case 1:
+                    if ($item['is_show'] && $item['is_used'] && $item['status'] && ($item['end_time'] > time())) $status = 1;
+                    $ret[] = [
+                        'activity_id' => $item['seckill_active_id'],
+                        'product_id' => $item['product_id'],
+                        'mer_id' => $item['mer_id'],
+                        'keyword' => $item['keyword'],
+                        'price' => $item['price'],
+                        'rank' => $item['rank'],
+                        'sort' => $item['sort'],
+                        'image' => $item['image'],
+                        'status' => $status,
+                        'temp_id' => $item['temp_id'],
+                        'store_name' => $item['store_name'],
+                        'product_type' => $item['product_type'],
+                    ];
+                    break;
+                case 2:
+                    if ($item['is_show'] && $item['action_status'] && $item['status'] && $item['product_status']) $status = 1;
+                    $ret[] = [
+                        'activity_id' => $item['product_presell_id'],
+                        'product_id' => $item['product_id'],
+                        'mer_id' => $item['mer_id'],
+                        'keyword' => $item['keyword'],
+                        'price' => $item['price'],
+                        'rank' => $item['rank'],
+                        'sort' => $item['sort'],
+                        'image' => $item['image'],
+                        'status' => $status,
+                        'temp_id' => $item['temp_id'],
+                        'store_name' => $item['store_name'],
+                        'product_type' => $item['product_type'],
+                    ];
+                    break;
+                case 3:
+                    if ($item['is_show'] && $item['action_status'] && $item['status'] && $item['product_status']) $status = 1;
+                    $ret[] = [
+                        'activity_id' => $item['product_assist_id'],
+                        'product_id' => $item['product_id'],
+                        'mer_id' => $item['mer_id'],
+                        'keyword' => $item['keyword'],
+                        'price' => $item['price'],
+                        'rank' => $item['rank'],
+                        'sort' => $item['sort'],
+                        'image' => $item['image'],
+                        'status' => $status,
+                        'temp_id' => $item['temp_id'],
+                        'store_name' => $item['store_name'],
+                        'product_type' => $item['product_type'],
+                    ];
+                    break;
+                case 4:
+                    if ($item['is_show'] && $item['action_status'] && $item['status'] && $item['product_status']) $status = 1;
+                    $ret[] = [
+                        'activity_id' => $item['product_group_id'],
+                        'product_id' => $item['product_id'],
+                        'mer_id' => $item['mer_id'],
+                        'keyword' => $item['keyword'],
+                        'price' => $item['price'],
+                        'rank' => $item['rank'],
+                        'sort' => $item['sort'],
+                        'image' => $item['image'],
+                        'status' => $status,
+                        'temp_id' => $item['temp_id'],
+                        'store_name' => $item['store_name'],
+                        'product_type' => $item['product_type'],
+                    ];
+                    break;
+            }
+        }
+        return $ret;
+    }
+}

+ 53 - 0
app/common/dao/store/product/ProductGroupBuyingDao.php

@@ -0,0 +1,53 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductGroupBuying;
+
+class ProductGroupBuyingDao extends  BaseDao
+{
+    public function getModel(): string
+    {
+        return ProductGroupBuying::class;
+    }
+
+
+    public function search($where)
+    {
+        $query = ProductGroupBuying::getDb()->alias('B')->join('StoreProductGroup G','B.product_group_id = G.product_group_id');
+
+        $query
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '', function($query)use($where){
+                $query->where('B.mer_id',$where['mer_id']);
+            })
+            ->when(isset($where['date']) && $where['date'] , function($query)use($where){
+                getModelTime($query,$where['date'],'B.create_time');
+            })
+            ->when(isset($where['status']) && $where['status'] !== '', function($query)use($where){
+                $query->where('B.status',$where['status']);
+            })
+            ->when(isset($where['user_name']) && $where['user_name'] !== '', function($query)use($where){
+                $query->join('StoreProductGroupUser U','U.group_buying_id = B.group_buying_id')->where('is_initiator',1)
+                    ->whereLike('uid|nickname',"%{$where['user_name']}%");
+            })
+            ->when(isset($where['keyword']) && $where['keyword'] !== '' , function($query)use($where){
+                $query->join('StoreProduct P','G.product_id = P.product_id')
+                    ->whereLike('P.product_id|store_name',"%{$where['keyword']}%");
+            })
+            ->when(isset($where['is_trader']) && $where['is_trader'] !== '', function($query)use($where){
+                $query->join('Merchant M','M.mer_id = B.mer_id')->where('is_trader',$where['is_trader']);
+            })
+        ;
+
+        return $query;
+    }
+}

+ 146 - 0
app/common/dao/store/product/ProductGroupDao.php

@@ -0,0 +1,146 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductGroup;
+use app\common\repositories\store\product\SpuRepository;
+
+class ProductGroupDao extends  BaseDao
+{
+    public function getModel(): string
+    {
+        return ProductGroup::class;
+    }
+
+    public function search($where)
+    {
+        $query = ProductGroup::hasWhere('product',function($query)use($where){
+            $query->where('status',1);
+            $query->when(isset($where['keyword']) && $where['keyword'] !== '',function($query)use($where){
+                $query->whereLike('store_name',"%{$where['keyword']}%");
+            });
+        });
+        $query->when(isset($where['is_show']) && $where['is_show'] !== '',function($query)use($where){
+                $query->where('ProductGroup.is_show',$where['is_show']);
+            })
+            ->when(isset($where['product_status']) && $where['product_status'] !== '',function($query)use($where){
+                if($where['product_status'] == -1){
+                    $query->where('ProductGroup.product_status','in',[-1,-2]);
+                }else{
+                    $query->where('ProductGroup.product_status',$where['product_status']);
+                }
+            })
+            ->when(isset($where['status']) && $where['status'] !== '',function($query)use($where){
+                $query->where('ProductGroup.status',$where['status']);
+            })
+            ->when(isset($where['end_time']) && $where['end_time'] !== '',function($query)use($where){
+                $query->whereTime('ProductGroup.end_time','>',$where['end_time']);
+            })
+            ->when(isset($where['active_type']) && $where['active_type'] !== '',function($query)use($where){
+                $query->where('ProductGroup.action_status',$where['active_type']);
+            })
+            ->when(isset($where['is_trader']) && $where['is_trader'] !== '',function($query)use($where){
+                $query->join('Merchant M','M.mer_id = ProductGroup.mer_id')->where('is_trader',$where['is_trader']);
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '',function($query)use($where){
+                $query->where('ProductGroup.mer_id',$where['mer_id']);
+            })
+            ->when(isset($where['product_group_id']) && $where['product_group_id'] !== '',function($query)use($where){
+                $query->where('ProductGroup.product_group_id',$where['product_group_id']);
+            })
+             ->when(isset($where['store_category_id']) && $where['store_category_id'] !== '',function($query)use($where){
+                 $query->join('StoreCategory C','Product.cate_id = C.store_category_id')
+                     ->whereLike('path',"/{$where['store_category_id']}/%");
+             })
+            ->when(isset($where['us_status']) && $where['us_status'] !== '',function($query)use($where){
+                if($where['us_status'] == 0) {
+                    $query->where('ProductGroup.is_show',0)->where('ProductGroup.status',1)->where('ProductGroup.product_status',1);
+                }
+                if($where['us_status'] == 1) {
+                    $query->where('ProductGroup.is_show',1)->where('ProductGroup.status',1)->where('ProductGroup.product_status',1);
+                }
+                if($where['us_status'] == -1) {
+                    $query->where(function($query){
+                        $query->where('ProductGroup.status',0)->whereOr('ProductGroup.product_status','<>',1);
+                    });
+                }
+            });
+
+        $query->join('StoreSpu U','ProductGroup.product_group_id = U.activity_id')->where('U.product_type',4);
+        $query->when(isset($where['star']) && $where['star'] !== '',function($query)use($where){
+            $query->where('U.star',$where['star']);
+        });
+        $query->when(isset($where['level']) && $where['level'] !== '',function($query)use($where) {
+            $query->where('U.star',$where['level']);
+        });
+        if(isset($where['order'])) {
+
+            switch ($where['order']) {
+                case 'sort':
+                    $order = 'U.sort DESC';
+                    break;
+                case 'rank':
+                    $order = 'U.rank DESC';
+                    break;
+                case 'star':
+                    $order = 'U.star DESC,U.rank DESC';
+                    break;
+                default:
+                    $order = 'U.star DESC,U.rank DESC,U.sort DES';
+                    break;
+            }
+
+            $query->order($order.',ProductGroup.create_time DESC');
+        }
+
+        return $query->where('ProductGroup.is_del',0);
+    }
+
+    public function actionShow()
+    {
+        return [
+            'is_show' => 1,
+            'action_status' => 1,
+            'product_status' => 1,
+            'status' => 1,
+            'end_time' => time()
+        ];
+    }
+
+    public function category()
+    {
+        $query = ProductGroup::alias('G')->join('StoreProduct P','G.product_id = P.product_id')
+            ->join('StoreCategory C','P.cate_id = C.store_category_id');
+        $query->where('G.is_show',1)->where('G.action_status',1)->where('G.product_status',1);
+        $query->group('G.product_id');
+        return $query->column('path');
+    }
+
+    /**
+     * TODO
+     * @author Qinii
+     * @day 1/27/21
+     */
+    public function valActiveStatus()
+    {
+        $query = $this->getModel()::getDB()->whereTime('end_time','<=',time())->where('action_status',1);
+        $id = $query->column($this->getPk());
+        if($id) {
+            $this->getModel()::getDB()->where($this->getPk(),'in',$id)->update(['action_status' => -1]);
+            $where = [
+                'product_type' => 4,
+                'activity_ids' => $id
+            ];
+            app()->make(SpuRepository::class)->getSearch($where)->update(['status' => 0]);
+        }
+    }
+}

+ 38 - 0
app/common/dao/store/product/ProductGroupSkuDao.php

@@ -0,0 +1,38 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductGroupSku;
+
+class ProductGroupSkuDao extends BaseDao
+{
+    public function getModel(): string
+    {
+        return ProductGroupSku::class;
+    }
+
+    public function clear($id)
+    {
+        return $this->getModel()::getDB()->where('product_group_id', $id)->delete();
+    }
+
+    public function incStock($product_group_id, $unique, $inc)
+    {
+        return ProductGroupSku::getDB()->where('product_group_id', $product_group_id)->where('unique', $unique)->inc('stock', $inc)->update();
+    }
+
+    public function descStock($product_group_id, $unique, $inc)
+    {
+        return ProductGroupSku::getDB()->where('product_group_id', $product_group_id)->where('unique', $unique)->dec('stock', $inc)->update();
+    }
+
+}

+ 41 - 0
app/common/dao/store/product/ProductGroupUserDao.php

@@ -0,0 +1,41 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductGroupUser;
+
+class ProductGroupUserDao extends  BaseDao
+{
+    public function getModel(): string
+    {
+        return ProductGroupUser::class;
+    }
+
+    public function successUser($id)
+    {
+        $query = ProductGroupUser::hasWhere('groupBuying',function($query){
+            $query->where('status',10);
+        });
+        $query->where('ProductGroupUser.product_group_id',$id);
+        return $query->setOption('field',[])->field('nickname,avatar')->select();
+    }
+
+    public function updateStatus(int $groupId)
+    {
+        return $this->getModel()::getDb()->where('group_buying_id',$groupId)->update(['status' => 10]);
+    }
+
+    public function groupOrderIds($productGroupId)
+    {
+        return ProductGroupUser::getDB()->where('group_buying_id', $productGroupId)->where('order_id', '>', 0)->column('order_id');
+    }
+}

+ 176 - 0
app/common/dao/store/product/ProductPresellDao.php

@@ -0,0 +1,176 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductPresell;
+use app\common\model\system\merchant\Merchant;
+use app\common\repositories\store\product\SpuRepository;
+use app\common\repositories\system\merchant\MerchantRepository;
+
+class ProductPresellDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return ProductPresell::class;
+    }
+
+    public function search(array $where)
+    {
+        $query = ProductPresell::hasWhere('product',function($query)use($where){
+            $query->when(isset($where['product_show']) && $where['product_show'] !== '',function($query)use($where){
+                    $query->where('is_del',0)->where('mer_status',1);
+                })
+                ->when(isset($where['product_type']) && $where['product_type'] !== '',function($query)use($where){
+                    $query->where('product_type',2);
+                })
+                ->where('status',1);
+        });
+        $query->when(isset($where['product_presell_id']) && $where['product_presell_id'] !== '',function($query)use($where){
+                $query->where('product_presell_id',$where['product_presell_id']);
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '',function($query)use($where){
+                $query->where('ProductPresell.mer_id',$where['mer_id']);
+            })
+            ->when(isset($where['action_status']) && $where['action_status'] !== '',function($query)use($where){
+                $query->where('ProductPresell.action_status',$where['action_status']);
+            })
+            ->when(isset($where['keyword']) && $where['keyword'] !== '',function($query)use($where){
+                $query->whereLike('ProductPresell.store_name|ProductPresell.product_id',"%{$where['keyword']}%");
+            })
+            ->when(isset($where['product_status']) && $where['product_status'] !== '',function($query)use($where){
+                if($where['product_status'] == -1){
+                    $query->where('ProductPresell.product_status','in',[-1,-2]);
+                }else{
+                    $query->where('ProductPresell.product_status',$where['product_status']);
+                }
+            })
+            ->when(isset($where['type']) && $where['type'] !== '',function($query)use($where){
+                switch ($where['type']){
+                    case 0: //未开始
+                        if(isset($where['api_type'])){
+                            $query->where('product_status',1);
+                        }
+                        $query->where(function($query){
+                            $query->where('start_time','> TIME',time())->whereOr(function($query){
+                                $query->whereOr('ProductPresell.status','<>',1)->whereOr('ProductPresell.is_show','<>',1);
+                            });
+                        });
+                        break;
+                    case 1: //进行中
+                        $query->whereTime('start_time','<=',time())->whereTime('end_time','>',time())
+                            ->where('product_status',1)->where('ProductPresell.status',1)->where('ProductPresell.is_show',1);
+                        break;
+                    case 2: //已结束
+//                        if(isset($where['api_type'])){
+//                            $query->where('ProductPresell.presell_type',2)
+//                                ->whereTime('end_time','<=',time())
+//                                ->whereTime('final_end_time','>=',time());
+//                        }else{
+                            $query->where(function($query){
+                                $query->where('action_status',-1)->whereOr('end_time','<= TIME',time());
+                            });
+//                        }
+                        break;
+                    case 3: //已关闭
+                        $query->where(function($query){
+                            $query->where(function($query){
+                                $query->where('ProductPresell.presell_type',1)->whereTime('end_time','<',time());
+                            })->whereOr(function($query){
+                                $query->where('ProductPresell.presell_type',2)->whereTime('final_end_time','<',time());
+                            });
+                        });
+                        break;
+                }
+            })
+            ->when(isset($where['presell_type']) && $where['presell_type'] !== '',function($query)use($where){
+                $query->where('ProductPresell.presell_type',$where['presell_type']);
+            })
+            ->when(isset($where['status']) && $where['status'] !== '',function($query)use($where){
+                $query->where('ProductPresell.status',$where['status']);
+            })
+            ->when(isset($where['is_show']) && $where['is_show'] !== '',function($query)use($where){
+                $query->where('ProductPresell.is_show',$where['is_show']);
+            })
+            ->when(isset($where['mer_name']) && $where['mer_name'] !== '',function($query)use($where){
+                $make = app()->make(MerchantRepository::class);
+                $mer_id = $make->search(['keyword' => $where['mer_name']])->column('mer_id');
+                $query->whereIn('ProductPresell.mer_id',$mer_id);
+            })
+            ->when(isset($where['is_trader']) && $where['is_trader'] !== '',function($query)use($where){
+                $make = app()->make(MerchantRepository::class);
+                $mer_id = $make->search(['is_trader' => $where['is_trader']])->column('mer_id');
+                $query->whereIn('ProductPresell.mer_id',$mer_id);
+            })
+            ->when(isset($where['us_status']) && $where['us_status'] !== '',function($query)use($where){
+               if($where['us_status'] == 0) {
+                  $query->where('ProductPresell.is_show',0)->where('ProductPresell.status',1)->where('ProductPresell.product_status',1);
+               }
+               if($where['us_status'] == 1) {
+                   $query->where('ProductPresell.is_show',1)->where('ProductPresell.status',1)->where('ProductPresell.product_status',1);
+               }
+               if($where['us_status'] == -1) {
+                   $query->where(function($query){
+                       $query->where('ProductPresell.status',0)->whereOr('ProductPresell.product_status','<>',1);
+                   });
+               }
+            });
+            $query->when(isset($where['star']),function($query)use($where){
+                $query->Join('StoreSpu U', 'ProductPresell.product_presell_id = U.activity_id')->where('U.product_type', 2);
+                $query->when($where['star'] !== '', function ($query) use ($where) {
+                    $query->where('U.star', $where['star']);
+                });
+                $query->order('U.star DESC,U.rank DESC,ProductPresell.create_time DESC');
+            });
+        $query->where('ProductPresell.is_del',0);
+        return $query;
+    }
+
+    /**
+     * TODO 移动端展示 条件
+     * @return array
+     * @author Qinii
+     * @day 2020-10-19
+     */
+    public function presellShow()
+    {
+        return [
+            'product_show' => 1,
+            //'product_status' => 1,
+            'status' => 1,
+            'is_show' => 1,
+            'api_type' => 1
+        ];
+    }
+
+    /**
+     * TODO
+     * @author Qinii
+     * @day 1/27/21
+     */
+    public function valActiveStatus()
+    {
+        $query = $this->getModel()::getDB()->whereTime('end_time','<=',time())->where('action_status',1);
+        $id = $query->column($this->getPk());
+        if($id){
+            $this->getModel()::getDB()->where($this->getPk(),'in',$id)->update(['action_status' => -1]);
+            $where = [
+                'product_type' => 2,
+                'activity_ids' => $id
+            ];
+            app()->make(SpuRepository::class)->getSearch($where)->update(['status' => 0]);
+        }
+    }
+
+}
+

+ 85 - 0
app/common/dao/store/product/ProductPresellSkuDao.php

@@ -0,0 +1,85 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductPresellSku;
+use think\facade\Db;
+
+class ProductPresellSkuDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return ProductPresellSku::class;
+    }
+
+    public function clear($id)
+    {
+        $this->getModel()::getDB()->where('product_presell_id', $id)->delete();
+    }
+
+    public function descStock(int $product_presell_id, string $unique, int $desc)
+    {
+        return $this->getModel()::getDB()->where('product_presell_id', $product_presell_id)->where('unique', $unique)->update([
+            'stock' => Db::raw('stock-' . $desc),
+            'seles' => Db::raw('seles+' . $desc),
+        ]);
+    }
+
+    public function incStock(int $product_presell_id, string $unique, int $desc)
+    {
+        return $this->getModel()::getDB()->where('product_presell_id', $product_presell_id)->where('unique', $unique)->update([
+            'stock' => Db::raw('stock+' . $desc),
+            'seles' => Db::raw('seles-' . $desc),
+        ]);
+    }
+
+    /**
+     * TODO 增加 参与或支付成功 人数
+     * @param int $product_presell_id
+     * @param string $unique
+     * @param string $field
+     * @return mixed
+     * @author Qinii
+     * @day 2020-11-27
+     */
+    public function incCount(int $product_presell_id,string $unique,string $field,$inc = 1)
+    {
+        return $this->getModel()::getDB()->where('product_presell_id', $product_presell_id)->where('unique', $unique)
+            ->update([
+                $field => Db::raw($field.'+' . $inc)
+            ]);
+    }
+
+    /**
+     * TODO 减少 参与或支付成功 人数
+     * @param int $product_presell_id
+     * @param string $unique
+     * @param string $field
+     * @return mixed
+     * @author Qinii
+     * @day 2020-11-27
+     */
+    public function desCount(int $product_presell_id,string $unique,$inc = 1)
+    {
+        $res = $this->getModel()::getDB()->where('product_presell_id', $product_presell_id)->where('unique',$unique)->find();
+        if($res->presell->presell_type == 1 ){
+            $res->one_pay = ($res->one_pay > 0) ? $res->one_pay - $inc : 0;
+        }else{
+            $res->two_pay = ($res->two_pay > 0) ? $res->two_pay - $inc : 0;
+        }
+        return $res->save();
+    }
+}
+

+ 174 - 0
app/common/dao/store/product/ProductReplyDao.php

@@ -0,0 +1,174 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\product;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\ProductReply;
+use crmeb\jobs\UpdateProductReplyJob;
+use think\db\BaseQuery;
+use think\db\exception\DbException;
+use think\facade\Db;
+use think\facade\Queue;
+
+/**
+ * Class ProductReplyDao
+ * @package app\common\dao\store\product
+ * @author xaboy
+ * @day 2020/5/30
+ */
+class ProductReplyDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/5/30
+     */
+    protected function getModel(): string
+    {
+        return ProductReply::class;
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/6/1
+     */
+    public function search(array $where)
+    {
+        return ProductReply::getDB()->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+            $query->where('mer_id', $where['mer_id']);
+        })->when(isset($where['is_reply']) && $where['is_reply'] !== '', function ($query) use ($where) {
+            $query->where('is_reply', $where['is_reply']);
+        })->when(isset($where['is_virtual']) && $where['is_virtual'] !== '', function ($query) use ($where) {
+            $query->where('is_virtual', $where['is_virtual']);
+        })->when(isset($where['nickname']) && $where['nickname'] !== '', function ($query) use ($where) {
+            $query->whereLike('nickname', "%{$where['nickname']}%");
+        })->when(isset($where['product_id']) && $where['product_id'] !== '', function ($query) use ($where) {
+            $query->where('product_id', $where['product_id']);
+        })->when(isset($where['product_type']) && $where['product_type'] !== '', function ($query) use ($where) {
+            $query->where('product_type', 'product_type');
+        })->when(isset($where['is_del']) && $where['is_del'] !== '', function ($query) use ($where) {
+            $query->where('is_del', $where['is_del']);
+        });
+    }
+
+    public function searchJoinQuery(array $where)
+    {
+        return ProductReply::getDB()->alias('A')
+            ->join('StoreProduct B', 'A.product_id = B.product_id')
+            ->when(isset($where['is_reply']) && $where['is_reply'] !== '', function ($query) use ($where) {
+                $query->where('A.is_reply', $where['is_reply']);
+            })
+            ->when(isset($where['nickname']) && $where['nickname'] !== '', function ($query) use ($where) {
+                $query->whereLike('A.nickname', "%{$where['nickname']}%");
+            })
+            ->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+                $query->where(function ($query) use ($where) {
+                    $query->where('B.store_name', 'like', "%{$where['keyword']}%")
+                        ->whereOr('B.product_id', $where['keyword']);
+                });
+            })
+            ->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+                getModelTime($query, $where['date'], 'A.create_time');
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+                $query->where('A.mer_id', $where['mer_id']);
+            })->order('A.create_time DESC')
+            ->where('A.is_del', 0)
+            ->field('A.reply_id,A.is_reply,A.uid,A.product_score,A.service_score,A.postage_score,A.comment,A.pics,A.create_time,A.merchant_reply_content,A.nickname,A.avatar,B.store_name,B.image,B.product_id');
+    }
+
+    /**
+     * @param array $data
+     * @return int
+     * @author xaboy
+     * @day 2020/5/30
+     */
+    public function insertAll(array $data)
+    {
+        return ProductReply::getDB()->insertAll($data);
+    }
+
+    /**
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020/5/30
+     */
+    public function exists(int $id)
+    {
+        return ProductReply::getDB()->where($this->getPk(), $id)->where('is_del', 0)->count() > 0;
+    }
+
+    /**
+     * @param $merId
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020/6/28
+     */
+    public function merExists($merId, int $id)
+    {
+        return ProductReply::getDB()->where($this->getPk(), $id)->where('is_del', 0)->where('mer_id', $merId)->count() > 0;
+    }
+
+    /**
+     * @param int $id
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/5/30
+     */
+    public function delete(int $id)
+    {
+        $reply = ProductReply::getDB()->where('reply_id', $id)->find();
+        $reply->is_del = 1;
+        $reply->save();
+        Queue::push(UpdateProductReplyJob::class, $reply['product_id']);
+    }
+
+    /**
+     * 返回评论数
+     * @Author:Qinii
+     * @Date: 2020/6/2
+     * @param int $productId
+     * @param array $where
+     * @return mixed
+     */
+    public function getProductReplay(int $productId, $where = [0, 5])
+    {
+        return $this->getModel()::getDB()->where('product_id', $productId)->whereBetween('rate', $where)->select();
+    }
+
+    public function productTotalRate($productId)
+    {
+        return ProductReply::getDB()->where('product_id', $productId)->where('is_del', 0)->field('sum(rate) as total_rate,count(reply_id) as total_count')->find();
+    }
+
+    /**
+     * 计算商铺平均分
+     * @param $merId
+     * @return mixed
+     * @author Qinii
+     * @day 2020-06-11
+     */
+    public function merchantTotalRate($merId)
+    {
+        return ($this->getModel()::getDB())->where('mer_id', $merId)->field('avg(product_score) product_score ,avg(service_score) service_score,avg(postage_score) postage_score')->find()->toArray();
+
+    }
+}

+ 142 - 0
app/common/dao/store/product/SpuDao.php

@@ -0,0 +1,142 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\common\dao\store\product;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\product\Spu;
+use app\common\model\store\StoreCategory;
+use app\common\repositories\store\StoreCategoryRepository;
+use crmeb\services\VicWordService;
+
+class SpuDao extends  BaseDao
+{
+    public function getModel(): string
+    {
+        return Spu::class;
+    }
+
+    public function search($where)
+    {
+        $order = 'P.sort DESC,S.create_time DESC';
+        if(isset($where['order'])){
+            if(in_array($where['order'], ['is_new', 'price_asc', 'price_desc', 'rate', 'sales'])){
+                if ($where['order'] == 'price_asc') {
+                    $order = 'S.price ASC';
+                } else if ($where['order'] == 'price_desc') {
+                    $order = 'S.price DESC';
+                } else {
+                    $order = 'P.'.$where['order'] . ' DESC';
+                }
+            }elseif($where['order'] == 'star'){
+                $order = 'S.star DESC,S.rank DESC,S.create_time DESC';
+            }else{
+                $order = 'S.'.$where['order'].' DESC,S.create_time DESC';
+            }
+        }
+        $query = Spu::getDB()->alias('S')->join('StoreProduct P','S.product_id = P.product_id');
+        $query->when(isset($where['is_del']) && $where['is_del'] !== '',function($query)use($where){
+                $query->where('P.is_del',$where['is_del']);
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '',function($query)use($where){
+                $query->where('P.mer_id',$where['mer_id']);
+            })
+            ->when(isset($where['keyword']) && $where['keyword'] !== '',function($query)use($where){
+                if (is_numeric($where['keyword'])) {
+                    $query->whereLike("S.store_name|S.keyword|S.product_id", "%{$where['keyword']}%");
+                } else {
+                    $word = app()->make(VicWordService::class)->getWord($where['keyword']);
+                    $query->where(function ($query) use ($word) {
+                        foreach ($word as $item) {
+                            $query->whereOr('S.store_name|S.keyword', 'LIKE', "%$item%");
+                        }
+                    });
+                }
+            })
+            ->when(isset($where['cate_pid']) && $where['cate_pid'], function ($query) use ($where) {
+                $storeCategoryRepository = app()->make(StoreCategoryRepository::class);
+                $cate = array_merge($storeCategoryRepository->findChildrenId((int)$where['cate_pid']), [(int)$where['cate_pid']]);
+                $query->whereIn('P.cate_id', $cate);
+            })
+            ->when(isset($where['cate_id']) && $where['cate_id'] !== '', function ($query) use ($where) {
+                is_array($where['cate_id']) ? $query->whereIn('P.cate_id', $where['cate_id']) : $query->where('P.cate_id', $where['cate_id']);
+            })
+            ->when(isset($where['common']) && $where['common'] !== '', function ($query) use ($where) {
+                $query->whereIn('P.product_type', [0, 1]);
+            })
+            ->when(isset($where['price_on']) && $where['price_on'] !== '',function($query)use($where){
+                $query->where('P.price','>=',$where['price_on']);
+            })
+            ->when(isset($where['price_off']) && $where['price_off'] !== '',function($query)use($where){
+                $query->where('P.price','<=',$where['price_off']);
+            })
+            ->when(isset($where['brand_id']) && $where['brand_id'] !== '', function ($query) use ($where) {
+                $query->whereIn('P.brand_id', array_map('intval', explode(',', $where['brand_id'])));
+            })
+            ->when(isset($where['is_gift_bag']) && $where['is_gift_bag'] !== '',function($query)use($where){
+                $query->where('P.is_gift_bag',$where['is_gift_bag']);
+            })
+            ->when(isset($where['product_type']) && $where['product_type'] !== '',function($query)use($where){
+                $query->where('S.product_type',$where['product_type']);
+            })
+            ->when(isset($where['action']) && $where['action'] !== '',function($query)use($where){
+                $query->where('S.product_type','>',0);
+            })
+            ->when(isset($where['mer_cate_id']) && $where['mer_cate_id'] !== '',function($query)use($where){
+                $ids = (StoreCategory::where('path','like','%/'.$where['mer_cate_id'].'/%'))->column('store_category_id');
+                $ids[] = intval($where['mer_cate_id']);
+                $query->join('StoreProductCate C','S.product_id = C.product_id')->where('mer_cate_id','in',$ids);
+            })
+            ->when(isset($where['mer_status']) && $where['mer_status'] !== '',function($query)use($where){
+                $query->where('mer_status',$where['mer_status']);
+            })
+            ->when(isset($where['spu_status']) && $where['spu_status'] !== '',function($query)use($where){
+                $query->where('S.status',$where['spu_status']);
+            })
+            ->when(isset($where['pid']) && $where['pid'] !== '', function ($query) use ($where) {
+                $query->join('StoreCategory CT','P.cate_id = CT.store_category_id')->where('CT.pid',$where['pid']);
+            })
+            ->when(isset($where['hot_type']) && $where['hot_type'] !== '', function ($query) use ($where) {
+                if ($where['hot_type'] == 'new') $query->where('P.is_new', 1);
+                else if ($where['hot_type'] == 'hot') $query->where('P.is_hot', 1);
+                else if ($where['hot_type'] == 'best') $query->where('P.is_best', 1);
+                else if ($where['hot_type'] == 'good') $query->where('P.is_benefit', 1);
+            });
+
+        return $query->order($order);
+    }
+
+    public function findOrCreateAll(array $where)
+    {
+        foreach ($where as $item) {
+            $item['activity_id'] = $item['activity_id'] ?? 0;
+            $data = $this->getModel()::getDB()->where('product_id', $item['product_id'])
+                ->where('product_type', $item['product_type'])
+                ->where('activity_id', $item['activity_id'])
+                ->find();
+            if (!$data) $this->create($item);
+        }
+    }
+
+    public function delProduct($id, $isDel = 1)
+    {
+        $this->getModel()::getDb()->where('product_id', $id)->update(['is_del' => $isDel]);
+    }
+
+
+    public function getActivecategory($type)
+    {
+        $query = Spu::getDB()->alias('S')->join('StoreProduct P','S.product_id = P.product_id')
+            ->join('StoreCategory C','C.store_category_id = P.cate_id');
+
+        $query->where('S.status',1)->where('S.product_type',$type);
+        return $query->group('S.product_id')->column('C.path');
+    }
+}

+ 171 - 0
app/common/dao/store/service/StoreServiceDao.php

@@ -0,0 +1,171 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\service;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\store\service\StoreService;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+/**
+ * Class StoreServiceDao
+ * @package app\common\dao\store\service
+ * @author xaboy
+ * @day 2020/5/29
+ */
+class StoreServiceDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/5/29
+     */
+    protected function getModel(): string
+    {
+        return StoreService::class;
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/5/29
+     */
+    public function search(array $where)
+    {
+        return StoreService::getDB()->where('is_del', 0)->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) {
+            $query->where('status', $where['status']);
+        })->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+            $query->whereLike('nickname', "%{$where['keyword']}%");
+        })->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+            $query->whereLike('mer_id', $where['mer_id']);
+        })->order('sort DESC');
+    }
+
+    public function getService($uid, $merId = null)
+    {
+        return StoreService::getDB()->where('uid', $uid)->when($merId, function ($query, $merId) {
+            $query->where('mer_id', $merId);
+        })->where('is_del', 0)->find();
+    }
+
+    /**
+     * @param int $merId
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020-05-13
+     */
+    public function merExists(int $merId, int $id)
+    {
+        return StoreService::getDB()->where($this->getPk(), $id)->where('mer_id', $merId)->where('is_del', 0)->count($this->getPk()) > 0;
+    }
+
+    /**
+     * @param $merId
+     * @param $uid
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020/5/29
+     */
+    public function issetService($merId, $uid, ?int $except = null)
+    {
+        return StoreService::getDB()->where('uid', $uid)->when($except, function ($query, $except) {
+                $query->where($this->getPk(), '<>', $except);
+            })->where('mer_id', $merId)->where('is_del', 0)->count($this->getPk()) > 0;
+    }
+
+    /**
+     * @param $uid
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020/5/29
+     */
+    public function isBindService($uid, ?int $except = null)
+    {
+        return StoreService::getDB()->where('uid', $uid)->when($except, function ($query, $except) {
+                $query->where($this->getPk(), '<>', $except);
+            })->where('is_del', 0)->count($this->getPk()) > 0;
+    }
+
+    /**
+     * @param int $id
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020/5/29
+     */
+    public function delete(int $id)
+    {
+        return StoreService::getDB()->where($this->getPk(), $id)->update(['is_del' => 1]);
+    }
+
+    /**
+     * @param $merId
+     * @return array|Model|null
+     * @throws DbException
+     * @throws DataNotFoundException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/5/29
+     */
+    public function getChatService($merId)
+    {
+        return StoreService::getDB()->where('mer_id', $merId)->where('is_del', 0)->where('status', 1)->order('status DESC, sort DESC, create_time ASC')
+            ->hidden(['is_del'])->find();
+    }
+
+    public function getRandService($merId)
+    {
+        $services = StoreService::getDB()->where('mer_id', $merId)->where('is_del', 0)->where('status', 1)->order('status DESC, sort DESC, create_time ASC')
+            ->hidden(['is_del'])->select();
+        if (!$services || !count($services)) return null;
+        if (count($services) === 1) $services[0];
+        return $services[max(random_int(0, count($services) - 1), 0)];
+    }
+
+    /**
+     * @param $id
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/5/29
+     */
+    public function getValidServiceInfo($id)
+    {
+        return StoreService::getDB()->where('service_id', $id)->where('status', 1)->where('is_del', 0)->hidden(['is_del'])->find();
+    }
+
+    /**
+     * @param $merId
+     * @return array
+     * @author xaboy
+     * @day 2020/7/1
+     */
+    public function getNoticeServiceInfo($merId)
+    {
+        return StoreService::getDB()->where('mer_id', $merId)->where('status', 1)->where('notify', 1)
+            ->where('is_del', 0)->column('uid,phone,nickname');
+    }
+
+}

+ 182 - 0
app/common/dao/store/service/StoreServiceLogDao.php

@@ -0,0 +1,182 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\store\service;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\store\service\StoreServiceLog;
+use think\db\BaseQuery;
+
+/**
+ * Class StoreServiceLogDao
+ * @package app\common\dao\store\service
+ * @author xaboy
+ * @day 2020/5/29
+ */
+class StoreServiceLogDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/5/29
+     */
+    protected function getModel(): string
+    {
+        return StoreServiceLog::class;
+    }
+
+    /**
+     * @param $merId
+     * @param $uid
+     * @return int
+     * @throws \think\db\exception\DbException
+     * @author xaboy
+     * @day 2020/6/16
+     */
+    public function userRead($merId, $uid)
+    {
+        return StoreServiceLog::getDB()->where('mer_id', $merId)->where('uid', $uid)->where('type', '<>', 1)->update(['type' => 1]);
+    }
+
+    /**
+     * @param $uid
+     * @param $merId
+     * @return bool
+     * @author xaboy
+     * @day 2020/6/16
+     */
+    public function issetLog($uid, $merId)
+    {
+        return StoreServiceLog::getDB()->where('mer_id', $merId)->where('uid', $uid)->where('send_type', 0)->limit(1)->count() > 0;
+    }
+
+    /**
+     * @param $merId
+     * @param $uid
+     * @param $serviceId
+     * @return int
+     * @throws \think\db\exception\DbException
+     * @author xaboy
+     * @day 2020/10/15
+     */
+    public function serviceRead($merId, $uid, $serviceId)
+    {
+        return StoreServiceLog::getDB()->where('mer_id', $merId)->where('uid', $uid)->where('service_id', $serviceId)->where('service_type', '<>', 1)->update(['service_type' => 1]);
+    }
+
+    /**
+     * @param array $where
+     * @return \think\db\BaseQuery
+     * @author xaboy
+     * @day 2020/6/16
+     */
+    public function search(array $where)
+    {
+        return StoreServiceLog::getDB()->when(isset($where['uid']) && $where['uid'] !== '', function ($query) use ($where) {
+            $query->where('uid', $where['uid']);
+        })->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+            $query->where('mer_id', $where['mer_id']);
+        })->when(isset($where['service_id']) && $where['service_id'] !== '', function ($query) use ($where) {
+            $query->where('service_id', $where['service_id']);
+        });
+    }
+
+    /**
+     * @param $merId
+     * @param $uid
+     * @return mixed
+     * @author xaboy
+     * @day 2020/5/29
+     */
+    public function getLastServiceId($merId, $uid)
+    {
+        return StoreServiceLog::getDB()->where('mer_id', $merId)->order('service_log_id DESC')->where('uid', $uid)->value('service_id');
+    }
+
+    /**
+     * @param $uid
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/6/16
+     */
+    public function getMerchantListQuery($uid)
+    {
+        return StoreServiceLog::getDB()->where('uid', $uid)->group('mer_id');
+    }
+
+    /**
+     * TODO 客服的所有用户
+     * @param $serviceId
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/6/16
+     */
+    public function getUserListQuery($serviceId)
+    {
+        return StoreServiceLog::getDB()->where('service_id', $serviceId)->group('uid');
+    }
+
+    /**
+     * TODO 商户的所有用户
+     * @param $merId
+     * @return mixed
+     * @author Qinii
+     * @day 2020-06-19
+     */
+    public function getMerchantUserList($merId)
+    {
+        return StoreServiceLog::getDB()->where('mer_id', $merId)->group('uid');
+    }
+
+    /**
+     * @param $merId
+     * @param $uid
+     * @return array|\think\Model|null
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/19
+     */
+    public function getLastLog($merId, $uid)
+    {
+        return StoreServiceLog::getDB()->where('mer_id', $merId)->where('uid', $uid)->order('service_log_id DESC')->find();
+    }
+
+    /**
+     * @param $merId
+     * @param $uid
+     * @param $sendType
+     * @return int
+     * @author xaboy
+     * @day 2020/6/19
+     */
+    public function getUnReadNum($merId, $uid, $sendType)
+    {
+        return StoreServiceLog::getDB()->where('uid', $uid)->where('mer_id', $merId)->where('send_type', $sendType)->where($sendType ? 'type' : 'service_type', 0)->count();
+    }
+
+    /**
+     * @param $uid
+     * @return int
+     * @author xaboy
+     * @day 2020/6/19
+     */
+    public function totalUnReadNum($uid)
+    {
+        return StoreServiceLog::getDB()->where('uid', $uid)->where('send_type', 1)->where('type', 0)->count();
+    }
+}

+ 30 - 0
app/common/dao/store/shipping/CityDao.php

@@ -0,0 +1,30 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\shipping;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\shipping\City as model;
+
+class CityDao  extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    public function getAll(array $where)
+    {
+        return ($this->getModel()::getDB())->where($where)
+            ->order('city_id ASC')->field('city_id,name,merger_name,parent_id,level')->select();
+    }
+}

+ 65 - 0
app/common/dao/store/shipping/ExpressDao.php

@@ -0,0 +1,65 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\shipping;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\shipping\Express as model;
+
+class ExpressDao  extends BaseDao
+{
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/13
+     * @return string
+     */
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/13
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     */
+    public function merFieldExists($field, $value, $except = null, $id = null, $isUser = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->when($id, function ($query) use ($id) {
+                $query->where($this->getPk(), '<>', $id);
+            })->when($isUser, function ($query) {
+                $query->where('is_show', 1);
+            })->where($field, $value)->count() > 0;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/13
+     * @param array $where
+     * @return mixed
+     */
+    public function search(array $where)
+    {
+        $query = ($this->getModel()::getDB())
+            ->when(isset($where['name']) && $where['name'],function($query) use ($where){
+                $query->where('name|code','like','%'.$where['name'].'%');
+            })->where(isset($where['code']) && $where['code'],function($query)use($where){
+                $query->where('code',$where['name']);
+            });
+        return $query->order('sort DESC');
+    }
+}

+ 94 - 0
app/common/dao/store/shipping/ShippingTemplateDao.php

@@ -0,0 +1,94 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\shipping;
+
+use think\facade\Db;
+use app\common\dao\BaseDao;
+use app\common\model\store\shipping\ShippingTemplate as model;
+
+class ShippingTemplateDao  extends BaseDao
+{
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @return string
+     */
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/7
+     * @param int $merId
+     * @param array $where
+     * @return mixed
+     */
+    public function search(int $merId,array $where)
+    {
+        $query = ($this->getModel()::getDB())->where('mer_id',$merId)->order('sort desc');
+        if(isset($where['name']) && !empty($where['name']))
+            $query->where('name','like','%'.$where['name'].'%');
+        if(isset($where['type']) && !empty($where['type']))
+            $query->where('type',$where['type']);
+        return $query->order('sort DESC,create_time DESC');
+    }
+
+    /**
+     * 查询是否存在
+     * @Author:Qinii
+     * @Date: 2020/5/7
+     * @param int $merId
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     */
+    public function merFieldExists(int $merId, $field, $value, $except = null)
+    {
+       return  ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->where('mer_id', $merId)->where($field, $value)->count() > 0;
+    }
+
+    /**
+     * 关联删除
+     * @Author:Qinii
+     * @Date: 2020/5/7
+     * @param int $id
+     * @return int|void
+     */
+    public function delete(int $id)
+    {
+        $result = $this->getModel()::with(['free','region','undelives'])->find($id);
+        $result->together(['free','region','undelives'])->delete();
+    }
+
+    /**
+     * 批量删除
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @param int $id
+     * @return mixed
+     */
+    public function batchRemove(int $id)
+    {
+        return ($this->getModel())::getDB()->where($this->getPk(),'in',$id)->delete();
+    }
+
+    public function getList($merId)
+    {
+        return ($this->getModel())::getDB()->where('mer_id',$merId)->field('shipping_template_id,name')->order('sort DESC,create_time DESC')->select();
+    }
+}

+ 72 - 0
app/common/dao/store/shipping/ShippingTemplateFreeDao.php

@@ -0,0 +1,72 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\shipping;
+
+use think\facade\Db;
+use app\common\dao\BaseDao;
+use app\common\model\store\shipping\ShippingTemplateFree as model;
+
+class ShippingTemplateFreeDao  extends BaseDao
+{
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @return string
+     */
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     */
+    public function merFieldExists($field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->where($field, $value)->count() > 0;
+    }
+
+    /**
+     * 批量删除
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @param array $id
+     * @param array $temp_id
+     */
+    public function batchRemove(array $id,array $temp_id)
+    {
+        if($id)
+            ($this->getModel())::getDB()->where($this->getPk(),'in',$id)->delete();
+        if($temp_id)
+            ($this->getModel())::getDB()->where('temp_id','in',$temp_id)->delete();
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/13
+     * @param array $data
+     * @return mixed
+     */
+    public function insertAll(array $data)
+    {
+        return ($this->getModel()::getDB())->insertAll($data);
+    }
+}

+ 72 - 0
app/common/dao/store/shipping/ShippingTemplateRegionDao.php

@@ -0,0 +1,72 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\shipping;
+
+use think\facade\Db;
+use app\common\dao\BaseDao;
+use app\common\model\store\shipping\ShippingTemplateRegion as model;
+
+class ShippingTemplateRegionDao  extends BaseDao
+{
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @return string
+     */
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     */
+    public function merFieldExists($field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->where($field, $value)->count() > 0;
+    }
+
+    /**
+     * 批量删除
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @param array $id
+     * @param array $temp_id
+     */
+    public function batchRemove(array $id,array $temp_id)
+    {
+        if($id)
+            ($this->getModel())::getDB()->where($this->getPk(),'in',$id)->delete();
+        if($temp_id)
+            ($this->getModel())::getDB()->where('temp_id','in',$temp_id)->delete();
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/13
+     * @param array $data
+     * @return mixed
+     */
+    public function insertAll(array $data)
+    {
+        return ($this->getModel()::getDB())->insertAll($data);
+    }
+
+}

+ 60 - 0
app/common/dao/store/shipping/ShippingTemplateUndeliveryDao.php

@@ -0,0 +1,60 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\store\shipping;
+
+use app\common\dao\BaseDao;
+use app\common\model\store\shipping\ShippingTemplateUndelivery as model;
+
+class ShippingTemplateUndeliveryDao  extends BaseDao
+{
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @return string
+     */
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     */
+    public function merFieldExists($field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->where($field, $value)->count() > 0;
+    }
+
+
+    /**
+     * 批量删除
+     * @Author:Qinii
+     * @Date: 2020/5/8
+     * @param array $id
+     * @param array $temp_id
+     */
+    public function batchRemove(array $id,array $temp_id)
+    {
+        if($id)
+            ($this->getModel())::getDB()->where($this->getPk(),'in',$id)->delete();
+        if($temp_id)
+            ($this->getModel())::getDB()->where('temp_id','in',$temp_id)->delete();
+    }
+}

+ 66 - 0
app/common/dao/system/CacheDao.php

@@ -0,0 +1,66 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\Cache;
+use think\db\exception\DbException;
+
+/**
+ * Class CacheDao
+ * @package app\common\dao\system
+ * @author xaboy
+ * @day 2020-04-24
+ */
+class CacheDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return Cache::class;
+    }
+
+    /**
+     * @param $key
+     * @return mixed
+     * @author xaboy
+     * @day 2020-04-24
+     */
+    public function getResult($key)
+    {
+        $val = Cache::getDB()->where('key', $key)->value('result');
+        return $val ? json_decode($val, true) : null;
+    }
+
+    /**
+     * @param string $key
+     * @param $data
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-04-24
+     */
+    public function keyUpdate(string $key, $data)
+    {
+        if (isset($data['result']))
+            $data['result'] = json_encode($data['result'], JSON_UNESCAPED_UNICODE);
+        Cache::getDB()->where('key', $key)->update($data);
+    }
+}

+ 117 - 0
app/common/dao/system/admin/AdminDao.php

@@ -0,0 +1,117 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\admin;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\admin\Admin;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+class AdminDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return Admin::class;
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-04-09
+     */
+    public function search(array $where = [], $is_del = 0,$level = true)
+    {
+        $query = Admin::getDB();
+        if($level) $query->where('level', '<>', 0);
+        $query->when($is_del !== null, function ($query) use ($is_del) {
+            $query->where('is_del', $is_del);
+        })->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+            getModelTime($query, $where['date']);
+        });
+        if (isset($where['keyword']) && $where['keyword'] !== '') {
+            $query = $query->whereLike('real_name|account', '%' . $where['keyword'] . '%');
+        }
+        if (isset($where['status']) && $where['status'] !== '') {
+            $query = $query->where('status', intval($where['status']));
+        }
+        return $query;
+    }
+
+    public function exists(int $id)
+    {
+        $query = ($this->getModel())::getDB()->where($this->getPk(), $id)->where('is_del', 0);
+        return $query->count() > 0;
+    }
+
+
+    /**
+     * @param int $id
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-09
+     */
+    public function get( $id)
+    {
+        return Admin::getInstance()->where('is_del', 0)->find($id);
+    }
+
+
+    /**
+     * @param $field
+     * @param $value
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    public function fieldExists($field, $value, ?int $except = null): bool
+    {
+        $query = ($this->getModel())::getDB()->where($field, $value)->where('is_del', 0);
+        if (!is_null($except)) $query->where($this->getPk(), '<>', $except);
+        return $query->count() > 0;
+    }
+
+    /**
+     * @param string $account
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-09
+     */
+    public function accountByAdmin(string $account)
+    {
+        return Admin::getInstance()->where('account', $account)
+            ->where('is_del', 0)
+            ->field(['account', 'pwd', 'real_name', 'login_count', 'admin_id', 'status'])
+            ->find();
+    }
+}
+

+ 60 - 0
app/common/dao/system/admin/LogDao.php

@@ -0,0 +1,60 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\admin;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\admin\Log;
+use think\db\BaseQuery;
+
+/**
+ * Class LogDao
+ * @package app\common\dao\system\admin
+ * @author xaboy
+ * @day 2020-04-16
+ */
+class LogDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return Log::class;
+    }
+
+    /**
+     * @param array $where
+     * @param $merId
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-04-16
+     */
+    public function search(array $where, $merId)
+    {
+        $query = Log::getDB()->where('mer_id', $merId)->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+            getModelTime($query, $where['date']);
+        });
+        if (isset($where['method']) && $where['method'] !== '') $query->where('method', $where['method']);
+        if (isset($where['admin_id']) && $where['admin_id'] !== '') $query->where('admin_id', $where['admin_id']);
+        if (isset($where['section_startTime']) && $where['section_startTime'] && isset($where['section_endTime']) && $where['section_endTime'])
+            $query->where('create_time', '>', $where['section_startTime'])->where('create_time', '<', $where['section_endTime']);
+
+        return $query;
+    }
+}

+ 183 - 0
app/common/dao/system/attachment/AttachmentCategoryDao.php

@@ -0,0 +1,183 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\attachment;
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\attachment\AttachmentCategory;
+use think\Collection;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\exception\ValidateException;
+use think\Model;
+
+/**
+ * Class AttachmentCategoryDao
+ * @package app\common\dao\system\attachment
+ * @author xaboy
+ * @day 2020-04-22
+ */
+class AttachmentCategoryDao extends BaseDao
+{
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return AttachmentCategory::class;
+    }
+
+    /**
+     * @param int $mer_id
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function getAll($mer_id = 0)
+    {
+        return AttachmentCategory::getDB()->where('mer_id', $mer_id)->order('sort DESC')->select();
+    }
+
+    /**
+     * 通过 $attachmentCategoryEName 获取主键
+     * @param string $attachmentCategoryEName 需要检测的数据
+     * @return int
+     * @author 张先生
+     * @date 2020-03-30
+     */
+    public function getPkByAttachmentCategoryEName($attachmentCategoryEName)
+    {
+        return AttachmentCategory::getInstance()->where('attachment_category_enname', $attachmentCategoryEName)->value($this->getPk());
+    }
+
+    /**
+     * 通过id 获取path
+     * @param int $id 需要检测的数据
+     * @return string
+     * @author 张先生
+     * @date 2020-03-30
+     */
+    public function getPathById($id)
+    {
+        return AttachmentCategory::getInstance()->where($this->getPk(), $id)->value('path');
+    }
+
+    /**
+     * 通过id获取所有子集的id
+     * @param int $id 需要检测的数据
+     * @return array
+     * @author 张先生
+     * @date 2020-03-30
+     */
+    public function getIdListContainsPath($id)
+    {
+        return AttachmentCategory::getInstance()
+            ->where($this->getPk(), $id)
+            ->whereOrRaw("locate ('/{$id}/', path)")
+            ->column($this->getPk());
+    }
+
+    /**
+     * @param int $mer_id
+     * @return array
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function getAllOptions($mer_id = 0)
+    {
+        return AttachmentCategory::getDB()->where('mer_id', $mer_id)->order('sort DESC')->column('pid,attachment_category_name', 'attachment_category_id');
+    }
+
+    /**
+     * @param int $merId
+     * @param int $id
+     * @param null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function merExists(int $merId, int $id, $except = null)
+    {
+        return $this->merFieldExists($merId, $this->getPk(), $id, $except);
+    }
+
+    /**
+     * @param int $merId
+     * @param $field
+     * @param $value
+     * @param null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function merFieldExists(int $merId, $field, $value, $except = null)
+    {
+        return ($this->getModel())::getDB()->when($except, function ($query, $except) use ($field) {
+                $query->where($field, '<>', $except);
+            })->where('mer_id', $merId)->where($field, $value)->count() > 0;
+    }
+
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function get($id, $merId = 0)
+    {
+        return ($this->getModel())::getDB()->where('mer_id', $merId)->find($id);
+    }
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function delete(int $id, $merId = 0)
+    {
+        return ($this->getModel())::getDB()->where($this->getPk(), $id)->where('mer_id', $merId)->delete();
+    }
+
+    /**
+     * @param string $oldPath
+     * @param string $path
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-30
+     */
+    public function updatePath(string $oldPath, string $path)
+    {
+        AttachmentCategory::getDB()->whereLike('path', $oldPath . '%')->field('attachment_category_id,path')->select()->each(function ($val) use ($oldPath, $path) {
+            $newPath = str_replace($oldPath, $path, $val['path']);
+            if (substr_count(trim($newPath, '/'), '/') > 1) throw new ValidateException('素材分类最多添加三级');
+            AttachmentCategory::getDB()->where('attachment_category_id', $val['attachment_category_id'])->update(['path' => $newPath]);
+        });
+    }
+}

+ 120 - 0
app/common/dao/system/attachment/AttachmentDao.php

@@ -0,0 +1,120 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\attachment;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\attachment\Attachment;
+use think\db\BaseQuery;
+use think\db\exception\DbException;
+
+/**
+ * Class AttachmentDao
+ * @package app\common\dao\system\attachment
+ * @author xaboy
+ * @day 2020-04-16
+ */
+class AttachmentDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return Attachment::class;
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function search(array $where)
+    {
+        $query = Attachment::getDB()->order('create_time DESC');
+        if (isset($where['user_type'])) $query->where('user_type', (int)$where['user_type']);
+        if (isset($where['upload_type'])) $query->where('upload_type', (int)$where['upload_type']);
+        if (isset($where['attachment_category_id']) && $where['attachment_category_id'])
+            $query->where('attachment_category_id', (int)$where['attachment_category_id']);
+        if (isset($where['attachment_name']) && $where['attachment_name'])
+            $query->whereLike('attachment_name', "%{$where['attachment_name']}%");
+
+        $query->order('create_time DESC');
+
+        return $query;
+    }
+
+    /**
+     * @param int $id
+     * @param int $userType
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-04-16
+     */
+    public function delete(int $id, $userType = 0)
+    {
+        return ($this->getModel())::getDB()->where('user_type', $userType)->where($this->getPk(), $id)->delete();
+    }
+
+    /**
+     * @param array $ids
+     * @param int $userType
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-04-15
+     */
+    public function batchDelete(array $ids, $userType = 0)
+    {
+        return ($this->getModel())::getDB()->where('user_type', $userType)->whereIn($this->getPk(), $ids)->delete();
+    }
+
+    /**
+     * @param int $id
+     * @param int $userType
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-16
+     */
+    public function exists(int $id, $userType = 0)
+    {
+        return ($this->getModel())::getDB()->where($this->getPk(), $id)->count() > 0;
+    }
+
+    /**
+     * @param array $ids
+     * @param array $data
+     * @param int $user_type
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-04-16
+     */
+    public function batchChange(array $ids, array $data, int $user_type = 0)
+    {
+        return ($this->getModel())::getDB()->where('user_type', $user_type)->whereIn($this->getPk(), $ids)->update($data);
+    }
+
+    public function clearCache()
+    {
+        return Attachment::getDB()->where('user_type', -1)->delete();
+    }
+}
+

+ 162 - 0
app/common/dao/system/config/SystemConfigClassifyDao.php

@@ -0,0 +1,162 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\config;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\config\SystemConfigClassify;
+use think\Collection;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+/**
+ * Class SystemConfigClassifyDao
+ * @package app\common\dao\system\config
+ * @author xaboy
+ * @day 2020-03-27
+ */
+class SystemConfigClassifyDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return SystemConfigClassify::class;
+    }
+
+    /**
+     * @return array
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function getOptions()
+    {
+        return SystemConfigClassify::column('pid,classify_name', 'config_classify_id');
+    }
+
+    /**
+     * @return array
+     * @author xaboy
+     * @day 2020-04-22
+     */
+    public function getTopOptions()
+    {
+        return SystemConfigClassify::getDB()->where('pid', 0)->column('classify_name', 'config_classify_id');
+    }
+
+    /**
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-03-31
+     */
+    public function all()
+    {
+        return SystemConfigClassify::getDB()->select();
+    }
+
+    /**
+     * @return int
+     * @author xaboy
+     * @day 2020-03-31
+     */
+    public function count()
+    {
+        return SystemConfigClassify::getDB()->count();
+    }
+
+    /**
+     * @param int $pid
+     * @param string $field
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function children(int $pid, string $field = 'id,classify_name')
+    {
+        return SystemConfigClassify::getDB()->where('pid', $pid)->field($field)->select();
+    }
+
+    /**
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function existsChild(int $id): bool
+    {
+        return $this->fieldExists('pid', $id);
+    }
+
+    /**
+     * @param $key
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function keyExists($key, ?int $except = null): bool
+    {
+        return $this->fieldExists('classify_key', $key, $except);
+    }
+
+    /**
+     * @param int $pid
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function pidExists(int $pid, ?int $except = null): bool
+    {
+        return $this->fieldExists('config_classify_id', $pid, $except);
+    }
+
+    /**
+     * @param string $key
+     * @return mixed
+     * @author xaboy
+     * @day 2020-04-22
+     */
+    public function keyById(string $key)
+    {
+        return SystemConfigClassify::getDB()->where('classify_key', $key)->value('config_classify_id');
+    }
+
+    /**
+     * @param string $key
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-22
+     */
+    public function keyByData(string $key)
+    {
+        return SystemConfigClassify::getDB()->where('classify_key', $key)->find();
+    }
+}

+ 111 - 0
app/common/dao/system/config/SystemConfigDao.php

@@ -0,0 +1,111 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\config;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\config\SystemConfig;
+use think\Collection;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+
+/**
+ * Class SystemConfigDao
+ * @package app\common\dao\system\config
+ * @author xaboy
+ * @day 2020-03-27
+ */
+class SystemConfigDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return SystemConfig::class;
+    }
+
+    /**
+     * @param int $classify_id
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function classifyIdExists(int $classify_id)
+    {
+        return $this->fieldExists('config_classify_id', $classify_id);
+    }
+
+    /**
+     * @param $key
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function keyExists($key, ?int $except = null): bool
+    {
+        return $this->fieldExists('config_key', $key, $except);
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-03-31
+     */
+    public function search(array $where)
+    {
+        $query = SystemConfig::getDB();
+        if ($where['keyword'])
+            $query->where('config_name|config_key', '%' . $where['keyword'] . '%');
+        if (isset($where['pid']) && $where['pid'] !== '') $query->where('config_classify_id', $where['pid']);
+        if (isset($where['config_classify_id']))
+            $query->where('config_classify_id', $where['config_classify_id']);
+        return $query;
+    }
+
+    /**
+     * @param int $cid
+     * @param int $user_type
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-23
+     */
+    public function cidByConfig(int $cid, int $user_type)
+    {
+        return SystemConfig::getDB()->where('config_classify_id', $cid)->where('user_type', $user_type)->where('status', 1)->select();
+    }
+
+    /**
+     * @param int $cid
+     * @param $keys
+     * @return array
+     * @author xaboy
+     * @day 2020-04-22
+     */
+    public function intersectionKey(int $cid, $keys): array
+    {
+        return SystemConfig::where('config_classify_id', $cid)->whereIn('config_key', $keys)->where('status', 1)->column('config_type,config_name', 'config_key');
+    }
+}

+ 113 - 0
app/common/dao/system/config/SystemConfigValueDao.php

@@ -0,0 +1,113 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\config;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\config\SystemConfigValue;
+use think\db\exception\DbException;
+
+/**
+ * Class SystemConfigValueDao
+ * @package app\common\dao\system\config
+ * @author xaboy
+ * @day 2020-03-27
+ */
+class SystemConfigValueDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return SystemConfigValue::class;
+    }
+
+    /**
+     * @param int $merId
+     * @param string $key
+     * @param array $data
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function merUpdate(int $merId, string $key, array $data)
+    {
+        if (isset($data['value'])) $data['value'] = json_encode($data['value']);
+        return SystemConfigValue::getDB()->where('mer_id', $merId)->where('config_key', $key)->update($data);
+    }
+
+    /**
+     * @param array $keys
+     * @param int $merId
+     * @return array
+     * @author xaboy
+     * @day 2020-04-22
+     */
+    public function fields(array $keys, int $merId)
+    {
+        $result = SystemConfigValue::getDB()->whereIn('config_key', $keys)->where('mer_id', $merId)->withAttr('value', function ($val, $data) {
+            return json_decode($val, true);
+        })->column('value', 'config_key');
+        foreach ($result as $k => $val) {
+            $result[$k] = json_decode($val, true);
+        }
+        return $result;
+    }
+
+    /**
+     * @param array $keys
+     * @param int $merId
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-05-18
+     */
+    public function clear(array $keys, int $merId)
+    {
+        return SystemConfigValue::getDB()->whereIn('config_key', $keys)->where('mer_id', $merId)->delete();
+    }
+
+
+    /**
+     * @param string $key
+     * @param int $merId
+     * @return mixed|null
+     * @author xaboy
+     * @day 2020-05-08
+     */
+    public function value(string $key, int $merId)
+    {
+        $value = SystemConfigValue::getDB()->where('config_key', $key)->where('mer_id', $merId)->value('value');
+        $value = is_null($value) ? null : json_decode($value, true);
+        return $value;
+    }
+
+    /**
+     * @param string $key
+     * @param int $merId
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function merExists(string $key, int $merId): bool
+    {
+        return SystemConfigValue::getDB()->where('config_key', $key)->where('mer_id', $merId)->count() > 0;
+    }
+}

+ 69 - 0
app/common/dao/system/financial/FinancialDao.php

@@ -0,0 +1,69 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\financial;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\system\financial\Financial;
+
+class FinancialDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return Financial::class;
+    }
+
+    public function search(array $where)
+    {
+        $query = Financial::hasWhere('merchant',function($query) use ($where){
+            $query->when(isset($where['is_trader']) && $where['is_trader'] !=='',function($query) use($where){
+                $query->where('is_trader',$where['is_trader']);
+            });
+            $query->where('is_del',0);
+        });
+
+        $query->when(isset($where['status']) && $where['status'] !=='',function($query) use($where){
+                $query->where('Financial.status',$where['status']);
+            })
+            ->when(isset($where['financial_type']) && $where['financial_type'] !=='',function($query) use($where){
+                $query->where('Financial.financial_type',$where['financial_type']);
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !=='',function($query) use($where){
+                $query->where('Financial.mer_id',$where['mer_id']);
+            })
+            ->when(isset($where['financial_status']) && $where['financial_status'] !=='',function($query) use($where){
+                $query->where('Financial.financial_status',$where['financial_status']);
+            })
+            ->when(isset($where['keyword']) && $where['keyword'] !=='',function($query) use($where){
+                $query->join('SystemAdmin A','Financial.admin_id = A.admin_id')->field('A.real_name,A.admin_id')->whereLike('A.real_name',"%{$where['keyword']}%");
+            })
+            ->when(isset($where['keywords_']) && $where['keywords_'] !=='',function($query) use($where){
+                $query->join('MerchantAdmin M','Financial.mer_admin_id = M.merchant_admin_id')->field('M.real_name,M.merchant_admin_id')->whereLike('M.real_name',"%{$where['keywords_']}%");
+            })
+            ->when(isset($where['financial_id']) && $where['financial_id'] !=='',function($query) use($where){
+                $query->where('Financial.financial_id',$where['financial_id']);
+            })
+            ->when(isset($where['date']) && $where['date'] !=='',function($query) use($where){
+                getModelTime($query,$where['date'],'Financial.create_time');
+            })
+            ->when(isset($where['is_del']) && $where['is_del'] !=='',function($query) use($where){
+                $query->where('Financial.is_del',$where['is_del']);
+            });
+        $query->order('Financial.create_time DESC');
+
+        return $query;
+    }
+
+}

+ 114 - 0
app/common/dao/system/groupData/GroupDao.php

@@ -0,0 +1,114 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\groupData;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\system\groupData\SystemGroup;
+use think\Collection;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+
+
+/**
+ * Class GroupDao
+ * @package app\common\dao\system\groupData
+ * @author xaboy
+ * @day 2020-03-27
+ */
+class GroupDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return SystemGroup::class;
+    }
+
+
+    /**
+     * @return Collection
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-01
+     */
+    public function all()
+    {
+        return SystemGroup::getDB()->select();
+    }
+
+    /**
+     * @return int
+     * @author xaboy
+     * @day 2020-04-01
+     */
+    public function count()
+    {
+        return SystemGroup::getDB()->count();
+    }
+
+    /**
+     * @param $page
+     * @param $limit
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-04-01
+     */
+    public function page($page, $limit)
+    {
+        return SystemGroup::getDB()->page($page, $limit);
+    }
+
+    /**
+     * @param $key
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-27
+     */
+    public function keyExists($key, ?int $except = null): bool
+    {
+        return parent::fieldExists('group_key', $key, $except);
+    }
+
+    /**
+     * @param $id
+     * @return mixed
+     * @author xaboy
+     * @day 2020-04-02
+     */
+    public function fields($id)
+    {
+        return json_decode(SystemGroup::getDB()->where('group_id', $id)->value('fields'), true);
+    }
+
+    /**
+     * @param string $key
+     * @return mixed
+     * @author xaboy
+     * @day 2020/5/27
+     */
+    public function keyById(string $key)
+    {
+        return SystemGroup::getDB()->where('group_key', $key)->value('group_id');
+    }
+}

+ 172 - 0
app/common/dao/system/groupData/GroupDataDao.php

@@ -0,0 +1,172 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\groupData;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\groupData\SystemGroupData;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+/**
+ * Class GroupDataDao
+ * @package app\common\dao\system\groupData
+ * @author xaboy
+ * @day 2020-03-27
+ */
+class GroupDataDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return SystemGroupData::class;
+    }
+
+    /**
+     * @param $merId
+     * @param $groupId
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    public function getGroupDataWhere($merId, $groupId): BaseQuery
+    {
+        return SystemGroupData::getDB()->withAttr('value', function ($val) {
+            return json_decode($val, true);
+        })->where('mer_id', $merId)->where('group_id', $groupId)->order('sort DESC');
+    }
+
+    /**
+     * @param $merId
+     * @param $groupId
+     * @param int|null $page
+     * @param int|null $limit
+     * @return array
+     * @author xaboy
+     * @day 2020/5/27
+     */
+    public function getGroupData($merId, $groupId, ?int $page = null, ?int $limit = 10)
+    {
+        $query = SystemGroupData::getDB()->where('mer_id', $merId)->where('group_id', $groupId)->where('status', 1)->order('sort DESC');
+        if (!is_null($page)) $query->page($page, $limit);
+        $groupData = [];
+        foreach ($query->column('value') as $k => $v) {
+            $groupData[] = json_decode($v, true);
+        }
+        return $groupData;
+    }
+
+    public function groupDataCount($merId, $groupId)
+    {
+        return SystemGroupData::getDB()->where('mer_id', $merId)->where('group_id', $groupId)->where('status', 1)->count();
+    }
+
+    /**
+     * @param $merId
+     * @param $groupId
+     * @param int|null $page
+     * @param int|null $limit
+     * @return array
+     * @author xaboy
+     * @day 2020/6/3
+     */
+    public function getGroupDataId($merId, $groupId, ?int $page = null, ?int $limit = 10)
+    {
+        $query = SystemGroupData::getDB()->where('mer_id', $merId)->where('group_id', $groupId)->where('status', 1)->order('sort DESC');
+        if (!is_null($page)) $query->page($page, $limit);
+        $groupData = [];
+        foreach ($query->column('value', 'group_data_id') as $k => $v) {
+            $groupData[] = ['id' => $k, 'data' => json_decode($v, true)];
+        }
+        return $groupData;
+    }
+
+    /**
+     * @param $merId
+     * @param $id
+     * @param $data
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    public function merUpdate($merId, $id, $data)
+    {
+        $data['value'] = json_encode($data['value']);
+        return SystemGroupData::getDB()->where('group_data_id', $id)->where('mer_id', $merId)->update($data);
+    }
+
+    /**
+     * @param $merId
+     * @param $id
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    public function merDelete($merId, $id)
+    {
+        return SystemGroupData::getDB()->where('mer_id', $merId)->where('group_data_id', $id)->delete();
+    }
+
+    /**
+     * @param int $merId
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-02
+     */
+    public function merExists(int $merId, int $id)
+    {
+        return ($this->getModel())::getDB()->where('mer_id', $merId)->where($this->getPk(), $id)->count() > 0;
+    }
+
+    /**
+     * @param int $groupId
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-05-16
+     */
+    public function clearGroup(int $groupId)
+    {
+        return SystemGroupData::getDB()->where('group_id', $groupId)->delete();
+    }
+
+    /**
+     * @param $id
+     * @param $merId
+     * @return array|Model|null
+     * @throws DbException
+     * @throws DataNotFoundException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/6/2
+     */
+    public function merGet($id, $merId)
+    {
+        $data = SystemGroupData::getDB()->where('group_data_id', $id)->where('mer_id', $merId)->find();
+        return $data ? $data['value'] : null;
+    }
+
+}

+ 328 - 0
app/common/dao/system/menu/MenuDao.php

@@ -0,0 +1,328 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\menu;
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\auth\Menu;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\Model;
+
+/**
+ * Class MenuDao
+ * @package app\common\dao\system\menu
+ * @author xaboy
+ * @day 2020-04-08
+ */
+class MenuDao extends BaseDao
+{
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return Menu::class;
+    }
+
+    /**
+     * @param array $where
+     * @param int $is_mer
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function search(array $where, int $is_mer = 0)
+    {
+        $query = Menu::getDB()->where('is_mer', $is_mer)->order('sort DESC,menu_id ASC');
+        if (isset($where['pid'])) $query->where('pid', (int)$where['pid']);
+        if (isset($where['keyword'])) $query->whereLike('menu_name|route', "%{$where['keyword']}%");
+        if (isset($where['is_menu'])) $query->where('is_menu', (int)$where['is_menu']);
+        return $query;
+    }
+
+
+    /**
+     * @param int $is_mer
+     * @return array
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function getAllMenu($is_mer = 0)
+    {
+        return Menu::getDB()->where('is_mer', $is_mer)->where('is_menu', 1)->order('sort DESC,menu_id ASC')->select()->toArray();
+    }
+
+    /**
+     * @param int $is_mer
+     * @return array
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function getAll($is_mer = 0)
+    {
+        return Menu::getInstance()->where('is_mer', $is_mer)->order('sort DESC,menu_id ASC')->select()->toArray();
+    }
+
+    /**
+     * @param int $id
+     * @param int $is_mer
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function menuExists(int $id, $is_mer = 0)
+    {
+        return Menu::getDB()->where($this->getPk(), $id)->where('is_menu', 1)->where('is_mer', $is_mer)->count() > 0;
+    }
+
+    /**
+     * @param int $id
+     * @param int $is_mer
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-16
+     */
+    public function merExists(int $id, $is_mer = 0)
+    {
+        return Menu::getDB()->where($this->getPk(), $id)->where('is_mer', $is_mer)->count() > 0;
+    }
+
+    /**
+     * @param int $id
+     * @param int $is_mer
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function authExists(int $id, $is_mer = 0)
+    {
+        return Menu::getDB()->where($this->getPk(), $id)->where('is_menu', 0)->where('is_mer', $is_mer)->count() > 0;
+    }
+
+    /**
+     * @param string $route
+     * @param int $is_mer
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function routeExists(string $route, $is_mer = 0)
+    {
+        return Menu::getDB()->where('route', $route)->where('is_menu', 0)->where('is_mer', $is_mer)->count() > 0;
+    }
+
+    /**
+     * @param int $is_mer
+     * @return array
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function getAllMenuOptions($is_mer = 0)
+    {
+        return Menu::getDB()->where('is_menu', 1)->where('is_mer', $is_mer)->order('sort DESC,menu_id ASC')->column('menu_name,pid', 'menu_id');
+    }
+
+    /**
+     * @param array $rule
+     * @param int $is_mer
+     * @return array
+     * @author xaboy
+     * @day 2020-04-10
+     */
+    public function ruleByMenuList(array $rule, $is_mer = 0)
+    {
+        $paths = Menu::getDB()->whereIn($this->getPk(), $rule)->column('path', 'menu_id');
+        $ids = [];
+        foreach ($paths as $id => $path) {
+            $ids = array_merge($ids, explode('/', trim($path, '/')));
+            array_push($ids, $id);
+        }
+        return Menu::getDB()->where('is_menu', 1)->where('is_show', 1)->order('sort DESC,menu_id ASC')->where('is_mer', $is_mer)
+            ->whereIn('menu_id', array_unique(array_filter($ids)))
+            ->column('menu_name,route,params,icon,pid,menu_id');
+    }
+
+    /**
+     * @param int $is_mer
+     * @return array
+     * @author xaboy
+     * @day 2020-04-10
+     */
+    public function getValidMenuList($is_mer = 0)
+    {
+        return Menu::getDB()->where('is_menu', 1)->where('is_show', 1)->order('sort DESC,menu_id ASC')->where('is_mer', $is_mer)
+            ->column('menu_name,route,params,icon,pid,menu_id');
+    }
+
+    /**
+     * @param int $is_mer
+     * @return array
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function getAllOptions($is_mer = 0)
+    {
+        return Menu::getDB()->where('is_mer', $is_mer)->order('sort DESC,menu_id ASC')->column('menu_name,pid', 'menu_id');
+    }
+
+    /**
+     * @param $id
+     * @param int $is_mer
+     * @return mixed
+     * @author xaboy
+     * @day 2020-04-09
+     */
+    public function getPath($id, $is_mer = 0)
+    {
+        return Menu::getDB()->where('is_mer', $is_mer)->where('menu_id', $id)->value('path');
+    }
+
+    /**
+     * @param int $id
+     * @param int $is_mer
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function getMenu(int $id, $is_mer = 0)
+    {
+        return Menu::getDB()->where('is_mer', $is_mer)->where('is_menu', 1)->where($this->getPk(), $id)->find();
+    }
+
+    /**
+     * @param int $id
+     * @param int $is_mer
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function getAuth(int $id, $is_mer = 0)
+    {
+        return Menu::getDB()->where('is_mer', $is_mer)->where('is_menu', 0)->where($this->getPk(), $id)->find();
+    }
+
+    /**
+     * @param int $id
+     * @param int $is_mer
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function delete(int $id, $is_mer = 0)
+    {
+        return Menu::getDB()->where('is_mer', $is_mer)->delete($id);
+    }
+
+    /**
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-08
+     */
+    public function pidExists(int $id)
+    {
+        return $this->fieldExists('pid', $id);
+    }
+
+    /**
+     * @param array $ids
+     * @return array
+     * @author xaboy
+     * @day 2020-04-10
+     */
+    public function idsByRoutes(array $ids)
+    {
+        return Menu::getDB()->where('is_menu', 0)->whereIn($this->getPk(), $ids)->column('params,route');
+    }
+
+    /**
+     * @param string $oldPath
+     * @param string $path
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-30
+     */
+    public function updatePath(string $oldPath, string $path)
+    {
+        Menu::getDB()->whereLike('path', $oldPath . '%')->field('menu_id,path')->select()->each(function ($val) use ($oldPath, $path) {
+            $newPath = str_replace($oldPath, $path, $val['path']);
+            Menu::getDB()->where('menu_id', $val['menu_id'])->update(['path' => $newPath]);
+        });
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/26
+     * @param $field
+     * @param $value
+     * @return array|Model|null
+     */
+    public function getFieldExists($field,$value)
+    {
+        return (($this->getModel()::getDB())->where($field,$value)->find());
+    }
+
+    /**
+     * @Author:Qinii
+     * @Date: 2020/5/26
+     * @param array $data
+     * @return int
+     */
+    public function insertAll(array $data)
+    {
+        return ($this->getModel()::getDB())->insertAll($data);
+    }
+
+    public function deleteCommandMenu($where)
+    {
+        $this->getModel()::getDB()->where($where)->delete();
+    }
+
+    public function all()
+    {
+        return ($this->getModel()::getDB())->select();
+    }
+
+    /**
+     *  根据每个路由分组获取是否存在父级
+     * @Author:Qinii
+     * @Date: 2020/9/8
+     * @param array $data
+     * @return mixed
+     */
+    public function getMenuPid(array $data)
+    {
+        return ($this->getModel()::getDB())->where('route','in',$data)->field('menu_id,pid,path')->order('path ASC')->select()->toArray();
+    }
+}

+ 101 - 0
app/common/dao/system/menu/RoleDao.php

@@ -0,0 +1,101 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\menu;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\auth\Role;
+
+/**
+ * Class RoleDao
+ * @package app\common\dao\system\menu
+ * @author xaboy
+ * @day 2020-04-18
+ */
+class RoleDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return Role::class;
+    }
+
+    /**
+     * @param $merId
+     * @param array $where
+     * @return BaseModel|Role
+     * @author xaboy
+     * @day 2020-04-18
+     */
+    public function search($merId, array $where = [])
+    {
+        $roleModel = Role::getInstance();
+
+        if (isset($where['role_name'])) {
+            $roleModel = $roleModel->whereLike('role_name', '%' . $where['role_name'] . '%');
+        }
+
+        if (isset($where['status'])) {
+            $roleModel = $roleModel->where('status', intval($where['status']));
+        }
+        return $roleModel->where('mer_id', $merId);
+    }
+
+    /**
+     * @param int $merId
+     * @return array
+     * @author xaboy
+     * @day 2020-04-18
+     */
+    public function getAllOptions(int $merId)
+    {
+        return Role::getDB()->where('status', 1)->where('mer_id', $merId)->column('role_name', 'role_id');
+    }
+
+    /**
+     * @param $merId
+     * @param array $ids
+     * @return array
+     * @author xaboy
+     * @day 2020-04-18
+     */
+    public function idsByRules($merId, array $ids)
+    {
+        $rules = Role::getDB()->where('status', 1)->where('mer_id', $merId)->whereIn($this->getPk(), $ids)->column('rules');
+        $data = [];
+        foreach ($rules as $rule) {
+            $data = array_merge(explode(',', $rule), $data);
+        }
+        return array_unique($data);
+    }
+
+    /**
+     * @param int $merId
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-18
+     */
+    public function merExists(int $merId, int $id)
+    {
+        return Role::getDB()->where($this->getPk(), $id)->where('mer_id', $merId)->count() > 0;
+    }
+}
+

+ 88 - 0
app/common/dao/system/merchant/FinancialRecordDao.php

@@ -0,0 +1,88 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\merchant;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\system\merchant\FinancialRecord;
+
+class FinancialRecordDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return FinancialRecord::class;
+    }
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    public function getSn()
+    {
+        list($msec, $sec) = explode(' ', microtime());
+        $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
+        $orderId = 'jy' . $msectime . mt_rand(10000, max(intval($msec * 10000) + 10000, 98369));
+        return $orderId;
+    }
+
+    public function inc(array $data, $merId)
+    {
+        $data['mer_id'] = $merId;
+        $data['financial_pm'] = 1;
+        $data['financial_record_sn'] = $this->getSn();
+        return $this->create($data);
+    }
+
+    public function dec(array $data, $merId)
+    {
+        $data['mer_id'] = $merId;
+        $data['financial_pm'] = 0;
+        $data['financial_record_sn'] = $this->getSn();
+        return $this->create($data);
+    }
+
+    public function search(array $where)
+    {
+        $query = $this->getModel()::getDB()
+            ->when(isset($where['financial_type']) && $where['financial_type'] !== '', function ($query) use ($where) {
+                $query->whereIn('financial_type', $where['financial_type']);
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+                $query->where('mer_id', $where['mer_id']);
+            })
+            ->when(isset($where['user_info']) && $where['user_info'] !== '', function ($query) use ($where) {
+                $query->where('user_info', $where['user_info']);
+            })
+            ->when(isset($where['user_id']) && $where['user_id'] !== '', function ($query) use ($where) {
+                $query->where('user_id', $where['user_id']);
+            })
+            ->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+                $query->whereLike('order_sn|user_info|financial_record_sn', "%{$where['keyword']}%");
+            })
+            ->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+                getModelTime($query, $where['date'], 'create_time');
+            })
+            ->when(isset($where['is_mer']) && $where['is_mer'] !== '', function ($query) use ($where) {
+                if($where['is_mer']){
+                    $query->where('mer_id',$where['is_mer'])->where('type','in',[0,1]);
+                }else{
+                    $query->where('type','in',[1,2]);
+                }
+            });
+        return $query;
+    }
+
+}

+ 218 - 0
app/common/dao/system/merchant/MerchantAdminDao.php

@@ -0,0 +1,218 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\merchant;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\system\merchant\MerchantAdmin;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\facade\Db;
+use think\Model;
+
+/**
+ * Class MerchantAdminDao
+ * @package app\common\dao\system\merchant
+ * @author xaboy
+ * @day 2020-04-17
+ */
+class MerchantAdminDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020-04-16
+     */
+    protected function getModel(): string
+    {
+        return MerchantAdmin::class;
+    }
+
+    /**
+     * @param int $merId
+     * @param array $where
+     * @param int|null $level
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-04-18
+     */
+    public function search(int $merId, array $where = [], ?int $level = null)
+    {
+        $query = MerchantAdmin::getDB()->where('is_del', 0)->where('mer_id', $merId)
+            ->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+                getModelTime($query, $where['date']);
+            });
+
+        if (!is_null($level)) $query->where('level', $level);
+
+        if (isset($where['keyword']) && $where['keyword'] !== '') {
+            $query = $query->whereLike('real_name|account', '%' . $where['keyword'] . '%');
+        }
+
+        if (isset($where['status']) && $where['status'] !== '') {
+            $query = $query->where('status', intval($where['status']));
+        }
+
+        return $query;
+    }
+
+    /**
+     * @param int $merId
+     * @return string
+     * @author xaboy
+     * @day 2020-04-16
+     */
+    public function merIdByAccount(int $merId): string
+    {
+        return MerchantAdmin::getDB()->where('mer_id', $merId)->where('level', 0)->value('account');
+    }
+
+    /**
+     * @param int $merId
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020/7/7
+     */
+    public function merIdByAdmin(int $merId)
+    {
+        return MerchantAdmin::getDB()->where('mer_id', $merId)->where('level', 0)->find();
+    }
+
+    /**
+     * @param string $account
+     * @param int $merId
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function accountByAdmin(string $account, int $merId)
+    {
+        return MerchantAdmin::getInstance()->where('account', $account)
+            ->where('is_del', 0)->where('mer_id', $merId)
+            ->field(['account', 'pwd', 'real_name', 'login_count', 'merchant_admin_id', 'status', 'mer_id'])
+            ->find();
+    }
+
+    /**
+     * @param string $account
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function accountByTopAdmin(string $account)
+    {
+        return MerchantAdmin::getInstance()->where('account', $account)
+            ->where('is_del', 0)->where('level', 0)
+            ->field(['account', 'pwd', 'real_name', 'login_count', 'merchant_admin_id', 'status', 'mer_id'])
+            ->find();
+    }
+
+    /**
+     * @param string $account
+     * @return mixed
+     * @author xaboy
+     * @day 2020-04-20
+     */
+    public function accountByMerchantId(string $account)
+    {
+        return MerchantAdmin::getInstance()->where('account', $account)->value('mer_id');
+    }
+
+
+    /**
+     * @param int $id
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-17
+     */
+    public function get( $id)
+    {
+        return MerchantAdmin::getInstance()->where('is_del', 0)->find($id);
+    }
+
+    /**
+     * @param int $id
+     * @param int $merId
+     * @param int|null $level
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-18
+     */
+    public function exists(int $id, int $merId = 0, ?int $level = null)
+    {
+        $query = MerchantAdmin::getDB()->where($this->getPk(), $id)->where('is_del', 0);
+        if ($merId) $query->where('mer_id', $merId);
+        if (!is_null($level)) $query->where('level', $level);
+        return $query->count() > 0;
+    }
+
+    /**
+     * @param int $merId
+     * @param $field
+     * @param $value
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-18
+     */
+    public function merFieldExists(int $merId, $field, $value, ?int $except = null): bool
+    {
+        $query = MerchantAdmin::getDB()->where($field, $value)->where('mer_id', $merId);
+        if (!is_null($except)) $query->where($this->getPk(), '<>', $except);
+        return $query->count() > 0;
+    }
+
+    /**
+     * @param int $id
+     * @return bool
+     * @author xaboy
+     * @day 2020-04-18
+     */
+    public function topExists(int $id)
+    {
+        $query = MerchantAdmin::getDB()->where($this->getPk(), $id)->where('is_del', 0)->where('level', 0);
+        return $query->count() > 0;
+    }
+
+    /**
+     * @param int $merId
+     * @return mixed
+     * @author xaboy
+     * @day 2020-04-17
+     */
+    public function merchantIdByTopAdminId(int $merId)
+    {
+        return MerchantAdmin::getDB()->where('mer_id', $merId)->where('is_del', 0)->where('level', 0)->value('merchant_admin_id');
+    }
+
+    public function deleteMer($merId)
+    {
+        MerchantAdmin::getDB()->where('mer_id', $merId)->update(['account' => Db::raw('CONCAT(`account`,\'$del\')')]);
+    }
+}

+ 77 - 0
app/common/dao/system/merchant/MerchantCategoryDao.php

@@ -0,0 +1,77 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\merchant;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\merchant\MerchantCategory;
+use think\db\BaseQuery;
+use think\facade\Db;
+
+/**
+ * Class MerchantCategoryDao
+ * @package app\common\dao\system\merchant
+ * @author xaboy
+ * @day 2020-05-06
+ */
+class MerchantCategoryDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return MerchantCategory::class;
+    }
+
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-05-06
+     */
+    public function search(array $where = [])
+    {
+        return MerchantCategory::getDB();
+    }
+
+    /**
+     * @return array
+     * @author xaboy
+     * @day 2020-05-06
+     */
+    public function allOptions()
+    {
+        return MerchantCategory::getDB()->column('category_name', 'merchant_category_id');
+    }
+
+    public function dateMerchantPriceGroup($date, $limit = 4)
+    {
+        return MerchantCategory::getDB()->alias('A')->leftJoin('Merchant B', 'A.merchant_category_id = B.category_id')
+            ->leftJoin('StoreOrder C', 'C.mer_id = B.mer_id')->field(Db::raw('sum(C.pay_price) as pay_price,A.category_name'))
+            ->when($date, function ($query, $date) {
+                getModelTime($query, $date, 'C.pay_time');
+            })->group('A.merchant_category_id')->where('pay_price', '>', 0)->order('pay_price DESC')->limit($limit)->select();
+    }
+
+    public function names(array $ids)
+    {
+        return MerchantCategory::getDB()->whereIn('merchant_category_id', $ids)->column('category_name');
+    }
+}

+ 245 - 0
app/common/dao/system/merchant/MerchantDao.php

@@ -0,0 +1,245 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\merchant;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\system\merchant\Merchant;
+use crmeb\services\VicWordService;
+use think\db\BaseQuery;
+use think\db\exception\DataNotFoundException;
+use think\db\exception\DbException;
+use think\db\exception\ModelNotFoundException;
+use think\facade\Db;
+use think\Model;
+
+class MerchantDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020-04-16
+     */
+    protected function getModel(): string
+    {
+        return Merchant::class;
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-04-16
+     */
+    public function search(array $where, $is_del = 0)
+    {
+        $query = Merchant::getDB()
+            ->when($is_del !== null, function ($query) use ($is_del) {
+                $query->where('is_del', $is_del);
+            })
+            ->when(isset($where['is_trader']) && $where['is_trader'] !== '', function ($query) use ($where) {
+                $query->where('is_trader', $where['is_trader']);
+            })
+            ->when(isset($where['is_best']) && $where['is_best'] !== '', function ($query) use ($where) {
+                $query->where('is_best', $where['is_best']);
+            })
+            ->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+                getModelTime($query, $where['date']);
+            })
+            ->when(isset($where['mer_state']) && $where['mer_state'] !== '', function ($query) use ($where) {
+                $query->where('mer_state', $where['mer_state']);
+            })
+            ->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+                $query->where('mer_id', $where['mer_id']);
+            })
+            ->when(isset($where['category_id']) && $where['category_id'] !== '', function ($query) use ($where) {
+                is_array($where['category_id']) ? $query->whereIn('category_id', $where['category_id']) : $query->where('category_id', $where['category_id']);
+            });
+
+        if (isset($where['keyword']) && $where['keyword']) {
+            if (is_numeric($where['keyword'])) {
+                $query->whereLike('mer_name|mer_keyword|mer_phone', "%{$where['keyword']}%");
+            } else {
+                $word = app()->make(VicWordService::class)->getWord($where['keyword']);
+                $query->where(function ($query) use ($word, $where) {
+                    foreach ($word as $item) {
+                        if(mb_strlen($item) > 1) {
+                            $query->whereOr('mer_name', 'LIKE', "%$item%");
+                        }
+                    }
+                    $query->whereOr('mer_name|mer_keyword', 'LIKE', "%{$where['keyword']}%");
+                });
+            }
+        }
+        if (isset($where['status']) && $where['status'] !== '')
+            $query->where('status', $where['status']);
+        $order = $where['order'] ?? '';
+        $query->when($order, function ($query) use ($where, $order) {
+            if ($order == 'rate') {
+                $query->order('is_best DESC, product_score DESC,service_score DESC,postage_score DESC');
+            } else if ($order == 'location' && isset($where['location']['long'], $where['location']['lat'])) {
+                $lng = (float)$where['location']['long'];
+                $lat = (float)$where['location']['lat'];
+                $query->whereNotNull('lat')->whereNotNull('long')
+                    ->order(Db::raw("(2 * 6378.137 * ASIN(
+	SQRT(
+	POW( SIN( PI( ) * ( $lng- `long` ) / 360 ), 2 ) + COS( PI( ) * $lat / 180 ) * COS( `lat` * PI( ) / 180 ) * POW( SIN( PI( ) * ( $lat- `lat` ) / 360 ), 2 ) 
+	) 
+	) 
+	) ASC "));
+            } else {
+                $query->order('is_best DESC, sales DESC,sort DESC');
+            }
+        }, function ($query) use ($order) {
+            $query->order('is_best DESC, sort DESC,sales DESC');
+        });
+        return $query;
+    }
+
+    /**
+     * @param int $id
+     * @return array|Model|null
+     * @throws DataNotFoundException
+     * @throws DbException
+     * @throws ModelNotFoundException
+     * @author xaboy
+     * @day 2020-04-17
+     */
+    public function get($id)
+    {
+        return Merchant::getInstance()->where('is_del', 0)->find($id);
+    }
+
+    /**
+     * @param $id
+     * @author Qinii
+     */
+    public function apiGetOne($id)
+    {
+        return Merchant::getInstance()->where(['is_del' => 0, 'status' => 1, 'mer_state' => 1])->find($id);
+    }
+
+    /**
+     * @param int $merId
+     * @author Qinii
+     */
+    public function incCareCount(int $merId)
+    {
+        ($this->getModel()::getDB())->where($this->getPk(), $merId)->inc('care_count', 1)->update();
+    }
+
+    /**
+     * @param int $merId
+     * @param int $inc
+     * @author xaboy
+     * @day 2020/9/25
+     */
+    public function incSales($merId, $inc)
+    {
+        ($this->getModel()::getDB())->where($this->getPk(), $merId)->inc('sales', $inc)->update();
+    }
+
+    /**
+     * @param int $merId
+     * @author Qinii
+     */
+    public function decCareCount(int $merId)
+    {
+        ($this->getModel()::getDB())->where($this->getPk(), $merId)->where('care_count', '>', 0)->dec('care_count', 1)->update();
+    }
+
+    public function dateMerchantNum($date)
+    {
+        return Merchant::getDB()->where('is_del', 0)->when($date, function ($query, $date) {
+            getModelTime($query, $date);
+        })->count();
+    }
+
+    /**
+     * TODO 获取复制商品次数
+     * @param int $merId
+     * @return mixed
+     * @author Qinii
+     * @day 2020-08-06
+     */
+    public function getCopyNum(int $merId)
+    {
+        return Merchant::getDB()->where('mer_id', $merId)->value('copy_product_num');
+    }
+
+    /**
+     * TODO 变更复制次数
+     * @param int $merId
+     * @param int $num 正负数
+     * @return mixed
+     * @author Qinii
+     * @day 2020-08-06
+     */
+    public function changeCopyNum(int $merId, int $num)
+    {
+        return $this->getModel()::where('mer_id', $merId)->inc('copy_product_num', $num)->update();
+    }
+
+    /**
+     * @param $field
+     * @param $value
+     * @param int|null $except
+     * @return bool
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    public function fieldExists($field, $value, ?int $except = null): bool
+    {
+        $query = ($this->getModel())::getDB()->where($field, $value);
+        if (!is_null($except)) $query->where($this->getPk(), '<>', $except);
+        return $query->where('is_del', 0)->count() > 0;
+    }
+
+    public function names(array $ids)
+    {
+        return Merchant::getDB()->whereIn('mer_id',$ids)->column('mer_name');
+    }
+
+    /**
+     * TODO 增加商户余额
+     * @param int $merId
+     * @param float $num
+     * @author Qinii
+     * @day 3/19/21
+     */
+    public function addMoney(int $merId,float $num)
+    {
+        $merchant = $this->getModel()::getDB()->where('mer_id', $merId)->find();
+        $mer_money = bcadd($merchant['mer_money'], $num, 2);
+        $merchant->mer_money = $mer_money;
+        $merchant->save();
+    }
+
+    /**
+     * TODO 减少商户余额
+     * @param int $merId
+     * @param float $num
+     * @author Qinii
+     * @day 3/19/21
+     */
+    public function subMoney(int $merId,float $num)
+    {
+        $merchant = $this->getModel()::getDB()->where('mer_id', $merId)->find();
+        $mer_money = bcsub($merchant['mer_money'], $num, 2);
+        $merchant->mer_money = $mer_money;
+        $merchant->save();
+    }
+
+}

+ 49 - 0
app/common/dao/system/merchant/MerchantIntentionDao.php

@@ -0,0 +1,49 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\merchant;
+
+use app\common\dao\BaseDao;
+use app\common\model\system\merchant\MerchantIntention;
+
+class MerchantIntentionDao extends BaseDao
+{
+    protected function getModel(): string
+    {
+        return MerchantIntention::class;
+    }
+
+    public function search(array $where)
+    {
+        $query = $this->getModel()::getDB()->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+            $query->where('mer_id', $where['mer_id']);
+        })->when(isset($where['uid']) && $where['uid'] !== '', function ($query) use ($where) {
+            $query->where('uid', $where['uid']);
+        })->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) {
+            $query->where('status', (int)$where['status']);
+        })->when(isset($where['mer_intention_id']) && $where['mer_intention_id'] !== '', function ($query) use ($where) {
+            $query->where('mer_intention_id', $where['mer_intention_id']);
+        })->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+            $query->where('mer_name|phone|mark', 'like', '%' . $where['keyword'] . '%');
+        })->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+            getModelTime($query, $where['date']);
+        })->where('is_del', 0);
+
+        return $query;
+    }
+
+    public function form($id, $data)
+    {
+        $this->getModel()::getDB()->where($this->getPk(), $id)->update(['status' => $data['status'], 'mark' => $data['mark']]);
+    }
+}

+ 36 - 0
app/common/dao/system/notice/SystemNoticeDao.php

@@ -0,0 +1,36 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\notice;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\system\notice\SystemNotice;
+
+class SystemNoticeDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return SystemNotice::class;
+    }
+
+    public function search(array $where)
+    {
+        return SystemNotice::getDB()->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+            $query->whereLike('notice_title|notice_content', '%' . $where['keyword'] . '%');
+        })->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+            getModelTime($query, $where['date'], 'create_time');
+        })->where('is_del', 0);
+    }
+}

+ 81 - 0
app/common/dao/system/notice/SystemNoticeLogDao.php

@@ -0,0 +1,81 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\notice;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\notice\SystemNoticeLog;
+
+/**
+ * Class SystemNoticeLogDao
+ * @package app\common\dao\system\notice
+ * @author xaboy
+ * @day 2020/11/6
+ */
+class SystemNoticeLogDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/11/6
+     */
+    protected function getModel(): string
+    {
+        return SystemNoticeLog::class;
+    }
+
+    /**
+     * @param $id
+     * @param $merId
+     * @return int
+     * @throws \think\db\exception\DbException
+     * @author xaboy
+     * @day 2020/11/6
+     */
+    public function read($id, $merId)
+    {
+        return SystemNoticeLog::getDB()->where('notice_log_id', $id)->where('mer_id', $merId)->update(['is_read' => 1, 'read_time' => date('Y-m-d H:i:s')]);
+    }
+
+    public function unreadCount($merId)
+    {
+        return SystemNoticeLog::getDB()->where('mer_id', $merId)->where('is_read', 0)->count();
+    }
+
+    /**
+     * @param $id
+     * @param $merId
+     * @return int
+     * @throws \think\db\exception\DbException
+     * @author xaboy
+     * @day 2020/11/6
+     */
+    public function del($id, $merId)
+    {
+        return SystemNoticeLog::getDB()->where('notice_log_id', $id)->where('mer_id', $merId)->delete();
+    }
+
+    public function search(array $where)
+    {
+        return SystemNoticeLog::getDB()->alias('A')->join('SystemNotice B', 'A.notice_id = B.notice_id')->where('mer_id', $where['mer_id'])->when(isset($where['is_read']) && $where['is_read'] !== '', function ($query) use ($where) {
+            $query->where('A.is_read', intval($where['is_read']));
+        })->when(isset($where['date']) && $where['date'] !== '', function ($query) use ($where) {
+            getModelTime($query, $where['date'], 'B.create_time');
+        })->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+            $query->whereLike('B.notice_title|B.notice_content', "%{$where['keyword']}%");
+        })->where('A.is_del', 0);
+    }
+}

+ 89 - 0
app/common/dao/system/sms/SmsRecordDao.php

@@ -0,0 +1,89 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\system\sms;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\system\sms\SmsRecord;
+use think\db\BaseQuery;
+use think\db\exception\DbException;
+
+/**
+ * Class SmsRecordDao
+ * @package app\common\dao\system\sms
+ * @author xaboy
+ * @day 2020-05-18
+ */
+class SmsRecordDao extends BaseDao
+{
+
+    /**
+     * @return BaseModel
+     * @author xaboy
+     * @day 2020-03-30
+     */
+    protected function getModel(): string
+    {
+        return SmsRecord::class;
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020-05-18
+     */
+    public function search(array $where)
+    {
+        return SmsRecord::getDB()->when(isset($where['type']) && $where['type'] !== '', function ($query) use ($where) {
+            $query->where('resultcode', $where['type']);
+        })->order('create_time DESC');
+    }
+
+    /**
+     * @return int
+     * @author xaboy
+     * @day 2020-05-18
+     */
+    public function count()
+    {
+        return SmsRecord::count($this->getPk());
+    }
+
+    /**
+     * @param $record_id
+     * @param $resultcode
+     * @return int
+     * @throws DbException
+     * @author xaboy
+     * @day 2020-05-18
+     */
+    public function updateRecordStatus($record_id, $resultcode)
+    {
+        return SmsRecord::getDB()->where('record_id', $record_id)->update(['resultcode' => $resultcode]);
+    }
+
+
+    /**
+     * @param $time
+     * @return array
+     * @author xaboy
+     * @day 2020/6/9
+     */
+    public function getTimeOutIds($time)
+    {
+        return SmsRecord::getDB()->where('resultcode', null)->where('create_time', '<=', $time)->column('record_id');
+    }
+}

+ 42 - 0
app/common/dao/user/FeedbackCateoryDao.php

@@ -0,0 +1,42 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\common\dao\user;
+
+use app\common\dao\BaseDao;
+use app\common\model\user\FeedBackCategory as model;
+use crmeb\traits\CategoresDao;
+
+class FeedbackCateoryDao extends BaseDao
+{
+
+    use CategoresDao;
+
+    /**
+     * @return string
+     * @author Qinii
+     */
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+    /**
+     * @return int
+     * @author Qinii
+     */
+    public function getMaxLevel()
+    {
+        return 2;
+    }
+
+}

+ 80 - 0
app/common/dao/user/FeedbackDao.php

@@ -0,0 +1,80 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\user;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\BaseModel;
+use app\common\model\user\Feedback;
+use think\db\BaseQuery;
+
+/**
+ * Class FeedbackDao
+ * @package app\common\dao\user
+ * @author xaboy
+ * @day 2020/5/28
+ */
+class FeedbackDao extends BaseDao
+{
+
+    /**
+     * @return string
+     * @author xaboy
+     * @day 2020/5/28
+     */
+    protected function getModel(): string
+    {
+        return Feedback::class;
+    }
+
+    /**
+     * @param array $where
+     * @return BaseQuery
+     * @author xaboy
+     * @day 2020/5/28
+     */
+    public function search(array $where)
+    {
+        return Feedback::getDB()->when(isset($where['uid']) && $where['uid'] !== '', function ($query) use ($where) {
+            $query->where('uid', $where['uid']);
+        })->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+            $query->where('content','like', '%'.$where['keyword'].'%')->whereOr('reply','like', '%'.$where['keyword'].'%')->whereOr('remake','like', '%'.$where['keyword'].'%');
+        })->when(isset($where['type']) && $where['type'] !== '', function ($query) use ($where) {
+            $query->where('type',$where['type']);
+        })->when(isset($where['status']) && $where['status'] !== '', function ($query) use ($where) {
+            $query->where('status', $where['status']);
+        })->when(isset($where['realname']) && $where['realname'] !== '', function ($query) use ($where) {
+            $query->where('realname','like', '%'.$where['realname'].'%');
+        })->when(isset($where['is_del']) && $where['is_del'] !== '', function ($query) use ($where) {
+            $query->where('is_del',$where['is_del']);
+        })->order('create_time DESC');
+    }
+
+    /**
+     * @param $id
+     * @param $uid
+     * @return bool
+     * @author xaboy
+     * @day 2020/5/28
+     */
+    public function uidExists($id, $uid): bool
+    {
+        return Feedback::getDB()->where($this->getPk(), $id)->where('uid', $uid)->where('is_del', 0)->count($this->getPk()) > 0;
+    }
+
+    public function merExists(int $id)
+    {
+        return $this->getModel()::getDB()->where($this->getPk(), $id)->where('is_del', 0)->count() > 0;
+    }
+}

+ 38 - 0
app/common/dao/user/LabelRuleDao.php

@@ -0,0 +1,38 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\user;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\user\LabelRule;
+
+class LabelRuleDao extends BaseDao
+{
+
+    protected function getModel(): string
+    {
+        return LabelRule::class;
+    }
+
+    public function search(array $where)
+    {
+        return LabelRule::hasWhere('label')->when(isset($where['keyword']) && $where['keyword'] !== '', function ($query) use ($where) {
+            $query->whereLike('UserLabel.label_name', "%{$where['keyword']}%");
+        })->when(isset($where['type']) && $where['type'] !== '', function ($query) use ($where) {
+            $query->where('LabelRule.type', intval($where['type']));
+        })->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) {
+            $query->where('LabelRule.mer_id', intval($where['mer_id']));
+        });
+    }
+}

+ 48 - 0
app/common/dao/user/UserAddressDao.php

@@ -0,0 +1,48 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+
+namespace app\common\dao\user;
+
+
+use app\common\dao\BaseDao;
+use app\common\model\user\UserAddress as model;
+
+class UserAddressDao extends BaseDao
+{
+
+
+    /**
+     * @return string
+     * @author Qinii
+     */
+    protected function getModel(): string
+    {
+        return model::class;
+    }
+
+
+    public function userFieldExists($field, $value,$uid): bool
+    {
+        return (($this->getModel()::getDB())->where('uid',$uid)->where($field,$value)->count()) > 0;
+    }
+
+    public function changeDefault(int $uid)
+    {
+        return ($this->getModel()::getDB())->where('uid',$uid)->update(['is_default' => 0]);
+    }
+
+    public function getAll(int $uid)
+    {
+        return (($this->getModel()::getDB())->where('uid',$uid));
+    }
+}

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