zhanglinxin 2 years ago
parent
commit
eb88f901b6
100 changed files with 17508 additions and 1 deletions
  1. 3 0
      .constant
  2. 1 0
      .htaccess
  3. 22 0
      .phpstorm.meta.php
  4. 42 0
      .travis.yml
  5. 6 0
      .version
  6. 7 0
      404.html
  7. 34 0
      LICENSE.txt
  8. 119 1
      README.md
  9. BIN
      app/.DS_Store
  10. 31 0
      app/AppService.php
  11. 68 0
      app/ExceptionHandle.php
  12. 186 0
      app/Request.php
  13. BIN
      app/adminapi/.DS_Store
  14. 96 0
      app/adminapi/AdminApiExceptionHandle.php
  15. 158 0
      app/adminapi/common.php
  16. 25 0
      app/adminapi/config/route.php
  17. 93 0
      app/adminapi/controller/AuthController.php
  18. 409 0
      app/adminapi/controller/Common.php
  19. 126 0
      app/adminapi/controller/Login.php
  20. 47 0
      app/adminapi/controller/PublicController.php
  21. 16 0
      app/adminapi/controller/Test.php
  22. 2334 0
      app/adminapi/controller/UpgradeController.php
  23. 187 0
      app/adminapi/controller/v1/agent/AgentLevel.php
  24. 184 0
      app/adminapi/controller/v1/agent/AgentLevelTask.php
  25. 282 0
      app/adminapi/controller/v1/agent/AgentManage.php
  26. 239 0
      app/adminapi/controller/v1/agent/Division.php
  27. 201 0
      app/adminapi/controller/v1/application/routine/RoutineTemplate.php
  28. 57 0
      app/adminapi/controller/v1/application/wechat/Menus.php
  29. 171 0
      app/adminapi/controller/v1/application/wechat/Reply.php
  30. 203 0
      app/adminapi/controller/v1/application/wechat/WechatNewsCategory.php
  31. 188 0
      app/adminapi/controller/v1/application/wechat/WechatQrcode.php
  32. 61 0
      app/adminapi/controller/v1/application/wechat/WechatTemplate.php
  33. 138 0
      app/adminapi/controller/v1/cms/Article.php
  34. 178 0
      app/adminapi/controller/v1/cms/ArticleCategory.php
  35. 646 0
      app/adminapi/controller/v1/diy/Diy.php
  36. 115 0
      app/adminapi/controller/v1/diy/PageLink.php
  37. 446 0
      app/adminapi/controller/v1/export/ExportExcel.php
  38. 138 0
      app/adminapi/controller/v1/file/SystemAttachment.php
  39. 122 0
      app/adminapi/controller/v1/file/SystemAttachmentCategory.php
  40. 101 0
      app/adminapi/controller/v1/finance/Finance.php
  41. 58 0
      app/adminapi/controller/v1/finance/UserBalance.php
  42. 140 0
      app/adminapi/controller/v1/finance/UserExtract.php
  43. 97 0
      app/adminapi/controller/v1/finance/UserRecharge.php
  44. 173 0
      app/adminapi/controller/v1/freight/Express.php
  45. 313 0
      app/adminapi/controller/v1/kefu/StoreService.php
  46. 111 0
      app/adminapi/controller/v1/kefu/StoreServiceFeedback.php
  47. 165 0
      app/adminapi/controller/v1/kefu/StoreServiceSpeechcraft.php
  48. 146 0
      app/adminapi/controller/v1/kefu/StoreServiceSpeechcraftCate.php
  49. 149 0
      app/adminapi/controller/v1/marketing/StoreAdvance.php
  50. 226 0
      app/adminapi/controller/v1/marketing/StoreBargain.php
  51. 244 0
      app/adminapi/controller/v1/marketing/StoreCombination.php
  52. 159 0
      app/adminapi/controller/v1/marketing/StoreCouponIssue.php
  53. 75 0
      app/adminapi/controller/v1/marketing/StoreCouponUser.php
  54. 176 0
      app/adminapi/controller/v1/marketing/StoreSeckill.php
  55. 66 0
      app/adminapi/controller/v1/marketing/UserPoint.php
  56. 138 0
      app/adminapi/controller/v1/marketing/integral/StoreIntegral.php
  57. 349 0
      app/adminapi/controller/v1/marketing/integral/StoreIntegralOrder.php
  58. 110 0
      app/adminapi/controller/v1/marketing/integral/StorePointRecord.php
  59. 118 0
      app/adminapi/controller/v1/marketing/live/LiveAnchor.php
  60. 161 0
      app/adminapi/controller/v1/marketing/live/LiveGoods.php
  61. 154 0
      app/adminapi/controller/v1/marketing/live/LiveRoom.php
  62. 225 0
      app/adminapi/controller/v1/marketing/lottery/LuckLottery.php
  63. 76 0
      app/adminapi/controller/v1/marketing/lottery/LuckLotteryRecord.php
  64. 170 0
      app/adminapi/controller/v1/merchant/SystemStore.php
  65. 186 0
      app/adminapi/controller/v1/merchant/SystemStoreStaff.php
  66. 85 0
      app/adminapi/controller/v1/merchant/SystemVerifyOrder.php
  67. 76 0
      app/adminapi/controller/v1/notification/sms/SmsAdmin.php
  68. 135 0
      app/adminapi/controller/v1/notification/sms/SmsConfig.php
  69. 88 0
      app/adminapi/controller/v1/notification/sms/SmsPay.php
  70. 77 0
      app/adminapi/controller/v1/notification/sms/SmsPublicTemp.php
  71. 97 0
      app/adminapi/controller/v1/notification/sms/SmsTemplateApply.php
  72. 142 0
      app/adminapi/controller/v1/order/DeliveryService.php
  73. 100 0
      app/adminapi/controller/v1/order/OtherOrder.php
  74. 231 0
      app/adminapi/controller/v1/order/RefundOrder.php
  75. 770 0
      app/adminapi/controller/v1/order/StoreOrder.php
  76. 140 0
      app/adminapi/controller/v1/order/StoreOrderInvoice.php
  77. 114 0
      app/adminapi/controller/v1/product/CopyTaobao.php
  78. 172 0
      app/adminapi/controller/v1/product/StoreCategory.php
  79. 402 0
      app/adminapi/controller/v1/product/StoreProduct.php
  80. 112 0
      app/adminapi/controller/v1/product/StoreProductReply.php
  81. 87 0
      app/adminapi/controller/v1/product/StoreProductRule.php
  82. 83 0
      app/adminapi/controller/v1/serve/Export.php
  83. 117 0
      app/adminapi/controller/v1/serve/Login.php
  84. 213 0
      app/adminapi/controller/v1/serve/Serve.php
  85. 121 0
      app/adminapi/controller/v1/serve/Sms.php
  86. 105 0
      app/adminapi/controller/v1/setting/LangCode.php
  87. 79 0
      app/adminapi/controller/v1/setting/LangCountry.php
  88. 95 0
      app/adminapi/controller/v1/setting/LangType.php
  89. 113 0
      app/adminapi/controller/v1/setting/ShippingTemplates.php
  90. 210 0
      app/adminapi/controller/v1/setting/SystemAdmin.php
  91. 54 0
      app/adminapi/controller/v1/setting/SystemAgreement.php
  92. 143 0
      app/adminapi/controller/v1/setting/SystemCity.php
  93. 413 0
      app/adminapi/controller/v1/setting/SystemConfig.php
  94. 159 0
      app/adminapi/controller/v1/setting/SystemConfigTab.php
  95. 215 0
      app/adminapi/controller/v1/setting/SystemGroup.php
  96. 316 0
      app/adminapi/controller/v1/setting/SystemGroupData.php
  97. 240 0
      app/adminapi/controller/v1/setting/SystemMenus.php
  98. 124 0
      app/adminapi/controller/v1/setting/SystemNotification.php
  99. 261 0
      app/adminapi/controller/v1/setting/SystemOutAccount.php
  100. 154 0
      app/adminapi/controller/v1/setting/SystemRole.php

+ 3 - 0
.constant

@@ -0,0 +1,3 @@
+<?php
+define('INSTALL_DATE',1681979110);
+define('SERIALNUMBER','ToEgQd');

+ 1 - 0
.htaccess

@@ -0,0 +1 @@
+ 

+ 22 - 0
.phpstorm.meta.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace PHPSTORM_META {
+
+    use think\Container;
+    use function \app;
+
+    override(
+        \app(),
+        map([
+            'json' => \crmeb\utils\Json::class
+        ])
+    );
+
+    override(
+        \think\Container::make(),
+        map([
+            '' => '@'
+        ])
+    );
+
+}

+ 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

+ 6 - 0
.version

@@ -0,0 +1,6 @@
+version=CRMEB-BZ v4.7.1
+version_code=471
+platform=CRMEB
+app_id=ze7x9rxsv09l6pvsyo
+app_key=fuF7U9zaybLa5gageVQzxtxQMFnvU2OI
+project_signature=a553194888c6b5e5f9cb4cb240ebf9e6

+ 7 - 0
404.html

@@ -0,0 +1,7 @@
+<html>
+<head><title>404 Not Found</title></head>
+<body>
+<center><h1>404 Not Found</h1></center>
+<hr><center>nginx</center>
+</body>
+</html>

+ 34 - 0
LICENSE.txt

@@ -0,0 +1,34 @@
+版权所有 (c)2017-2027,西安众邦网络科技有限公司 保留所有权利。
+感谢您选择CRMEB开源客户管理+电商系统(简称CRMEB),CRMEB是国内稳定、功能强大、技术先进的互联网电商平台解决方案之一,CRMEB基于 PHP + MySQL 的技术,采用ThinkPHP5.0框架开发。
+为了使你正确并合法的使用本软件,请你在使用前务必阅读清楚下面的协议条款:
+本授权协议适用且仅适用于CRMEB任何版本,CRMEB官方对本授权协议的最终解释权和修改权。
+
+一、协议许可的权利
+1、您可以在完全遵守本最终用户授权协议的基础上,将本软件应用于非商业用途,而不必支付软件版权授权费用。
+2、您可以在协议规定的约束和限制范围内修改 CRMEB 源代码或界面风格以适应您的网站要求。
+3、您拥有使用本软件构建的网站全部内容所有权,并独立承担与这些内容的相关法律义务。
+4、您可以将本软件应用于商业用途,但必须保留版权,去版权需要申请。
+
+二、协议许可的权利和限制
+1、未获去版权授权之前,不得删除网站底部及相应的官方版权信息和链接。购买商业授权请联系西安众邦网络科技有限公司了解最新说明。CRMEB著作权已在中华人民共和国国家版权局注册(中国国家版权局著作权登记号 2018SR024463),著作权受到法律和国际公约保护。
+2、未经官方许可,不得对本软件或与之关联的商业授权进行出租、出售、抵押或发放子许可证。
+3、不管你的网站是否整体使用 CRMEB ,还是部份栏目使用 CRMEB,在你使用了 CRMEB 的网站主页上必须加上 CRMEB 官方网址(www.crmeb.com)的链接。
+4、未经官方许可,禁止在 CRMEB 的整体或任何部分基础上以发展任何派生版本、修改版本或第三方版本用于重新分发。
+5、如果您未能遵守本协议的条款,您的授权将被终止,所被许可的权利将被收回,并承担相应法律责任。
+
+三、有限担保和免责声明
+1、本软件及所附带的文件是作为不提供任何明确的或隐含的赔偿或担保的形式提供的。
+2、本软件提供源代码,您在使用过程中产生的责任与西安众邦网络科技有限公司无关。
+3、用户出于自愿而使用本软件,您必须了解使用本软件的风险,在尚未购买产品技术服务之前,我们不承诺对免费用户提供任何形式的技术支持、使用担保,也不承担任何因使用本软件而产生问题的相关责任。
+4、电子文本形式的授权协议如同双方书面签署的协议一样,具有完全的和等同的法律效力。您一旦开始确认本协议并安装 CRMEB,即被视为完全理解并接受本协议的各项条款,在享有上述条款授予的权力的同时,受到相关的约束和限制。协议许可范围以外的行为,将直接违反本授权协议并构成侵权,我们有权随时终止授权,责令停止损害,并保留追究相关责任的权力。
+
+协议发布时间: 2017年8月01日
+版本最新更新: 2022年6月15日 By CRMEB
+
+CRMEB官方网站:http://www.crmeb.com
+CRMEB演示站:http://demo.crmeb.com
+-----------------------------------------------------
+运营团队: 众邦科技
+电   话: 400-8888-794
+邮   箱: admin@xazbkj.com
+网   址: http://www.xazbkj.com

+ 119 - 1
README.md

@@ -1,2 +1,120 @@
-# waimao
+CRMEB v4.5 后端程序目录
+===============
 
+> 运行环境要求PHP7.1-7.4。
+
+## 安装
+
+## 一键安装
+上传你的代码,站点入口目录设置/public
+在浏览器中输入你的域名或IP(例如:www.yourdomain.com),
+安装程序会自动执行安装。期间系统会提醒你输入数据库信息以完成安装,安装完成后建议删除install目录下index.php文件或将其改名。
+
+后台访问地址:
+1.域名/admin
+2.域名/index.php/admin
+3.域名/index.php?s=/admin
+公众号和H5首页访问地址:
+1.域名/
+
+安装过程中请牢记您的账号密码!
+
+## 重新安装
+1. 清除数据库
+2. 删除/public/install.lock 文件
+
+## 手动安装
+1.创建数据库,倒入数据库文件
+数据库文件目录/public/install/crmeb.sql
+2.修改数据库连接文件
+配置文件路径/.env
+~~~
+APP_DEBUG = true
+
+[APP]
+DEFAULT_TIMEZONE = Asia/Shanghai
+
+[DATABASE]
+TYPE = mysql
+HOSTNAME = 127.0.0.1 #数据库连接地址
+DATABASE = test #数据库名称
+USERNAME = username #数据库登录账号
+PASSWORD = password #数据库登录密码
+HOSTPORT = 3306 #数据库端口
+CHARSET = utf8
+DEBUG = true
+
+[LANG]
+default_lang = zh-cn
+
+[REDIS]
+REDIS_HOSTNAME = 127.0.0.1 # redis链接地址
+PORT = 6379 #端口号
+REDIS_PASSWORD = 123456 #密码
+SELECT = 0 #数据库
+~~~
+3.修改目录权限(linux系统)777
+/public
+/runtime
+4.后台登录:
+http://域名/admin
+默认账号:admin 密码:crmeb.com
+## 消息队列
+```sh
+php think queue:listen --queue
+```
+
+## 消息队列
+```sh
+php think queue:listen --queue
+```
+
+## 定时任务
+在自动收货,库存预警等功能使用到
+```sh
+php think timer [ status ] [ --d ]
+```
+参数
+- status: 状态
+  - start: 启动
+  - stop: 关闭
+  - restart: 重启
+- --d : 后台执行
+
+## 长连接服务
+在h5聊天,后台管理员消息通知等功能使用到
+```sh
+php think workerman [ status ]  [ --d ]
+```
+windows环境下需要分三步执行
+```sh
+# 内部通讯服务
+php think workerman start --d
+```
+参数
+- status: 状态
+  - start: 启动
+  - stop: 关闭
+  - restart: 重启
+- --d : 后台执行
+
+## 文档
+
+[使用手册](https://doc.crmeb.com)
+[TP6开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content)
+
+
+## 参与开发
+
+请参阅 [CRMEB](https://github.com/crmeb/CRMEB)。
+
+## 版权信息
+
+
+本项目包含的第三方源码和二进制文件之版权信息另行标注。
+
+版权所有Copyright © 2017-2023 by CRMEB (http://www.crmeb.com)
+
+All rights reserved。
+
+CRMEB® 商标和著作权所有者为西安众邦网络科技有限公司。

BIN
app/.DS_Store


+ 31 - 0
app/AppService.php

@@ -0,0 +1,31 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app;
+
+use crmeb\services\SystemConfigService;
+use crmeb\services\GroupDataService;
+use crmeb\utils\Json;
+use think\Service;
+
+class AppService extends Service
+{
+
+    public $bind = [
+        'json' => Json::class,
+        'sysConfig' => SystemConfigService::class,
+        'sysGroupData' => GroupDataService::class
+    ];
+
+    public function boot()
+    {
+        defined('DS') || define('DS', DIRECTORY_SEPARATOR);
+    }
+}

+ 68 - 0
app/ExceptionHandle.php

@@ -0,0 +1,68 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 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\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
+    {
+        // 添加自定义异常处理机制
+
+        // 其他错误交给系统处理
+        return parent::render($request, $e);
+    }
+}

+ 186 - 0
app/Request.php

@@ -0,0 +1,186 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app;
+
+use Spatie\Macroable\Macroable;
+
+/**
+ * Class Request
+ * @package app
+ * @method tokenData() 获取token信息
+ * @method user(string $key = null) 获取用户信息
+ * @method uid() 获取用户uid
+ * @method isAdminLogin() 后台登陆状态
+ * @method adminId() 后台管理员id
+ * @method adminInfo() 后台管理信息
+ * @method kefuId() 客服id
+ * @method kefuInfo() 客服信息
+ */
+class Request extends \think\Request
+{
+    use Macroable;
+
+    /**
+     * 不过滤变量名
+     * @var array
+     */
+    protected $except = ['menu_path', 'api_url', 'unique_auth', 'description', 'custom_form', 'content'];
+
+    /**
+     * 获取请求的数据
+     * @param array $params
+     * @param bool $suffix
+     * @param bool $filter
+     * @return array
+     */
+    public function more(array $params, bool $suffix = false, bool $filter = true): array
+    {
+        $p = [];
+        $i = 0;
+        foreach ($params as $param) {
+            if (!is_array($param)) {
+                $p[$suffix == true ? $i++ : $param] = $this->filterWord(is_string($this->param($param)) ? trim($this->param($param)) : $this->param($param), $filter && !in_array($param, $this->except));
+            } else {
+                if (!isset($param[1])) $param[1] = null;
+                if (!isset($param[2])) $param[2] = '';
+                if (is_array($param[0])) {
+                    $name = is_array($param[1]) ? $param[0][0] . '/a' : $param[0][0] . '/' . $param[0][1];
+                    $keyName = $param[0][0];
+                } else {
+                    $name = is_array($param[1]) ? $param[0] . '/a' : $param[0];
+                    $keyName = $param[0];
+                }
+                $p[$suffix == true ? $i++ : ($param[3] ?? $keyName)] = $this->filterWord(is_string($this->param($name, $param[1], $param[2])) ? trim($this->param($name, $param[1], $param[2])) : $this->param($name, $param[1], $param[2]), $filter && !in_array($keyName, $this->except));
+            }
+        }
+        return $p;
+    }
+
+    /**
+     * 过滤接受的参数
+     * @param $str
+     * @param bool $filter
+     * @return array|mixed|string|string[]
+     */
+    public function filterWord($str, bool $filter = true)
+    {
+        if (!$str || !$filter) return $str;
+        // 把数据过滤
+        $farr = [
+            "/<(\\/?)(script|i?frame|style|html|body|title|link|meta|object|\\?|\\%)([^>]*?)>/isU",
+            "/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU",
+            "/select|join|where|drop|like|modify|rename|insert|update|table|database|alter|truncate|\'|\/\*|\.\.\/|\.\/|union|into|load_file|outfile/is"
+        ];
+        if (is_array($str)) {
+            foreach ($str as &$v) {
+                if (is_array($v)) {
+                    foreach ($v as &$vv) {
+                        if (!is_array($vv)) $vv = preg_replace($farr, '', $vv);
+                    }
+                } else {
+                    $v = preg_replace($farr, '', $v);
+                }
+            }
+        } else {
+            $str = preg_replace($farr, '', $str);
+        }
+        return $str;
+    }
+
+    /**
+     * 获取get参数
+     * @param array $params
+     * @param bool $suffix
+     * @param bool $filter
+     * @return array
+     */
+    public function getMore(array $params, bool $suffix = false, bool $filter = true): array
+    {
+        return $this->more($params, $suffix, $filter);
+    }
+
+    /**
+     * 获取post参数
+     * @param array $params
+     * @param bool $suffix
+     * @param bool $filter
+     * @return array
+     */
+    public function postMore(array $params, bool $suffix = false, bool $filter = true): array
+    {
+        return $this->more($params, $suffix, $filter);
+    }
+
+    /**
+     * 获取用户访问端
+     * @return array|string|null
+     */
+    public function getFromType()
+    {
+        return $this->header('Form-type', '');
+    }
+
+    /**
+     * 当前访问端
+     * @param string $terminal
+     * @return bool
+     */
+    public function isTerminal(string $terminal)
+    {
+        return strtolower($this->getFromType()) === $terminal;
+    }
+
+    /**
+     * 是否是H5端
+     * @return bool
+     */
+    public function isH5()
+    {
+        return $this->isTerminal('h5');
+    }
+
+    /**
+     * 是否是微信端
+     * @return bool
+     */
+    public function isWechat()
+    {
+        return $this->isTerminal('wechat');
+    }
+
+    /**
+     * 是否是小程序端
+     * @return bool
+     */
+    public function isRoutine()
+    {
+        return $this->isTerminal('routine');
+    }
+
+    /**
+     * 是否是app端
+     * @return bool
+     */
+    public function isApp()
+    {
+        return $this->isTerminal('app');
+    }
+
+    /**
+     * 是否是app端
+     * @return bool
+     */
+    public function isPc()
+    {
+        return $this->isTerminal('pc');
+    }
+}

BIN
app/adminapi/.DS_Store


+ 96 - 0
app/adminapi/AdminApiExceptionHandle.php

@@ -0,0 +1,96 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi;
+
+
+use crmeb\exceptions\AdminException;
+use crmeb\exceptions\ApiException;
+use crmeb\exceptions\AuthException;
+use think\db\exception\DbException;
+use think\exception\Handle;
+use think\exception\ValidateException;
+use think\facade\Env;
+use think\facade\Log;
+use think\Response;
+use Throwable;
+
+class AdminApiExceptionHandle extends Handle
+{
+    /**
+     * 不需要记录信息(日志)的异常类列表
+     * @var array
+     */
+    protected $ignoreReport = [
+        ValidateException::class,
+        AuthException::class,
+        AdminException::class,
+        ApiException::class,
+    ];
+
+    /**
+     * 记录异常信息(包括日志或者其它方式记录)
+     * @access public
+     * @param Throwable $exception
+     * @return void
+     */
+    public function report(Throwable $exception): void
+    {
+        if (!$this->isIgnoreReport($exception)) {
+            $data = [
+                'file' => $exception->getFile(),
+                'line' => $exception->getLine(),
+                'message' => $this->getMessage($exception),
+                'code' => $this->getCode($exception),
+            ];
+
+            //日志内容
+            $log = [
+                request()->adminId(),                                                                 //管理员ID
+                request()->ip(),                                                                      //客户ip
+                ceil(msectime() - (request()->time(true) * 1000)),                               //耗时(毫秒)
+                request()->rule()->getMethod(),                                                       //请求类型
+                str_replace("/", "", request()->rootUrl()),                             //应用
+                request()->baseUrl(),                                                                 //路由
+                json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),//请求参数
+                json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),             //报错数据
+
+            ];
+            Log::write(implode("|", $log), "error");
+        }
+    }
+
+    /**
+     * 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
+    {
+        $massageData = Env::get('app_debug', false) ? [
+            'message' => $e->getMessage(),
+            'file' => $e->getFile(),
+            'line' => $e->getLine(),
+            'trace' => $e->getTrace(),
+            'previous' => $e->getPrevious(),
+        ] : [];
+        $message = $e->getMessage();
+        // 添加自定义异常处理机制
+        if ($e instanceof AuthException || $e instanceof AdminException || $e instanceof ApiException || $e instanceof ValidateException) {
+            return app('json')->make($e->getCode() ?: 400, $message, $massageData);
+        } else {
+            return app('json')->fail($message, $massageData);
+        }
+    }
+
+}

+ 158 - 0
app/adminapi/common.php

@@ -0,0 +1,158 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+if (!function_exists('get_this_class_methods')) {
+    /**获取当前类方法
+     * @param $class
+     * @return array
+     */
+    function get_this_class_methods($class, $unarray = [])
+    {
+        $arrayall = get_class_methods($class);
+        if ($parent_class = get_parent_class($class)) {
+            $arrayparent = get_class_methods($parent_class);
+            $arraynow = array_diff($arrayall, $arrayparent);//去除父级的
+        } else {
+            $arraynow = $arrayall;
+        }
+        return array_diff($arraynow, $unarray);//去除无用的
+    }
+}
+
+
+if (!function_exists('setconfig')) {
+    /**
+     * 修改config的函数
+     * @param $arr1 or $string 配置前缀
+     * @param $arr2 or $string 数据变量
+     * @return bool 返回状态
+     */
+    function setconfig($name, $pat, $rep)
+    {
+        /**
+         * 原理就是 打开config配置文件 然后使用正则查找替换 然后在保存文件. 不能修改值为数组的配置
+         * 传递的参数为2个数组 前面的为配置 后面的为数值.  正则的匹配为单引号  如果你的是分号 请自行修改为分号
+         * $pat[0] = 参数前缀;  例:   default_return_type
+         * $rep[0] = 要替换的内容;    例:  json
+         */
+        $pats = $reps = [];
+        if (is_array($pat) && is_array($rep)) {
+            for ($i = 0; $i < count($pat); $i++) {
+                $pats[$i] = '/\'' . $pat[$i] . '\'(.*?),/';
+                $reps[$i] = "'" . $pat[$i] . "'" . "=>" . "'" . $rep[$i] . "',";
+            }
+            $fileurl = app()->getConfigPath() . $name . ".php";
+            $string = file_get_contents($fileurl); //加载配置文件
+            $string = preg_replace($pats, $reps, $string); // 正则查找然后替换
+            @file_put_contents($fileurl, $string); // 写入配置文件
+            return true;
+        } else if (is_string($pat) && is_string($rep)) {
+            $pats = '/\'' . $pat . '\'(.*?),/';
+            if (substr_count($rep, '[')) {
+                $reps = "'" . $pat . "'" . "=>" . $rep . ",";
+            } else {
+                $rep = str_replace('\'', "", $rep);
+                $reps = "'" . $pat . "'" . "=>" . "'" . $rep . "',";
+            }
+            $fileurl = app()->getConfigPath() . $name . ".php";
+            $string = file_get_contents($fileurl); //加载配置文件
+            $string = preg_replace($pats, $reps, $string); // 正则查找然后替换
+            @file_put_contents($fileurl, $string); // 写入配置文件
+            return true;
+        } else {
+            return false;
+
+        }
+    }
+}
+if (!function_exists('arrayToText')) {
+    /**
+     * 修改config的函数
+     * @param $array
+     * @return string
+     */
+    function arrayToText($array)
+    {
+        $config = print_r($array, true);
+        $config = str_replace('[', "\"", $config);
+        $config = str_replace(']', "\"", $config);
+        $input = explode("\n", $config);
+        foreach ($input as $k => $v) {
+            if (empty($v) || strpos($v, 'Array') !== false || strpos($v, '(') !== false || strpos($v, ')') !== false) {
+                continue;
+            }
+            $tmpValArr = explode('=>', $v);
+            if (count($tmpValArr) == 2) {
+                $input[$k] = $tmpValArr[0] . '=> \'' . trim($tmpValArr[1]) . '\',';
+            }
+        }
+        $config = implode("\n", $input);
+        $config = str_replace('Array', "", $config);
+        $config = str_replace('(', "[", $config);
+        $config = str_replace(')', "],", $config);
+        $config = rtrim($config, "\n");
+        $config = rtrim($config, ",");
+        $config = "<?php \n return " . $config . ';';
+//        $fileurl = app()->getConfigPath() ."templates.php";
+//        @file_put_contents($fileurl, $config); // 写入配置文件
+        return $config;
+    }
+}
+if (!function_exists('attr_format')) {
+    /**
+     * 格式化属性
+     * @param $arr
+     * @return array
+     */
+    function attr_format($arr): array
+    {
+        $len = count($arr);
+        $title = array_column($arr, 'value');
+        $result = [];
+
+        if ($len > 0) {
+            if ($len > 1) {
+                $result = $arr[0]['detail'];
+                for ($i = 0; $i < $len - 1; $i++) {
+                    $temp = $result;
+                    $result = [];
+                    foreach ($temp as $item) {
+                        foreach ($arr[$i + 1]['detail'] as $datum) {
+                            $result[] = trim($item) . ',' . trim($datum);
+                        }
+                    }
+                }
+            } else {
+                foreach ($arr[0]['detail'] as $item) {
+                    $result[] = trim($item);
+                }
+            }
+        }
+        return [$result, $title];
+    }
+}
+
+if (!function_exists('verify_domain')) {
+
+    /**
+     * 验证域名是否合法
+     * @param string $domain
+     * @return bool
+     */
+    function verify_domain(string $domain): bool
+    {
+        $res = "/^(?=^.{3,255}$)(http(s)?:\/\/)(www\.)?[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+(:\d+)*(\/\w+\.\w+)*$/";
+        if (preg_match($res, $domain))
+            return true;
+        else
+            return false;
+    }
+}

+ 25 - 0
app/adminapi/config/route.php

@@ -0,0 +1,25 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+// +----------------------------------------------------------------------
+// | 应用设置
+// +----------------------------------------------------------------------
+
+return [
+    // 是否强制使用路由
+    'url_route_must'        => true,
+    // 合并路由规则
+    'route_rule_merge'      => true,
+    // 路由是否完全匹配
+    'route_complete_match'  => true,
+    // 是否自动转换URL中的控制器和操作名
+    'url_convert'           => false,
+];

+ 93 - 0
app/adminapi/controller/AuthController.php

@@ -0,0 +1,93 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller;
+
+
+use crmeb\basic\BaseController;
+use think\facade\Validate;
+
+/**
+ * 基类 所有控制器继承的类
+ * Class AuthController
+ * @package app\adminapi\controller
+ */
+class AuthController extends BaseController
+{
+    /**
+     * 当前登陆管理员信息
+     * @var
+     */
+    protected $adminInfo;
+
+    /**
+     * 当前登陆管理员ID
+     * @var
+     */
+    protected $adminId;
+
+    /**
+     * 当前管理员权限
+     * @var array
+     */
+    protected $auth = [];
+
+
+    /**
+     * 初始化
+     */
+    protected function initialize()
+    {
+        $this->adminId = $this->request->adminId();
+        $this->adminInfo = $this->request->adminInfo();
+        $this->auth = $this->request->adminInfo['rule'] ?? [];
+    }
+
+    /**
+     * 验证数据
+     * @param array $data
+     * @param $validate
+     * @param null $message
+     * @param bool $batch
+     * @return bool
+     */
+    final protected function validate(array $data, $validate, $message = null, bool $batch = false)
+    {
+        if (is_array($validate)) {
+            $v = new Validate();
+            $v->rule($validate);
+        } else {
+            if (strpos($validate, '.')) {
+                // 支持场景
+                list($validate, $scene) = explode('.', $validate);
+            }
+            $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
+            $v = new $class();
+            if (!empty($scene)) {
+                $v->scene($scene);
+            }
+
+            if (is_string($message) && empty($scene)) {
+                $v->scene($message);
+            }
+        }
+
+        if (is_array($message))
+            $v->message($message);
+
+
+        // 是否批量验证
+        if ($batch) {
+            $v->batch(true);
+        }
+
+        return $v->failException(true)->check($data);
+    }
+}

+ 409 - 0
app/adminapi/controller/Common.php

@@ -0,0 +1,409 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller;
+
+use app\services\system\config\SystemConfigServices;
+use app\services\system\SystemAuthServices;
+use app\services\order\StoreOrderServices;
+use app\services\product\product\StoreProductServices;
+use app\services\product\product\StoreProductReplyServices;
+use app\services\system\UpgradeServices;
+use app\services\user\UserExtractServices;
+use app\services\product\sku\StoreProductAttrValueServices;
+use app\services\system\SystemMenusServices;
+use app\services\user\UserServices;
+use crmeb\services\HttpService;
+use think\facade\Cache;
+
+/**
+ * 公共接口基类 主要存放公共接口
+ * Class Common
+ * @package app\adminapi\controller
+ */
+class Common extends AuthController
+{
+    /**
+     * 获取logo
+     * @return mixed
+     */
+    public function getLogo()
+    {
+        return app('json')->success([
+            'logo' => sys_config('site_logo'),
+            'logo_square' => sys_config('site_logo_square'),
+            'site_name' => sys_config('site_name')
+        ]);
+    }
+
+    /**
+     * 获取授权信息
+     * @return mixed
+     */
+    public function auth()
+    {
+        $version = get_crmeb_version();
+        $host = $this->request->host();
+        // 正常域名
+        $res = HttpService::request('http://authorize.crmeb.net/api/auth_cert_query', 'post', [
+            'domain_name' => $host,
+            'label' => 19,
+            'version' => $version
+        ]);
+        $res = $res ? json_decode($res, true) : [];
+
+        //兼容test.
+        if ($res['data']['status'] !== 1) {
+            $host = str_replace('test.', '', $host);
+            $res = HttpService::request('http://authorize.crmeb.net/api/auth_cert_query', 'post', [
+                'domain_name' => $host,
+                'label' => 19,
+                'version' => $version
+            ]);
+            $res = $res ? json_decode($res, true) : [];
+        }
+
+        //如果是主域名兼容www.
+        if ($res['data']['status'] !== 1) {
+            $host = str_replace('www.', '', $host);
+            $res = HttpService::request('http://authorize.crmeb.net/api/auth_cert_query', 'post', [
+                'domain_name' => $host,
+                'label' => 19,
+                'version' => $version
+            ]);
+            $res = $res ? json_decode($res, true) : [];
+        }
+
+//        //升级状态
+//        /** @var UpgradeServices $upgradeServices */
+//        $upgradeServices = app()->make(UpgradeServices::class);
+//        $upgradeStatus = $upgradeServices->getUpgradeStatus();
+
+        $status = $res['data']['status'] ?? -9;
+        switch ((int)$status) {
+            case 1:
+                //审核成功
+                $authCode = $res['data']['auth_code'] ?? '';
+                $autoContent = $res['data']['auto_content'] ?? '';
+                try {
+                    /** @var SystemConfigServices $services */
+                    $services = app()->make(SystemConfigServices::class);
+                    if ($services->count(['menu_name' => 'cert_crmeb'])) {
+                        $services->update(['menu_name' => 'cert_crmeb'], ['value' => json_encode($autoContent . ',' . $authCode)]);
+                    } else {
+                        $services->save([
+                            'menu_name' => 'cert_crmeb',
+                            'type' => 'text',
+                            'input_type' => 'input',
+                            'config_tab_id' => 1,
+                            'value' => json_encode($autoContent . ',' . $authCode),
+                            'status' => 2,
+                            'info' => '授权密钥'
+                        ]);
+                    }
+                } catch (\Throwable $e) {
+                    return app('json')->fail(400330);
+                }
+                return app('json')->success(['status' => 1, 'copyright' => $res['data']['copyright'], 'authCode' => $authCode, 'day' => 0, 'force_reminder' => $upgradeStatus['force_reminder'] ?? 0]);
+            default:
+                return app('json')->success(['status' => -9, 'force_reminder' => $upgradeStatus['force_reminder'] ?? 0]);
+        }
+    }
+
+    /**
+     * 申请授权
+     * @return mixed
+     */
+    public function auth_apply(SystemAuthServices $services)
+    {
+        $data = $this->request->postMore([
+            ['company_name', ''],
+            ['domain_name', ''],
+            ['order_id', ''],
+            ['phone', ''],
+            ['label', 19],
+            ['captcha', ''],
+        ]);
+        if (!$data['company_name']) {
+            return app('json')->fail(400331);
+        }
+        if (!$data['domain_name']) {
+            return app('json')->fail(400332);
+        }
+
+        if (!$data['phone']) {
+            return app('json')->fail(400333);
+        }
+        if (!$data['order_id']) {
+            return app('json')->fail(400334);
+        }
+        if (!$data['captcha']) {
+            return app('json')->fail(400137);
+        }
+        $services->authApply($data);
+        return app('json')->success(400335);
+
+    }
+
+    /**
+     * 首页头部统计数据
+     * @return mixed
+     */
+    public function homeStatics()
+    {
+        /** @var StoreOrderServices $orderServices */
+        $orderServices = app()->make(StoreOrderServices::class);
+        $info = $orderServices->homeStatics();
+        return app('json')->success(compact('info'));
+    }
+
+    //增长率
+    public function growth($nowValue, $lastValue)
+    {
+        if ($lastValue == 0 && $nowValue == 0) return 0;
+        if ($lastValue == 0) return round($nowValue, 2);
+        if ($nowValue == 0) return -round($lastValue, 2);
+        return bcmul(bcdiv((bcsub($nowValue, $lastValue, 2)), $lastValue, 2), 100, 2);
+    }
+
+    /**
+     * 订单图表
+     */
+    public function orderChart()
+    {
+        $cycle = $this->request->param('cycle') ?: 'thirtyday';//默认30天
+        /** @var StoreOrderServices $orderServices */
+        $orderServices = app()->make(StoreOrderServices::class);
+        $chartdata = $orderServices->orderCharts($cycle);
+        return app('json')->success($chartdata);
+    }
+
+    /**
+     * 用户图表
+     */
+    public function userChart()
+    {
+        /** @var UserServices $uServices */
+        $uServices = app()->make(UserServices::class);
+        $chartdata = $uServices->userChart();
+        return app('json')->success($chartdata);
+    }
+
+    /**
+     * 交易额排行
+     * @return mixed
+     */
+    public function purchaseRanking()
+    {
+        /** @var StoreProductAttrValueServices $valueServices */
+        $valueServices = app()->make(StoreProductAttrValueServices::class);
+        $list = $valueServices->purchaseRanking();
+        return app('json')->success(compact('list'));
+    }
+
+    /**
+     * 待办事统计
+     * @return mixed
+     */
+    public function jnotice()
+    {
+        /** @var StoreOrderServices $orderServices */
+        $orderServices = app()->make(StoreOrderServices::class);
+        $data['ordernum'] = $orderServices->storeOrderCount();
+        $store_stock = sys_config('store_stock');
+        if ($store_stock < 0) $store_stock = 2;
+        /** @var StoreProductServices $storeServices */
+        $storeServices = app()->make(StoreProductServices::class);
+        $data['inventory'] = $storeServices->count(['type' => 5, 'store_stock' => $store_stock]);//警戒库存
+        /** @var StoreProductReplyServices $replyServices */
+        $replyServices = app()->make(StoreProductReplyServices::class);
+        $data['commentnum'] = $replyServices->replyCount();
+        /** @var UserExtractServices $extractServices */
+        $extractServices = app()->make(UserExtractServices::class);
+        $data['reflectnum'] = $extractServices->userExtractCount();//提现
+        $data['msgcount'] = intval($data['ordernum']) + intval($data['inventory']) + intval($data['commentnum']) + intval($data['reflectnum']);
+        $data['newOrderId'] = $orderServices->newOrderId(1);
+        if (count($data['newOrderId'])) $orderServices->newOrderUpdate($data['newOrderId']);
+        $value = [];
+        if ($data['ordernum'] != 0) {
+            $value[] = [
+                'title' => "您有$data[ordernum]个待发货的订单",
+                'type' => 'bulb',
+                'url' => '/admin/order/list?status=1'
+            ];
+        }
+        if ($data['inventory'] != 0) {
+            $value[] = [
+                'title' => "您有$data[inventory]个商品库存预警",
+                'type' => 'information',
+                'url' => '/admin/product/product_list?type=5',
+            ];
+        }
+        if ($data['commentnum'] != 0) {
+            $value[] = [
+                'title' => "您有$data[commentnum]条评论待回复",
+                'type' => 'bulb',
+                'url' => '/admin/product/product_reply?is_reply=0'
+            ];
+        }
+        if ($data['reflectnum'] != 0) {
+            $value[] = [
+                'title' => "您有$data[reflectnum]个提现申请待审核",
+                'type' => 'bulb',
+                'url' => '/admin/finance/user_extract/index?status=0',
+            ];
+        }
+        return app('json')->success($this->noticeData($value));
+    }
+
+    /**
+     * 消息返回格式
+     * @param array $data
+     * @return array
+     */
+    public function noticeData(array $data): array
+    {
+        // 消息图标
+        $iconColor = [
+            // 邮件 消息
+            'mail' => [
+                'icon' => 'md-mail',
+                'color' => '#3391e5'
+            ],
+            // 普通 消息
+            'bulb' => [
+                'icon' => 'md-bulb',
+                'color' => '#87d068'
+            ],
+            // 警告 消息
+            'information' => [
+                'icon' => 'md-information',
+                'color' => '#fe5c57'
+            ],
+            // 关注 消息
+            'star' => [
+                'icon' => 'md-star',
+                'color' => '#ff9900'
+            ],
+            // 申请 消息
+            'people' => [
+                'icon' => 'md-people',
+                'color' => '#f06292'
+            ],
+        ];
+        // 消息类型
+        $type = array_keys($iconColor);
+        // 默认数据格式
+        $default = [
+            'icon' => 'md-bulb',
+            'iconColor' => '#87d068',
+            'title' => '',
+            'url' => '',
+            'type' => 'bulb',
+            'read' => 0,
+            'time' => 0
+        ];
+        $value = [];
+        foreach ($data as $item) {
+            $val = array_merge($default, $item);
+            if (isset($item['type']) && in_array($item['type'], $type)) {
+                $val['type'] = $item['type'];
+                $val['iconColor'] = $iconColor[$item['type']]['color'] ?? '';
+                $val['icon'] = $iconColor[$item['type']]['icon'] ?? '';
+            }
+            $value[] = $val;
+        }
+        return $value;
+    }
+
+    /**
+     * 格式化菜单
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function menusList()
+    {
+        /** @var SystemMenusServices $menusServices */
+        $menusServices = app()->make(SystemMenusServices::class);
+        $list = $menusServices->getSearchList();
+        $counts = $menusServices->getColumn([
+            ['is_show', '=', 1],
+            ['auth_type', '=', 1],
+            ['is_del', '=', 0],
+            ['is_show_path', '=', 0],
+        ], 'pid');
+        $data = [];
+        foreach ($list as $key => $item) {
+            $pid = $item->getData('pid');
+            $data[$key] = json_decode($item, true);
+            $data[$key]['pid'] = $pid;
+            $data[$key]['menu_path'] = '/' . config('app.admin_prefix', 'admin') . $item['menu_path'];
+            if (in_array($item->id, $counts)) {
+                $data[$key]['type'] = 1;
+            } else {
+                $data[$key]['type'] = 0;
+            }
+        }
+        return app('json')->success(sort_list_tier($data));
+    }
+
+    /**
+     * 查询购买版权
+     * @return mixed
+     */
+    public function copyright()
+    {
+        $copyrightContext = sys_config('nncnL_crmeb_copyright', '');
+        $copyrightImage = sys_config('nncnL_crmeb_copyright_image', '');
+        return app('json')->success(compact('copyrightContext', 'copyrightImage'));
+    }
+
+    /**
+     * 保存版权
+     * @return mixed
+     */
+    public function saveCopyright()
+    {
+        [$copyright, $copyrightImg] = $this->request->postMore(['copyright', 'copyright_img',], true);
+        /** @var SystemConfigServices $services */
+        $services = app()->make(SystemConfigServices::class);
+        if ($services->count(['menu_name' => 'nncnL_crmeb_copyright'])) {
+            $services->update(['menu_name' => 'nncnL_crmeb_copyright'], ['value' => json_encode($copyright)]);
+        } else {
+            $services->save([
+                'menu_name' => 'nncnL_crmeb_copyright',
+                'type' => 'text',
+                'input_type' => 'input',
+                'config_tab_id' => 1,
+                'value' => json_encode($copyright),
+                'status' => 2,
+                'info' => ''
+            ]);
+        }
+        if ($services->count(['menu_name' => 'nncnL_crmeb_copyright_image'])) {
+            $services->update(['menu_name' => 'nncnL_crmeb_copyright_image'], ['value' => json_encode($copyrightImg)]);
+        } else {
+            $services->save([
+                'menu_name' => 'nncnL_crmeb_copyright_image',
+                'type' => 'text',
+                'input_type' => 'input',
+                'config_tab_id' => 1,
+                'value' => json_encode($copyrightImg),
+                'status' => 2,
+                'info' => ''
+            ]);
+        }
+        return app('json')->success(100000);
+    }
+
+
+}

+ 126 - 0
app/adminapi/controller/Login.php

@@ -0,0 +1,126 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller;
+
+use crmeb\services\CacheService;
+use think\facade\App;
+use crmeb\utils\Captcha;
+use app\services\system\admin\SystemAdminServices;
+
+/**
+ * 后台登陆
+ * Class Login
+ * @package app\adminapi\controller
+ */
+class Login extends AuthController
+{
+
+    /**
+     * Login constructor.
+     * @param App $app
+     * @param SystemAdminServices $services
+     */
+    public function __construct(App $app, SystemAdminServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    protected function initialize()
+    {
+        // TODO: Implement initialize() method.
+    }
+
+    /**
+     * 验证码
+     * @return $this|\think\Response
+     */
+    public function captcha()
+    {
+        return app()->make(Captcha::class)->create();
+    }
+
+    /**
+     * @return mixed
+     */
+    public function ajcaptcha()
+    {
+        $captchaType = $this->request->get('captchaType');
+        return app('json')->success(aj_captcha_create($captchaType));
+    }
+
+    /**
+     * 一次验证
+     * @return mixed
+     */
+    public function ajcheck()
+    {
+        [$token, $pointJson, $captchaType] = $this->request->postMore([
+            ['token', ''],
+            ['pointJson', ''],
+            ['captchaType', ''],
+        ], true);
+        try {
+            aj_captcha_check_one($captchaType, $token, $pointJson);
+            return app('json')->success();
+        } catch (\Throwable $e) {
+            return app('json')->fail(400336);
+        }
+    }
+
+    /**
+     * 登陆
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function login()
+    {
+        [$account, $password, $key, $captchaVerification, $captchaType] = $this->request->postMore([
+            'account',
+            'pwd',
+            ['key', ''],
+            ['captchaVerification', ''],
+            ['captchaType', '']
+        ], true);
+
+        if ($captchaVerification != '') {
+            try {
+                aj_captcha_check_two($captchaType, $captchaVerification);
+            } catch (\Throwable $e) {
+                return app('json')->fail(400336);
+            }
+        }
+
+        $this->validate(['account' => $account, 'pwd' => $password], \app\adminapi\validate\setting\SystemAdminValidata::class, 'get');
+        $result = $this->services->login($account, $password, 'admin', $key);
+        if (!$result) {
+            $num = CacheService::get('login_captcha',1);
+            if ($num > 1) {
+                return app('json')->fail(400140, ['login_captcha' => 1]);
+            }
+            CacheService::set('login_captcha', $num + 1, 60);
+            return app('json')->fail(400140, ['login_captcha' => 0]);
+        }
+        CacheService::delete('login_captcha');
+        return app('json')->success($result);
+    }
+
+    /**
+     * 获取后台登录页轮播图以及LOGO
+     * @return mixed
+     */
+    public function info()
+    {
+        return app('json')->success($this->services->getLoginInfo());
+    }
+}

+ 47 - 0
app/adminapi/controller/PublicController.php

@@ -0,0 +1,47 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller;
+
+
+use crmeb\services\CacheService;
+use think\Response;
+
+class PublicController
+{
+
+    /**
+     * 下载文件
+     * @param string $key
+     * @return Response|\think\response\File
+     */
+    public function download(string $key = '')
+    {
+        if (!$key) {
+            return Response::create()->code(500);
+        }
+        $fileName = CacheService::get($key);
+        if (is_array($fileName) && isset($fileName['path']) && isset($fileName['fileName']) && $fileName['path'] && $fileName['fileName'] && file_exists($fileName['path'])) {
+            CacheService::delete($key);
+            return download($fileName['path'], $fileName['fileName']);
+        }
+        return Response::create()->code(500);
+    }
+
+    /**
+     * 获取workerman请求域名
+     * @return mixed
+     */
+    public function getWorkerManUrl()
+    {
+        return app('json')->success(getWorkerManUrl());
+    }
+}

+ 16 - 0
app/adminapi/controller/Test.php

@@ -0,0 +1,16 @@
+<?php
+/**
+ * @author: liaofei<136327134@qq.com>
+ * @day: 2020/9/12
+ */
+
+namespace app\adminapi\controller;
+
+class Test
+{
+    public function index()
+    {
+
+    }
+}
+

+ 2334 - 0
app/adminapi/controller/UpgradeController.php

@@ -0,0 +1,2334 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller;
+
+use app\Request;
+use app\services\activity\coupon\StoreCouponIssueServices;
+use app\services\activity\coupon\StoreCouponProductServices;
+use app\services\order\StoreOrderCartInfoServices;
+use app\services\order\StoreOrderCreateServices;
+use app\services\order\StoreOrderRefundServices;
+use app\services\order\StoreOrderServices;
+use app\services\system\UpgradeServices;
+use app\services\user\UserBillServices;
+use app\services\user\UserBrokerageServices;
+use app\services\user\UserMoneyServices;
+use app\services\user\UserBrokerageFrozenServices;
+use think\facade\Db;
+use think\facade\Env;
+
+
+class UpgradeController
+{
+    /**
+     * @var UpgradeServices
+     */
+    private $services;
+
+    /**
+     * UpgradeController constructor.
+     * @param UpgradeServices $services
+     */
+    public function __construct(UpgradeServices $services)
+    {
+        $this->services = $services;
+    }
+
+    /**
+     * 升级程序页面
+     * @param Request $request
+     * @return \think\response\View
+     */
+    public function index(Request $request)
+    {
+        $data = $this->upData();
+        $Title = "CRMEB升级程序";
+        $Powered = "Powered by CRMEB";
+
+        //获取当前版本号
+        $version_now = $this->getversion('.version')['version'];
+        $version_new = $data['new_version'];
+        $isUpgrade = true;
+        $executeIng = false;
+
+        return view('/upgrade/step1', [
+            'title' => $Title,
+            'powered' => $Powered,
+            'version_now' => $version_now,
+            'version_new' => $version_new,
+            'isUpgrade' => json_encode($isUpgrade),
+            'executeIng' => json_encode($executeIng),
+            'next' => 1,
+            'action' => 'upgrade'
+        ]);
+    }
+
+    /**
+     * 获取当前版本号
+     * @return array
+     */
+    public function getversion($str)
+    {
+        $version_arr = [];
+        $curent_version = @file(app()->getRootPath() . $str);
+
+        foreach ($curent_version as $val) {
+            list($k, $v) = explode('=', $val);
+            $version_arr[$k] = $v;
+        }
+        return $version_arr;
+    }
+
+    /**
+     * 写入升级过程
+     * @param string $field
+     * @param int $n
+     * @return bool
+     */
+    public function setIsUpgrade(string $field, int $n = 0)
+    {
+        $upgrade = parse_ini_file(public_path('upgrade') . '.upgrade');
+        if ($n) {
+            if (!is_array($upgrade)) {
+                $upgrade = [];
+            }
+            $string = '';
+            foreach ($upgrade as $key => $item) {
+                $string .= $key . '=' . $item . "\r\n";
+            }
+            $string .= $field . '=' . $n . "\r\n";
+            file_put_contents(public_path('upgrade') . '.upgrade', $string);
+            return true;
+        } else {
+            if (!is_array($upgrade)) {
+                return false;
+            }
+            return isset($upgrade[$field]);
+        }
+    }
+
+    public function upgrade(Request $request)
+    {
+        list($sleep, $page, $prefix) = $request->getMore([
+            ['sleep', 0],
+            ['page', 1],
+            ['prefix', 'eb_'],
+        ], true);
+        $data = $this->upData();
+        $code_now = $this->getversion('.version')['version_code'];
+        if ($data['new_code'] == $code_now) {
+            return app('json')->success(['sleep' => -1]);
+        }
+        $sql_arr = [];
+        foreach ($data['update_sql'] as $items) {
+            if ($items['code'] > $code_now) {
+                $sql_arr[] = $items;
+            }
+        }
+        //sql 执行完成,开始执行修改数据
+        if (!isset($sql_arr[$sleep])) {
+//            $limit = 100;
+//            if (!$this->setIsUpgrade('money')) {
+//                $res = $this->handleMoney((int)$sleep, (int)$page, (int)$limit);
+//                return app('json')->success($res);
+//            } elseif (!$this->setIsUpgrade('brokerage')) {
+//                $res = $this->handleBrokerage((int)$sleep, (int)$page, (int)$limit);
+//                return app('json')->success($res);
+//            } elseif (!$this->setIsUpgrade('orderRefund')) {
+//                $res = $this->handleOrderRefund((int)$sleep, (int)$page, (int)$limit);
+//                return app('json')->success($res);
+//            } else {
+//                file_put_contents(app()->getRootPath() . '.version', "version=" . $data['new_version'] . "\nversion_code=" . $data['new_code']);
+//                return app('json')->success(['sleep' => -1]);
+//            }
+//            $limit = 100;
+//            if (!$this->setIsUpgrade('cartInfo')) {
+//                $res = $this->handleCartInfo((int)$sleep, (int)$page, (int)$limit);
+//                return app('json')->success($res);
+//            } else {
+//                file_put_contents(app()->getRootPath() . '.version', "version=" . $data['new_version'] . "\nversion_code=" . $data['new_code'] . "\napp_id=ze7x9rxsv09l6pvsyo" . "\napp_key=fuF7U9zaybLa5gageVQzxtxQMFnvU2OI");
+//                $this->services->generateSignature();
+//                return app('json')->success(['sleep' => -1]);
+//            }
+            $limit = 100;
+            if (!$this->setIsUpgrade('coupon')) {
+                $res = $this->handleCoupon((int)$sleep, (int)$page, (int)$limit);
+                return app('json')->success($res);
+            } else {
+                $this->setEnv();
+                file_put_contents(app()->getRootPath() . '.version', "version=" . $data['new_version'] . "\nversion_code=" . $data['new_code'] . "\nplatform=CRMEB\napp_id=ze7x9rxsv09l6pvsyo" . "\napp_key=fuF7U9zaybLa5gageVQzxtxQMFnvU2OI");
+                $this->services->generateSignature();
+                return app('json')->success(['sleep' => -1]);
+            }
+        }
+        $sql = $sql_arr[$sleep];
+        Db::startTrans();
+        try {
+            if ($sql['type'] == 1) {
+                if (isset($sql['findSql']) && $sql['findSql']) {
+                    $table = $prefix . $sql['table'];
+                    $findSql = str_replace('@table', $table, $sql['findSql']);
+                    if (!empty(Db::query($findSql))) {
+                        $item['table'] = $table;
+                        $item['status'] = 1;
+                        $item['error'] = $table . '表已存在';
+                        $item['sleep'] = $sleep + 1;
+                        $item['add_time'] = date('Y-m-d H:i:s', time());
+                        Db::commit();
+                        return app('json')->success($item);
+                    }
+                }
+                if (isset($sql['sql']) && $sql['sql']) {
+                    $upSql = $sql['sql'];
+                    $upSql = str_replace('@table', $table, $upSql);
+                    Db::execute($upSql);
+                    $item['table'] = $table;
+                    $item['status'] = 1;
+                    $item['error'] = $table . '表添加成功';
+                    $item['sleep'] = $sleep + 1;
+                    $item['add_time'] = date('Y-m-d H:i:s', time());
+                    Db::commit();
+                    return app('json')->success($item);
+                }
+            } elseif ($sql['type'] == 2) {
+                if (isset($sql['findSql']) && $sql['findSql']) {
+                    $table = $prefix . $sql['table'];
+                    $findSql = str_replace('@table', $table, $sql['findSql']);
+                    if (empty(Db::query($findSql))) {
+                        $item['table'] = $table;
+                        $item['status'] = 1;
+                        $item['error'] = $table . '表不存在';
+                        $item['sleep'] = $sleep + 1;
+                        $item['add_time'] = date('Y-m-d H:i:s', time());
+                        Db::commit();
+                        return app('json')->success($item);
+                    }
+                }
+                if (isset($sql['sql']) && $sql['sql']) {
+                    $upSql = $sql['sql'];
+                    $upSql = str_replace('@table', $table, $upSql);
+                    Db::execute($upSql);
+                    $item['table'] = $table;
+                    $item['status'] = 1;
+                    $item['error'] = $table . '表删除成功';
+                    $item['sleep'] = $sleep + 1;
+                    $item['add_time'] = date('Y-m-d H:i:s', time());
+                    Db::commit();
+                    return app('json')->success($item);
+                }
+            } elseif ($sql['type'] == 3) {
+                if (isset($sql['findSql']) && $sql['findSql']) {
+                    $table = $prefix . $sql['table'];
+                    $findSql = str_replace('@table', $table, $sql['findSql']);
+                    if (!empty(Db::query($findSql))) {
+                        $item['table'] = $table;
+                        $item['status'] = 1;
+                        $item['error'] = $table . '表中' . $sql['field'] . '已存在';
+                        $item['sleep'] = $sleep + 1;
+                        $item['add_time'] = date('Y-m-d H:i:s', time());
+                        Db::commit();
+                        return app('json')->success($item);
+                    }
+                }
+                if (isset($sql['sql']) && $sql['sql']) {
+                    $upSql = $sql['sql'];
+                    $upSql = str_replace('@table', $table, $upSql);
+                    Db::execute($upSql);
+                    $item['table'] = $table;
+                    $item['status'] = 1;
+                    $item['error'] = $table . '表中' . $sql['field'] . '字段添加成功';
+                    $item['sleep'] = $sleep + 1;
+                    $item['add_time'] = date('Y-m-d H:i:s', time());
+                    Db::commit();
+                    return app('json')->success($item);
+                }
+            } elseif ($sql['type'] == 4) {
+                if (isset($sql['findSql']) && $sql['findSql']) {
+                    $table = $prefix . $sql['table'];
+                    $findSql = str_replace('@table', $table, $sql['findSql']);
+                    if (empty(Db::query($findSql))) {
+                        $item['table'] = $table;
+                        $item['status'] = 1;
+                        $item['error'] = $table . '表中' . $sql['field'] . '不存在';
+                        $item['sleep'] = $sleep + 1;
+                        $item['add_time'] = date('Y-m-d H:i:s', time());
+                        Db::commit();
+                        return app('json')->success($item);
+                    }
+                }
+                if (isset($sql['sql']) && $sql['sql']) {
+                    $upSql = $sql['sql'];
+                    $upSql = str_replace('@table', $table, $upSql);
+                    Db::execute($upSql);
+                    $item['table'] = $table;
+                    $item['status'] = 1;
+                    $item['error'] = $table . '表中' . $sql['field'] . '字段修改成功';
+                    $item['sleep'] = $sleep + 1;
+                    $item['add_time'] = date('Y-m-d H:i:s', time());
+                    Db::commit();
+                    return app('json')->success($item);
+                }
+            } elseif ($sql['type'] == 5) {
+                if (isset($sql['findSql']) && $sql['findSql']) {
+                    $table = $prefix . $sql['table'];
+                    $findSql = str_replace('@table', $table, $sql['findSql']);
+                    if (empty(Db::query($findSql))) {
+                        $item['table'] = $table;
+                        $item['status'] = 1;
+                        $item['error'] = $table . '表中' . $sql['field'] . '不存在';
+                        $item['sleep'] = $sleep + 1;
+                        $item['add_time'] = date('Y-m-d H:i:s', time());
+                        Db::commit();
+                        return app('json')->success($item);
+                    }
+                }
+                if (isset($sql['sql']) && $sql['sql']) {
+                    $upSql = $sql['sql'];
+                    $upSql = str_replace('@table', $table, $upSql);
+                    Db::execute($upSql);
+                    $item['table'] = $table;
+                    $item['status'] = 1;
+                    $item['error'] = $table . '表中' . $sql['field'] . '字段删除成功';
+                    $item['sleep'] = $sleep + 1;
+                    $item['add_time'] = date('Y-m-d H:i:s', time());
+                    Db::commit();
+                    return app('json')->success($item);
+                }
+            } elseif ($sql['type'] == 6) {
+                $table = $prefix . $sql['table'] ?? '';
+                if (isset($sql['findSql']) && $sql['findSql']) {
+                    $findSql = str_replace('@table', $table, $sql['findSql']);
+                    if (!empty(Db::query($findSql))) {
+                        $item['table'] = $prefix . $sql['table'];
+                        $item['status'] = 1;
+                        $item['error'] = $table . '表中此数据已存在';
+                        $item['sleep'] = $sleep + 1;
+                        $item['add_time'] = date('Y-m-d H:i:s', time());
+                        Db::commit();
+                        return app('json')->success($item);
+                    }
+                }
+                if (isset($sql['sql']) && $sql['sql']) {
+                    $upSql = $sql['sql'];
+                    $upSql = str_replace('@table', $table, $upSql);
+                    if (isset($sql['whereSql']) && $sql['whereSql']) {
+                        $whereTable = $prefix . $sql['whereTable'] ?? '';
+                        $whereSql = str_replace('@whereTable', $whereTable, $sql['whereSql']);
+                        $tabId = Db::query($whereSql)[0]['tabId'] ?? 0;
+                        if (!$tabId) {
+                            $item['table'] = $whereTable;
+                            $item['status'] = 1;
+                            $item['error'] = '查询父类ID不存在';
+                            $item['sleep'] = $sleep + 1;
+                            $item['add_time'] = date('Y-m-d H:i:s', time());
+                            Db::commit();
+                            return app('json')->success($item);
+                        }
+                        $upSql = str_replace('@tabId', $tabId, $upSql);
+                    }
+                    if (Db::execute($upSql)) {
+                        $item['table'] = $table;
+                        $item['status'] = 1;
+                        $item['error'] = '数据添加成功';
+                        $item['sleep'] = $sleep + 1;
+                        $item['add_time'] = date('Y-m-d H:i:s', time());
+                        Db::commit();
+                        return app('json')->success($item);
+                    }
+                }
+            } elseif ($sql['type'] == 7) {
+                $table = $prefix . $sql['table'] ?? '';
+                if (isset($sql['findSql']) && $sql['findSql']) {
+                    $findSql = str_replace('@table', $table, $sql['findSql']);
+                    if (empty(Db::query($findSql))) {
+                        $item['table'] = $prefix . $sql['table'];
+                        $item['status'] = 1;
+                        $item['error'] = $table . '表中此数据不存在';
+                        $item['sleep'] = $sleep + 1;
+                        $item['add_time'] = date('Y-m-d H:i:s', time());
+                        Db::commit();
+                        return app('json')->success($item);
+                    }
+                }
+                if (isset($sql['sql']) && $sql['sql']) {
+                    $upSql = $sql['sql'];
+                    $upSql = str_replace('@table', $table, $upSql);
+                    if (isset($sql['whereSql']) && $sql['whereSql']) {
+                        $whereTable = $prefix . $sql['whereTable'] ?? '';
+                        $whereSql = str_replace('@whereTable', $whereTable, $sql['whereSql']);
+                        $tabId = Db::query($whereSql)[0]['tabId'] ?? 0;
+                        if (!$tabId) {
+                            $item['table'] = $whereTable;
+                            $item['status'] = 1;
+                            $item['error'] = '查询父类ID不存在';
+                            $item['sleep'] = $sleep + 1;
+                            $item['add_time'] = date('Y-m-d H:i:s', time());
+                            Db::commit();
+                            return app('json')->success($item);
+                        }
+                        $upSql = str_replace('@tabId', $tabId, $upSql);
+                    }
+                    if (Db::execute($upSql)) {
+                        $item['table'] = $table;
+                        $item['status'] = 1;
+                        $item['error'] = '数据修改成功';
+                        $item['sleep'] = $sleep + 1;
+                        $item['add_time'] = date('Y-m-d H:i:s', time());
+                        Db::commit();
+                        return app('json')->success($item);
+                    }
+                }
+            } elseif ($sql['type'] == 8) {
+
+            } elseif ($sql['type'] == -1) {
+                $table = $prefix . $sql['table'];
+                if (isset($sql['sql']) && $sql['sql']) {
+                    $upSql = $sql['sql'];
+                    $upSql = str_replace('@table', $table, $upSql);
+                    if (isset($sql['new_table']) && $sql['new_table']) {
+                        $new_table = $prefix . $sql['new_table'];
+                        $upSql = str_replace('@new_table', $new_table, $upSql);
+                    }
+                    Db::execute($upSql);
+                    $item['table'] = $table;
+                    $item['status'] = 1;
+                    $item['error'] = $table . ' sql执行成功';
+                    $item['sleep'] = $sleep + 1;
+                    $item['add_time'] = date('Y-m-d H:i:s', time());
+                    Db::commit();
+                    return app('json')->success($item);
+                }
+            }
+        } catch (\Throwable $e) {
+            $item['table'] = $prefix . $sql['table'];
+            $item['status'] = 0;
+            $item['sleep'] = $sleep + 1;
+            $item['add_time'] = date('Y-m-d H:i:s', time());
+            $item['error'] = $e->getMessage();
+            Db::rollBack();
+            return app('json')->success($item);
+        }
+    }
+
+    /**
+     * 重写.env文件
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/04
+     */
+    public function setEnv()
+    {
+        $unique = uniqid();
+        //读取配置文件,并替换真实配置数据1
+        $strConfig = file_get_contents(root_path() . 'public/install/.env');
+        $strConfig = str_replace('#DB_HOST#', Env::get('DATABASE.HOSTNAME', ''), $strConfig);
+        $strConfig = str_replace('#DB_NAME#', Env::get('DATABASE.DATABASE', ''), $strConfig);
+        $strConfig = str_replace('#DB_USER#', Env::get('DATABASE.USERNAME', ''), $strConfig);
+        $strConfig = str_replace('#DB_PWD#', Env::get('DATABASE.PASSWORD', ''), $strConfig);
+        $strConfig = str_replace('#DB_PORT#', Env::get('DATABASE.HOSTPORT', ''), $strConfig);
+        $strConfig = str_replace('#DB_PREFIX#', Env::get('DATABASE.PREFIX', ''), $strConfig);
+        $strConfig = str_replace('#DB_CHARSET#', 'utf8', $strConfig);
+        $strConfig = str_replace('#CACHE_TYPE#', 'redis', $strConfig);
+        $strConfig = str_replace('#CACHE_PREFIX#', 'cache_' . $unique . ':', $strConfig);
+        $strConfig = str_replace('#CACHE_TAG_PREFIX#', 'cache_tag_' . $unique . ':', $strConfig);
+        $strConfig = str_replace('#RB_HOST#', Env::get('REDIS.REDIS_HOSTNAME', ''), $strConfig);
+        $strConfig = str_replace('#RB_PORT#', Env::get('REDIS.PORT', ''), $strConfig);
+        $strConfig = str_replace('#RB_PWD#', Env::get('REDIS.REDIS_PASSWORD', ''), $strConfig);
+        $strConfig = str_replace('#RB_SELECT#', Env::get('REDIS.SELECT', ''), $strConfig);
+        $strConfig = str_replace('#QUEUE_NAME#', $unique, $strConfig);
+        @chmod(root_path() . '/.env', 0777); //数据库配置文件的地址
+        @file_put_contents(root_path() . '/.env', $strConfig); //数据库配置文件的地址
+    }
+
+    /**
+     * 更新分类券
+     * @param int $sleep
+     * @param int $page
+     * @param int $limit
+     * @return array
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/04
+     */
+    public function handleCoupon(int $sleep = 1, int $page = 1, int $limit = 100)
+    {
+        $list = app()->make(StoreCouponIssueServices::class)->selectList([['category_id', '>', 0]], 'id,category_id', $page, $limit)->toArray();
+        if (count($list)) {
+            $allData = [];
+            foreach ($list as $item) {
+                $data = [
+                    'coupon_id' => $item['id'],
+                    'product_id' => 0,
+                    'category_id' => $item['category_id']
+                ];
+                $allData[] = $data;
+            }
+            if ($allData) {
+                app()->make(StoreCouponProductServices::class)->saveAll($allData);
+            }
+            $info['table'] = 'store_coupon_product';
+            $info['status'] = 1;
+            $info['error'] = '分类券数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = $page + 1;
+            $info['add_time'] = date('Y-m-d H:i:s', time());
+            return $info;
+        } else {
+            $this->setIsUpgrade('coupon', 1);
+            $info['table'] = 'store_coupon_product';
+            $info['status'] = 1;
+            $info['error'] = '分类券数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = 1;
+            $info['add_time'] = date('Y-m-d H:i:s', time());
+            return $info;
+        }
+    }
+
+    /**
+     * 处理历史余额数据
+     * @param int $sleep
+     * @param int $page
+     * @param int $limit
+     * @return mixed
+     */
+    public function handleMoney(int $sleep = 1, int $page = 1, int $limit = 100)
+    {
+        /** @var UserBillServices $userBillServics */
+        $userBillServics = app()->make(UserBillServices::class);
+        $where = ['category' => 'now_money', 'type' => ['pay_product', 'pay_product_refund', 'system_add', 'system_sub', 'recharge', 'lottery_use', 'lottery_add']];
+        $list = $userBillServics->getList($where, '*', $page, $limit, [], 'id asc');
+        if ($list) {
+            $allData = $data = [];
+            foreach ($list as $item) {
+                $data = [
+                    'uid' => $item['uid'],
+                    'link_id' => $item['link_id'],
+                    'pm' => $item['pm'],
+                    'title' => $item['title'],
+                    'type' => $item['type'],
+                    'number' => $item['number'],
+                    'balance' => $item['balance'],
+                    'mark' => $item['mark'],
+                    'add_time' => strtotime($item['add_time']),
+                ];
+                $allData[] = $data;
+            }
+            if ($allData) {
+                /** @var UserMoneyServices $userMoneyServices */
+                $userMoneyServices = app()->make(UserMoneyServices::class);
+                $userMoneyServices->saveAll($allData);
+            }
+            $info['table'] = 'user_money';
+            $info['status'] = 1;
+            $info['error'] = '余额数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = $page + 1;
+            $info['add_time'] = date('Y-m-d H:i:s', time());
+            return $info;
+        } else {
+            $this->setIsUpgrade('money', 1);
+            $info['table'] = 'user_money';
+            $info['status'] = 1;
+            $info['error'] = '余额数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = 1;
+            $info['add_time'] = date('Y-m-d H:i:s', time());
+            return $info;
+        }
+    }
+
+    /**
+     * 处理历史佣金数据
+     * @param int $sleep
+     * @param int $page
+     * @param int $limit
+     * @return mixed
+     */
+    public function handleBrokerage(int $sleep = 1, int $page = 1, int $limit = 100)
+    {
+        /** @var UserBillServices $userBillServics */
+        $userBillServics = app()->make(UserBillServices::class);
+        $where = ['category' => ['', 'now_money'], 'type' => ['brokerage', 'brokerage_user', 'extract', 'refund', 'extract_fail']];
+        $list = $userBillServics->getList($where, '*', $page, $limit, [], 'id asc');
+        if ($list) {
+            $allData = $data = [];
+            /** @var  $brokerageFrozenServices */
+            $brokerageFrozenServices = app()->make(UserBrokerageFrozenServices::class);
+            $frozenList = $brokerageFrozenServices->getColumn([['uill_id', 'in', array_column($list, 'id')], ['frozen_time', '>', time()]], 'uill_id,frozen_time', 'uill_id');
+            foreach ($list as $item) {
+                if (in_array($item['type'], ['brokerage_user', 'extract', 'refund', 'extract_fail'])) {
+                    $type = $item['type'];
+                } else {
+                    if (strpos($item['mark'], '二级')) {
+                        $type = 'two_brokerage';
+                    } else {
+                        $type = 'one_brokerage';
+                    }
+                }
+                $data = [
+                    'uid' => $item['uid'],
+                    'link_id' => $item['link_id'],
+                    'pm' => $item['pm'],
+                    'title' => $item['title'],
+                    'type' => $type,
+                    'number' => $item['number'],
+                    'balance' => $item['balance'],
+                    'mark' => $item['mark'],
+                    'frozen_time' => $frozenList[$item['id']]['frozen_time'] ?? 0,
+                    'add_time' => strtotime($item['add_time']),
+                ];
+                $allData[] = $data;
+            }
+            if ($allData) {
+                /** @var UserBrokerageServices $userBrokerageServices */
+                $userBrokerageServices = app()->make(UserBrokerageServices::class);
+                $userBrokerageServices->saveAll($allData);
+            }
+            $info['table'] = 'user_brokerage';
+            $info['status'] = 1;
+            $info['error'] = '佣金数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = $page + 1;
+            $info['add_time'] = date('Y-m-d H:i:s', time());
+            return $info;
+        } else {
+            $this->setIsUpgrade('brokerage', 1);
+            $info['table'] = 'user_brokerage';
+            $info['status'] = 1;
+            $info['error'] = '佣金数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = 1;
+            $info['add_time'] = date('Y-m-d H:i:s', time());
+            return $info;
+        }
+    }
+
+    /**
+     * 处理历史退款数据
+     * @param int $sleep
+     * @param int $page
+     * @param int $limit
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function handleOrderRefund(int $sleep = 1, int $page = 1, int $limit = 100)
+    {
+        /** @var StoreOrderServices $storeOrderServices */
+        $storeOrderServices = app()->make(StoreOrderServices::class);
+        $list = $storeOrderServices->getSplitOrderList(['refund_status' => [1, 2], ['refund_type' => [1, 2, 4, 5, 6]]], ['*'], [], $page, $limit, 'id asc');
+        $allData = $refundOrderData = [];
+        if ($list) {
+            /** @var StoreOrderCreateServices $storeOrderCreateServices */
+            $storeOrderCreateServices = app()->make(StoreOrderCreateServices::class);
+            /** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
+            $storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
+            $time = time();
+            foreach ($list as $order) {
+                //生成退款订单
+                $refundOrderData['uid'] = $order['uid'];
+                $refundOrderData['store_id'] = $order['store_id'];
+                $refundOrderData['store_order_id'] = $order['id'];
+                $refundOrderData['order_id'] = $storeOrderCreateServices->getNewOrderId('');
+                $refundOrderData['refund_num'] = $order['total_num'];
+                $refundOrderData['refund_type'] = $order['refund_type'];
+                $refundOrderData['refund_price'] = $order['pay_price'];
+                $refundOrderData['refunded_price'] = 0;
+                $refundOrderData['refund_explain'] = $order['refund_reason_wap_explain'];
+                $refundOrderData['refund_img'] = $order['refund_reason_wap_img'];
+                $refundOrderData['refund_reason'] = $order['refund_reason_wap'];
+                $refundOrderData['refund_express'] = $order['refund_express'];
+                $refundOrderData['refunded_time'] = $order['refund_type'] == 6 ? $order['refund_reason_time'] : 0;
+                $refundOrderData['add_time'] = $order['refund_reason_time'];
+                $cartInfos = $storeOrderCartInfoServices->getCartColunm(['oid' => $order['id']], 'id,cart_id,cart_num,cart_info');
+                foreach ($cartInfos as &$cartInfo) {
+                    $cartInfo['cart_info'] = is_string($cartInfo['cart_info']) ? json_decode($cartInfo['cart_info'], true) : $cartInfo['cart_info'];
+                }
+                $refundOrderData['cart_info'] = json_encode(array_column($cartInfos, 'cart_info'));
+                $allData[] = $refundOrderData;
+            }
+            if ($allData) {
+                /** @var StoreOrderRefundServices $storeOrderRefundServices */
+                $storeOrderRefundServices = app()->make(StoreOrderRefundServices::class);
+                $storeOrderRefundServices->saveAll($allData);
+            }
+            $info['table'] = 'store_order_refund';
+            $info['status'] = 1;
+            $info['error'] = '退款数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = $page + 1;
+            $info['add_time'] = date('Y-m-d H:i:s', time());
+            return $info;
+        } else {
+            $this->setIsUpgrade('orderRefund', 1);
+            $info['table'] = 'store_order_refund';
+            $info['status'] = 1;
+            $info['error'] = '退款数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = 1;
+            $info['add_time'] = date('Y-m-d H:i:s', time());
+            return $info;
+        }
+    }
+
+    /**
+     * 更新订单商品表
+     * @param int $sleep
+     * @param int $page
+     * @param int $limit
+     * @return array
+     */
+    public function handleCartInfo(int $sleep = 1, int $page = 1, int $limit = 100)
+    {
+        /** @var StoreOrderCartInfoServices $storeOrderCartInfoServices */
+        $storeOrderCartInfoServices = app()->make(StoreOrderCartInfoServices::class);
+        $list = $storeOrderCartInfoServices->selectList(['uid' => 0], 'id,oid', $page, $limit)->toArray();
+        $allData = $cartData = [];
+        if ($list) {
+            /** @var StoreOrderServices $storeOrderServices */
+            $storeOrderServices = app()->make(StoreOrderServices::class);
+            $uids = $storeOrderServices->getColumn([['id', 'in', array_column($list, 'oid')]], 'uid', 'id');
+            foreach ($list as $cart) {
+                $cartData['id'] = $cart['id'];
+                $cartData['uid'] = $uids[$cart['oid']] ?? 0;
+                $allData[] = $cartData;
+            }
+            if ($allData) {
+                $storeOrderCartInfoServices->saveAll($allData);
+            }
+            $info['table'] = 'store_order_cart_info';
+            $info['status'] = 1;
+            $info['error'] = '订单商品数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = $page + 1;
+        } else {
+            $this->setIsUpgrade('cartInfo', 1);
+            $info['table'] = 'store_order_cart_info';
+            $info['status'] = 1;
+            $info['error'] = '订单商品数据更新成功';
+            $info['sleep'] = $sleep + 1;
+            $info['page'] = 1;
+        }
+        $info['add_time'] = date('Y-m-d H:i:s', time());
+        return $info;
+    }
+
+
+    /**
+     * 升级数据
+     * @return mixed
+     */
+    public function upData()
+    {
+        $data['new_version'] = 'CRMEB-BZ v4.7.0';
+        $data['new_code'] = 470;
+        $data['update_sql'] = [
+            [
+                'code' => 470,
+                'type' => -1,
+                'table' => "store_coupon_issue_user",
+                'sql' => "ALTER TABLE `@table` DROP INDEX `uid`"
+            ],
+            [
+                'code' => 470,
+                'type' => 3,
+                'table' => "store_coupon_issue",
+                'field' => "receive_limit",
+                'findSql' => "show columns from `@table` like 'receive_limit'",
+                'sql' => "ALTER TABLE `@table` ADD `receive_limit` int(10) NOT NULL DEFAULT '0' COMMENT '每个人个领取的优惠券数量'"
+            ],
+            [
+                'code' => 470,
+                'type' => 3,
+                'table' => "store_coupon_product",
+                'field' => "category_id",
+                'findSql' => "show columns from `@table` like 'category_id'",
+                'sql' => "ALTER TABLE `@table` ADD `category_id` int(11) NOT NULL DEFAULT '0' COMMENT '分类id'"
+            ],
+            [
+                'code' => 470,
+                'type' => -1,
+                'table' => "store_order",
+                'sql' => "ALTER TABLE `@table` CHANGE `cart_id` `cart_id` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '购物车id'"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config_tab",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `eng_title` = 'online_translation'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='store'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, @tabId, '机器翻译配置', 'online_translation', 1, 0, '', 0, 0)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config_tab",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `eng_title` = 'fey_config'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='printing_deploy'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, @tabId, '飞鹅云配置', 'fey_config', 1, 0, '', 3, 0)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config_tab",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `eng_title` = 'allinpay'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='pay_config'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, @tabId, '通联支付', 'allinpay', 1, 0, '', 3, 0)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config_tab",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `eng_title` = 'pay_basic'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='pay_config'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, @tabId, '基础配置', 'pay_basic', 1, 0, '', 3, 100)"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config_tab",
+                'findSql' => "select id from @table where `eng_title` = 'offline_pay'",
+                'sql' => "DELETE FROM `@table` WHERE `eng_title` = 'offline_pay'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config_tab",
+                'findSql' => "select id from @table where `eng_title` = 'balance_pay'",
+                'sql' => "DELETE FROM `@table` WHERE `eng_title` = 'balance_pay'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config_tab",
+                'findSql' => "select id from @table where `eng_title` = 'friend_pay'",
+                'sql' => "DELETE FROM `@table` WHERE `eng_title` = 'friend_pay'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'wechat_appid'",
+                'sql' => "UPDATE `@table` SET `desc` = '微信公众号的AppID' WHERE `menu_name` = 'wechat_appid'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'wechat_appsecret'",
+                'sql' => "UPDATE `@table` SET `desc` = '微信公众号的AppSecret' WHERE `menu_name` = 'wechat_appsecret'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'wechat_encodingaeskey'",
+                'sql' => "UPDATE `@table` SET `desc` = '公众号消息加解密Key,在使用安全模式情况下要填写该值,请先在管理中心修改,然后填写该值,仅支持认证服务号' WHERE `menu_name` = 'wechat_encodingaeskey'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'wechat_qrcode'",
+                'sql' => "UPDATE `@table` SET `desc` = '引导关注公众号显示的公众号关注二维码' WHERE `menu_name` = 'wechat_qrcode'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'pay_weixin_open'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='pay_basic'",
+                'sql' => "UPDATE `@table` SET `config_tab_id` = @tabId,`parameter` = '0=>关闭\nweixin=>微信\nallinpay=>通联',`upload_type` = 1,`value` = '\"weixin\"',`info` = '微信支付',`desc` = '请选择微信支付通道,关闭用户端不展示',`sort` = 100 WHERE `menu_name` = 'pay_weixin_open'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'store_free_postage'",
+                'sql' => "UPDATE `@table` SET `desc` = '商城商品满多少金额即可包邮,此项优先于其他的运费设置' WHERE `menu_name` = 'store_free_postage'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'api'",
+                'sql' => "UPDATE `@table` SET `desc` = '配置服务器域名使用的接口地址,直接复制输入框内容(此项系统生成,无法修改)' WHERE `menu_name` = 'api'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'store_stock'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`desc` = '商品待补货数量低于多少时,提示库存不足' WHERE `menu_name` = 'store_stock'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'stor_reason'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='refund_config'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`config_tab_id` = @tabId,`upload_type` = 1 WHERE `menu_name` = 'stor_reason'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'h5_avatar'",
+                'sql' => "UPDATE `@table` SET `info` = '用户默认头像',`desc` = '用户默认头像,后台添加用户以及用户登录的默认头像显示,尺寸(80*80)' WHERE `menu_name` = 'h5_avatar'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'offline_pay_status'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='pay_basic'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`config_tab_id` = @tabId,`upload_type` = 1,`info` = '线下支付',`desc` = '线下支付请选择开启或关闭',`sort` = 89 WHERE `menu_name` = 'offline_pay_status'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'recharge_switch'",
+                'sql' => "UPDATE `@table` SET `desc` = '仅小程序端的充值开关,小程序提交审核前,需要关闭此功能' WHERE `menu_name` = 'recharge_switch'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'pay_success_printing_switch'",
+                'sql' => "UPDATE `@table` SET `desc` = '支付成功自动小票打印功能,需要购买易联云K4或者K6无线打印机,或者购买飞鹅云V58系列' WHERE `menu_name` = 'pay_success_printing_switch'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'develop_id'",
+                'sql' => "UPDATE `@table` SET `desc` = '易联云申请应用后页面开发者信息中的用户ID' WHERE `menu_name` = 'develop_id'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'printing_api_key'",
+                'sql' => "UPDATE `@table` SET `desc` = '易联云申请应用后页面开发者信息中的应用密钥' WHERE `menu_name` = 'printing_api_key'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'printing_client_id'",
+                'sql' => "UPDATE `@table` SET `desc` = '易联云申请应用后页面开发者信息中的应用ID' WHERE `menu_name` = 'printing_client_id'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'terminal_number'",
+                'sql' => "UPDATE `@table` SET `desc` = '易联云打印机标签上的终端号' WHERE `menu_name` = 'terminal_number'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'yue_pay_status'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='pay_basic'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`config_tab_id` = @tabId,`upload_type` = 1,`info` = '余额支付',`sort` = 95 WHERE `menu_name` = 'yue_pay_status'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'copy_product_apikey'",
+                'sql' => "UPDATE `@table` SET `desc` = '注册99api采集接口在个人中心复制key' WHERE `menu_name` = 'copy_product_apikey'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'member_price_status'",
+                'sql' => "UPDATE `@table` SET `desc` = '商城会员折扣价格展示' WHERE `menu_name` = 'member_price_status'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'store_user_mobile'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`desc` = '用户在授权之后强制绑定手机号,可以实现用户多端统一' WHERE `menu_name` = 'store_user_mobile'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'ali_pay_status'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='pay_basic'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`config_tab_id` = @tabId,`parameter` = '0=>关闭\nalipay=>支付宝\nallinpay=>通联',`upload_type` = 1,`value` = '\"alipay\"',`info` = '支付宝支付',`desc` = '请选择支付宝通道,关闭用户端不显示',`sort` = 98 WHERE `menu_name` = 'ali_pay_status'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'alipay_public_key'",
+                'sql' => "UPDATE `@table` SET `desc` = '支付宝加签完成后申城的支付宝公钥' WHERE `menu_name` = 'alipay_public_key'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'config_export_siid'",
+                'sql' => "UPDATE `@table` SET `desc` = '请购买快递100二代云打印机(KX100L3),官网:https://www.kuaidi100.com/cloud/print/cloudprinterSecond.shtml' WHERE `menu_name` = 'config_export_siid'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'service_feedback'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`desc` = '暂无客服在线是,联系客服跳转的客服反馈页面的显示文字' WHERE `menu_name` = 'service_feedback'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'tourist_avatar'",
+                'sql' => "DELETE FROM `@table` WHERE `menu_name` = 'tourist_avatar'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'pc_logo'",
+                'sql' => "UPDATE `@table` SET `status` = 0 WHERE `menu_name` = 'pc_logo'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'record_No'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = '网站的备案号,显示在H5和PC端底部' WHERE `menu_name` = 'record_No'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'routine_contact_type'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`parameter` = '0=>跟随系统\n1=>小程序客服',`upload_type` = 1,`desc` = '跟随系统:跟随系统使用默认客服、电话或者跳转链接;小程序客服:需要在小程序后台配置客服用户;' WHERE `menu_name` = 'routine_contact_type'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'station_open'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`upload_type` = 1,`desc` = '站点开始|关闭(用于升级等临时关闭),关闭后前端会弹窗显示站点升级中,请稍后访问' WHERE `menu_name` = 'station_open'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'uni_brokerage_price'",
+                'sql' => "UPDATE `@table` SET `info` = '推广佣金单价' WHERE `menu_name` = 'uni_brokerage_price'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'is_self_brokerage'",
+                'sql' => "UPDATE `@table` SET `sort` = 99 WHERE `menu_name` = 'is_self_brokerage'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'refund_name'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = '用户退货退款后台同意之后,显示在退货订单详情显示的接受退货的人员姓名' WHERE `menu_name` = 'refund_name'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'refund_phone'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = '用户退货退款后台同意之后,显示在退货订单详情显示的接受退货的人员电话' WHERE `menu_name` = 'refund_phone'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'refund_address'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = '用户退货退款后台同意之后,显示在退货订单详情显示的接受退货的地址信息' WHERE `menu_name` = 'refund_address'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'wechat_open_app_id'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`info` = '开放平台AppID',`desc` = '微信开放平台申请网页应用后给予的AppID' WHERE `menu_name` = 'wechat_open_app_id'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'wechat_open_app_secret'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`info` = '开放平台AppSecret',`desc` = '微信开放平台申请网页应用后给予的AppSecret' WHERE `menu_name` = 'wechat_open_app_secret'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'contact_number'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = 'PC底部显示的联系电话' WHERE `menu_name` = 'contact_number'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'company_address'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = 'PC底部显示的公司地址' WHERE `menu_name` = 'company_address'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'copyright'",
+                'sql' => "DELETE FROM `@table` WHERE `menu_name` = 'copyright'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'site_keywords'",
+                'sql' => "UPDATE `@table` SET `status` = 0 WHERE `menu_name` = 'site_keywords'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'site_description'",
+                'sql' => "UPDATE `@table` SET `status` = 0 WHERE `menu_name` = 'site_description'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'product_phone_buy_url'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`upload_type` = 1,`desc` = '商品详情手机购买显示公众号码或者小程序码' WHERE `menu_name` = 'product_phone_buy_url'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'customer_type'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`upload_type` = 1,`desc` = '系统客服:点击联系客服使用系统的自带客服;拨打电话:点击联系客服拨打客服电话;跳转链接:跳转外部链接联系客服' WHERE `menu_name` = 'customer_type'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'customer_url'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = '客服类型选择跳转链接时,跳转的链接地址' WHERE `menu_name` = 'customer_url'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'customer_phone'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = '客服类型选择不打电话是,用户点击联系客服的联系电话' WHERE `menu_name` = 'customer_phone'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'wechat_app_appid'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = '微信开放平台申请移动应用后给予的APPID' WHERE `menu_name` = 'wechat_app_appid'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'wechat_app_appsecret'",
+                'sql' => "UPDATE `@table` SET `upload_type` = 1,`width` = 0,`desc` = '微信开放平台申请移动应用后给予的AppSecret' WHERE `menu_name` = 'wechat_app_appsecret'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'statistic_script'",
+                'sql' => "UPDATE `@table` SET `desc` = '程序访问统计代码,填写script标签内的内容' WHERE `menu_name` = 'statistic_script'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'weixin_ckeck_file'",
+                'sql' => "UPDATE `@table` SET `desc` = '配置微信网页授权域名时候下载的微信校验文件,在此处上传' WHERE `menu_name` = 'weixin_ckeck_file'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'ico_path'",
+                'sql' => "UPDATE `@table` SET `desc` = '程序ICO图标,更换后需要清除浏览器缓存' WHERE `menu_name` = 'ico_path'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'print_type'",
+                'sql' => "UPDATE `@table` SET `parameter` = '1=>易联云\n2=>飞鹅云',`desc` = '打印平台选择' WHERE `menu_name` = 'print_type'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'customer_corpId'",
+                'sql' => "UPDATE `@table` SET `width` = 0,`desc` = '如果客服链接填写企业微信客服,小程序需要跳转企业微信客服的话需要配置此项,并且在小程序客服中绑定企业ID' WHERE `menu_name` = 'customer_corpId'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'friend_pay_status'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='pay_basic'",
+                'sql' => "UPDATE `@table` SET `input_type` = 'input',`config_tab_id` = @tabId,`info` = '好友代付开关' WHERE `menu_name` = 'friend_pay_status'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'aliyun_RegionId'",
+                'sql' => "UPDATE `@table` SET `status` = 0 WHERE `menu_name` = 'aliyun_RegionId'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'hs_accesskey'",
+                'sql' => "UPDATE `@table` SET `desc` = '' WHERE `menu_name` = 'hs_accesskey'"
+            ],
+            [
+                'code' => 470,
+                'type' => 7,
+                'table' => "system_config",
+                'findSql' => "select id from @table where `menu_name` = 'hs_secretkey'",
+                'sql' => "UPDATE `@table` SET `desc` = '' WHERE `menu_name` = 'hs_secretkey'"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'fey_user'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='fey_config'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'fey_user', 'text', 'input', @tabId, '', 1, '', 0, 0, '\"\"', '飞鹅云USER', '飞鹅云后台注册账号', 10, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'fey_ukey'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='fey_config'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'fey_ukey', 'text', 'input', @tabId, '', 1, '', 0, 0, '\"\"', '飞鹅云UYEK', '飞鹅云后台注册账号后生成的UKEY 【备注:这不是填打印机的KEY】', 7, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'fey_sn'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='fey_config'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'fey_sn', 'text', 'input', @tabId, '', 1, '', 100, 0, '\"\"', '飞鹅云SN', '打印机标签上的编号,必须要在管理后台里添加打印机或调用API接口添加之后,才能调用API', 0, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'allin_private_key'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='allinpay'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'allin_private_key', 'text', 'input', @tabId, '', 1, '', 100, 5, '\"\"', '通联MD5私钥', '通联支付的MD5私钥,可以在商户后台设置中进行配置', 96, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'allin_cusid'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='allinpay'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'allin_cusid', 'text', '', @tabId, '', 1, '', 0, 0, '\"\"', '通联商户号', '通联支付商户号,由贵公司申请获得', 99, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'allin_appid'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='allinpay'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'allin_appid', 'text', '', @tabId, '', 1, '', 100, 0, '\"\"', '通联支付Appid', '通联商户后台的设置-》对接设置中查看', 98, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'queue_open'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='web_site'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'queue_open', 'radio', 'input', @tabId, '0=>关闭\n1=>开启', 1, '', 0, 0, '\"0\"', '消息队列', '是否启用消息队列,启用后提升程序运行速度,启用前必须配置Redis缓存,文档地址:https://doc.crmeb.com/single/crmeb_v4/7217', 0, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'get_avatar'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='routine'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'get_avatar', 'radio', 'input', @tabId, '0=>关闭\n1=>开启', 1, '', 0, 0, '\"0\"', '强制获取昵称头像', '是否在小程序用户授权之后,弹窗获取用户的昵称和头像', 0, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'share_qrcode'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='wechat'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'share_qrcode', 'radio', 'input', @tabId, '0=>商城\n1=>公众号', 1, '', 0, 0, '\"0\"', '公众号推广码类型', '公众号生成的推广码类型:商城:扫码直接进入商城,公众号:扫码进入公众号后推送商城的链接', 0, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'member_brokerage'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='brokerage_set'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'member_brokerage', 'radio', 'input', @tabId, '1=>开启\n0=>关闭', 1, '', 0, 0, '\"0\"', '购买付费会员返佣', '购买付费会员是否按照设置的佣金比例进行返佣', 98, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => 6,
+                'table' => "system_config",
+                'whereTable' => "system_config_tab",
+                'findSql' => "select id from @table where `menu_name` = 'user_brokerage_type'",
+                'whereSql' => "SELECT id as tabId FROM `@whereTable` WHERE `eng_title`='brokerage_set'",
+                'sql' => "INSERT INTO `@table` VALUES (NULL, 'user_brokerage_type', 'radio', 'input', @tabId, '0=>按照商品价格返佣\n1=>按照实际支付价格返佣', 1, '', 0, 0, '\"0\"', '返佣类型', '选择返佣类型,按照商品价格返佣(按照商品售价计算返佣金额)以及按照实际支付价格返佣(按照商品的实际支付价格计算返佣 )', 97, 1)"
+            ],
+            [
+                'code' => 470,
+                'type' => -1,
+                'table' => "system_menus",
+                'sql' => "truncate table `@table`"
+            ],
+            [
+                'code' => 470,
+                'type' => -1,
+                'table' => "system_menus",
+                'sql' => <<<SQL
+INSERT INTO `@table` (`id`, `pid`, `icon`, `menu_name`, `module`, `controller`, `action`, `api_url`, `methods`, `params`, `sort`, `is_show`, `is_show_path`, `access`, `menu_path`, `path`, `auth_type`, `header`, `is_header`, `unique_auth`, `is_del`) VALUES
+(1, 0, 'md-basket', '商品', 'admin', 'product', 'index', '', '', '[]', 115, 1, 0, 1, '/product', '', 1, '0', 1, 'admin-product', 0),
+(2, 1, '', '商品管理', 'admin', 'product.product', 'index', '', '', '[]', 1, 1, 0, 1, '/product/product_list', '', 1, '', 0, 'admin-store-storeProuduct-index', 0),
+(3, 1, '', '商品分类', 'admin', 'product.storeCategory', 'index', '', '', '[]', 1, 1, 0, 1, '/product/product_classify', '', 1, 'product', 0, 'admin-store-storeCategory-index', 0),
+(4, 0, 'md-cart', '订单', 'admin', 'order', 'index', '', '', '[]', 120, 1, 0, 1, '/order', '', 1, 'home', 1, 'admin-order', 0),
+(5, 4, '', '订单管理', 'admin', 'order.store_order', 'index', '', '', '[]', 10, 1, 0, 1, '/order/list', '4', 1, 'order', 0, 'admin-order-storeOrder-index', 0),
+(6, 1, '', '商品评论', 'admin', 'store.store_product_reply', 'index', '', '', '[]', 0, 1, 0, 1, '/product/product_reply', '', 1, 'product', 0, 'product-product-reply', 0),
+(7, 0, 'md-home', '主页', 'admin', 'index', '', '', '', '[]', 127, 1, 0, 1, '/home/', '', 1, 'home', 1, 'admin-index-index', 0),
+(9, 0, 'md-person', '用户', 'admin', 'user.user', '', '', '', '[]', 125, 1, 0, 1, '/user', '', 1, 'user', 1, 'admin-user', 0),
+(10, 9, '', '用户管理', 'admin', 'user.user', 'index', '', '', '[]', 10, 1, 0, 1, '/user/list', '', 1, 'user', 0, 'admin-user-user-index', 0),
+(11, 9, '', '用户等级', 'admin', 'user.user_level', 'index', '', '', '[]', 7, 1, 0, 1, '/user/level', '', 1, 'user', 0, 'user-user-level', 0),
+(12, 0, 'md-settings', '设置', 'admin', 'setting.system_config', 'index', '', '', '[]', 1, 1, 0, 1, '/setting', '', 1, 'setting', 1, 'admin-setting', 0),
+(14, 12, '', '管理权限', 'admin', 'setting.system_admin', '', '', '', '[]', 0, 1, 0, 1, '/setting/auth/list', '', 1, 'setting', 0, 'setting-system-admin', 0),
+(19, 14, '', '角色管理', 'admin', 'setting.system_role', 'index', '', '', '[]', 1, 1, 0, 1, '/setting/system_role/index', '', 1, 'setting', 0, 'setting-system-role', 0),
+(20, 14, '', '管理员列表', 'admin', 'setting.system_admin', 'index', '', '', '[]', 1, 1, 0, 1, '/setting/system_admin/index', '', 1, 'setting', 0, 'setting-system-list', 0),
+(21, 14, '', '权限规则', 'admin', 'setting.system_menus', 'index', '', '', '[]', 1, 1, 0, 1, '/setting/system_menus/index', '', 1, 'setting', 0, 'setting-system-menus', 0),
+(22, 1, '', '产品添加', 'admin', 'store.store_product', 'save', '', '', '[]', 1, 1, 1, 1, '/product/add_product', '', 1, 'product', 0, 'product-product-save', 0),
+(23, 12, '', '系统设置', 'admin', 'setting.system_config', 'index', '', '', '[]', 10, 1, 0, 1, '/setting/system_config', '', 1, 'setting', 0, 'setting-system-config', 0),
+(25, 0, 'md-hammer', '维护', 'admin', 'system', '', '', '', '[]', 0, 1, 0, 1, '/system', '', 1, 'setting', 1, 'admin-system', 0),
+(26, 0, 'ios-people', '分销', 'admin', 'agent', '', '', '', '[]', 104, 1, 0, 1, '/agent', '', 1, 'user', 1, 'admin-agent', 0),
+(27, 0, 'ios-paper-plane', '营销', 'admin', 'marketing', '', '', '', '[]', 110, 1, 0, 1, '/marketing', '', 1, 'home', 1, 'admin-marketing', 0),
+(28, 26, '', '分销设置', 'admin', 'setting.system_config', '', '', '', '[]', 1, 1, 0, 1, '/setting/system_config_retail/2/9', '', 1, 'setting', 0, 'setting-system-config', 0),
+(29, 26, '', '分销员管理', 'admin', 'agent.agent_manage', 'index', '', '', '[]', 99, 1, 0, 1, '/agent/agent_manage/index', '', 1, 'user', 0, 'agent-agent-manage', 0),
+(30, 27, '', '优惠券', 'admin', 'marketing.store_coupon', '', '', '', '[]', 100, 1, 0, 1, '/marketing/store_coupon', '27', 1, 'marketing', 0, 'marketing-store_coupon-index', 0),
+(31, 27, '', '砍价管理', 'admin', 'marketing.store_bargain', '', '', '', '[]', 85, 1, 0, 1, '/marketing/store_bargain', '27', 1, 'marketing', 0, 'marketing-store_bargain-index', 0),
+(32, 27, '', '拼团管理', 'admin', 'marketing.store_combination', '', '', '', '[]', 80, 1, 0, 1, '/marketing/store_combination', '27', 1, 'marketing', 0, 'marketing-store_combination-index', 0),
+(33, 27, '', '秒杀管理', 'admin', 'marketing.store_seckill', '', '', '', '[]', 75, 1, 0, 1, '/marketing/store_seckill', '27', 1, 'marketing', 0, 'marketing-store_seckill-index', 0),
+(34, 27, '', '积分管理', 'admin', 'marketing.user_point', '', '', '', '[]', 95, 1, 0, 1, '/marketing/user_point', '27', 1, 'marketing', 0, 'marketing-user_point-index', 0),
+(35, 0, 'logo-usd', '财务', 'admin', 'finance', '', '', '', '[]', 90, 1, 0, 1, '/finance', '', 1, 'home', 1, 'admin-finance', 0),
+(36, 35, '', '财务操作', 'admin', 'finance', '', '', '', '[]', 1, 1, 0, 1, '/finance/user_extract', '', 1, 'finance', 0, 'finance-user_extract-index', 0),
+(37, 35, '', '财务记录', 'admin', 'finance', '', '', '', '[]', 1, 1, 0, 1, '/finance/user_recharge', '', 1, 'finance', 0, 'finance-user-recharge-index', 0),
+(38, 35, '', '佣金记录', 'admin', 'finance', '', '', '', '[]', 1, 1, 0, 1, '/finance/finance', '', 1, 'finance', 0, 'finance-finance-index', 0),
+(39, 36, '', '提现申请', 'admin', 'finance.user_extract', '', '', '', '[]', 1, 1, 0, 1, '/finance/user_extract/index', '', 1, 'finance', 0, 'finance-user_extract', 0),
+(40, 37, '', '充值记录', 'admin', 'finance.user_recharge', '', '', '', '[]', 1, 1, 0, 1, '/finance/user_recharge/index', '', 1, 'finance', 0, 'finance-user-recharge', 0),
+(42, 38, '', '佣金记录', 'admin', 'finance.finance', '', '', '', '[]', 1, 1, 0, 1, '/finance/finance/commission', '', 1, 'finance', 0, 'finance-finance-commission', 0),
+(43, 0, 'ios-book', '内容', 'admin', 'cms', '', '', '', '[]', 85, 1, 0, 1, '/cms', '', 1, 'home', 1, 'admin-cms', 0),
+(44, 43, '', '文章管理', 'admin', 'cms.article', 'index', '', '', '[]', 1, 1, 0, 1, '/cms/article/index', '', 1, 'cms', 0, 'cms-article-index', 0),
+(45, 43, '', '文章分类', 'admin', 'cms.article_category', 'index', '', '', '[]', 1, 1, 0, 1, '/cms/article_category/index', '', 1, 'cms', 0, 'cms-article-category', 0),
+(46, 43, '', '文章添加', 'admin', 'cms.article', 'add_article', '', '', '[]', 0, 1, 1, 1, '/cms/article/add_article', '', 1, 'cms', 0, 'cms-article-creat', 0),
+(47, 65, '', '系统日志', 'admin', 'system.system_log', 'index', '', '', '[]', 0, 1, 0, 1, '/system/maintain/system_log/index', '', 1, 'system', 0, 'system-maintain-system-log', 0),
+(48, 7, '', '控制台', 'admin', 'index', 'index', '', '', '[]', 127, 1, 0, 1, '/home/index', '', 1, 'home', 0, '', 1),
+(56, 25, '', '开发配置', 'admin', 'system', '', '', '', '[]', 10, 1, 0, 1, '/system/config', '', 1, 'system', 0, 'system-config-index', 0),
+(57, 65, '', '刷新缓存', 'admin', 'system', 'clear', '', '', '[]', 1, 1, 0, 1, '/system/maintain/clear/index', '', 1, 'system', 0, 'system-clear', 0),
+(64, 65, '', '文件校验', 'admin', 'system.system_file', 'index', '', '', '[]', 0, 1, 0, 1, '/system/maintain/system_file/index', '', 1, 'system', 0, 'system-maintain-system-file', 0),
+(65, 25, '', '安全维护', 'admin', 'system', '', '', '', '[]', 7, 1, 0, 1, '/system/maintain', '', 1, 'system', 0, 'system-maintain-index', 0),
+(66, 1073, '', '清除数据', 'admin', 'system.system_cleardata', 'index', '', '', '[]', 0, 1, 0, 1, '/system/maintain/system_cleardata/index', '25/1073', 1, 'system', 0, 'system-maintain-system-cleardata', 0),
+(67, 1073, '', '数据备份', 'admin', 'system.system_databackup', 'index', '', '', '[]', 0, 1, 0, 1, '/system/maintain/system_databackup/index', '25/1073', 1, 'system', 0, 'system-maintain-system-databackup', 0),
+(69, 135, '', '公众号', 'admin', 'wechat', '', '', '', '[]', 4, 1, 0, 1, '/app/wechat', '135', 1, 'app', 0, 'admin-wechat', 0),
+(70, 30, '', '优惠券模板', 'admin', 'marketing.store_coupon', 'index', '', '', '[]', 0, 0, 0, 1, '/marketing/store_coupon/index', '', 1, 'marketing', 0, 'marketing-store_coupon', 0),
+(71, 30, '', '优惠券列表', 'admin', 'marketing.store_coupon_issue', 'index', '', '', '[]', 0, 1, 0, 1, '/marketing/store_coupon_issue/index', '', 1, 'marketing', 0, 'marketing-store_coupon_issue', 0),
+(72, 30, '', '用户领取记录', 'admin', 'marketing.store_coupon_user', 'index', '', '', '[]', 0, 1, 0, 1, '/marketing/store_coupon_user/index', '', 1, 'marketing', 0, 'marketing-store_coupon_user', 0),
+(74, 31, '', '砍价商品', 'admin', 'marketing.store_bargain', 'index', '', '', '[]', 0, 1, 0, 1, '/marketing/store_bargain/index', '', 1, 'marketing', 0, 'marketing-store_bargain', 0),
+(75, 32, '', '拼团商品', 'admin', 'marketing.store_combination', 'index', '', '', '[]', 0, 1, 0, 1, '/marketing/store_combination/index', '', 1, 'marketing', 0, 'marketing-store_combination', 0),
+(76, 32, '', '拼团列表', 'admin', 'marketing.store_combination', 'combina_list', '', '', '[]', 0, 1, 0, 1, '/marketing/store_combination/combina_list', '', 1, 'marketing', 0, 'marketing-store_combination-combina_list', 0),
+(77, 33, '', '秒杀商品', 'admin', 'marketing.store_seckill', 'index', '', '', '[]', 0, 1, 0, 1, '/marketing/store_seckill/index', '', 1, 'marketing', 0, 'marketing-store_seckill', 0),
+(78, 33, '', '秒杀配置', 'admin', 'marketing.store_seckill', 'index', '', '', '[]', 0, 1, 0, 1, '/marketing/store_seckill_data/index/49', '', 1, 'marketing', 0, 'marketing-store_seckill-data', 0),
+(79, 34, '', '积分配置', 'admin', 'setting.system_config/index.html', 'index', '', '', '[]', 0, 1, 0, 1, '/marketing/integral/system_config/3/11', '', 1, 'marketing', 0, 'marketing-integral-system_config', 0),
+(90, 32, '', '拼团添加', 'admin', 'marketing.store_combination', '', '', '', '[]', 0, 1, 0, 1, '/marketing/store_combination/add_commodity/:id', '', 1, 'marketing', 0, '', 1),
+(91, 69, '', '公众号配置', 'admin', 'application.wechat', '', '', '', '[]', 0, 1, 0, 1, '/app/wechat/setting', '', 1, 'app', 0, '', 1),
+(92, 69, '', '微信菜单', 'admin', 'application.wechat_menus', 'index', '', '', '[]', 0, 1, 0, 1, '/app/wechat/setting/menus/index', '', 1, 'app', 0, 'application-wechat-menus', 0),
+(94, 1056, '', '一号通', 'admin', 'setting.sms_config', '', '', '', '[]', 8, 1, 0, 1, '/setting/sms/sms_config/index', '12/1056', 1, 'setting', 0, 'setting-sms', 0),
+(95, 94, '', '账户管理', 'admin', 'sms.sms_config', 'index', '', '', '[]', 0, 0, 0, 1, '/setting/sms/sms_config/index', '', 1, 'setting', 0, 'setting-sms-sms-config', 0),
+(96, 94, '', '短信模板', 'admin', 'sms.sms_template_apply', 'index', '', '', '[]', 0, 0, 0, 1, '/setting/sms/sms_template_apply/index', '', 1, 'setting', 0, 'setting-sms-config-template', 0),
+(97, 94, '', '套餐购买', 'admin', 'sms.sms_pay', 'index', '', '', '[]', 0, 0, 0, 1, '/setting/sms/sms_pay/index', '', 1, 'setting', 0, 'setting-sms-sms-template', 0),
+(99, 1, '', '商品规格', 'admin', 'store.store_product', 'index', '', '', '[]', 1, 1, 0, 1, '/product/product_attr', '', 1, 'product', 0, 'product-product-attr', 0),
+(105, 22, '', '添加产品保存', 'admin', 'store.store_product', 'save', 'product/product/<id>', 'POST', '[]', 0, 0, 0, 1, '/product/save', '', 2, 'product', 0, 'product-save', 0),
+(108, 2, '', '产品列表', 'admin', 'product.product', 'index', 'product/product', 'GET', '[]', 20, 0, 0, 1, '/product/product', '1/2', 2, 'product', 0, 'product-product-index', 0),
+(109, 69, '', '图文管理', 'admin', 'wechat.wechat_news_category', 'index', '', '', '[]', 0, 1, 0, 1, '/app/wechat/news_category/index', '', 1, 'app', 0, 'wechat-wechat-news-category-index', 0),
+(110, 69, '', '图文添加', 'admin', 'wechat.wechat_news_category', 'save', '', '', '[]', 0, 1, 1, 1, '/app/wechat/news_category/save', '', 1, 'app', 0, 'wechat-wechat-news-category-save', 0),
+(111, 56, '', '配置分类', 'admin', 'setting.system_config_tab', 'index', '', '', '[]', 99, 1, 0, 1, '/system/config/system_config_tab/index', '25/56', 1, 'system', 0, 'system-config-system_config-tab', 0),
+(112, 56, '', '组合数据', 'admin', 'setting.system_group', 'index', '', '', '[]', 98, 1, 0, 1, '/system/config/system_group/index', '25/56', 1, 'system', 0, 'system-config-system_config-group', 0),
+(113, 114, '', '关注回复', 'admin', 'wechat.reply', 'index', '', '', '[]', 0, 1, 0, 1, '/app/wechat/reply/follow/subscribe', '135/69/114', 1, 'app', 0, 'wechat-wechat-reply-subscribe', 0),
+(114, 69, '', '自动回复', 'admin', 'wechat.reply', '', '', '', '[]', 0, 1, 0, 1, '/app/wechat/reply', '', 1, 'app', 0, 'wechat-wechat-reply-index', 0),
+(115, 114, '', '关键字回复', 'admin', 'wechat.reply', 'keyword', '', '', '[]', 0, 1, 0, 1, '/app/wechat/reply/keyword', '', 1, 'app', 0, 'wechat-wechat-reply-keyword', 0),
+(116, 114, '', '无效词回复', 'admin', 'wechat.reply', 'index', '', '', '[]', 0, 1, 0, 1, '/app/wechat/reply/index/default', '135/69/114', 1, 'app', 0, 'wechat-wechat-reply-default', 0),
+(125, 111, '', '配置列表', 'admin', 'system.config', 'index', '', '', '[]', 0, 0, 1, 1, '/system/config/system_config_tab/list', '25/56/111', 1, 'system', 0, 'system-config-system_config_tab-list', 0),
+(126, 112, '', '组合数据列表', 'admin', 'system.system_group', 'list', '', '', '[]', 0, 0, 1, 1, '/system/config/system_group/list', '25/56/112', 1, 'system', 0, 'system-config-system_config-list', 0),
+(128, 656, '', '数据配置', 'admin', 'setting.system_group_data', 'index', '', '', '[]', 2, 1, 0, 1, '/setting/system_visualization_data', '12/656', 1, 'system', 0, 'admin-setting-system_visualization_data', 0),
+(134, 114, '', '关键字添加', 'admin', '', 'index', '', '', '[]', 0, 1, 1, 1, '/app/wechat/reply/keyword/save', '', 1, 'app', 0, 'wechat-wechat-reply-save', 0),
+(135, 0, 'md-cube', '应用', 'admin', 'app', 'index', '', '', '[]', 70, 1, 0, 1, '/app', '', 1, 'app', 1, 'admin-app', 0),
+(144, 303, '', '提货点设置', 'admin', 'merchant.system_store', 'index', '', '', '[]', 5, 1, 0, 1, '/setting/merchant/system_store/index', '', 1, '', 0, 'setting-system-config-merchant', 0),
+(145, 1073, '', '物流公司', 'admin', 'freight.express', 'index', '', '', '[]', 4, 1, 0, 1, '/setting/freight/express/index', '25/1073', 1, '', 0, 'setting-freight-express', 0),
+(146, 31, '', '添加砍价', 'admin', '/marketing.store_bargain', 'create', '', '', '[]', 0, 1, 1, 1, '/marketing/store_bargain/create', '', 1, '', 0, 'marketing-store_bargain-create', 0),
+(147, 32, '', '添加拼团', 'admin', 'marketing.store_combination', 'create', '', '', '[]', 0, 1, 1, 1, '/marketing/store_combination/create', '', 1, '', 0, 'marketing-store_combination-create', 0),
+(148, 33, '', '添加秒杀', 'admin', 'marketing.store_seckill', 'create', '', '', '[]', 0, 1, 1, 1, '/marketing/store_seckill/create', '', 1, '', 0, 'marketing-store_seckill-create', 0),
+(154, 34, '', '签到配置', 'admin', 'setting.system_group_data', 'index', '', '', '[]', 0, 1, 0, 1, '/marketing/sign', '', 1, '', 0, 'marketing-sign-index', 0),
+(165, 0, 'md-chatboxes', '客服', 'admin', 'setting.storeService', 'index', '', '', '[]', 104, 1, 0, 1, '/kefu', '', 1, '', 1, 'setting-store-service', 0),
+(166, 65, '', '日志', 'admin', '', '', '', '', '[]', 0, 1, 1, 1, '/system/log', '25/65', 1, '', 0, 'system-log', 0),
+(169, 577, '', '商品删除', 'admin', 'product', '商品删除', 'product/product/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '0', 0, '', 0),
+(170, 3, '', '分类列表', 'admin', '', '', 'product/category', 'GET', '[]', 0, 0, 0, 1, 'product/category', '', 2, '', 0, '', 0),
+(171, 578, '', '删除分类', 'admin', '', '', 'product/category/<id>', 'DELETE', '[]', 0, 0, 0, 1, 'product/category/<id>', '', 2, '', 0, '', 0),
+(172, 578, '', '修改分类', 'admin', '', '', 'product/category/<id>', 'PUT', '[]', 0, 0, 0, 1, 'product/category/<id>', '', 2, '', 0, '', 0),
+(173, 578, '', '新增分类', 'admin', '', '', 'product/category', 'POST', '[]', 0, 0, 0, 1, 'product/category', '', 2, '', 0, 'product-save-cate', 0),
+(174, 578, '', '分类状态', 'admin', '', '', 'product/category/set_show/<id>/<is_show>', 'PUT', '[]', 0, 0, 0, 1, 'product/category/set_show/<id>/<is_show>', '', 2, '', 0, '', 0),
+(175, 578, '', '快速编辑', 'admin', '', '', 'product/category/set_category/<id>', 'PUT', '[]', 0, 0, 0, 1, 'product/category/set_category/<id>', '', 2, '', 0, '', 0),
+(176, 578, '', '分类表单添加', 'admin', '', '', 'product/category/create', 'GET', '[]', 0, 0, 0, 1, 'category/create', '', 2, '', 0, '', 0),
+(177, 578, '', '分类表单编辑', 'admin', '', '', 'product/category/<id>', 'GET', '[]', 0, 0, 0, 1, 'category/<id>/edit', '', 2, '', 0, '', 0),
+(178, 3, '', '分类树形列表', 'admin', '', '', 'product/category/tree/<type>', 'GET', '[]', 0, 0, 0, 1, 'category/tree/:type', '', 2, '', 0, '', 0),
+(179, 577, '', '产品状态', 'admin', '', '', 'product/product/set_show/<id>/<is_show>', 'PUT', '[]', 0, 0, 0, 1, 'product/set_show/<id>/<is_show>', '', 2, '', 0, '', 0),
+(180, 577, '', '快速编辑', 'admin', '', '', 'product/product/set_product/<id>', 'PUT', '[]', 0, 0, 0, 1, 'product/product/set_product/<id>', '', 2, '', 0, '', 0),
+(181, 577, '', '批量上架商品', 'admin', '', '', 'product/product/product_show', 'PUT', '[]', 0, 0, 0, 1, 'product/product/product_show', '', 2, '', 0, 'product-product-product_show', 0),
+(182, 577, '', '采集商品', 'admin', '', '', 'product/copy', 'POST', '[]', 0, 0, 0, 1, 'product/crawl', '', 2, '', 0, 'product-crawl-save', 0),
+(183, 577, '', '采集商品保存', 'admin', '', '', 'product/crawl/save', 'POST', '[]', 0, 0, 0, 1, 'product/crawl/save', '', 2, '', 0, '', 0),
+(184, 579, '', '虚拟评论表单', 'admin', '', '', 'product/reply/fictitious_reply/<product_id>', 'GET', '[]', 0, 0, 0, 1, 'product/reply/fictitious_reply', '', 2, '', 0, '', 0),
+(185, 579, '', '保存虚拟评论', 'admin', '', '', 'product/reply/save_fictitious_reply', 'POST', '[]', 0, 0, 0, 1, 'product/reply/save_fictitious_reply', '', 2, '', 0, 'product-reply-save_fictitious_reply', 0),
+(186, 22, '', '获取属性模板列表', 'admin', '', '', 'product/product/get_rule', 'GET', '[]', 0, 0, 0, 1, 'product/product/get_rule', '', 2, '', 0, '', 0),
+(187, 22, '', '运费模板列表', 'admin', '', '', 'product/product/get_template', 'GET', '[]', 0, 0, 0, 1, 'product/product/get_template', '', 2, '', 0, '', 0),
+(188, 579, '', '删除评论', 'admin', '', '', 'product/reply/<id>', 'DELETE', '[]', 0, 0, 0, 1, 'product/reply/<id>', '', 2, '', 0, '', 0),
+(189, 579, '', '评论回复', 'admin', '', '', 'product/reply/set_reply/<id>', 'PUT', '[]', 0, 0, 0, 1, 'reply/set_reply/<id>', '', 2, '', 0, '', 0),
+(190, 6, '', '评论列表', 'admin', '', '', 'product/reply', 'GET', '[]', 0, 0, 0, 1, 'product/reply', '', 2, '', 0, '', 0),
+(191, 22, '', '生成属性', 'admin', '', '', 'product/generate_attr/<id>/<type>', 'POST', '[]', 0, 0, 0, 1, 'product/generate_attr/<id>', '', 2, '', 0, '', 0),
+(192, 2, '', '商品列表头部', 'admin', '', '', 'product/product/type_header', 'GET', '[]', 10, 0, 0, 1, 'product/product/type_header', '', 2, '', 0, '', 0),
+(193, 577, '', '商品列表插件', 'admin', '', '', 'product/product/list', 'GET', '[]', 0, 0, 0, 1, 'product/product/list', '', 2, '', 0, '', 0),
+(194, 99, '', '属性规则列表', 'admin', '', '', 'product/product/rule', 'GET', '[]', 0, 0, 0, 1, 'product/product/rule', '', 2, '', 0, '', 0),
+(195, 580, '', '保存修改规则', 'admin', '', '', 'product/product/rule/<id>', 'POST', '[]', 0, 0, 0, 1, 'product/rule/<id>', '', 2, '', 0, 'product-rule-save', 0),
+(196, 580, '', '规则详情', 'admin', '', '', 'product/product/rule/<id>', 'GET', '[]', 0, 0, 0, 1, 'product/product/rule/<id>', '', 2, '', 0, '', 0),
+(197, 580, '', '删除规则', 'admin', '', '', 'product/product/rule/delete', 'DELETE', '[]', 0, 0, 0, 1, 'product/product/rule/delete', '', 2, '', 0, 'product-product-rule-delete', 0),
+(198, 5, '', '订单列表', 'admin', '', '', 'order/list', 'GET', '[]', 0, 0, 0, 1, 'order/list', '', 2, '', 0, '', 0),
+(199, 5, '', '订单数据', 'admin', '', '', 'order/chart', 'GET', '[]', 0, 0, 0, 1, 'order/chart', '', 2, '', 0, '', 0),
+(200, 581, '', '订单核销', 'admin', '', '', 'order/write', 'POST', '[]', 0, 0, 0, 1, 'order/write', '', 2, '', 0, 'order-write', 0),
+(201, 215, '', '订单修改表格', 'admin', '', '', 'order/edit/<id>', 'GET', '[]', 0, 0, 0, 1, 'order/edit/<id>', '', 2, '', 0, '', 0),
+(202, 215, '', '订单修改', 'admin', '', '', 'order/update/<id>', 'PUT', '[]', 0, 0, 0, 1, 'order/update/<id>', '', 2, '', 0, '', 0),
+(203, 581, '', '订单收货', 'admin', '', '', 'order/take/<id>', 'PUT', '[]', 0, 0, 0, 1, 'order/take/<id>', '', 2, '', 0, '', 0),
+(204, 209, '', '订单发货', 'admin', '', '', 'order/delivery/<id>', 'PUT', '[]', 0, 0, 0, 1, 'order/delivery/<id>', '', 2, '', 0, '', 0),
+(205, 214, '', '订单退款表格', 'admin', '', '', 'order/refund/<id>', 'GET', '[]', 0, 0, 0, 1, 'order/refund/<id>', '', 2, '', 0, '', 0),
+(206, 214, '', '订单退款', 'admin', '', '', 'order/refund/<id>', 'PUT', '[]', 0, 0, 0, 1, 'order/refund/<id>', '', 2, '', 0, '', 0),
+(207, 581, '', '订单物流信息', 'admin', '', '', 'order/express/<id>', 'GET', '[]', 0, 0, 0, 1, 'order/express/<id>', '', 2, '', 0, '', 0),
+(208, 209, '', '物流公司列表', 'admin', '', '', 'order/express_list', 'GET', '[]', 0, 0, 0, 1, 'order/express_list', '', 2, '', 0, '', 0),
+(209, 581, '', '发货', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, 'order/delivery', '', 1, '', 0, '', 0),
+(210, 767, '', '附加权限', 'admin', '', '', '', 'GET', '[]', 99, 1, 0, 1, 'order/info/<id>', '', 2, '', 0, '', 0),
+(211, 213, '', '订单配送表格', 'admin', '', '', 'order/distribution/<id>', 'GET', '[]', 0, 0, 0, 1, 'order/distribution/<id>', '', 2, '', 0, '', 0),
+(212, 213, '', '修改配送信息', 'admin', '', '', 'order/distribution/<id>', 'PUT', '[]', 0, 0, 0, 1, 'order/distribution/<id>', '', 2, '', 0, '', 0),
+(213, 581, '', '订单配送', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, 'order/distribution', '', 1, '', 0, '', 0),
+(214, 581, '', '退款', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, 'order/refund', '', 1, '', 0, '', 0),
+(215, 581, '', '修改', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, 'order/update', '', 1, '', 0, '', 0),
+(216, 581, '', '不退款', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, 'order/no_refund', '', 1, '', 0, '', 0),
+(217, 216, '', '不退款表格', 'admin', '', '', 'order/no_refund/<id>', 'GET', '[]', 0, 0, 0, 1, 'order/no_refund/<id>', '', 2, '', 0, '', 0),
+(218, 216, '', '不退款理由修改', 'admin', '', '', 'order/no_refund/<id>', 'PUT', '[]', 0, 0, 0, 1, 'order/no_refund/<id>', '', 2, '', 0, '', 0),
+(219, 581, '', '线下支付', 'admin', '', '', 'order/pay_offline/<id>', 'POST', '[]', 98, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(220, 581, '', '退积分', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, 'order/refund_integral', '', 1, '', 0, '', 0),
+(221, 220, '', '退积分表单', 'admin', '', '', 'order/refund_integral/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(222, 220, '', '修改退积分', 'admin', '', '', 'order/refund_integral/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(223, 581, '', '订单备注', 'admin', '', '', 'order/remark/<id>', 'PUT', '[]', 97, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(224, 209, '', '获取电子面单信息', 'admin', '', '', 'order/express/temp', 'GET', '[]', 96, 0, 1, 1, '', '4/5/581/209', 2, '', 0, '', 0),
+(225, 581, '', '订单删除', 'admin', '', '', 'order/del/<id>', 'DELETE', '[]', 95, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(226, 581, '', '批量删除订单', 'admin', '', '', 'order/dels', 'POST', '[]', 100, 0, 0, 1, '', '4/5/581', 2, '', 0, 'order-dels', 0),
+(227, 9, '', '用户分组', 'admin', 'user.user_group', 'index', '', '', '[]', 9, 1, 0, 1, '/user/group', '', 1, 'user', 0, 'user-user-group', 0),
+(229, 1073, '', '城市数据', 'admin', 'setting.system_city', '', '', '', '[]', 1, 1, 0, 1, '/setting/freight/city/list', '25/1073', 1, 'setting', 0, 'setting-system-city', 0),
+(230, 303, '', '运费模板', 'admin', 'setting.shipping_templates', '', '', '', '[]', 0, 1, 0, 1, '/setting/freight/shipping_templates/list', '', 1, 'setting', 0, 'setting-shipping-templates', 0),
+(231, 767, '', '发票列表', 'admin', '', '', 'order/invoice/list', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, 'admin-order-invoice-index', 0),
+(232, 585, '', '用户详情', 'admin', '', '', 'user/one_info/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(233, 585, '', '创建用户表单', 'admin', '', '', 'user/user/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(234, 585, '', '修改用户信息表单', 'admin', '', '', 'user/user/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(235, 585, '', '获取用户信息', 'admin', '', '', 'user/user/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(236, 585, '', '修改用户信息', 'admin', '', '', 'user/user/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(238, 585, '', '发送优惠卷', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/coupon', '', 1, '', 0, 'admin-user-coupon', 0),
+(239, 238, '', '优惠卷列表', 'admin', '', '', 'marketing/coupon/grant', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(240, 238, '', '发送优惠卷', 'admin', '', '', 'marketing/coupon/user/grant', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(241, 585, '', '发送图文', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/wechat/news/', '', 1, '', 0, 'admin-wechat-news', 0),
+(242, 241, '', '图文列表', 'admin', '', '', 'app/wechat/news', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(243, 241, '', '发送图文', 'admin', '', '', 'app/wechat/push', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(244, 585, '', '批量用户分组', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/group_set/', '', 1, '', 0, 'admin-user-group_set', 0),
+(245, 244, '', '用户分组表单', 'admin', '', '', 'user/set_group/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(246, 244, '', '保存分组', 'admin', '', '', 'user/set_group', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(247, 586, '', '添加修改用户等级', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/level_add', '', 1, '', 0, 'admin-user-level_add', 0),
+(248, 247, '', '添加会员等级表单', 'admin', '', '', 'user/user_level/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(249, 247, '', '保存会员等级', 'admin', '', '', 'user/user_level', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(250, 11, '', '用户等级列表', 'admin', '', '', 'user/user_level/vip_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(251, 586, '', '用户等级是否显示', 'admin', '', '', 'user/user_level/set_show/<id>/<is_show>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(252, 586, '', '删除用户等级', 'admin', '', '', 'user/user_level/delete/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(253, 586, '', '等级任务', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/user_level', '', 1, '', 0, '', 0),
+(254, 253, '', '等级任务列表', 'admin', '', '', 'user/user_level/task/<level_id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(255, 253, '', '等级任务显示隐藏', 'admin', '', '', 'user/user_level/set_task_show/<id>/<is_show>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(256, 253, '', '等级任务是否必达', 'admin', '', '', 'user/user_level/set_task_must/<id>/<is_must>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(257, 253, '', '添加修改等级任务', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(258, 257, '', '添加等级任务表单', 'admin', '', '', 'user/user_level/create_task', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(259, 257, '', '保存修改任务', 'admin', '', '', 'user/user_level/save_task', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(260, 253, '', '删除等级任务', 'admin', '', '', 'user/user_level/delete_task/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(261, 227, '', '用户分组列表', 'admin', '', '', 'user/user_group/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(262, 227, '', '删除用户分组', 'admin', '', '', 'user/user_group/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(263, 227, '', '添加修改用户分组', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/group', '', 1, '', 0, 'admin-user-group', 0),
+(264, 263, '', '添加修改用户分组表单', 'admin', '', '', 'user/user_group/add/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(265, 263, '', '保存修改用户分组', 'admin', '', '', 'user/user_group/save', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(266, 29, '', '分销员列表', 'admin', '', '', 'agent/index', 'GET', '[]', 0, 0, 0, 1, '', '26/29', 2, '', 0, '', 0),
+(267, 584, '', '分销员数据', 'admin', '', '', 'agent/statistics', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(268, 29, '', '推广人列表', 'admin', '', '', 'agent/stair', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(269, 29, '', '推广人订单列表', 'admin', '', '', 'agent/stair/order', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(270, 584, '', '清除推广人', 'admin', '', '', 'agent/stair/delete_spread/<uid>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(271, 584, '', '推广二维码', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(272, 271, '', '公众号推广二维码', 'admin', '', '', 'agent/look_code', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(273, 271, '', '小程序推广二维码', 'admin', '', '', 'agent/look_xcx_code', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(274, 583, '', '添加优惠卷', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/marketing/store_coupon/add', '', 1, '', 0, 'admin-marketing-store_coupon-add', 0),
+(275, 274, '', '添加优惠卷表单', 'admin', '', '', 'marketing/coupon/create/<type>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(276, 274, '', '保存优惠卷', 'admin', '', '', 'marketing/coupon/save_coupon', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(277, 583, '', '发布优惠卷', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/marketing/store_coupon/push', '', 1, '', 0, 'admin-marketing-store_coupon-push', 0),
+(278, 277, '', '发布优惠卷表单', 'admin', '', '', 'marketing/coupon/issue/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(279, 277, '', '发布优惠卷', 'admin', '', '', 'marketing/coupon/issue/<id>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(280, 583, '', '立即失效', 'admin', '', '', 'marketing/coupon/status/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(281, 583, '', '删除优惠卷', 'admin', '', '', 'marketing/coupon/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(282, 71, '', '优惠卷已发布列表', 'admin', '', '', 'marketing/coupon/released', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(283, 71, '', '领取记录', 'admin', '', '', 'marketing/coupon/released/issue_log/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(284, 71, '', '删除优惠卷', 'admin', '', '', 'marketing/coupon/released/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(285, 71, '', '修改状态', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(286, 285, '', '修改状态表单', 'admin', '', '', 'marketing/coupon/released/<id>/status', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(287, 285, '', '保存修改状态', 'admin', '', '', 'marketing/coupon/released/status/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(290, 405, '', '审核状态通过', 'admin', '', '', 'finance/extract/adopt/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(291, 405, '', '拒绝申请', 'admin', '', '', 'finance/extract/refuse/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(292, 405, '', '提现编辑', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(293, 292, '', '编辑表单', 'admin', '', '', 'finance/extract/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(294, 292, '', '保存修改', 'admin', '', '', 'finance/extract/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(295, 40, '', '充值列表', 'admin', '', '', 'finance/recharge', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(296, 40, '', '充值数据', 'admin', '', '', 'finance/recharge/user_recharge', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(297, 40, '', '退款', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(298, 297, '', '获取退款表单', 'admin', '', '', 'finance/recharge/<id>/refund_edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(299, 297, '', '保存退款', 'admin', '', '', 'finance/recharge/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(300, 144, '', '提货点', 'admin', 'merchant.system_store', 'index', '', '', '[]', 0, 1, 0, 1, '/setting/merchant/system_store/list', '', 1, 'setting', 0, 'setting-merchant-system-store', 0),
+(301, 144, '', '核销员', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/merchant/system_store_staff/index', '', 1, 'setting', 0, 'setting-merchant-system-store-staff', 0),
+(302, 4, '', '核销订单', 'admin', '', 'index', '', '', '[]', 0, 1, 0, 1, '/setting/merchant/system_verify_order/index', '4', 1, 'setting', 0, 'setting-merchant-system-verify-order', 0),
+(303, 12, '', '发货设置', 'admin', 'setting', 'index', '', '', '[]', 0, 1, 0, 1, '/setting/freight', '', 1, '', 0, '', 0),
+(304, 303, '', '物流配置', 'admin', 'setting.systemConfig', 'index', '', '', '[]', 0, 0, 0, 1, '/setting/system_config_logistics/3/10', '', 1, '', 0, 'setting-system-config-logistics', 0),
+(305, 44, '', '文章列表', 'admin', '', '', 'cms/cms', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(306, 409, '', '文章分类', 'admin', '', '', 'cms/category', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(307, 42, '', '佣金记录列表', 'admin', '', '', 'finance/finance/commission_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(308, 42, '', '用户详情', 'admin', 'finance.finance', 'user_info', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(309, 308, '', '获取用户信息', 'admin', '', '', 'finance/finance/user_info/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(310, 308, '', '佣金详细列表', 'admin', '', '', 'finance/finance/extract_list/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(313, 23, '', '获取头部导航', 'admin', '', '', 'setting/config/header_basics', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(314, 23, '', '获取配置列表', 'admin', '', '', 'setting/config/edit_basics', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(315, 23, '', '修改配置', 'admin', '', '', 'setting/config/save_basics', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(316, 423, '', '添加客服', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/store_service/add', '', 1, '', 0, 'setting-store_service-add', 0),
+(317, 316, '', '客服用户列表', 'admin', '', '', 'app/wechat/kefu/add', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(318, 316, '', '保存客服', 'admin', '', '', 'app/wechat/kefu', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(319, 423, '', '聊天记录', 'admin', '', '', 'app/wechat/kefu/record/', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(320, 423, '', '编辑客服', 'admin', '', '', '', '', '[]', 80, 0, 0, 1, '/setting/store_service/edit', '', 1, '', 0, 'setting-store_service-edit', 0),
+(321, 423, '', '删除客服', 'admin', '', '', 'app/wechat/kefu/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(322, 423, '', '客服是否开启', 'admin', '', '', 'app/wechat/kefu/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(323, 320, '', '编辑客服表单', 'admin', '', '', 'app/wechat/kefu/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(324, 320, '', '修改客服', 'admin', '', '', 'app/wechat/kefu/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(325, 19, '', '添加身份', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/system_role/add', '', 1, '', 0, 'setting-system_role-add', 0),
+(326, 325, '', '添加身份表单', 'admin', '', '', 'setting/role/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(327, 325, '', '添加修改身份', 'admin', '', '', 'setting/role/<id>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(328, 325, '', '修改身份表单', 'admin', '', '', 'setting/role/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(329, 19, '', '修改身份状态', 'admin', '', '', 'setting/role/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(330, 19, '', '删除身份', 'admin', '', '', 'setting/role/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(331, 20, '', '添加管理员', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/system_admin/add', '', 1, '', 0, 'setting-system_admin-add', 0),
+(332, 331, '', '添加管理员表单', 'admin', '', '', 'setting/admin/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(333, 331, '', '添加管理员', 'admin', '', '', 'setting/admin', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(334, 20, '', '编辑管理员', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, ' /setting/system_admin/edit', '', 1, '', 0, ' setting-system_admin-edit', 0),
+(335, 334, '', '编辑管理员表单', 'admin', '', '', 'setting/admin/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(336, 334, '', '修改管理员', 'admin', '', '', 'setting/admin/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(337, 20, '', '删除管理员', 'admin', '', '', 'setting/admin/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(338, 21, '', '添加规则', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/system_menus/add', '', 1, '', 0, 'setting-system_menus-add', 0),
+(339, 338, '', '添加权限表单', 'admin', '', '', 'setting/menus/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(340, 338, '', '添加权限', 'admin', '', '', 'setting/menus', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(341, 21, '', '修改权限', 'admin', 'setting.system_menus', 'edit', '', '', '[]', 0, 0, 0, 1, '/setting/system_menus/edit', '', 1, '', 0, '/setting-system_menus-edit', 0),
+(342, 341, '', '编辑权限表单', 'admin', '', '', 'setting/menus/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(343, 341, '', '修改权限', 'admin', '', '', 'setting/menus/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(344, 21, '', '修改权限状态', 'admin', '', '', 'setting/menus/show/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(345, 21, '', '删除权限菜单', 'admin', '', '', 'setting/menus/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(346, 338, '', '添加子菜单', 'admin', 'setting.system_menus', 'add', '', '', '[]', 0, 0, 0, 1, '/setting/system_menus/add_sub', '', 1, '', 0, 'setting-system_menus-add_sub', 0),
+(347, 361, '', '是否登陆短信平台', 'admin', '', '', 'notify/sms/is_login', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(348, 361, '', '短信剩余条数', 'admin', '', '', 'notify/sms/number', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(349, 95, '', '获取短信验证码', 'admin', '', '', 'serve/captcha', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(350, 95, '', '修改注册账号', 'admin', '', '', 'serve/register', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(351, 95, '', '登陆短信平台', 'admin', '', '', 'serve/login', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(353, 95, '', '退出短信登陆', 'admin', '', '', 'notify/sms/logout', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(355, 96, '', '短信模板列表', 'admin', '', '', 'serve/sms/temps', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(356, 96, '', '申请模板', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/sms/sms_template_apply/add', '', 1, '', 0, 'setting-sms-sms_template_apply-add', 0),
+(357, 356, '', '申请短信模板表单', 'admin', '', '', 'notify/sms/temp/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(358, 356, '', '保存申请短信模板', 'admin', '', '', 'notify/sms/temp', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(359, 97, '', '短信套餐', 'admin', '', '', 'serve/meal_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(360, 97, '', '短信购买支付码', 'admin', '', '', 'serve/pay_meal', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(361, 94, '', '短信设置附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/sms/attach', '', 1, '', 0, '', 0),
+(362, 300, '', '门店数据', 'admin', '', '', 'merchant/store/get_header', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(363, 300, '', '门店列表展示', 'admin', '', '', 'merchant/store', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(364, 424, '', '修改门店状态', 'admin', '', '', 'merchant/store/set_show/<id>/<is_show>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(366, 7, '', '首页统计数据', 'admin', '', '', 'home/header', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(367, 7, '', '首页订单图表', 'admin', '', '', 'home/order', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(368, 7, '', '首页用户图表', 'admin', '', '', 'home/user', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(369, 7, '', '首页交易额排行', 'admin', '', '', 'home/rank', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(370, 72, '', '优惠卷领取列表', 'admin', '', '', 'marketing/coupon/user', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(371, 74, '', '砍价列表', 'admin', '', '', 'marketing/bargain', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(372, 74, '', '附加权限', 'admin', 'marketing.store_bargain', '', '', '', '[]', 0, 0, 0, 1, '/marketing/store_bargain/attr', '', 1, '', 0, '', 0),
+(373, 372, '', '修改砍价状态', 'admin', '', '', 'marketing/bargain/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(374, 372, '', '砍价商品详情', 'admin', '', '', 'marketing/bargain/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(375, 74, '', '公共权限', 'admin', 'marketing.store_bargain', 'public', '', '', '[]', 0, 0, 0, 1, '/marketing/store_bargain/public', '', 1, '', 0, '', 0),
+(376, 375, '', '分类树型列表', 'admin', '', '', 'product/category/tree/<type>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(377, 375, '', '商品插件列表', 'admin', '', '', 'product/product/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(378, 375, '', '运费模板', 'admin', '', '', 'product/product/get_template', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(379, 372, '', '修改添加砍价商品', 'admin', '', '', 'marketing/bargain/<id>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(380, 372, '', '删除砍价商品', 'admin', '', '', 'marketing/bargain/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(381, 75, '', '拼团列表', 'admin', '', '', 'marketing/combination', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(382, 75, '', '拼团数据', 'admin', '', '', 'marketing/combination/statistics', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(383, 75, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(384, 383, '', '拼团状态', 'admin', '', '', 'marketing/combination/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(385, 383, '', '删除拼团', 'admin', '', '', 'marketing/combination/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(386, 75, '', '公共权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(387, 386, '', '树型分类列表', 'admin', '', '', 'product/category/tree/<type>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(388, 386, '', '商品插件列表', 'admin', '', '', 'product/product/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(389, 386, '', '运费模板列表', 'admin', '', '', 'product/product/get_template', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(390, 383, '', '获取拼团详情', 'admin', '', '', 'marketing/combination/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(391, 383, '', '编辑添加拼团', 'admin', '', '', 'marketing/combination/<id>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(392, 76, '', '正在拼团列表', 'admin', '', '', 'marketing/combination/combine/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(393, 76, '', '拼团人员列表', 'admin', '', '', 'marketing/combination/order_pink/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(395, 77, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(396, 395, '', '修改拼团状态', 'admin', '', '', 'marketing/seckill/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(397, 77, '', '公共权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(398, 397, '', '分类树型列表', 'admin', '', '', 'product/category/tree/<type>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(399, 397, '', '商品插件列表', 'admin', '', '', 'product/product/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(400, 397, '', '运费模板列表', 'admin', '', '', 'product/product/get_template', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(401, 397, '', '秒杀时间段列表', 'admin', '', '', 'marketing/seckill/time_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(402, 395, '', '编辑添加秒杀商品', 'admin', '', '', 'marketing/seckill/<id>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(403, 395, '', '删除秒杀商品', 'admin', '', '', 'marketing/seckill/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(404, 39, '', '提现申请列表', 'admin', '', '', 'finance/extract', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(405, 39, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(406, 44, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(407, 406, '', '保存修改文章', 'admin', '', '', 'cms/cms', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(408, 406, '', '获取文章详情', 'admin', '', '', 'cms/cms/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(409, 44, '', '公共权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(410, 406, '', '关联商品列表', 'admin', '', '', 'product/product/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(411, 406, '', '分类树型列表', 'admin', '', '', 'product/category/tree/<type>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(412, 406, '', '关联商品', 'admin', '', '', 'cms/cms/relation/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(413, 406, '', '取消关联', 'admin', '', '', 'cms/cms/unrelation/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(414, 406, '', '删除文章', 'admin', '', '', 'cms/cms/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(415, 45, '', '文章列表', 'admin', '', '', 'cms/category', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(416, 45, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(417, 416, '', '文章分类添加表单', 'admin', '', '', 'cms/category/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'cms-category-create', 0),
+(418, 416, '', '保存文章分类', 'admin', '', '', 'cms/category', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(419, 416, '', '编辑文章分类', 'admin', '', '', 'cms/category/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(420, 416, '', '修改文章分类', 'admin', '', '', 'cms/category/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(421, 416, '', '删除文章分类', 'admin', '', '', 'cms/category/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(422, 678, '', '客服列表', 'admin', '', '', 'app/wechat/kefu', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(423, 678, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(424, 300, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(425, 144, '', '公共权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(426, 425, '', '地图KEY权限', 'admin', '', '', 'merchant/store/address', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(427, 424, '', '添加编辑门店', 'admin', '', '', 'merchant/store/<id>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'setting-merchant-system_store-save', 0),
+(428, 424, '', '设置门店隐藏显示', 'admin', '', '', 'merchant/store/set_show/<id>/<is_show>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(429, 424, '', '门店详情', 'admin', '', '', 'merchant/store/get_info/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(430, 424, '', '删除门店', 'admin', '', '', 'merchant/store/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(431, 425, '', '店员搜索门店列表', 'admin', '', '', 'merchant/store_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(432, 301, '', '店员列表', 'admin', '', '', 'merchant/store_staff', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(433, 301, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(434, 433, '', '添加店员表单', 'admin', '', '', 'merchant/store_staff/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'merchant-store_staff-create', 0),
+(435, 425, '', '选择用户插件列表', 'admin', '', '', 'app/wechat/kefu/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(436, 433, '', '添加修改店员', 'admin', '', '', 'merchant/store_staff/save/<id>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(437, 433, '', '店员显示隐藏', 'admin', '', '', 'merchant/store_staff/set_show/<id>/<is_show>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(438, 433, '', '编辑店员表单', 'admin', '', '', 'merchant/store_staff/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(439, 433, '', '删除店员', 'admin', '', '', 'merchant/store_staff/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(440, 302, '', '核销订单列表', 'admin', '', '', 'merchant/verify_order', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(441, 302, '', '核销订单数据', 'admin', '', '', 'merchant/verify_badge', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(442, 229, '', '城市数据列表', 'admin', '', '', 'setting/city/list/<parent_id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(443, 229, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(444, 443, '', '获取添加城市表单', 'admin', '', '', 'setting/city/add/<parent_id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(445, 443, '', '保存修改城市数据', 'admin', '', '', 'setting/city/save', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(446, 443, '', '获取修改城市表单', 'admin', '', '', 'setting/city/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(447, 443, '', '删除城市数据', 'admin', '', '', 'setting/city/del/<city_id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(448, 145, '', '物流公司列表', 'admin', '', '', 'freight/express', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(449, 145, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(450, 449, '', '修改物流公司状态', 'admin', '', '', 'freight/express/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(451, 449, '', '获取添加物流公司表单', 'admin', '', '', 'freight/express/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(452, 449, '', '保存物流公司', 'admin', '', '', 'freight/express', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(453, 449, '', '获取编辑物流公司表单', 'admin', '', '', 'freight/express/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(454, 449, '', '修改物流公司', 'admin', '', '', 'freight/express/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(455, 449, '', '删除物流公司', 'admin', '', '', 'freight/express/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(456, 230, '', '运费模板列表', 'admin', '', '', 'setting/shipping_templates/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(457, 230, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(458, 457, '', '运费模板城市数据', 'admin', '', '', 'setting/shipping_templates/city_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(459, 457, '', '保存或者修改运费模板', 'admin', '', '', 'setting/shipping_templates/save/<id>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(460, 457, '', '删除运费模板', 'admin', '', '', 'setting/shipping_templates/del/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(461, 111, '', '配置分类列表', 'admin', '', '', 'setting/config_class', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(462, 111, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(463, 462, '', '配置分类添加表单', 'admin', '', '', 'setting/config_class/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(464, 462, '', '保存配置分类', 'admin', '', '', 'setting/config_class', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(465, 641, '', '编辑配置分类', 'admin', '', '', 'setting/config_class/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(466, 462, '', '删除配置分类', 'admin', '', '', 'setting/config_class/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(467, 125, '', '配置列表展示', 'admin', '', '', 'setting/config', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(468, 125, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(469, 468, '', '添加配置字段表单', 'admin', '', '', 'setting/config/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(470, 468, '', '保存配置字段', 'admin', '', '', 'setting/config', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(471, 468, '', '编辑配置字段表单', 'admin', '', '', 'setting/config/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(472, 468, '', '编辑配置分类', 'admin', '', '', 'setting/config/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(473, 468, '', '删除配置', 'admin', '', '', 'setting/config/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(474, 468, '', '修改配置状态', 'admin', '', '', 'setting/config/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(475, 112, '', '组合数据列表', 'admin', '', '', 'setting/group', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, '', 0),
+(476, 112, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(477, 476, '', '新增组合数据', 'admin', '', '', 'setting/group', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(478, 476, '', '获取组合数据', 'admin', '', '', 'setting/group/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(479, 476, '', '修改组合数据', 'admin', '', '', 'setting/group/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(480, 476, '', '删除组合数据', 'admin', '', '', 'setting/group/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(481, 126, '', '组合数据列表表头', 'admin', '', '', 'setting/group_data/header', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(482, 126, '', '组合数据列表', 'admin', '', '', 'setting/group_data', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(483, 126, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(484, 483, '', '获取组合数据添加表单', 'admin', '', '', 'setting/group_data/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(485, 483, '', '保存组合数据', 'admin', '', '', 'setting/group_data', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(486, 483, '', '获取组合数据信息', 'admin', '', '', 'setting/group_data/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(487, 483, '', '修改组合数据信息', 'admin', '', '', 'setting/group_data/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(488, 483, '', '删除组合数据', 'admin', '', '', 'setting/group_data/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(489, 483, '', '修改组合数据状态', 'admin', '', '', 'setting/group_data/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(490, 57, '', '清除缓存', 'admin', '', '', 'system/refresh_cache/cache', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(491, 57, '', '清除日志', 'admin', '', '', 'system/refresh_cache/log', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(492, 47, '', '管理员搜索列表', 'admin', '', '', 'system/log/search_admin', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(493, 47, '', '系统日志列表', 'admin', '', '', 'system/log', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(494, 64, '', '文件校验列表', 'admin', '', '', 'system/file', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(495, 66, '', '清除数据接口', 'admin', '', '', 'system/clear/<type>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(496, 67, '', '数据库列表', 'admin', '', '', 'system/backup', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(497, 67, '', '数据库备份列表', 'admin', '', '', 'system/backup/file_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(498, 67, '', '数据表详情', 'admin', '', '', 'system/backup/read', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(499, 67, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(500, 499, '', '备份表', 'admin', '', '', 'system/backup/backup', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(501, 499, '', '优化表', 'admin', '', '', 'system/backup/optimize', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(502, 499, '', '修复表', 'admin', '', '', 'system/backup/repair', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(503, 499, '', '导入sql', 'admin', '', '', 'system/backup/import', 'POST', '[]', 0, 0, 1, 1, '', '', 2, '', 0, '', 0),
+(504, 499, '', '删除数据库备份', 'admin', '', '', 'system/backup/del_file', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(505, 499, '', '备份下载', 'admin', '', '', 'backup/download', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(507, 92, '', '微信菜单列表', 'admin', '', '', 'app/wechat/menu', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(508, 92, '', '保存微信菜单', 'admin', '', '', 'app/wechat/menu', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(553, 109, '', '图文列表', 'admin', '', '', 'app/wechat/news', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(554, 109, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(555, 554, '', '保存图文', 'admin', '', '', 'app/wechat/news', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(556, 554, '', '图文详情', 'admin', '', '', 'app/wechat/news/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(557, 554, '', '删除图文', 'admin', '', '', 'app/wechat/news/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(558, 114, '', '公共权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(559, 558, '', '回复关键词', 'admin', '', '', 'app/wechat/reply', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(560, 115, '', '关键词回复列表', 'admin', '', '', 'app/wechat/keyword', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(561, 115, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(562, 558, '', '保存修改关键字', 'admin', '', '', 'app/wechat/keyword/<id>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(563, 561, '', '获取关键字信息', 'admin', '', '', 'app/wechat/keyword/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(564, 561, '', '修改关键字状态', 'admin', '', '', 'app/wechat/keyword/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(565, 561, '', '删除关键字', 'admin', '', '', 'app/wechat/keyword/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(566, 656, '', '素材管理', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/system/file', '12/656', 1, '', 0, 'system-file', 0),
+(567, 566, '', '附件列表', 'admin', '', '', 'file/file', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(568, 566, '', '附件分类', 'admin', '', '', 'file/category', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(569, 566, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(570, 569, '', '附件分类表单', 'admin', '', '', 'file/category/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(571, 569, '', '附件分类保存', 'admin', '', '', 'file/category', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(572, 569, '', '删除附件', 'admin', '', '', 'file/file/delete', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(573, 569, '', '移动附件分类', 'admin', '', '', 'file/file/do_move', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(574, 566, '', '上传附件', 'admin', '', '', 'file/upload/<upload_type?>', 'POST', '[]', 10, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(575, 569, '', '附件分类编辑表单', 'admin', '', '', 'file/category/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(576, 569, '', '附件分类修改', 'admin', '', '', 'file/category/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(577, 2, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(578, 3, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(579, 6, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(580, 99, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(581, 5, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(582, 70, '', '优惠卷模板列表', 'admin', '', '', 'marketing/coupon/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(583, 70, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(584, 29, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(585, 10, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(586, 11, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(587, 25, '', '个人中心', 'admin', '', '', '', '', '[]', 0, 1, 1, 1, '/system/user', '', 1, '', 0, 'system-user', 0),
+(589, 9, '', '用户标签', 'admin', 'user.user_label', 'index', '', '', '[]', 8, 1, 0, 1, '/user/label', '', 1, 'user', 0, 'user-user-label', 0),
+(590, 589, '', '获取用户标签', 'admin', '', '', 'user/label/<uid>', 'GET', '[]', 0, 0, 0, 1, '', '9/589', 2, '', 0, '', 0),
+(591, 589, '', '删除用户标签', 'admin', '', '', 'user/user_label/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(592, 589, '', '添加修改用户标签', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/label_add', '', 1, '', 0, 'admin-user-label_add', 0),
+(593, 592, '', '添加修改用户标签表单', 'admin', '', '', 'user/user_label/add/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(594, 592, '', '保存修改用户标签', 'admin', '', '', 'user/user_label/save', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(596, 2, '', '商品导出', 'admin', '', '', 'export/storeProduct', 'GET', '[]', 10, 0, 0, 1, '', '', 2, '', 0, 'export-storeProduct', 0),
+(597, 5, '', '订单导出', 'admin', '', '', 'export/storeorder', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'export-storeOrder', 0),
+(598, 77, '', '秒杀商品导出', 'admin', '', '', 'export/storeSeckill', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'export-storeSeckill', 0),
+(600, 75, '', '拼团商品导出', 'admin', '', '', 'export/storeCombination', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'export-storeCombination', 0),
+(601, 74, '', '砍价商品导出', 'admin', '', '', 'export/storeBargain', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'export-storeBargain', 0),
+(602, 29, '', '推广员列表导出', 'admin', '', '', 'export/userAgent', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'export-userAgent', 0),
+(603, 40, '', '用户充值导出', 'admin', '', '', 'export/userRecharge', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'export-userRecharge', 0),
+(605, 25, '', '商业授权', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/system/maintain/auth', '', 1, '', 0, 'system-maintain-auth', 0),
+(606, 29, '', '分销员数据', 'admin', '', '', 'agent/statistics', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(607, 587, '', '修改密码', 'admin', '', '', 'setting/update_admin', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(608, 605, '', '商业授权', 'admin', '', '', 'auth', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, '', 0),
+(610, 20, '', '管理员列表', 'admin', '', '', 'setting/admin', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(611, 19, '', '身份列表', 'admin', '', '', 'setting/role', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(612, 2, '', '批量上下架', 'admin', '', '', 'product/product/product_show', 'PUT', '[]', 5, 0, 0, 1, '', '', 2, '', 0, 'product-product-product_show', 0),
+(613, 585, '', '批量设置标签', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/set_label', '', 1, '', 0, 'admin-user-set_label', 0),
+(614, 613, '', '获取标签表单', 'admin', '', '', 'user/set_label', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(615, 613, '', '保存标签', 'admin', '', '', 'user/save_set_label', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(618, 42, '', '佣金导出', 'admin', '', '', 'export/userCommission', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'export-userCommission', 0),
+(619, 21, '', '权限列表', 'admin', '', '', 'setting/menus', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(620, 22, '', '商品详情', 'admin', '', '', 'product/product/<id>', 'GET', '[]', 0, 1, 1, 1, '', '', 2, '', 0, '', 0),
+(621, 585, '', '保存用户信息', 'admin', '', '', 'user/user', 'POST', '[]', 10, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(622, 585, '', '积分余额', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/edit_other', '', 1, '', 0, '', 0),
+(623, 622, '', '获取修改用户详情表单', 'admin', '', '', 'user/edit_other/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(624, 622, '', '修改用户余额', 'admin', '', '', 'user/update_other/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(625, 585, '', '赠送用户', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/user_level', '', 1, '', 0, '', 0),
+(626, 625, '', '获取表单', 'admin', '', '', 'user/give_level/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(627, 625, '', '赠送会员等级', 'admin', '', '', 'user/save_give_level/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(628, 585, '', '单个用户分组设置', 'admin', '', '', 'user/save_set_group', 'PUT', '[]', 10, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(630, 375, '', '获取商品属性', 'admin', '', '', 'product/product/attrs/<id>/<type>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(631, 386, '', '商品规格获取', 'admin', '', '', 'product/product/attrs/<id>/<type>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(632, 397, '', '商品规格和获取', 'admin', '', '', 'product/product/attrs/<id>/<type>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(633, 395, '', '获取秒杀详情', 'admin', '', '', 'marketing/seckill/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(634, 40, '', '删除充值记录', 'admin', '', '', 'finance/recharge/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(635, 20, '', '修改管理员状态', 'admin', '', '', 'setting/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(636, 25, '', '其他权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/system/other', '', 1, '', 0, '', 0),
+(637, 636, '', '消息提醒', 'admin', '', '', 'jnotice', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(638, 457, '', '获取运费模板详情', 'admin', '', '', 'setting/shipping_templates/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(639, 457, '', '删除运费模板', 'admin', '', '', 'setting/shipping_templates/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(640, 462, '', '修改配置分类状态', 'admin', '', '', 'setting/config_class/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(641, 462, '', '编辑配置分类', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, 'system/config/system_config_tab/edit', '', 1, '', 0, '', 0),
+(642, 641, '', '获取编辑配置分类表单', 'admin', '', '', 'setting/config_class/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(655, 65, '', '在线升级', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/system/onlineUpgrade/index', '25/65', 1, '', 0, 'system-onlineUpgrade-index', 0),
+(656, 0, 'md-construct', '装修', 'admin', '', '', '', '', '[]', 80, 1, 0, 1, '/setting/pages', '', 1, '', 1, 'admin-setting-pages', 0),
+(657, 656, '', '页面设计', 'admin', '', '', '', '', '[]', 3, 1, 0, 1, '/setting/pages/devise', '12/656', 1, '', 0, 'admin-setting-pages-devise', 0),
+(658, 656, '', '页面编辑', 'admin', '', '', '', '', '[]', 3, 1, 1, 1, '/setting/pages/diy', '12/656', 1, '', 0, 'admin-setting-pages-diy', 0),
+(660, 656, '', '页面链接', 'admin', '', '', '', '', '[]', 3, 0, 0, 1, '/setting/pages/links', '12/656', 1, '', 0, 'admin-setting-pages-links', 0),
+(661, 657, '', 'DIY列表', 'admin', '', '', 'diy/get_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(662, 657, '', '组件文章分类', 'admin', '', '', 'cms/category_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(663, 657, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/diy', '', 1, '', 0, 'admin-setting-diy-additional', 0),
+(664, 663, '', '获取页面设计', 'admin', '', '', 'diy/get_info/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(665, 663, '', '保存和修改页面', 'admin', '', '', 'diy/save/<id?>', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'admin-setting-pages-diy-save', 0),
+(666, 660, '', '路径列表', 'admin', '', '', 'diy/get_url', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(667, 663, '', '删除页面', 'admin', '', '', 'diy/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(668, 663, '', '修改页面状态', 'admin', '', '', 'diy/set_status/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(669, 2, '', '批量下架', 'admin', '', '', 'product/product/product_unshow', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(670, 581, '', '订单打印', 'admin', '', '', 'order/print/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(671, 585, '', '清除会员等级', 'admin', '', '', 'user/del_level/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(672, 271, '', 'H5推广二维码', 'admin', '', '', 'agent/look_h5_code', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(673, 416, '', '修改文章分类状态', 'admin', '', '', 'cms/category/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(674, 229, '', '清除城市缓存', 'admin', '', '', 'setting/city/clean_cache', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(675, 657, '', '组件商品分类', 'admin', '', '', 'diy/get_category', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(676, 657, '', '组件商品列表', 'admin', '', '', 'diy/get_product', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(677, 581, '', '订单号核销', 'admin', '', '', 'order/write_update/<order_id>', 'PUT', '[]', 0, 0, 0, 1, 'order/dels', '', 2, '', 0, 'admin-order-write_update', 0),
+(678, 165, '', '客服列表', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/store_service/index', '', 1, '', 0, 'admin-setting-store_service-index', 0),
+(679, 165, '', '客服话术', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/store_service/speechcraft', '', 1, '', 0, 'admin-setting-store_service-speechcraft', 0),
+(685, 22, '', '上传商品视频', 'admin', '', '', 'product/product/get_temp_keys', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(686, 27, '', '直播管理', 'admin', '', '', '', '', '[]', 65, 1, 0, 1, '/marketing/live', '27', 1, '', 0, 'admin-marketing-live', 0),
+(687, 686, '', '直播间管理', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/live/live_room', '', 1, '', 0, 'admin-marketing-live-live_room', 0),
+(688, 686, '', '直播商品管理', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/live/live_goods', '', 1, '', 0, 'admin-marketing-live-live_goods', 0),
+(689, 686, '', '主播管理', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/live/anchor', '', 1, '', 0, 'admin-marketing-live-anchor', 0),
+(690, 687, '', '添加直播间', 'admin', '', '', '', '', '[]', 0, 0, 1, 1, '/marketing/live/add_live_room', '', 1, '', 0, 'admin-marketing-live-add_live_room', 0),
+(691, 688, '', '添加直播商品', 'admin', '', '', '', '', '[]', 0, 0, 1, 1, '/marketing/live/add_live_goods', '', 1, '', 0, 'admin-marketing-live-add_live_goods', 0),
+(693, 689, '', '主播列表', 'admin', '', '', 'live/anchor/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'admin-marketing-live-anchor', 0),
+(694, 689, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/*', '', 1, '', 0, '', 0),
+(695, 694, '', '添加/修改主播表单', 'admin', '', '', 'live/anchor/add/<id>', 'GET', '[]', 0, 0, 0, 1, 'live/anchor/add/<id>', '', 2, '', 0, 'live-anchor-add', 0),
+(696, 694, '', '添加/修改提交', 'admin', '', '', 'live/anchor/save', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(697, 694, '', '删除主播', 'admin', '', '', 'live/anchor/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(698, 694, '', '设置主播是否显示', 'admin', '', '', 'live/anchor/set_show/<id>/<is_show>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(699, 688, '', '直播商品列表', 'admin', '', '', 'live/goods/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(700, 691, '', '生成直播商品', 'admin', '', '', 'live/goods/create', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(701, 691, '', '保存直播商品', 'admin', '', '', 'live/goods/add', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(702, 688, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/*', '', 1, '', 0, '/admin/*', 0),
+(703, 702, '', '直播商品详情', 'admin', '', '', 'live/goods/detail/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(704, 702, '', '删除直播商品', 'admin', '', '', 'live/goods/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(705, 702, '', '同步直播商品', 'admin', '', '', 'live/goods/syncGoods', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(706, 702, '', '设置直播商品是否显示', 'admin', '', '', 'live/goods/set_show/<id>/<is_show>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(707, 687, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/*', '', 1, '', 0, '', 0),
+(708, 687, '', '直播间列表', 'admin', '', '', 'live/room/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(709, 707, '', '添加直播间提交', 'admin', '', '', 'live/room/add', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(710, 707, '', '直播间详情', 'admin', '', '', 'live/room/detail/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(711, 707, '', '直播间添加(关联)商品', 'admin', '', '', 'live/room/add_goods', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(712, 707, '', '删除直播间', 'admin', '', '', 'live/room/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(713, 707, '', '设置直播间是否显示', 'admin', '', '', 'live/room/set_show/<id>/<is_show>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(714, 707, '', '同步直播间状态', 'admin', '', '', 'live/room/syncRoom', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(715, 898, '', '一键同步订阅消息', 'admin', '', '', 'app/routine/syncSubscribe', 'GET', '[]', 0, 0, 0, 1, '', '12/898', 2, '', 0, 'app-wechat-template-sync', 0),
+(716, 0, 'md-stats', '统计', 'admin', '', '', '', '', '[]', 105, 1, 0, 1, '/statistic', '', 1, '', 1, 'admin-statistic', 0),
+(717, 716, '', '商品统计', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/statistic/product', '', 1, '', 0, 'admin-statistic', 0),
+(718, 716, '', '用户统计', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/statistic/user', '', 1, '', 0, 'admin-statistic', 0),
+(719, 71, '', '添加优惠卷', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/marketing/store_coupon_issue/create', '27/30/71', 1, '', 0, 'marketing-store_coupon_issue-create', 0),
+(720, 303, '', '配送员管理', 'admin', '', '', '', '', '[]', 10, 1, 0, 1, '/setting/delivery_service/index', '', 1, '', 0, 'setting-delivery-service', 0),
+(721, 729, '', '编辑配送员', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/delivery_service/edit', '', 1, '', 0, 'setting-delivery_service-edit', 0),
+(722, 720, '', '配送员列表', 'admin', '', '', 'order/delivery/index', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(723, 721, '', '修改配送员', 'admin', '', '', 'order/delivery/update/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(724, 729, '', '添加配送员', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/delivery_service/add', '', 1, '', 0, 'setting-delivery_service-add', 0),
+(725, 724, '', '获取添加配送员表单', 'admin', '', '', 'order/delivery/add', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(726, 724, '', '保存配送员', 'admin', '', '', 'order/delivery/save', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(727, 729, '', '删除配送员', 'admin', '', '', 'order/delivery/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(728, 729, '', '配送员是否开启', 'admin', '', '', 'order/delivery/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(729, 720, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(731, 27, '', '付费会员', 'admin', '', '', '', '', '[]', 70, 1, 0, 1, '/user/grade', '27', 1, '', 0, 'user-user-grade', 0),
+(732, 762, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 1, 1, '*', '', 1, '', 0, '', 0),
+(733, 732, '', ' 添加会员批次', 'admin', '', '', 'user/member_batch/save/<id>', 'POST', '[]', 0, 1, 0, 1, '', '', 2, '', 0, '', 0),
+(734, 732, '', '列表字段修改', 'admin', '', '', 'user/member_batch/set_value/<id>', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, 'user-member_batch-set_value', 0),
+(735, 732, '', '会员卡导出', 'admin', '', '', 'export/memberCard/<id>', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, 'export-member_card', 0),
+(736, 762, '', '卡密列表', 'admin', '', '', 'user/member_batch/index', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, '', 0),
+(737, 732, '', '会员卡列表', 'admin', '', '', 'user/member_card/index', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'user-member_card-index', 0),
+(738, 165, '', '用户留言', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/store_service/feedback', '', 1, '', 0, 'admin-setting-store_service-feedback', 0),
+(739, 738, '', '列表展示', 'admin', '', '', 'app/feedback', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(740, 738, '', '附件权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(741, 740, '', '删除反馈', 'admin', '', '', 'app/feedback/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(742, 679, '', '列表展示', 'admin', '', '', 'app/wechat/speechcraft', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(743, 679, '', '附件权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '*', '', 1, '', 0, '', 0),
+(744, 743, '', '添加话术', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/store_service/speechcraft/add', '', 1, '', 0, 'admin-setting-store_service-speechcraft-add', 0),
+(745, 743, '', '编辑话术', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/store_service/speechcraft/edit', '', 1, '', 0, 'admin-setting-store_service-speechcraft-edit', 0),
+(746, 744, '', '获取添加话术表单', 'admin', '', '', 'app/wechat/speechcraft/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(747, 744, '', '保存话术', 'admin', '', '', 'app/wechat/speechcraft', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(748, 745, '', '获取编辑话术表单', 'admin', '', '', 'app/wechat/speechcraft/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(749, 745, '', '确认修改', 'admin', '', '', 'app/wechat/speechcraft/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(750, 743, '', '删除话术', 'admin', '', '', 'app/wechat/speechcraft/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(751, 731, '', '会员类型', 'admin', '', '', '', '', '[]', 5, 1, 0, 1, '/user/grade/type', '', 1, '', 0, 'admin-user-member-type', 0),
+(752, 751, '', '会员分类列表', 'admin', '', '', 'user/member/ship', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'user-member-ship', 0),
+(753, 751, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 1, 1, '*', '', 1, '', 0, '', 0),
+(754, 753, '', '会员卡类型保存', 'admin', '', '', 'user/member_ship/save/<id>', 'POST', '[]', 0, 1, 1, 1, '', '', 2, '', 0, 'user-member_ship-save', 0),
+(755, 31, '', '砍价列表', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/store_bargain/bargain_list', '', 1, '', 0, 'marketing-store_bargain-bargain_list', 0),
+(756, 585, '', '添加用户', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/save', '', 1, '', 0, 'admin-user-save', 0),
+(757, 756, '', '获取添加用户表单', 'admin', '', '', 'user/user/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(758, 756, '', '保存用户', 'admin', '', '', 'user/user', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(759, 585, '', '同步公众号用户', 'admin', '', '', 'user/user/syncUsers', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'admin-user-synchro', 0),
+(760, 4, '', '收银订单', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/order/offline', '', 1, '', 0, 'admin-order-offline', 0),
+(761, 760, '', '线下收银订单', 'admin', '', '', 'order/scan_list', 'GET', '[]', 0, 0, 1, 1, '', '', 2, '', 0, 'admin-order-scan_list', 0),
+(762, 731, '', '卡密会员', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/user/grade/card', '', 1, '', 0, 'admin-user-grade-card', 0),
+(763, 731, '', '会员记录', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/user/grade/record', '', 1, '', 0, 'admin-user-grade-record', 0),
+(764, 763, '', '会员记录列表', 'admin', '', '', 'user/member/record', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'user-member-record', 0),
+(765, 731, '', '会员权益', 'admin', '', '', '', '', '[]', 4, 1, 0, 1, '/user/grade/right', '', 1, '', 0, 'admin-user-grade-right', 0),
+(766, 716, '', '交易统计', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/statistic/transaction', '', 1, '', 0, 'admin-statistic', 0),
+(767, 36, '', '发票管理', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/order/invoice/list', '', 1, '', 0, 'admin-order-startOrderInvoice-index', 0),
+(768, 210, '', '编辑', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '', '', 2, '', 0, 'admin-order-invoice-edit', 0),
+(769, 210, '', '订单信息', 'admin', '', '', 'order/invoice_order_info/<id>', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, 'admin-order-invoice-orderInfo', 0),
+(770, 210, '', '编辑提交', 'admin', '', '', 'order/invoice/set/<id>', 'POST', '[]', 0, 1, 0, 1, '', '', 2, '', 0, 'admin-order-invoice-update', 0),
+(771, 765, '', '会员权益列表', 'admin', '', '', 'user/member/right', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'user-member-right', 0),
+(772, 765, '', '附加权限', 'admin', '', '', '', '', '[]', 0, 0, 1, 1, '*', '', 1, '', 0, '', 0),
+(773, 772, '', '会员权益保存', 'admin', '', '', 'user/member_right/save/<id>', 'POST', '[]', 0, 1, 1, 1, '', '', 2, '', 0, 'user-member_right-save', 0),
+(774, 589, '', '用户标签列表', 'admin', '', '', 'user/user_label_cate/all', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, 'admin-user-user_lable_cate-all', 0),
+(778, 740, '', '获取修改备注表单接口', 'admin', '', '', 'app/feedback/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(779, 740, '', '修改用户备注接口', 'admin', '', '', 'app/feedback/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(780, 589, '', '标签分类', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/label_cate', '', 1, '', 0, '', 0),
+(781, 780, '', '获取标签分类列表', 'admin', '', '', 'user/user_label_cate/all', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(782, 780, '', '添加标签分类', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/label_cate/add', '', 1, '', 0, '', 0),
+(783, 782, '', '获取标签分类表单', 'admin', '', '', 'user/user_label_cate/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(784, 782, '', '保存标签分类', 'admin', '', '', 'user/user_label_cate', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(785, 780, '', '修改标签分类', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/user/label_cate/edit', '', 1, '', 0, '', 0),
+(786, 785, '', '获取修改标签分类表单', 'admin', '', '', 'user/user_label_cate/<id>/edit', 'GET', '[]', 0, 0, 0, 1, 'user/user_label_cate/<id>/edit', '', 2, '', 0, '', 0),
+(787, 785, '', '保存用户标签分类', 'admin', '', '', 'user/user_label_cate/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(788, 780, '', '删除用户标签分类', 'admin', '', '', 'user/user_label_cate/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(789, 743, '', '话术分类', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/store_service/speechcraft/cate', '', 1, '', 0, 'admin-setting-store_service-speechcraft-cate', 0),
+(790, 789, '', '获取话术分类列表', 'admin', '', '', 'app/wechat/speechcraftcate', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(791, 789, '', '添加话术分类', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/store_service/speechcraft/cate/create', '', 1, '', 0, '', 0),
+(792, 791, '', '获取话术分类表单', 'admin', '', '', 'app/wechat/speechcraftcate/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(793, 791, '', '保存话术分类', 'admin', '', '', 'app/wechat/speechcraftcate', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(794, 795, '', '获取话术分类表单', 'admin', '', '', 'app/wechat/speechcraftcate/<id>/edit', 'GET', '[]', 0, 0, 0, 1, 'app/wechat/speechcraftcate/<id>/edit', '', 2, '', 0, '', 0),
+(795, 789, '', '修改话术分类', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/setting/store_service/speechcraft/cate/edit', '', 1, '', 0, '', 0),
+(796, 795, '', '保存修改客户话术分类', 'admin', '', '', 'app/wechat/speechcraftcate/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(797, 789, '', '删除话术分类', 'admin', '', '', 'app/wechat/speechcraftcate/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(798, 209, '', '获取送货人列表', 'admin', '', '', 'order/delivery/list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(799, 209, '', '获取电子面单打印默认配置', 'admin', '', '', 'order/sheet_info', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(800, 581, '', '电子面单打印', 'admin', '', '', 'order/order_dump/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(801, 760, '', '获取收银二维码', 'admin', '', '', 'order/offline_scan', 'GET', '[]', 0, 0, 0, 1, '', '4/760', 2, '', 0, '', 0),
+(802, 767, '', '获取订单发票数据', 'admin', '', '', 'order/invoice/chart', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(803, 762, '', '下载卡密二维码', 'admin', '', '', 'user/member_scan', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(805, 584, '', '修改推广人', 'admin', '', '', 'agent/spread', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(806, 71, '', '复制优惠券', 'admin', '', '', 'marketing/coupon/copy/<id>', 'GET', '[]', 0, 0, 0, 1, 'marketing/coupon/copy/369', '', 2, '', 0, '', 0),
+(807, 755, '', '获取砍价列表', 'admin', '', '', 'marketing/bargain_list', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(808, 77, '', '秒杀商品列表', 'admin', '', '', 'marketing/seckill', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(809, 95, '', '获取平台用户信息', 'admin', '', '', 'serve/info', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(810, 95, '', '获取平台消费列表', 'admin', '', '', 'serve/record', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(811, 95, '', '修改手机号', 'admin', '', '', 'serve/update_phone', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(812, 95, '', '修改签名', 'admin', '', '', 'serve/sms/sign', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(813, 95, '', '修改账号密码', 'admin', '', '', 'serve/modify', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(814, 721, '', '获取编辑配送员表单', 'admin', '', '', 'order/delivery/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(815, 717, '', '获取基础商品接口', 'admin', '', '', 'statistic/product/get_basic', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(816, 717, '', '获取商品趋势', 'admin', '', '', 'statistic/product/get_trend', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(817, 717, '', '获取商品排行', 'admin', '', '', 'statistic/product/get_product_ranking', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(818, 718, '', '获取用户基础', 'admin', '', '', 'statistic/user/get_basic', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(819, 718, '', '获取用户趋势', 'admin', '', '', 'statistic/user/get_trend', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(820, 718, '', '获取用户地区排行', 'admin', '', '', 'statistic/user/get_region', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(821, 718, '', '获取用户性别排行', 'admin', '', '', 'statistic/user/get_sex', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(822, 766, '', '获取交易趋势', 'admin', '', '', 'statistic/trade/top_trade', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(823, 766, '', '获取订单趋势', 'admin', '', '', 'statistic/trade/bottom_trade', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(824, 718, '', '导出用户统计', 'admin', '', '', 'statistic/user/get_excel', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(825, 717, '', '导出商品统计', 'admin', '', '', 'statistic/product/get_excel', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(828, 10, '', '用户列表', 'admin', '', '', 'user/user', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(830, 732, '', '卡密列表', 'admin', '', '', 'user/member_card/index/<card_batch_id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(831, 423, '', '进入工作台', 'admin', '', '', 'app/wechat/kefu/login/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(832, 71, '', '保存优惠券', 'admin', '', '', 'marketing/coupon/save_coupon', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(833, 755, '', '砍价详情', 'admin', '', '', 'marketing/bargain_list_info/<id>', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(834, 95, '', '短信记录列表', 'admin', '', '', 'notify/sms/record', 'GET', '[]', 0, 0, 0, 1, 'notify/sms/record', '', 2, '', 0, '', 0),
+(835, 28, '', '分销设置表单', 'admin', '', '', 'agent/config/edit_basics', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(836, 28, '', '分销设置表单提交', 'admin', '', '', 'agent/config/save_basics', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(837, 79, '', '积分配置表单', 'admin', '', '', 'marketing/integral_config/edit_basics', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, '', 0),
+(838, 79, '', '积分配置表单提交', 'admin', '', '', 'marketing/integral_config/save_basics', 'POST', '[]', 0, 1, 0, 1, '', '', 2, '', 0, '', 0),
+(843, 154, '', '签到天数头部数据', 'admin', '', '', 'setting/sign_data/header', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, '', 0),
+(844, 154, '', '设置签到数据状态', 'admin', '', '', 'setting/sign_data/set_status/<id>/<status>', 'PUT', '[]', 0, 1, 0, 1, '', '', 2, '', 0, '', 0),
+(845, 154, '', '签到天数列表', 'admin', '', '', 'setting/sign_data', 'GET', '[]', 0, 1, 0, 1, '', '', 2, '', 0, '', 0),
+(846, 154, '', '添加签到天数表单', 'admin', '', '', 'setting/sign_data/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(847, 154, '', '添加签到天数', 'admin', '', '', 'setting/sign_data', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(848, 154, '', '编辑签到天数表单', 'admin', '', '', 'setting/sign_data/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(849, 154, '', '编辑签到天数', 'admin', '', '', 'setting/sign_data/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(850, 154, '', '删除签到天数', 'admin', '', '', 'setting/sign_data/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(876, 78, '', '秒杀配置列表', 'admin', '', '', 'setting/seckill_data', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(877, 78, '', '添加秒杀表单', 'admin', '', '', 'setting/seckill_data/create', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(878, 78, '', '添加秒杀', 'admin', '', '', 'setting/seckill_data', 'POST', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(879, 78, '', '编辑秒杀表单', 'admin', '', '', 'setting/seckill_data/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(880, 78, '', '编辑秒杀', 'admin', '', '', 'settting/seckill_data/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(881, 78, '', '删除秒杀', 'admin', '', '', 'setting/seckill_data/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(884, 128, '', '获取数据分类', 'admin', '', '', 'setting/group_all', 'GET', '[]', 0, 0, 0, 1, '', '', 2, '', 0, '', 0),
+(885, 569, '', '附件名称修改', 'admin', '', '', 'file/file/update/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '25/566/569', 2, '', 0, '', 0),
+(886, 577, '', '用户标签接口', 'admin', '', '', 'user/user_label', 'GET', '[]', 0, 0, 0, 1, '', '1/2/577', 2, '', 0, '', 0),
+(887, 625, '', '获取赠送付费会员时长表单', 'admin', '', '', 'user/give_level_time/<id>', 'GET', '[]', 0, 0, 0, 1, '', '9/10/585/625', 2, '', 0, '', 0),
+(888, 625, '', '保存赠送付费会员时长', 'admin', '', '', 'user/save_give_level_time/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '9/10/585/625', 2, '', 0, '', 0),
+(889, 663, '', '添加页面', 'admin', '', '', 'diy/create', 'GET', '[]', 0, 0, 0, 1, '', '12/656/657/663', 2, '', 0, 'admin-template', 0),
+(890, 663, '', '保存新增', 'admin', '', '', 'diy/create', 'POST', '[]', 0, 0, 0, 1, '', '12/656/657/663', 2, '', 0, 'admin-template', 0),
+(891, 663, '', '设置默认数据', 'admin', '', '', 'diy/set_recovery/<id?>', 'GET', '[]', 0, 0, 0, 1, '', '12/656/657/663', 2, '', 0, '', 0),
+(892, 663, '', '获取商品列表', 'admin', '', '', 'diy/get_product_list', 'GET', '[]', 0, 0, 0, 1, '', '12/656/657/663', 2, '', 0, '', 0),
+(893, 577, '', '商品活动状态检测', 'admin', '', '', 'product/product/check_activity/<id>', 'GET', '[]', 0, 0, 0, 1, '', '1/2/577', 2, '', 0, '', 0),
+(894, 589, '', '会员标签列表', 'admin', '', '', 'user/user_label', 'GET', '[]', 0, 0, 0, 1, '', '9/589', 2, '', 0, '', 0),
+(895, 585, '', '新增客服选择用户列表', 'admin', '', '', 'app/wechat/kefu/create', 'GET', '[]', 0, 0, 0, 1, '', '9/10/585', 2, '', 0, '', 0),
+(896, 26, '', '分销等级', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/membership_level/index', '26', 1, '', 0, '', 0),
+(897, 4, '', '售后订单', 'admin', '', '', '', '', '[]', 9, 1, 0, 1, '/order/refund', '4', 1, '', 0, 'admin-order-refund', 0),
+(898, 12, '', '消息管理', 'admin', '', '', '', '', '[]', 9, 1, 0, 1, '/setting/notification/index', '12', 1, '', 0, 'setting-notification', 0),
+(902, 656, '', '主题风格', 'admin', '', '', '', '', '[]', 2, 1, 0, 1, '/setting/theme_style', '12/656', 1, '', 0, 'admin-setting-theme_style', 0),
+(903, 656, '', 'PC商城', 'admin', '', '', '', '', '[]', 2, 1, 0, 1, '/setting/pc_group_data', '12/656', 1, '', 0, 'setting-system-pc_data', 0),
+(904, 656, '', '客服页面广告', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/system_group_data/kf_adv', '', 1, '', 0, 'setting-system-group_data-kf_adv', 1),
+(905, 34, '', '积分商品', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/store_integral/index', '27/34', 1, '', 0, 'marketing-store_integral', 0),
+(906, 905, '', '积分商品列表', 'admin', '', '', 'marketing/integral_product', 'GET', '[]', 0, 0, 0, 1, '', '27/34/905', 2, '', 0, '', 0),
+(908, 905, '', '添加积分商品', 'admin', '', '', '', '', '[]', 0, 0, 1, 1, '/marketing/store_integral/create', '27/34/905', 1, '', 0, 'marketing-store_integral-create', 0),
+(909, 27, '', '抽奖管理', 'admin', '', '', '', '', '[]', 90, 1, 0, 1, '/marketing/lottery/index', '27', 1, '', 0, 'marketing-lottery-index', 0),
+(912, 34, '', '积分订单', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/store_integral/order_list', '27/34', 1, '', 0, 'marketing-store_integral-order', 0),
+(913, 905, '', '批量添加积分商品', 'admin', '', '', '', '', '[]', 0, 0, 1, 1, '/pages/marketing/store_integral/add_store_integral', '27/34/905', 1, '', 0, 'marketing-store_integral-create', 0),
+(914, 897, '', '售后订单列表', 'admin', '', '', 'refund/list', 'GET', '[]', 0, 0, 0, 1, '', '4/897', 2, '', 0, '', 0),
+(915, 5, '', '子订单列表', 'admin', '', '', 'order/split_order/<id>', 'GET', '[]', 0, 0, 0, 1, 'order/split_order/<id>', '4/5', 2, '', 0, '', 0),
+(916, 5, '', '订单详情', 'admin', '', '', 'order/info/<id>', 'GET', '[]', 0, 0, 1, 1, '', '4/5', 2, '', 0, '', 0),
+(917, 5, '', '订单记录', 'admin', '', '', 'order/status/<id>', 'GET', '[]', 0, 0, 1, 1, '', '4/5', 2, '', 0, '', 0),
+(918, 5, '', '可拆分商品列表', 'admin', '', '', 'order/split_cart_info/<id>', 'GET', '[]', 0, 0, 1, 1, '', '4/5', 2, '', 0, '', 0),
+(919, 5, '', '拆单发送货', 'admin', '', '', 'order/split_delivery/<id>', 'PUT', '[]', 0, 0, 1, 1, '', '4/5', 2, '', 0, '', 0),
+(920, 896, '', '修改分销等级状态', 'admin', '', '', 'agent/level/set_status/<id>/<status>', 'PUT', '{\"[PUT] agent\":\"level\",\"set_status\":\"<id>\"}', 0, 0, 1, 1, '', '26/896', 2, '', 0, '', 0),
+(921, 896, '', '修改分销等级任务状态', 'admin', '', '', 'agent/level_task/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(922, 896, '', '获取赠送分销等级表单', 'admin', '', '', 'agent/get_level_form', 'GET', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(923, 896, '', '赠送分销等级', 'admin', '', '', 'agent/give_level', 'POST', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(924, 896, '', '分销等级列表', 'admin', '', '', 'agent/level', 'GET', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(925, 896, '', '添加分销等级表单', 'admin', '', '', 'agent/level/create', 'GET', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(926, 896, '', '编辑分销等级表单', 'admin', '', '', 'agent/level/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(927, 896, '', '分销等级任务', 'admin', '', '', 'agent/level_task', 'GET', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(928, 896, '', '删除分销等级', 'admin', '', '', 'agent/level/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(929, 896, '', '添加分销员等级', 'admin', '', '', 'agent/level', 'POST', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(930, 896, '', '编辑分销员等级', 'admin', '', '', 'agent/level/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(931, 896, '', '添加分销员等级任务表单', 'admin', '', '', 'agent/level_task/create', 'GET', '[]', 0, 0, 0, 1, 'agent/level_task/create', '26/896', 2, '', 0, '', 0),
+(932, 896, '', '添加分销员等级任务', 'admin', '', '', 'agent/level_task', 'POST', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(933, 896, '', '编辑分销员等级任务表单', 'admin', '', '', 'agent/level_task/<id>/edit', 'GET', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(934, 896, '', '编辑分销员等级任务', 'admin', '', '', 'agent/level_task/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '26/896', 2, '', 0, '', 0),
+(935, 896, '', '删除分销员等级任务', 'admin', '', '', 'agent/level_task/<id>', 'DELETE', '[]', 0, 0, 0, 1, 'agent/level_task/<id>', '26/896', 2, '', 0, '', 0),
+(936, 423, '', '新增客服选择用户列表', 'admin', '', '', 'app/wechat/kefu/create', 'GET', '[]', 0, 0, 1, 1, '', '165/678/423', 2, '', 0, '', 0),
+(937, 78, '', '秒杀配置头部', 'admin', '', '', 'setting/seckill_data/header', 'GET', '[]', 0, 0, 0, 1, '', '27/33/78', 2, '', 0, '', 0),
+(938, 154, '', '签到配置编辑保存', 'admin', '', '', 'setting/group_data/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '27/34/154', 2, '', 0, '', 0),
+(939, 154, '', '签到配置添加保存', 'admin', '', '', 'setting/group_data', 'POST', '[]', 0, 0, 0, 1, '', '27/34/154', 2, '', 0, '', 0),
+(940, 905, '', '添加积分商品保存', 'admin', '', '', 'marketing/integral/<id>', 'POST', '[]', 0, 0, 0, 1, '', '27/34/905', 2, '', 0, '', 0),
+(941, 912, '', '积分订单头部', 'admin', '', '', 'marketing/integral/order/chart', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(942, 912, '', '积分订单列表', 'admin', '', '', 'marketing/integral/order/list', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(943, 905, '', '积分商品编辑', 'admin', '', '', 'marketing/integral/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/34/905', 2, '', 0, '', 0),
+(944, 912, '', '发货物流列表', 'admin', '', '', 'marketing/integral/order/express_list', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(945, 912, '', '快递列表', 'admin', '', '', 'marketing/integral/order/delivery/list', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(946, 912, '', '图表详情', 'admin', '', '', 'marketing/integral/order/sheet_info', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(947, 912, '', '发货', 'admin', '', '', 'marketing/integral/order/delivery/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(948, 912, '', '配送信息表单', 'admin', '', '', 'marketing/integral/order/distribution/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(949, 912, '', '配送信息保存', 'admin', '', '', 'marketing/integral/order/distribution/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(950, 912, '', '订单详情', 'admin', '', '', 'marketing/integral/order/info/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(951, 912, '', '订单记录', 'admin', '', '', 'marketing/integral/order/status/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(952, 912, '', '小票打印', 'admin', '', '', 'marketing/integral/order/print/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(953, 912, '', '物流查询', 'admin', '', '', 'marketing/integral/order/express/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(954, 912, '', '订单备注', 'admin', '', '', 'marketing/integral/order/remark/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(955, 912, '', '收货', 'admin', '', '', 'marketing/integral/order/take/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '27/34/912', 2, '', 0, '', 0),
+(960, 909, '', '抽奖列表', 'admin', '', '', 'marketing/lottery/list', 'GET', '[]', 0, 1, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(961, 909, '', '抽奖商品详情', 'admin', '', '', 'marketing/lottery/detail/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(962, 909, '', '用户等级', 'admin', '', '', 'user/user_label', 'GET', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(963, 909, '', '会员等级', 'admin', '', '', 'user/user_level/vip_list', 'GET', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(964, 909, '', '编辑保存', 'admin', '', '', 'marketing/lottery/edit/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(965, 27, '', '营销公共权限', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, 'admin-marketing', '27', 1, '', 0, '', 0),
+(966, 965, '', '附件分类', 'admin', '', '', 'file/category', 'GET', '[]', 0, 0, 0, 1, '', '27/965', 2, '', 0, '', 0),
+(967, 965, '', '附件列表', 'admin', '', '', 'file/file', 'GET', '[]', 0, 0, 0, 1, '', '27/965', 2, '', 0, '', 0),
+(968, 909, '', '删除抽奖', 'admin', '', '', 'marketing/lottery/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(969, 909, '', '抽奖记录列表', 'admin', '', '', 'marketing/lottery/record/list/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(970, 909, '', '物流公司', 'admin', '', '', 'order/express_list', 'GET', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(971, 909, '', '抽奖记录备注', 'admin', '', '', 'marketing/lottery/record/deliver', 'POST', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(972, 909, '', '抽奖状态', 'admin', '', '', 'marketing/lottery/set_status/<id>/<status>', 'POST', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(973, 909, '', '添加抽奖', 'admin', '', '', 'marketing/lottery/add', 'POST', '[]', 0, 0, 0, 1, '', '27/909', 2, '', 0, '', 0),
+(975, 28, '', '分销配置头部', 'admin', '', '', 'setting/config/header_basics', 'GET', '[]', 0, 0, 0, 1, '', '26/28', 2, '', 0, '', 0),
+(976, 717, '', '查看商品', 'admin', '', '', 'product/product/<id>', 'GET', '[]', 0, 0, 0, 1, '', '716/717', 2, '', 0, '', 0),
+(977, 657, '', '获取风格设置', 'admin', '', '', 'diy/get_color_change/<type>', 'GET', '[]', 0, 0, 0, 1, '', '12/656/657', 2, '', 0, '', 0),
+(978, 657, '', '获取个人中心菜单', 'admin', '', '', 'diy/get_member', 'GET', '[]', 0, 0, 0, 1, '', '12/656/657', 2, '', 0, '', 0),
+(979, 657, '', '个人中心组件分类', 'admin', '', '', 'diy/get_page_category', 'GET', '[]', 0, 0, 0, 1, '', '12/656/657', 2, '', 0, '', 0),
+(980, 657, '', '个人中心组件树形分类', 'admin', '', '', 'product/category/tree/<type>', 'GET', '[]', 0, 0, 0, 1, '', '12/656/657', 2, '', 0, '', 0),
+(981, 657, '', '获取页面链接', 'admin', '', '', 'diy/get_page_link/<cate_id>', 'GET', '[]', 0, 0, 0, 1, '', '12/656/657', 2, '', 0, '', 0),
+(982, 657, '', '商品分类页保存', 'admin', '', '', 'diy/color_change/<status>/<type>', 'PUT', '[]', 0, 0, 0, 1, '', '12/656/657', 2, '', 0, '', 0),
+(983, 657, '', '个人中心页保存', 'admin', '', '', 'diy/member_save', 'POST', '[]', 0, 0, 0, 1, '', '12/656/657', 2, '', 0, '', 0),
+(984, 128, '', '获取组合数据', 'admin', '', '', 'setting/group_data', 'GET', '[]', 0, 0, 0, 1, '', '12/656/128', 2, '', 0, '', 0),
+(985, 128, '', '获取头部', 'admin', '', '', 'setting/sign_data/header', 'GET', '[]', 0, 0, 0, 1, '', '12/656/128', 2, '', 0, '', 0),
+(986, 128, '', '保存配置', 'admin', '', '', 'setting/group_data/save_all', 'POST', '[]', 0, 0, 0, 1, '', '12/656/128', 2, '', 0, '', 0),
+(987, 128, '', '客服页面广告', 'admin', '', '', 'setting/get_kf_adv', 'GET', '[]', 0, 0, 0, 1, '', '12/656/128', 2, '', 0, '', 0),
+(988, 898, '', '消息管理列表', 'admin', '', '', 'setting/notification/index', 'GET', '[]', 0, 0, 0, 1, '', '12/898', 2, '', 0, '', 0),
+(989, 898, '', '模板消息详情', 'admin', '', '', 'setting/notification/info', 'GET', '[]', 0, 0, 0, 1, '', '12/898', 2, '', 0, '', 0),
+(990, 898, '', '编辑保存', 'admin', '', '', 'setting/notification/save', 'POST', '[]', 0, 0, 0, 1, '', '12/898', 2, '', 0, '', 0),
+(991, 898, '', '模板消息状态修改', 'admin', '', '', 'setting/notification/set_status/<type>/<status>/<id>', 'PUT', '[]', 0, 0, 0, 1, '', '12/898', 2, '', 0, '', 0),
+(992, 898, '', '一键同步模版消息', 'admin', '', '', 'app/wechat/syncSubscribe', 'GET', '[]', 0, 0, 0, 1, '', '12/898', 2, '', 0, '', 0),
+(993, 135, '', '小程序', 'admin', '', '', '', '', '[]', 3, 1, 0, 1, '/app/routine', '135', 1, '', 0, 'admin-routine', 0),
+(994, 993, '', '小程序下载', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/app/routine/download', '135/993', 1, '', 0, 'routine-download', 0),
+(995, 994, '', '下载小程序页面数据', 'admin', '', '', 'app/routine/info', 'GET', '[]', 0, 0, 0, 1, '', '135/993/994', 2, '', 0, '', 0),
+(996, 994, '', '下载小程序模版', 'admin', '', '', 'app/routine/download', 'POST', '[]', 0, 0, 0, 1, '', '135/993/994', 2, '', 0, '', 0),
+(997, 716, '', '订单统计', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/statistic/order', '716', 1, '', 0, 'admin-statistic', 0),
+(998, 37, '', '资金流水', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/finance/capital_flow/index', '35/37', 1, '', 0, 'finance-capital_flow-index', 0),
+(999, 37, '', '账单记录', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/finance/billing_records/index', '35/37', 1, '', 0, 'finance-billing_records-index', 0),
+(1000, 566, '', '富文本上传图片', 'admin', '', '', '', '', '[]', 0, 0, 1, 1, '/widget.images/index.html', '25/566', 1, '', 0, 'admin-user-user-index', 0),
+(1001, 34, '', '积分记录', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/point_record', '27/34', 1, '', 0, 'marketing-point_record-index', 0),
+(1002, 34, '', '积分统计', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/point_statistic', '27/34', 1, '', 0, 'marketing-point_statistic-index', 0),
+(1003, 35, '', '余额记录', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/finance/balance', '35', 1, '', 0, 'finance-balance-index', 0),
+(1004, 1003, '', '余额记录', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/finance/balance/balance', '35/1003', 1, '', 0, 'finance-user-balance', 0),
+(1005, 716, '', '余额统计', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/statistic/balance', '716', 1, '', 0, 'admin-statistic', 0),
+(1006, 69, '', '公众号配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/wechat_config/3/2', '135/69', 1, '', 0, 'setting-system-config', 0),
+(1007, 993, '', '小程序配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/routine_config/3/7', '135/993', 1, '', 0, 'setting-system-config', 0),
+(1008, 135, '', 'PC端', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/app/pc', '135', 1, '', 0, 'admin-pc', 0),
+(1009, 135, '', 'APP', 'admin', '', '', '', '', '[]', 2, 1, 0, 1, '/app/app', '135', 1, '', 0, 'admin-app', 0),
+(1010, 1008, '', 'PC端配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/pc_config/3/75', '135/1008', 1, '', 0, 'setting-system-config', 0),
+(1011, 1009, '', 'APP配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/app_config/3/77', '135/1009', 1, '', 0, 'setting-system-config', 0),
+(1012, 1056, '', '系统存储配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/storage', '12', 1, '', 0, 'setting-storage', 0),
+(1013, 26, '', '事业部', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/agent/division', '26', 1, '', 0, 'agent-division', 0),
+(1014, 1013, '', '事业部列表', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/division/index', '26/1013', 1, '', 0, 'agent-division-index', 0),
+(1015, 1013, '', '代理商列表', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/division/agent/index', '26/1013', 1, '', 0, 'agent-division-agent-index', 0),
+(1016, 1013, '', '代理商申请', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/division/agent/applyList', '26/1013', 1, '', 0, 'agent-division-agent-applyList', 0),
+(1018, 909, '', '抽奖配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/lottery/create', '27/909', 1, '', 0, 'admin-marketing-lottery-create', 0),
+(1019, 909, '', '中奖记录', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/marketing/lottery/recording_list', '27/909', 1, '', 0, 'admin-marketing-lottery-recording_list-id', 0),
+(1020, 1014, '', '事业部列表', 'admin', '', '', 'agent/division/list', 'GET', '[]', 0, 0, 0, 1, '', '26/1013/1014', 2, '', 0, '', 0),
+(1021, 1014, '', '添加事业部', 'admin', '', '', 'agent/division/create/<uid>', 'GET', '[]', 0, 0, 0, 1, '', '26/1013/1014', 2, '', 0, '', 0),
+(1023, 27, '', '渠道码', 'admin', '', '', '', '', '[]', 55, 1, 0, 1, '/marketing/channel_code/channelCodeIndex', '27', 1, '', 0, 'marketing-channel_code-index', 0),
+(1024, 1023, '', '添加公众号渠道码', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/marketing/channel_code/create', '27/1021', 1, '', 0, 'marketing-channel_code-create', 0),
+(1025, 1023, '', '渠道码统计', 'admin', '', '', '', '', '[]', 0, 0, 0, 1, '/marketing/channel_code/code_statistic', '27/1021', 1, '', 0, 'marketing-channel_code-statistic', 0),
+(1026, 1014, '', '事业部下级列表', 'admin', '', '', '/agent/division/down_list', 'GET', '[]', 0, 0, 0, 1, '', '26/1013/1014', 2, '', 0, '', 0),
+(1027, 1014, '', '事业部保存', 'admin', '', '', 'agent/division/save', 'POST', '[]', 0, 0, 0, 1, '', '26/1013/1014', 2, '', 0, '', 0),
+(1028, 1014, '', '事业部状态切换', 'admin', '', '', 'agent/division/set_status/<status>/<uid>', 'PUT', '[]', 0, 0, 0, 1, '', '26/1013/1014', 2, '', 0, '', 0),
+(1029, 1014, '', '事业部删除', 'admin', '', '', 'division/del/<type>/<uid>', 'DELETE', '[]', 0, 0, 0, 1, '', '26/1013/1014', 2, '', 0, '', 0),
+(1030, 1015, '', '代理商列表', 'admin', '', '', 'agent/division/list', 'GET', '[]', 0, 0, 0, 1, '', '26/1013/1015', 2, '', 0, '', 0),
+(1031, 1015, '', '代理商下级列表', 'admin', '', '', 'agent/division/down_list', 'GET', '[]', 0, 0, 0, 1, '', '26/1013/1015', 2, '', 0, '', 0),
+(1032, 1015, '', '添加代理商', 'admin', '', '', 'agent/division/agent/create/<uid>', 'GET', '[]', 0, 0, 0, 1, '', '26/1013/1015', 2, '', 0, '', 0),
+(1033, 1015, '', '代理商保存', 'admin', '', '', 'agent/division/agent/save', 'POST', '[]', 0, 0, 0, 1, '', '26/1013/1015', 2, '', 0, '', 0),
+(1034, 1015, '', '代理商状态切换', 'admin', '', '', 'agent/division/set_status/<status>/<uid>', 'PUT', '[]', 0, 0, 0, 1, '', '26/1013/1015', 2, '', 0, '', 0),
+(1035, 1015, '', '代理商删除', 'admin', '', '', 'agent/division/del/<type>/<uid>', 'DELETE', '[]', 0, 0, 0, 1, '', '26/1013/1015', 2, '', 0, '', 0),
+(1036, 1016, '', '代理商申请列表', 'admin', '', '', 'agent/division/agent_apply/list', 'GET', '[]', 0, 0, 0, 1, '', '26/1013/1016', 2, '', 0, '', 0),
+(1037, 1016, '', '代理商审核', 'admin', '', '', 'agent/division/examine_apply/<id>/<type>', 'GET', '[]', 0, 0, 0, 1, '', '26/1013/1016', 2, '', 0, '', 0),
+(1038, 1016, '', '提交审核', 'admin', '', '', 'agent/division/apply_agent/save', 'POST', '[]', 0, 0, 0, 1, '', '26/1013/1016', 2, '', 0, '', 0),
+(1039, 1016, '', '删除审核', 'admin', '', '', 'agent/division/del_apply/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '26/1013/1016', 2, '', 0, '', 0),
+(1042, 1023, '', '渠道码分类列表', 'admin', '', '', 'app/wechat_qrcode/cate/list', 'GET', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1043, 1023, '', '渠道码分类添加编辑表单', 'admin', '', '', 'app/wechat_qrcode/cate/create/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1044, 1023, '', '渠道码分类保存', 'admin', '', '', 'app/wechat_qrcode/cate/save', 'POST', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1045, 1023, '', '渠道码分类删除', 'admin', '', '', 'app/wechat_qrcode/cate/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1046, 1023, '', '保存渠道码', 'admin', '', '', 'app/wechat_qrcode/save/<id>', 'POST', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1047, 1023, '', '渠道码详情', 'admin', '', '', 'app/wechat_qrcode/info/<id>', 'GET', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1048, 1023, '', '渠道码列表', 'admin', '', '', 'app/wechat_qrcode/list', 'GET', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1049, 1023, '', '删除渠道码', 'admin', '', '', 'app/wechat_qrcode/del/<id>', 'DELETE', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1050, 1023, '', '渠道码状态切换', 'admin', '', '', 'app/wechat_qrcode/set_status/<id>/<status>', 'PUT', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1051, 1023, '', '渠道码用户列表', 'admin', '', '', 'app/wechat_qrcode/user_list/<qid>', 'GET', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1052, 1023, '', '获取用户标签', 'admin', '', '', 'user/user_label', 'GET', '[]', 0, 0, 0, 1, '', '27/1023', 2, '', 0, '', 0),
+(1053, 27, '', '充值配置', 'admin', '', '', '', '', '[]', 60, 1, 0, 1, '/marketing/recharge', '27', 1, '', 0, 'marketing-recharge-index', 0),
+(1055, 1009, '', '版本管理', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/app/app/version', '135/1009', 1, '', 0, 'admin-app-version', 0),
+(1056, 12, '', '接口配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/other_config', '12', 1, '', 0, 'setting-other', 0),
+(1057, 1056, '', '小票打印配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/other_config/print/2/21', '12/1056', 1, '', 0, 'setting-other-print', 0),
+(1058, 1056, '', '商品采集配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/other_config/copy/2/41', '12/1056', 1, '', 0, 'setting-other-copy', 0),
+(1059, 1056, '', '物流查询配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/other_config/logistics/2/64', '12/1056', 1, '', 0, 'setting-other-logistics', 0),
+(1060, 1056, '', '电子面单配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/other_config/electronic/2/66', '12/1056', 1, '', 0, 'setting-other-electronic', 0),
+(1061, 12, '', '协议设置', 'admin', '', '', '', '', '[]', 9, 1, 0, 1, '/setting/agreement', '12', 1, '', 0, 'setting-agreement', 0),
+(1062, 1056, '', '短信接口配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/other_config/sms/2/96', '12/1056', 1, '', 0, 'setting-other-sms', 0),
+(1063, 1056, '', '商城支付配置', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/other_config/pay/2/23', '12/1056', 1, '', 0, 'setting-other-pay', 0),
+(1064, 25, '', '对外接口', 'admin', '', '', '', '', '[]', 6, 1, 0, 1, '/setting/other_out_config', '25', 1, '', 0, 'setting-other-out', 0),
+(1066, 1064, '', '账号管理', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/system_out_account/index', '56/1064', 1, '', 0, 'setting-system-out-account-index', 0),
+(1067, 25, '', '语言设置', 'admin', '', '', '', '', '[]', 5, 1, 0, 1, '/setting/lang', '25', 1, '', 0, 'admin-lang', 0),
+(1068, 1067, '', '语言列表', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/lang/list', '12/1067', 1, '', 0, 'admin-lang-list', 0),
+(1069, 1067, '', '语言详情', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/lang/info', '12/1067', 1, '', 0, 'admin-lang-info', 0),
+(1070, 1067, '', '地区列表', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/lang/country', '25/1067', 1, '', 0, 'admin-lang-country', 0),
+(1071, 56, '', '文件管理', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/system/maintain/system_file/opendir', '25/56', 1, '', 0, 'system-maintain-system-file', 0),
+(1072, 1064, '', '接口文档', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/setting/system_out_interface/index', '56/1064', 1, '', 0, 'setting-system-out-interface-index', 0),
+(1073, 25, '', '数据维护', 'admin', '', '', '', '', '[]', 7, 1, 0, 1, 'system/database/index', '25', 1, '', 0, 'system-database-index', 0),
+(1075, 731, '', '会员配置', 'admin', '', '', '', '', '[]', 6, 1, 0, 1, '/marketing/member/system_config/3/67', '27/731', 1, '', 0, 'marketing-member-system_config', 0),
+(1076, 56, '', '定时任务', 'admin', '', '', '', '', '[]', 0, 1, 0, 1, '/system/crontab', '25/56', 1, '', 0, 'system-crontab-index', 0);
+SQL
+            ],
+            [
+                'code' => 470,
+                'type' => 1,
+                'table' => "system_timer",
+                'findSql' => "select * from information_schema.tables where table_name ='@table'",
+                'sql' => "CREATE TABLE IF NOT EXISTS `@table` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) NOT NULL DEFAULT '' COMMENT '定时器名称',
+  `mark` varchar(255) NOT NULL DEFAULT '' COMMENT '标签',
+  `content` varchar(255) NOT NULL DEFAULT '' COMMENT '说明',
+  `type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '周期状态 1=每隔多少秒 2=每隔多少分钟 3=每隔多少小时 4=每隔多少天 5=每天几点执行 6=每周周几几点执行 7=每月几号几点执行',
+  `week` int(11) NOT NULL DEFAULT '0' COMMENT '周',
+  `day` int(11) NOT NULL DEFAULT '0' COMMENT '日',
+  `hour` int(11) NOT NULL DEFAULT '0' COMMENT '时',
+  `minute` int(11) NOT NULL DEFAULT '0' COMMENT '分',
+  `second` int(11) NOT NULL DEFAULT '0' COMMENT '秒',
+  `last_execution_time` int(11) NOT NULL DEFAULT '0' COMMENT '上次执行时间',
+  `next_execution_time` int(11) NOT NULL DEFAULT '0' COMMENT '下次执行时间',
+  `add_time` int(11) NOT NULL DEFAULT '0' COMMENT '添加时间',
+  `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
+  `is_open` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否开启',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='定时器'"
+            ],
+            [
+                'code' => 470,
+                'type' => -1,
+                'table' => "system_timer",
+                'sql' => <<<SQL
+INSERT INTO `@table` (`id`, `name`, `mark`, `content`, `type`, `week`, `day`, `hour`, `minute`, `second`, `last_execution_time`, `next_execution_time`, `add_time`, `is_del`, `is_open`) VALUES
+(1, '未支付自动取消订单', 'orderCancel', '每隔30秒执行自动取消到期未支付的订单', 1, 1, 1, 1, 30, 30, 0, 1670642407, 1670642377, 0, 1),
+(2, '拼团到期订单处理', 'pinkExpiration', '每隔1分钟拼团到期之后的操作', 2, 1, 1, 1, 1, 0, 0, 1670642487, 1670642427, 0, 1),
+(3, '到期自动解绑上级', 'agentUnbind', '每隔1分钟执行到期的绑定关系的解除', 2, 1, 1, 1, 1, 0, 0, 1670642534, 1670642474, 0, 1),
+(4, '自动更新直播商品状态', 'liveProductStatus', '每隔3分钟执行更新直播商品状态', 2, 1, 1, 1, 3, 0, 0, 1670642694, 1670642514, 0, 1),
+(5, '自动更新直播间状态', 'liveRoomStatus', '每隔3分钟执行更新直播间状态', 2, 1, 1, 1, 3, 0, 0, 1670642709, 1670642529, 0, 1),
+(6, '订单自动收货', 'takeDelivery', '每隔5分钟执行订单到期自动收货', 2, 1, 1, 1, 5, 0, 0, 1670642891, 1670642591, 0, 1),
+(7, '预售商品到期自动下架', 'advanceOff', '每隔5分钟执行预售商品到期下架', 2, 1, 1, 1, 5, 0, 0, 1670642913, 1670642613, 0, 1),
+(8, '订单商品自动好评', 'productReplay', '每隔5分钟执行订单到期商品好评', 2, 1, 1, 1, 5, 0, 0, 1670642933, 1670642633, 0, 1),
+(9, '清除昨日海报', 'clearPoster', '每天0时30分0秒执行一次清除昨日海报', 5, 1, 1, 0, 30, 0, 0, 1670862600, 1670815378, 0, 1);
+SQL
+            ],
+        ];
+        return $data;
+    }
+
+    /**
+     * 升级列表
+     * @return mixed
+     */
+    public function upgradeList()
+    {
+        return app('json')->success($this->services->getUpgradeList());
+    }
+
+    /**
+     * 可升级列表
+     * @return mixed
+     */
+    public function upgradeableList()
+    {
+        return app('json')->success($this->services->getUpgradeableList());
+    }
+
+    /**
+     * 可升级列表
+     * @return mixed
+     */
+    public function agreement()
+    {
+        return app('json')->success($this->services->getAgreement());
+    }
+
+    /**
+     * 下载升级包
+     * @param $packageKey
+     * @return mixed
+     */
+    public function download($packageKey)
+    {
+        if (empty($packageKey)) {
+            return app('json')->fail(100100);
+        }
+
+        $this->services->packageDownload($packageKey);
+        return app('json')->success();
+    }
+
+    /**
+     * 升级进度
+     * @return mixed
+     */
+    public function progress()
+    {
+        $result = $this->services->getProgress();
+        return app('json')->success($result);
+    }
+
+    /**
+     * 获取升级状态
+     * @return mixed
+     */
+    public function upgradeStatus()
+    {
+        $data = $this->services->getUpgradeStatus();
+        return app('json')->success($data);
+    }
+
+    /**
+     * 升级记录
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     */
+    public function upgradeLogList()
+    {
+        $data = $this->services->getUpgradeLogList();
+        return app('json')->success($data);
+    }
+
+    /**
+     * 导出备份
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     */
+    public function export($id, $type)
+    {
+        if (!$id || !$type) {
+            return app('json')->fail(100026);
+        }
+        return app('json')->success($this->services->export((int)$id, $type));
+    }
+}

+ 187 - 0
app/adminapi/controller/v1/agent/AgentLevel.php

@@ -0,0 +1,187 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\agent;
+
+use app\adminapi\controller\AuthController;
+use app\services\agent\AgentLevelServices;
+use app\services\agent\AgentLevelTaskServices;
+use think\facade\App;
+
+/**
+ * 分销等级控制器
+ * Class AgentLevel
+ * @package app\controller\admin\v1\agent
+ */
+class AgentLevel extends AuthController
+{
+    /**
+     * AgentLevel constructor.
+     * @param App $app
+     * @param AgentLevelServices $services
+     */
+    public function __construct(App $app, AgentLevelServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 后台分销等级列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['keyword', '']
+        ]);
+        return app('json')->success($this->services->getLevelList($where));
+    }
+
+    /**
+     * 添加分销等级表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->createForm());
+    }
+
+    /**
+     * 保存分销等级
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['grade', 0],
+            ['image', ''],
+            ['one_brokerage', 0],
+            ['two_brokerage', 0],
+            ['status', 0]]);
+        if (!$data['name']) return app('json')->fail(400200);
+        if (!$data['grade']) return app('json')->fail(400201);
+        if (!$data['image']) return app('json')->fail(400202);
+        if ($data['two_brokerage'] > $data['one_brokerage']) {
+            return app('json')->fail(400203);
+        }
+        $grade = $this->services->get(['grade' => $data['grade'], 'is_del' => 0]);
+        if ($grade) {
+            return app('json')->fail(400204);
+        }
+        $data['add_time'] = time();
+        $this->services->save($data);
+        return app('json')->success(400205);
+    }
+
+    /**
+     * 显示指定的资源
+     * @param $id
+     */
+    public function read($id)
+    {
+
+    }
+
+    /**
+     * 编辑分销等级表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->editForm((int)$id));
+    }
+
+    /**
+     * 修改分销等级
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['grade', 0],
+            ['image', ''],
+            ['one_brokerage', 0],
+            ['two_brokerage', 0],
+            ['status', 0]]);
+        if (!$data['name']) return app('json')->fail(400200);
+        if (!$data['grade']) return app('json')->fail(400201);
+        if (!$data['image']) return app('json')->fail(400202);
+        if ($data['two_brokerage'] > $data['one_brokerage']) {
+            return app('json')->fail(400203);
+        }
+        if (!$levelInfo = $this->services->getLevelInfo((int)$id)) return app('json')->fail(400206);
+        $grade = $this->services->get(['grade' => $data['grade'], 'is_del' => 0]);
+        if ($grade && $grade['id'] != $id) {
+            return app('json')->fail(400204);
+        }
+
+        $levelInfo->name = $data['name'];
+        $levelInfo->grade = $data['grade'];
+        $levelInfo->image = $data['image'];
+        $levelInfo->one_brokerage = $data['one_brokerage'];
+        $levelInfo->two_brokerage = $data['two_brokerage'];
+        $levelInfo->status = $data['status'];
+        $levelInfo->save();
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除分销等级
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        //检查分销等级数据是否存在
+        $levelInfo = $this->services->getLevelInfo((int)$id);
+        if ($levelInfo) {
+            //更新数据为已删除
+            $res = $this->services->update($id, ['is_del' => 1]);
+            if (!$res)
+                return app('json')->fail(100008);
+            //删除该等级的任务为已删除
+            /** @var AgentLevelTaskServices $agentLevelTaskServices */
+            $agentLevelTaskServices = app()->make(AgentLevelTaskServices::class);
+            $agentLevelTaskServices->update(['level_id' => $id], ['is_del' => 1]);
+        }
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param int $id
+     * @param string $status
+     * @return mixed
+     */
+    public function set_status($id = 0, $status = '')
+    {
+        if ($status == '' || $id == 0) return app('json')->fail(100100);
+        $this->services->update($id, ['status' => $status]);
+        return app('json')->success(100014);
+    }
+}

+ 184 - 0
app/adminapi/controller/v1/agent/AgentLevelTask.php

@@ -0,0 +1,184 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\agent;
+
+use app\adminapi\controller\AuthController;
+use app\services\agent\AgentLevelTaskServices;
+use think\facade\App;
+
+/**
+ * 分销等级任务控制器
+ * Class AgentLevelTask
+ * @package app\controller\admin\v1\agent
+ */
+class AgentLevelTask extends AuthController
+{
+    /**
+     * AgentLevelTask constructor.
+     * @param App $app
+     * @param AgentLevelTaskServices $services
+     */
+    public function __construct(App $app, AgentLevelTaskServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示等级任务列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['id', 0],
+            ['status', ''],
+            ['keyword', '']
+        ]);
+        if (!$where['id']) {
+            return app('json')->fail(100100);
+        }
+        $where['level_id'] = $where['id'];
+        unset($where['id']);
+        return app('json')->success($this->services->getLevelTaskList($where));
+    }
+
+    /**
+     * 等级任务添加表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create()
+    {
+        [$level_id] = $this->request->postMore([
+            ['level_id', 0]], true);
+        if (!$level_id) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($this->services->createForm((int)$level_id));
+    }
+
+    /**
+     * 保存等级任务
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['level_id', 0],
+            ['name', ''],
+            ['type', ''],
+            ['number', 0],
+            ['desc', 0],
+            ['sort', 0],
+            ['status', 0]]);
+        if (!$data['level_id']) return app('json')->fail(100100);
+        if (!$data['name']) return app('json')->fail(400207);
+        if (!$data['type']) return app('json')->fail(400208);
+        if (!$data['number']) return app('json')->fail(400209);
+        $this->services->checkTypeTask(0, $data);
+        $data['add_time'] = time();
+        $this->services->save($data);
+        return app('json')->success(400210);
+    }
+
+    /**
+     * 显示指定的资源
+     * @param $id
+     */
+    public function read($id)
+    {
+
+    }
+
+    /**
+     * 等级任务修改表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->editForm((int)$id));
+    }
+
+    /**
+     * 修改等级任务
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['type', ''],
+            ['number', 0],
+            ['desc', 0],
+            ['sort', 0],
+            ['status', 0]]);
+        if (!$data['name']) return app('json')->fail(400207);
+        if (!$data['type']) return app('json')->fail(400208);
+        if (!$data['number']) return app('json')->fail(400209);
+        if (!$levelTaskInfo = $this->services->getLevelTaskInfo((int)$id)) return app('json')->fail(400211);
+        $this->services->checkTypeTask((int)$id, $data);
+        $levelTaskInfo->name = $data['name'];
+        $levelTaskInfo->type = $data['type'];
+        $levelTaskInfo->number = $data['number'];
+        $levelTaskInfo->desc = $data['desc'];
+        $levelTaskInfo->sort = $data['sort'];
+        $levelTaskInfo->status = $data['status'];
+        $levelTaskInfo->save();
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除等级任务
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $levelTaskInfo = $this->services->getLevelTaskInfo((int)$id);
+        if ($levelTaskInfo) {
+            $res = $this->services->update($id, ['is_del' => 1]);
+            if (!$res)
+                return app('json')->fail(100008);
+        }
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param int $id
+     * @param string $status
+     * @return mixed
+     */
+    public function set_status($id = 0, $status = '')
+    {
+        if ($status == '' || $id == 0) return app('json')->fail(100100);
+        $this->services->update($id, ['status' => $status]);
+        return app('json')->success(100014);
+    }
+
+}

+ 282 - 0
app/adminapi/controller/v1/agent/AgentManage.php

@@ -0,0 +1,282 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\agent;
+
+use app\adminapi\controller\AuthController;
+use app\services\agent\AgentLevelServices;
+use app\services\agent\AgentManageServices;
+use app\services\user\UserServices;
+use think\facade\App;
+
+/**
+ * 分销商管理控制器
+ * Class AgentManage
+ * @package app\adminapi\controller\v1\agent
+ */
+class AgentManage extends AuthController
+{
+    /**
+     * AgentManage constructor.
+     * @param App $app
+     * @param AgentManageServices $services
+     */
+    public function __construct(App $app, AgentManageServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 分销管理列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['nickname', ''],
+            ['data', ''],
+        ]);
+        return app('json')->success($this->services->agentSystemPage($where));
+    }
+
+    /**
+     * 分销头部统计
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function get_badge()
+    {
+        $where = $this->request->getMore([
+            ['data', ''],
+            ['nickname', ''],
+        ]);
+        return app('json')->success(['res' => $this->services->getSpreadBadge($where)]);
+    }
+
+    /**
+     * 推广人列表
+     * @return mixed
+     */
+    public function get_stair_list()
+    {
+        $where = $this->request->getMore([
+            ['uid', 0],
+            ['data', ''],
+            ['nickname', ''],
+            ['type', '']
+        ]);
+        return app('json')->success($this->services->getStairList($where));
+    }
+
+    /**
+     * 推广人列表头部统计
+     * @return mixed
+     */
+    public function get_stair_badge()
+    {
+        $where = $this->request->getMore([
+            ['uid', ''],
+            ['data', ''],
+            ['nickname', ''],
+            ['type', ''],
+        ]);
+        return app('json')->success(['res' => $this->services->getSairBadge($where)]);
+    }
+
+    /**
+     * 统计推广订单列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function get_stair_order_list()
+    {
+        $where = $this->request->getMore([
+            ['uid', 0],
+            ['data', ''],
+            ['order_id', ''],
+            ['type', ''],
+        ]);
+        return app('json')->success($this->services->getStairOrderList((int)$where['uid'], $where));
+    }
+
+    /**
+     * 查看公众号推广二维码
+     * @param string $uid
+     * @param string $action
+     * @return mixed
+     */
+    public function look_code($uid = '', $action = '')
+    {
+        if (!$uid || !$action) return app('json')->fail(100100);
+        try {
+            if (method_exists($this, $action)) {
+                $res = $this->$action($uid);
+                if ($res)
+                    return app('json')->success($res);
+                else
+                    return app('json')->fail(100016);
+            } else
+                return app('json')->fail(100029);
+        } catch (\Exception $e) {
+            return app('json')->fail(400212, ['line' => $e->getLine(), 'messag' => $e->getMessage()]);
+        }
+    }
+
+    /**
+     * 获取公众号二维码
+     * @param $uid
+     * @return array
+     */
+    public function wechant_code($uid)
+    {
+        $qr_code = $this->services->wechatCode((int)$uid);
+        if (isset($qr_code['url']))
+            return ['code_src' => $qr_code['url']];
+        else
+            return app('json')->fail(100016);
+    }
+
+    /**
+     * 查看小程序推广二维码
+     * @param string $uid
+     */
+    public function look_xcx_code($uid = '')
+    {
+        if (!strlen(trim($uid))) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($this->services->lookXcxCode((int)$uid));
+    }
+
+    /**
+     * 查看H5推广二维码
+     * @param string $uid
+     * @return mixed|string
+     */
+    public function look_h5_code($uid = '')
+    {
+        if (!strlen(trim($uid))) return app('json')->fail(100100);
+        return app('json')->success($this->services->lookH5Code((int)$uid));
+    }
+
+    /**
+     * 解除单个用户的推广权限
+     * @param $uid
+     * @return mixed
+     */
+    public function delete_spread($uid)
+    {
+        if (!$uid) app('json')->fail(100100);
+        return app('json')->success($this->services->delSpread((int)$uid) ? 100014 : 100015);
+    }
+
+    /**
+     * 修改上级推广人
+     * @param UserServices $services
+     * @return mixed
+     */
+    public function editSpread(UserServices $services)
+    {
+        [$uid, $spreadUid] = $this->request->postMore([
+            [['uid', 'd'], 0],
+            [['spread_uid', 'd'], 0],
+        ], true);
+        if (!$uid || !$spreadUid) {
+            return app('json')->fail(100100);
+        }
+        if ($uid == $spreadUid) {
+            return app('json')->fail(400213);
+        }
+        $userInfo = $services->get($uid);
+        if (!$userInfo) {
+            return app('json')->fail(400214);
+        }
+        if (!$services->count(['uid' => $spreadUid])) {
+            return app('json')->fail(400215);
+        }
+        if ($userInfo->spread_uid == $spreadUid) {
+            return app('json')->fail(400216);
+        }
+        $spreadInfo = $services->get($spreadUid);
+        if ($spreadInfo->spread_uid == $uid) {
+            return app('json')->fail(400217);
+        }
+        //之前的上级减少推广人数
+        if ($userInfo->spread_uid) {
+            $oldSpread = $services->get($userInfo->spread_uid);
+            $oldSpread->spread_count = $oldSpread->spread_count - 1;
+            $oldSpread->save();
+        }
+        $spreadInfo->spread_count = $spreadInfo->spread_count + 1;
+        $spreadInfo->save();
+        $userInfo->spread_uid = $spreadUid;
+        $userInfo->spread_time = time();
+        $userInfo->division_id = $spreadInfo->division_id;
+        $userInfo->agent_id = $spreadInfo->agent_id;
+        $userInfo->is_staff = $spreadInfo->is_staff;
+        $userInfo->save();
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 取消推广员推广资格
+     * @param $uid
+     * @return mixed
+     */
+    public function delete_system_spread($uid)
+    {
+        if (!$uid) app('json')->fail(100100);
+        return app('json')->success($this->services->delSystemSpread((int)$uid) ? 100019 : 100020);
+    }
+
+    /**
+     * 获取赠送分销等级表单
+     * @param AgentLevelServices $services
+     * @param $uid
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getLevelForm(AgentLevelServices $services, $uid)
+    {
+        if (!$uid) app('json')->fail(100100);
+        return app('json')->success($services->levelForm((int)$uid));
+    }
+
+    /**
+     * 赠送分销等级
+     * @param AgentLevelServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function giveAgentLevel(AgentLevelServices $services)
+    {
+        [$uid, $id] = $this->request->postMore([
+            [['uid', 'd'], 0],
+            [['id', 'd'], 0],
+        ], true);
+        if (!$uid || !$id) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($services->givelevel((int)$uid, (int)$id) ? 400218 : 400219);
+    }
+}

+ 239 - 0
app/adminapi/controller/v1/agent/Division.php

@@ -0,0 +1,239 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\agent;
+
+use app\adminapi\controller\AuthController;
+use app\services\agent\DivisionAgentApplyServices;
+use app\services\agent\DivisionServices;
+use app\services\other\AgreementServices;
+use app\services\user\UserServices;
+use crmeb\exceptions\AdminException;
+use think\facade\App;
+
+/**
+ * 事业部控制器
+ * Class Division
+ * @package app\adminapi\controller\v1\agent
+ */
+class Division extends AuthController
+{
+    /**
+     * Division constructor.
+     * @param App $app
+     * @param DivisionServices $services
+     */
+    public function __construct(App $app, DivisionServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 事业部列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function divisionList()
+    {
+        $where = $this->request->getMore([
+            ['division_type', 0],
+            ['keyword', '']
+        ]);
+        if ($where['division_type'] == 2) {
+            $where['division_id'] = $this->adminInfo['division_id'];
+        }
+        $data = $this->services->getDivisionList($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 下级列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function divisionDownList()
+    {
+        [$type, $uid] = $this->request->getMore([
+            ['division_type', 0],
+            ['uid', 0],
+        ], true);
+        $data = $this->services->divisionDownList($type, $uid);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 添加编辑事业部
+     * @param $uid
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function divisionCreate($uid)
+    {
+        return app('json')->success($this->services->getDivisionForm((int)$uid));
+    }
+
+    /**
+     * 保存事业部
+     * @return mixed
+     */
+    public function divisionSave()
+    {
+        $data = $this->request->postMore([
+            ['uid', 0],
+            ['aid', 0],
+            ['division_percent', 0],
+            ['division_end_time', ''],
+            ['division_status', 1],
+            ['account', ''],
+            ['pwd', ''],
+            ['conf_pwd', ''],
+            ['real_name', ''],
+            ['roles', []]
+        ]);
+        $this->services->divisionSave($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 添加编辑代理商
+     * @param $uid
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function divisionAgentCreate($uid)
+    {
+        return app('json')->success($this->services->getDivisionAgentForm((int)$uid));
+    }
+
+    /**
+     * 保存代理商
+     * @param UserServices $userServices
+     * @return mixed
+     */
+    public function divisionAgentSave(UserServices $userServices)
+    {
+        $data = $this->request->postMore([
+            ['uid', 0],
+            ['division_percent', 0],
+            ['division_end_time', ''],
+            ['division_status', 1],
+            ['edit', 0],
+        ]);
+        $userInfo = $userServices->get((int)$data['uid']);
+        if (!$userInfo) throw new AdminException(100100);
+        $data['division_id'] = $this->adminInfo['division_id'];
+        $this->services->divisionAgentSave($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 设置状态
+     * @param $status
+     * @param $uid
+     * @return mixed
+     */
+    public function setDivisionStatus($status, $uid)
+    {
+        $this->services->setDivisionStatus($status, $uid);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 删除成功
+     * @param $type
+     * @param $uid
+     * @return mixed
+     */
+    public function delDivision($type, $uid)
+    {
+        $this->services->delDivision($type, $uid);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 后台申请列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function AdminApplyList()
+    {
+        $where = $this->request->getMore([
+            ['uid', 0],
+            ['division_id', 0],
+            ['division_invite', ''],
+            ['status', ''],
+            ['keyword', ''],
+            ['time', ''],
+        ]);
+        $where['division_id'] = $this->adminInfo['division_id'];
+        /** @var DivisionAgentApplyServices $applyServices */
+        $applyServices = app()->make(DivisionAgentApplyServices::class);
+        $data = $applyServices->AdminApplyList($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 审核表单
+     * @param $id
+     * @param $type
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function examineApply($id, $type)
+    {
+        /** @var DivisionAgentApplyServices $applyServices */
+        $applyServices = app()->make(DivisionAgentApplyServices::class);
+        $data = $applyServices->examineApply($id, $type);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 代理商审核
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function applyAgentSave()
+    {
+        $data = $this->request->getMore([
+            ['type', 0],
+            ['id', 0],
+            ['division_percent', ''],
+            ['division_end_time', ''],
+            ['division_status', ''],
+            ['refusal_reason', 0]
+        ]);
+        /** @var DivisionAgentApplyServices $applyServices */
+        $applyServices = app()->make(DivisionAgentApplyServices::class);
+        $data = $applyServices->applyAgentSave($data);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 删除代理商审核
+     * @param $id
+     * @return mixed
+     */
+    public function delApply($id)
+    {
+        /** @var DivisionAgentApplyServices $applyServices */
+        $applyServices = app()->make(DivisionAgentApplyServices::class);
+        $applyServices->delApply($id);
+        return app('json')->success(100002);
+    }
+}

+ 201 - 0
app/adminapi/controller/v1/application/routine/RoutineTemplate.php

@@ -0,0 +1,201 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\application\routine;
+
+use app\jobs\notice\SyncMessageJob;
+use app\services\other\QrcodeServices;
+use app\services\message\TemplateMessageServices;
+use app\services\system\attachment\SystemAttachmentServices;
+use crmeb\exceptions\AdminException;
+use think\exception\ValidateException;
+use think\facade\App;
+use app\adminapi\controller\AuthController;
+use crmeb\services\FileService;
+use app\services\other\UploadService;
+use crmeb\services\app\MiniProgramService;
+
+/**
+ * Class RoutineTemplate
+ * @package app\adminapi\controller\v1\application\routine
+ */
+class RoutineTemplate extends AuthController
+{
+    protected $cacheTag = '_system_wechat';
+
+    /**
+     * 构造方法
+     * WechatTemplate constructor.
+     * @param App $app
+     * @param TemplateMessageServices $services
+     */
+    public function __construct(App $app, TemplateMessageServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 同步订阅消息
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function syncSubscribe()
+    {
+        if (!sys_config('routine_appId') || !sys_config('routine_appsecret')) {
+            throw new AdminException(400236);
+        }
+        $all = $this->services->getTemplateList(['status' => 1, 'type' => 0]);
+        $list = MiniProgramService::getSubscribeTemplateList();
+        foreach ($list->data as $v) {
+            MiniProgramService::delSubscribeTemplate($v['priTmplId']);
+        }
+        if ($all['list']) {
+            foreach ($all['list'] as $template) {
+                SyncMessageJob::dispatch('SyncSubscribe', [$template]);
+            }
+        }
+        return app('json')->success(100038);
+    }
+
+    /**
+     * 下载小程序
+     * @return mixed
+     */
+    public function downloadTemp()
+    {
+        [$name, $is_live] = $this->request->postMore([
+            ['name', ''],
+            ['is_live', 0]
+        ], true);
+        if (sys_config('routine_appId', '') == '') throw new AdminException(400236);
+        try {
+            @unlink(public_path() . 'statics/download/routine.zip');
+            //拷贝源文件
+            /** @var FileService $fileService */
+            $fileService = app(FileService::class);
+            $fileService->copyDir(public_path() . 'statics/mp_view', public_path() . 'statics/download');
+            //替换appid和名称
+            $this->updateConfigJson(sys_config('routine_appId'), $name != '' ? $name : sys_config('routine_name'));
+            //是否开启直播
+            if ($is_live == 0) $this->updateAppJson();
+            //替换url
+            $this->updateUrl('https://' . $_SERVER['HTTP_HOST']);
+            //压缩文件
+            $fileService->addZip(public_path() . 'statics/download', public_path() . 'statics/download/routine.zip', public_path() . 'statics/download');
+            $data['url'] = sys_config('site_url') . '/statics/download/routine.zip';
+            return app('json')->success($data);
+        } catch (\Throwable $e) {
+            throw new AdminException($e->getMessage());
+        }
+    }
+
+    /**
+     * 替换url
+     * @param $url
+     */
+    public function updateUrl($url)
+    {
+        $fileUrl = app()->getRootPath() . "public/statics/download/common/vendor.js";
+        $string = file_get_contents($fileUrl); //加载配置文件
+        $string = str_replace('https://demo.crmeb.com', $url, $string); // 正则查找然后替换
+        $newFileUrl = app()->getRootPath() . "public/statics/download/common/vendor.js";
+        @file_put_contents($newFileUrl, $string); // 写入配置文件
+
+    }
+
+    /**
+     * 判断是否开启直播(弃用)
+     * @param int $iszhibo
+     */
+    public function updateAppJson()
+    {
+        $fileUrl = app()->getRootPath() . "public/statics/download/app.json";
+        $string = file_get_contents($fileUrl); //加载配置文件
+        $pats = '/,
+      "plugins": \{
+        "live-player-plugin": \{
+          "version": "(.*?)",
+          "provider": "(.*?)"
+        }
+      }/';
+        $string = preg_replace($pats, '', $string); // 正则查找然后替换
+        $newFileUrl = app()->getRootPath() . "public/statics/download/app.json";
+        @file_put_contents($newFileUrl, $string); // 写入配置文件
+    }
+
+    /**
+     * 替换appid
+     * @param string $appid
+     * @param string $projectanme
+     */
+    public function updateConfigJson($appId = '', $projectName = '')
+    {
+        $fileUrl = app()->getRootPath() . "public/statics/download/project.config.json";
+        $string = file_get_contents($fileUrl); //加载配置文件
+        // 替换appid
+        $appIdOld = '/"appid"(.*?),/';
+        $appIdNew = '"appid"' . ': ' . '"' . $appId . '",';
+        $string = preg_replace($appIdOld, $appIdNew, $string); // 正则查找然后替换
+        // 替换小程序名称
+        $projectNameOld = '/"projectname"(.*?),/';
+        $projectNameNew = '"projectname"' . ': ' . '"' . $projectName . '",';
+        $string = preg_replace($projectNameOld, $projectNameNew, $string); // 正则查找然后替换
+        $newFileUrl = app()->getRootPath() . "public/statics/download/project.config.json";
+        @file_put_contents($newFileUrl, $string); // 写入配置文件
+    }
+
+    /**
+     * 获取小程序码
+     * @return string
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getDownloadInfo()
+    {
+        $data['routine_name'] = sys_config('routine_name', '');
+        if (sys_config('routine_appId') == '') {
+            $data['code'] = '';
+        } else {
+            $name = $data['routine_name'] . '.jpg';
+            /** @var SystemAttachmentServices $systemAttachmentModel */
+            $systemAttachmentModel = app()->make(SystemAttachmentServices::class);
+            $imageInfo = $systemAttachmentModel->getInfo(['name' => $name]);
+            if (!$imageInfo) {
+                /** @var QrcodeServices $qrcode */
+                $qrcode = app()->make(QrcodeServices::class);
+                $resForever = $qrcode->qrCodeForever(0, 'code');
+                if ($resForever) {
+                    $resCode = MiniProgramService::appCodeUnlimitService($resForever->id, '', 280);
+                    $res = ['res' => $resCode, 'id' => $resForever->id];
+                } else {
+                    $res = false;
+                }
+                if (!$res) throw new ValidateException(400237);
+                $upload = UploadService::init(1);
+                if ($upload->to('routine/code')->setAuthThumb(false)->stream((string)$res['res'], $name) === false) {
+                    return $upload->getError();
+                }
+                $imageInfo = $upload->getUploadInfo();
+                $imageInfo['image_type'] = 1;
+                $systemAttachmentModel->attachmentAdd($imageInfo['name'], $imageInfo['size'], $imageInfo['type'], $imageInfo['dir'], $imageInfo['thumb_path'], 1, $imageInfo['image_type'], $imageInfo['time'], 2);
+                $qrcode->update($res['id'], ['status' => 1, 'time' => time(), 'qrcode_url' => $imageInfo['dir']]);
+                $data['code'] = sys_config('site_url') . $imageInfo['dir'];
+            } else $data['code'] = sys_config('site_url') . $imageInfo['att_dir'];
+        }
+        $data['appId'] = sys_config('routine_appId');
+        $data['help'] = 'https://doc.crmeb.com/web/single/crmeb_v4/978';
+        return app('json')->success($data);
+    }
+}

+ 57 - 0
app/adminapi/controller/v1/application/wechat/Menus.php

@@ -0,0 +1,57 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\application\wechat;
+
+use app\adminapi\controller\AuthController;
+use app\services\wechat\WechatMenuServices;
+use think\facade\App;
+
+/**
+ * 微信菜单  控制器
+ * Class Menus
+ * @package app\admin\controller\wechat
+ */
+class Menus extends AuthController
+{
+    /**
+     * 构造方法
+     * Menus constructor.
+     * @param App $app
+     * @param WechatMenuServices $services
+     */
+    public function __construct(App $app, WechatMenuServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取菜单
+     * @return mixed
+     */
+    public function index()
+    {
+        $menus = $this->services->getWechatMenu();
+        return app('json')->success(compact('menus'));
+    }
+
+    /**
+     * 保存菜单
+     * @return mixed
+     */
+    public function save()
+    {
+        $buttons = request()->post('button/a', []);
+        if (!count($buttons)) return app('json')->fail(400238);
+        $this->services->saveMenu($buttons);
+        return app('json')->success(100001);
+    }
+}

+ 171 - 0
app/adminapi/controller/v1/application/wechat/Reply.php

@@ -0,0 +1,171 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\application\wechat;
+
+use app\services\other\QrcodeServices;
+use EasyWeChat\Core\Exceptions\HttpException;
+use app\adminapi\controller\AuthController;
+use app\services\wechat\WechatReplyServices;
+use app\services\wechat\WechatKeyServices;
+use think\facade\App;
+
+/**
+ * 关键字管理  控制器
+ * Class Reply
+ * @package app\admin\controller\wechat
+ */
+class Reply extends AuthController
+{
+    /**
+     * 构造方法
+     * Menus constructor.
+     * @param App $app
+     * @param WechatReplyServices $services
+     */
+    public function __construct(App $app, WechatReplyServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 关注回复
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function reply()
+    {
+        $where = $this->request->getMore([
+            ['key', ''],
+        ]);
+        if ($where['key'] == '') return app('json')->fail(100100);
+        $info = $this->services->getDataByKey($where['key']);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 关键字回复列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['key', ''],
+            ['type', ''],
+        ]);
+        $list = $this->services->getKeyAll($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 关键字详情
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function read($id)
+    {
+        $info = $this->services->getKeyInfo($id);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 保存关键字
+     * @param int $id
+     * @return mixed
+     */
+    public function save($id = 0)
+    {
+        $data = $this->request->postMore([
+            'key',
+            'type',
+            ['status', 0],
+            ['data', []],
+        ]);
+        try {
+            if (!isset($data['key']) && empty($data['key']))
+                return app('json')->fail(400239);
+            if (!isset($data['type']) && empty($data['type']))
+                return app('json')->fail(400240);
+            if (!in_array($data['type'], $this->services->replyType()))
+                return app('json')->fail(400241);
+
+            if (!isset($data['data']) || !is_array($data['data']))
+                return app('json')->fail(400242);
+            $res = $this->services->redact($data['data'], $id, $data['key'], $data['type'], $data['status']);
+            if (!$res)
+                return app('json')->fail(100006);
+            else
+                return app('json')->success(100000, $data);
+        } catch (HttpException $e) {
+            return app('json')->fail($e->getMessage());
+        }
+    }
+
+    /**
+     * 删除关键字
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if (!$this->services->delete($id)) {
+            return app('json')->fail(100008);
+        } else {
+            /** @var WechatKeyServices $keyServices */
+            $keyServices = app()->make(WechatKeyServices::class);
+            $res = $keyServices->delete($id, 'reply_id');
+            if (!$res) {
+                return app('json')->fail(100008);
+            }
+        }
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        if ($status == '' || $id == 0) return app('json')->fail(100100);
+        $this->services->update($id, ['status' => $status], 'id');
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 生成关注回复二维码
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function code_reply($id)
+    {
+        if (!$id) {
+            return app('json')->fail('100100');
+        }
+        /** @var QrcodeServices $qrcode */
+        $qrcode = app()->make(QrcodeServices::class);
+        $code = $qrcode->getForeverQrcode('reply', $id);
+        if (!$code['ticket']) {
+            return app('json')->fail(400237);
+        }
+        return app('json')->success($code->toArray());
+    }
+
+}

+ 203 - 0
app/adminapi/controller/v1/application/wechat/WechatNewsCategory.php

@@ -0,0 +1,203 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\application\wechat;
+
+use app\adminapi\controller\AuthController;
+use crmeb\services\app\WechatService;
+use think\facade\App;
+use app\services\wechat\WechatNewsCategoryServices;
+use app\services\article\ArticleServices;
+use think\facade\Log;
+
+/**
+ * 图文信息
+ * Class WechatNewsCategory
+ * @package app\admin\controller\wechat
+ *
+ */
+class WechatNewsCategory extends AuthController
+{
+    /**
+     * 构造方法
+     * Menus constructor.
+     * @param App $app
+     * @param WechatNewsCategoryServices $services
+     */
+    public function __construct(App $app, WechatNewsCategoryServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 图文消息列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['page', 1],
+            ['limit', 20],
+            ['cate_name', '']
+        ]);
+        $list = $this->services->getAll($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 图文详情
+     * @param $id
+     * @return mixed
+     */
+    public function read($id)
+    {
+        $info = $this->services->get($id);
+        /** @var ArticleServices $services */
+        $services = app()->make(ArticleServices::class);
+        $new = $services->articlesList($info['new_id']);
+        if ($new) $new = $new->toArray();
+        $info['new'] = $new;
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 删除图文
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if (!$this->services->delete($id))
+            return app('json')->fail(100008);
+        else
+            return app('json')->success(100002);
+    }
+
+    /**
+     * 新增或编辑保存
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['list', []],
+            ['id', 0]
+        ]);
+        try {
+            $id = [];
+            $countList = count($data['list']);
+            if (!$countList) return app('json')->fail(400243);
+            /** @var ArticleServices $services */
+            $services = app()->make(ArticleServices::class);
+            foreach ($data['list'] as $k => $v) {
+                if ($v['title'] == '') return app('json')->fail(400244);
+                if ($v['author'] == '') return app('json')->fail(400245);
+                if ($v['content'] == '') return app('json')->fail(400246);
+                if ($v['synopsis'] == '') return app('json')->fail(400247);
+                $v['status'] = 1;
+                $v['add_time'] = time();
+                if ($v['id']) {
+                    $idC = $v['id'];
+                    $services->save($v);
+                    unset($v['id']);
+                    $data['list'][$k]['id'] = $idC;
+                    $id[] = $idC;
+                } else {
+                    $res = $services->save($v);
+                    unset($v['id']);
+                    $id[] = $res['id'];
+                    $data['list'][$k]['id'] = $res['id'];
+                }
+            }
+            $countId = count($id);
+            if ($countId != $countList) {
+                if ($data['id']) return app('json')->fail(100007);
+                else return app('json')->fail(100022);
+            } else {
+                $newsCategory['cate_name'] = $data['list'][0]['title'];
+                $newsCategory['new_id'] = implode(',', $id);
+                $newsCategory['sort'] = 0;
+                $newsCategory['add_time'] = time();
+                $newsCategory['status'] = 1;
+                if ($data['id']) {
+                    $this->services->update($data['id'], $newsCategory, 'id');
+                    return app('json')->success(100001);
+                } else {
+                    $this->services->save($newsCategory);
+                    return app('json')->success(100021);
+                }
+            }
+        } catch (\Exception $e) {
+            return app('json')->fail(100101);
+        }
+    }
+
+    /**
+     * 发送消息
+     */
+    public function push()
+    {
+        $data = $this->request->postMore([
+            ['id', 0],
+            ['user_ids', '']
+        ]);
+        if (!$data['id']) return app('json')->fail(100100);
+        $list = $this->services->getWechatNewsItem($data['id']);
+        $wechatNews = [];
+        if ($list) {
+            if (is_array($list['new']) && count($list['new'])) {
+                $wechatNews['title'] = $list['new'][0]['title'];
+                $wechatNews['image_input'] = $list['new'][0]['image_input'];
+                $wechatNews['date'] = date('m月d日', time());
+                $wechatNews['description'] = $list['new'][0]['synopsis'];
+                $wechatNews['id'] = $list['new'][0]['id'];
+            }
+        }
+        if ($data['user_ids'] != '') {//客服消息
+            $wechatNews = $this->services->wechatPush($wechatNews);
+            $message = WechatService::newsMessage($wechatNews);
+            $errorLog = [];//发送失败的用户
+            $user = $this->services->getWechatUser($data['user_ids'], 'nickname,subscribe,openid', 'uid');
+            if ($user) {
+                foreach ($user as $v) {
+                    if ($v['subscribe'] && $v['openid']) {
+                        try {
+                            WechatService::staffService()->message($message)->to($v['openid'])->send();
+                        } catch (\Exception $e) {
+                            Log::error($v['nickname'] . '发送失败,原因' . $e->getMessage());
+                            $errorLog[] = $v['nickname'] . '发送失败';
+                        }
+                    } else {
+                        $errorLog[] = $v['nickname'] . '没有关注发送失败(不是微信公众号用户)';
+                    }
+                }
+            } else return app('json')->fail(100031);
+            if (!count($errorLog)) return app('json')->success(100030);
+            else return app('json')->success(100030);
+        }
+
+    }
+
+    /**
+     * 发送消息图文列表
+     * @return mixed
+     */
+    public function send_news()
+    {
+        $where = $this->request->getMore([
+            ['cate_name', ''],
+            ['page', 1],
+            ['limit', 10]
+        ]);
+        return app('json')->success($this->services->list($where));
+    }
+
+}

+ 188 - 0
app/adminapi/controller/v1/application/wechat/WechatQrcode.php

@@ -0,0 +1,188 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\application\wechat;
+
+use app\adminapi\controller\AuthController;
+use app\services\wechat\WechatQrcodeCateServices;
+use app\services\wechat\WechatQrcodeRecordServices;
+use app\services\wechat\WechatQrcodeServices;
+use think\facade\App;
+
+class WechatQrcode extends AuthController
+{
+    protected $qrcodeCateServices;
+    protected $wechatQrcodeServices;
+    protected $qrcodeRecordServices;
+
+    /**
+     * WechatQrcode constructor.
+     * @param App $app
+     * @param WechatQrcodeCateServices $services
+     */
+    public function __construct(App $app, WechatQrcodeCateServices $qrcodeCateServices, WechatQrcodeServices $wechatQrcodeServices, WechatQrcodeRecordServices $qrcodeRecordServices)
+    {
+        parent::__construct($app);
+        $this->qrcodeCateServices = $qrcodeCateServices;
+        $this->wechatQrcodeServices = $wechatQrcodeServices;
+        $this->qrcodeRecordServices = $qrcodeRecordServices;
+    }
+
+    /**
+     * 分类列表
+     * @return mixed
+     */
+    public function getCateList()
+    {
+        $data = $this->qrcodeCateServices->getCateList();
+        $count = $this->qrcodeCateServices->count(['is_del' => 0]);
+        return app('json')->success(compact('data', 'count'));
+    }
+
+    /**
+     * 添加编辑表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function createForm($id)
+    {
+        return app('json')->success($this->qrcodeCateServices->createForm($id));
+    }
+
+    /**
+     * 保存数据
+     * @return mixed
+     */
+    public function saveCate()
+    {
+        $data = $this->request->postMore([
+            ['id', 0],
+            ['cate_name', '']
+        ]);
+        $this->qrcodeCateServices->saveData($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 删除分类
+     * @param $id
+     * @return mixed
+     */
+    public function delCate($id)
+    {
+        $this->qrcodeCateServices->delCate($id);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 保存渠道码
+     * @param $id
+     * @return mixed
+     */
+    public function saveQrcode($id = 0)
+    {
+        $data = $this->request->postMore([
+            ['uid', 0],
+            ['name', ''],
+            ['image', ''],
+            ['cate_id', 0],
+            ['label_id', []],
+            ['type', 0],
+            ['content', ''],
+            ['time', 0],
+        ]);
+        $this->wechatQrcodeServices->saveQrcode($id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 获取渠道码列表
+     * @return mixed
+     */
+    public function qrcodeList()
+    {
+        $where = $this->request->getMore([
+            ['name', ''],
+            ['cate_id', 0]
+        ]);
+        $where['is_del'] = 0;
+        $data = $this->wechatQrcodeServices->qrcodeList($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 获取详情
+     * @param int $id
+     * @return mixed
+     */
+    public function qrcodeInfo($id = 0)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $info = $this->wechatQrcodeServices->qrcodeInfo($id);
+        return app('json')->success($info);
+    }
+
+    /**
+     * 删除渠道码
+     * @param int $id
+     * @return mixed
+     */
+    public function delQrcode($id = 0)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->wechatQrcodeServices->update($id, ['is_del' => 1]);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 切换状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function setStatus($id, $status)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->wechatQrcodeServices->update($id, ['status' => $status]);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 用户列表
+     * @param $qid
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function userList($qid)
+    {
+        return app('json')->success($this->qrcodeRecordServices->userList($qid));
+    }
+
+
+    /**
+     * 渠道码统计
+     * @param $qid
+     * @return mixed
+     */
+    public function qrcodeStatistic($qid)
+    {
+        [$time] = $this->request->getMore([
+            ['time', ''],
+        ], true);
+        $where['qid'] = $qid;
+        return app('json')->success($this->qrcodeRecordServices->qrcodeStatistic($where, $time));
+    }
+}

+ 61 - 0
app/adminapi/controller/v1/application/wechat/WechatTemplate.php

@@ -0,0 +1,61 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\application\wechat;
+
+use app\adminapi\controller\AuthController;
+use app\jobs\notice\SyncMessageJob;
+use crmeb\exceptions\AdminException;
+use app\services\message\TemplateMessageServices;
+use crmeb\services\app\WechatService;
+use think\facade\App;
+
+/**
+ * 微信模板消息
+ * Class WechatTemplate
+ * @package app\adminapi\controller\v1\application\wechat
+ */
+class WechatTemplate extends AuthController
+{
+    /**
+     * 构造方法
+     * WechatTemplate constructor.
+     * @param App $app
+     * @param TemplateMessageServices $services
+     */
+    public function __construct(App $app, TemplateMessageServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 同步微信模版消息
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function syncSubscribe()
+    {
+        if (!sys_config('wechat_appid') || !sys_config('wechat_appsecret')) {
+            throw new AdminException(400248);
+        }
+        $all = $this->services->getTemplateList(['status' => 1, 'type' => 1]);
+        $list = WechatService::getPrivateTemplates();
+        foreach ($list->template_list as $v) {
+            WechatService::deleleTemplate($v['template_id']);
+        }
+        foreach ($all['list'] as $template) {
+            SyncMessageJob::dispatch('SyncWechat', [$template]);
+        }
+        return app('json')->success(100038);
+    }
+}

+ 138 - 0
app/adminapi/controller/v1/cms/Article.php

@@ -0,0 +1,138 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\cms;
+
+use app\adminapi\controller\AuthController;
+use app\services\article\ArticleServices;
+use think\facade\App;
+
+/**
+ * 文章管理
+ * Class Article
+ * @package app\adminapi\controller\v1\cms
+ */
+class Article extends AuthController
+{
+    /**
+     * @var ArticleServices
+     */
+    protected $service;
+
+    /**
+     * Article constructor.
+     * @param App $app
+     * @param ArticleServices $service
+     */
+    public function __construct(App $app, ArticleServices $service)
+    {
+        parent::__construct($app);
+        $this->service = $service;
+    }
+
+    /**
+     * 获取列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['title', ''],
+            ['pid', 0, '', 'cid'],
+        ]);
+        $data = $this->service->getList($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 保存文章数据
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['id', 0],
+            ['cid', ''],
+            ['title', ''],
+            ['author', ''],
+            ['image_input', ''],
+            ['content', ''],
+            ['synopsis', 0],
+            ['share_title', ''],
+            ['share_synopsis', ''],
+            ['sort', 0],
+            ['url', ''],
+            ['is_banner', 0],
+            ['is_hot', 0],
+            ['status', 1]
+        ]);
+        $this->service->save($data);
+        return app('json')->success(100021);
+    }
+
+    /**
+     * 获取单个文章数据
+     * @param int $id
+     * @return mixed
+     */
+    public function read($id = 0)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $info = $this->service->read($id);
+        return app('json')->success($info);
+    }
+
+    /**
+     * 删除文章
+     * @param int $id
+     * @return mixed
+     */
+    public function delete($id = 0)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->service->del($id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 文章关联商品
+     * @param int $id
+     * @return mixed
+     */
+    public function relation($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        list($product_id) = $this->request->postMore([
+            ['product_id', 0]
+        ], true);
+        $res = $this->service->bindProduct($id, $product_id);
+        if ($res) {
+            return app('json')->success(400300);
+        } else {
+            return app('json')->fail(400301);
+        }
+    }
+
+    /**
+     * 取消商品关联
+     * @param int $id
+     * @return mixed
+     */
+    public function unrelation($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $res = $this->service->bindProduct($id);
+        if ($res) {
+            return app('json')->success(100019);
+        } else {
+            return app('json')->fail(100020);
+        }
+    }
+}

+ 178 - 0
app/adminapi/controller/v1/cms/ArticleCategory.php

@@ -0,0 +1,178 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\cms;
+
+use app\adminapi\controller\AuthController;
+use app\services\article\ArticleCategoryServices;
+use crmeb\services\CacheService;
+use think\facade\App;
+
+/**
+ * 文章分类管理
+ * Class ArticleCategory
+ * @package app\adminapi\controller\v1\cms
+ */
+class ArticleCategory extends AuthController
+{
+    /**
+     * @var ArticleCategoryServices
+     */
+    protected $service;
+
+    /**
+     * ArticleCategory constructor.
+     * @param App $app
+     * @param ArticleCategoryServices $service
+     */
+    public function __construct(App $app, ArticleCategoryServices $service)
+    {
+        parent::__construct($app);
+        $this->service = $service;
+    }
+
+    /**
+     * 获取分类列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['title', ''],
+            ['type', 0]
+        ]);
+        $type = $where['type'];
+        unset($where['type']);
+        $data = $this->service->getList($where);
+        if ($type == 1) $data = $data['list'];
+        return app('json')->success($data);
+    }
+
+    /**
+     * 创建新增表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create()
+    {
+        return app('json')->success($this->service->createForm(0));
+    }
+
+    /**
+     * 保存新建分类
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['title', ''],
+            ['pid', 0],
+            ['intr', ''],
+            ['image', ''],
+            ['sort', 0],
+            ['status', 0]
+        ]);
+        if (!$data['title']) {
+            return app('json')->fail(400100);
+        }
+        $data['add_time'] = time();
+        $this->service->save($data);
+        CacheService::delete('ARTICLE_CATEGORY');
+        return app('json')->success(100021);
+    }
+
+    /**
+     * 创建修改表单
+     * @param int $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id = 0)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($this->service->createForm($id));
+    }
+
+    /**
+     * 保存修改分类
+     * @param $id
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['id', 0],
+            ['title', ''],
+            ['pid', 0],
+            ['intr', ''],
+            ['image', ''],
+            ['sort', 0],
+            ['status', 0]
+        ]);
+        $this->service->update($data);
+        CacheService::delete('ARTICLE_CATEGORY');
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除文章分类
+     * @param $id
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->service->del($id);
+        CacheService::delete('ARTICLE_CATEGORY');
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 修改文章分类状态
+     * @param int $id
+     * @param int $status
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function set_status($id, $status)
+    {
+        if ($status == '' || $id == 0) return app('json')->fail(100100);
+        $this->service->setStatus($id, $status);
+        CacheService::delete('ARTICLE_CATEGORY');
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 获取文章分类
+     * @return mixed
+     */
+    public function categoryList()
+    {
+        return app('json')->success($this->service->getArticleTwoCategory());
+    }
+
+    /**
+     * 树形列表
+     * @return mixed
+     * @throws \ReflectionException
+     */
+    public function getTreeList()
+    {
+        $list = $this->service->getTreeList();
+        foreach ($list as &$item) {
+            $item['disabled'] = !$item['status'] || $item['is_del'];
+        }
+        return app('json')->success($list);
+    }
+}

+ 646 - 0
app/adminapi/controller/v1/diy/Diy.php

@@ -0,0 +1,646 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\diy;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\bargain\StoreBargainServices;
+use app\services\activity\combination\StoreCombinationServices;
+use app\services\activity\seckill\StoreSeckillServices;
+use app\services\article\ArticleServices;
+use app\services\diy\DiyServices;
+use app\services\other\CacheServices;
+use app\services\product\product\StoreCategoryServices;
+use app\services\product\product\StoreProductServices;
+use crmeb\exceptions\AdminException;
+use think\facade\App;
+
+/**
+ *
+ * Class Diy
+ * @package app\controller\admin\v1\diy
+ */
+class Diy extends AuthController
+{
+    /**
+     * @param App $app
+     * @param DiyServices $services
+     */
+    public function __construct(App $app, DiyServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * DIY列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getList()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['type', 0],
+            ['name', ''],
+            ['version', ''],
+        ]);
+        $where['type'] = -1;
+        $data = $this->services->getDiyList($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 保存可视化编辑资源
+     * @param int $id
+     * @return mixed
+     */
+    public function saveData(int $id = 0)
+    {
+        $data = $this->request->postMore([
+            ['value', ''],
+        ]);
+        $value_config = ['seckill', 'bargain', 'combination', 'goodList'];
+        $value = is_string($data['value']) ? json_decode($data['value'], true) : $data['value'];
+        foreach ($value as $key => &$val) {
+            if (in_array($key, $value_config) && is_array($val)) {
+                foreach ($val as $k => &$v) {
+                    if (isset($v['selectConfig']['list']) && $v['selectConfig']['list']) {
+                        $v['selectConfig']['list'] = [];
+                    }
+                    if (isset($v['goodsList']['list']) && $v['goodsList']['list'] && $v['tabConfig']['tabVal'] == 1) {
+                        $limitMax = config('database.page.limitMax', 50);
+                        if (count($v['goodsList']['list']) > $limitMax) {
+                            return app('json')->fail(400350);
+                        }
+                        $v['ids'] = array_column($v['goodsList']['list'], 'id');
+                        $v['goodsList']['list'] = [];
+                    }
+                }
+            }
+        }
+        $data['value'] = json_encode($value);
+        $data['version'] = uniqid();
+        $this->services->saveData($id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 保存Diy资源
+     * @param int $id
+     * @return mixed
+     */
+    public function saveDiyData(int $id = 0)
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['title', ''],
+            ['value', ''],
+            ['type', ''],
+            ['cover_image', ''],
+            ['is_show', 0],
+            ['is_bg_color', 0],
+            ['is_bg_pic', 0],
+            ['bg_tab_val', 0],
+            ['color_picker', ''],
+            ['bg_pic', ''],
+        ]);
+        $value = is_string($data['value']) ? json_decode($data['value'], true) : $data['value'];
+        $infoDiy = $id ? $this->services->get($id, ['is_diy']) : [];
+        if ($infoDiy && $infoDiy['is_diy']) {
+            foreach ($value as $key => &$item) {
+                if ($item['name'] === 'goodList') {
+                    if (isset($item['selectConfig']['list'])) {
+                        unset($item['selectConfig']['list']);
+                    }
+                    if (isset($item['goodsList']['list']) && is_array($item['goodsList']['list'])) {
+                        $limitMax = config('database.page.limitMax', 50);
+                        if (isset($item['numConfig']['val']) && isset($item['tabConfig']['tabVal']) && $item['tabConfig']['tabVal'] == 0 && $item['numConfig']['val'] > $limitMax) {
+                            return app('json')->fail(400350);
+                        }
+                        $item['goodsList']['ids'] = array_column($item['goodsList']['list'], 'id');
+                        unset($item['goodsList']['list']);
+                    }
+                } elseif ($item['name'] === 'articleList') {
+                    if (isset($item['selectList']['list']) && is_array($item['selectList']['list'])) {
+                        unset($item['selectList']['list']);
+                    }
+                } elseif ($item['name'] === 'promotionList') {
+                    unset($item['productList']['list']);
+                }
+            }
+            $data['value'] = json_encode($value);
+        } else {
+            if (isset($value['d_goodList']['selectConfig']['list'])) {
+                unset($value['d_goodList']['selectConfig']['list']);
+            } elseif (isset($value['d_goodList']['goodsList']['list'])) {
+                $limitMax = config('database.page.limitMax', 50);
+                if (isset($value['d_goodList']['numConfig']['val']) && isset($value['d_goodList']['tabConfig']['tabVal']) && $value['d_goodList']['tabConfig']['tabVal'] == 0 && $value['d_goodList']['numConfig']['val'] > $limitMax) {
+                    return app('json')->fail(400350);
+                }
+                $value['d_goodList']['goodsList']['ids'] = array_column($value['d_goodList']['goodsList']['list'], 'id');
+                unset($value['d_goodList']['goodsList']['list']);
+            } elseif (isset($value['k_newProduct']['goodsList']['list'])) {
+                $list = [];
+                foreach ($value['k_newProduct']['goodsList']['list'] as $item) {
+                    $list[] = [
+                        'image' => $item['image'],
+                        'store_info' => $item['store_info'],
+                        'store_name' => $item['store_name'],
+                        'id' => $item['id'],
+                        'price' => $item['price'],
+                        'ot_price' => $item['ot_price'],
+                    ];
+                }
+                $value['k_newProduct']['goodsList']['list'] = $list;
+            } elseif (isset($value['selectList']['list']) && is_array($value['selectList']['list'])) {
+                unset($value['goodsList']['list']);
+            }
+            $data['value'] = json_encode($value);
+        }
+        $data['version'] = '1.0';
+        $data['type'] = 2;
+        $data['is_diy'] = 1;
+        $data['version'] = uniqid();
+        return app('json')->success($id ? 100001 : 100000, ['id' => $this->services->saveData($id, $data)]);
+    }
+
+    /**
+     * 删除模板
+     * @param $id
+     * @return mixed
+     */
+    public function del($id)
+    {
+        $this->services->del($id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 使用模板
+     * @param $id
+     * @return mixed
+     */
+    public function setStatus($id)
+    {
+        $this->services->setStatus($id);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 获取一条数据
+     * @param int $id
+     * @param StoreProductServices $services
+     * @param StoreSeckillServices $seckillServices
+     * @param StoreCombinationServices $combinationServices
+     * @param StoreBargainServices $bargainServices
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getInfo(int $id, StoreProductServices $services, StoreSeckillServices $seckillServices, StoreCombinationServices $combinationServices, StoreBargainServices $bargainServices)
+    {
+        if (!$id) throw new AdminException(100100);
+        $info = $this->services->get($id);
+        if ($info) {
+            $info = $info->toArray();
+        } else {
+            throw new AdminException(400351);
+        }
+        if (!$info['value']) return app('json')->success(compact('info'));
+        $info['value'] = json_decode($info['value'], true);
+        $value_config = ['seckill', 'bargain', 'combination', 'goodList'];
+        foreach ($info['value'] as $key => &$val) {
+            if (in_array($key, $value_config) && is_array($val)) {
+                if ($key == 'goodList') {
+                    foreach ($val as $k => &$v) {
+                        if (isset($v['ids']) && $v['ids'] && $v['tabConfig']['tabVal'] == 1) {
+                            $v['goodsList']['list'] = $services->getSearchList(['ids' => $v['ids']]);
+                        }
+                    }
+                }
+                if ($key == "seckill") {
+                    foreach ($val as $k => &$v) {
+                        if (isset($v['ids']) && $v['ids'] && $v['tabConfig']['tabVal'] == 1) {
+                            $v['goodsList']['list'] = $seckillServices->getDiySeckillList(['ids' => $v['ids']])['list'];
+                        }
+                    }
+                }
+                if ($key == "bargain") {
+                    foreach ($val as $k => &$v) {
+                        if (isset($v['ids']) && $v['ids'] && $v['tabConfig']['tabVal'] == 1) {
+                            $v['goodsList']['list'] = $bargainServices->getHomeList(['ids' => $v['ids']])['list'];
+                        }
+                    }
+                }
+                if ($key == "combination") {
+                    foreach ($val as $k => &$v) {
+                        if (isset($v['ids']) && $v['ids'] && $v['tabConfig']['tabVal'] == 1) {
+                            $v['goodsList']['list'] = $combinationServices->getHomeList(['ids' => $v['ids']])['list'];
+                        }
+                    }
+                }
+
+            }
+        }
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 获取diy数据
+     * @param $id
+     * @param StoreProductServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getDiyInfo($id, StoreProductServices $services)
+    {
+        if (!$id) throw new AdminException(100100);
+        $info = $this->services->get($id);
+        if ($info) {
+            $info = $info->toArray();
+        } else {
+            throw new AdminException(400351);
+        }
+        $info['value'] = json_decode($info['value'], true);
+        if ($info['value']) {
+            /** @var ArticleServices $articleServices */
+            $articleServices = app()->make(ArticleServices::class);
+            if ($info['is_diy']) {
+                foreach ($info['value'] as &$item) {
+                    if ($item['name'] === 'goodList') {
+                        if (isset($item['goodsList']['ids']) && count($item['goodsList']['ids'])) {
+                            $item['goodsList']['list'] = $services->getSearchList(['ids' => $item['goodsList']['ids']]);
+                        } else {
+                            $item['goodsList']['list'] = [];
+                        }
+                    } elseif ($item['name'] === 'articleList') {//文章
+                        $data = [];
+                        if ($item['selectConfig']['activeValue'] ?? 0) {
+                            $data = $articleServices->getList(['cid' => $item['selectConfig']['activeValue'] ?? 0], 0, $item['numConfig']['val'] ?? 0);
+                        }
+                        $item['selectList']['list'] = $data['list'] ?? [];
+                    } elseif ($item['name'] === 'promotionList') {//活动模仿
+                        $data = [];
+                        if (isset($item['tabConfig']['tabCur']) && $typeArr = $item['tabConfig']['list'][$item['tabConfig']['tabCur']] ?? []) {
+                            $val = $typeArr['link']['activeVal'] ?? 0;
+                            if ($val) {
+                                $data = $this->get_groom_list($val, (int)($item['numConfig']['val'] ?? 0));
+                            }
+                        }
+                        $item['productList']['list'] = $data;
+                    }
+                }
+            } else {
+                if (isset($info['value']['d_goodList']['goodsList'])) {
+                    $info['value']['d_goodList']['goodsList']['list'] = [];
+                }
+                if (isset($info['value']['d_goodList']['goodsList']['ids']) && count($info['value']['d_goodList']['goodsList']['ids'])) {
+                    $info['value']['d_goodList']['goodsList']['list'] = $services->getSearchList(['ids' => $info['value']['d_goodList']['goodsList']['ids']]);
+                }
+            }
+        }
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 获取推荐商品
+     * @param $type
+     * @param int $num
+     * @return array|array[]
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    protected function get_groom_list($type, int $num = 0)
+    {
+        /** @var StoreProductServices $services */
+        $services = app()->make(StoreProductServices::class);
+        $info = [];
+        if ($type == 1) {// 精品推荐
+            $info = $services->getRecommendProduct(0, 'is_best', $num);// 精品推荐个数
+        } else if ($type == 2) {//  热门榜单
+            $info = $services->getRecommendProduct(0, 'is_hot', $num);// 热门榜单 猜你喜欢
+        } else if ($type == 3) {// 首发新品
+            $info = $services->getRecommendProduct(0, 'is_new', $num);// 首发新品
+        } else if ($type == 4) {// 促销单品
+            $info = $services->getRecommendProduct(0, 'is_benefit', $num);// 促销单品
+        } else if ($type == 5) {// 会员商品
+            $whereVip = [
+                ['vip_price', '>', 0],
+                ['is_vip', '=', 1],
+            ];
+            $info = $services->getRecommendProduct(0, $whereVip, $num);// 会员商品
+        }
+        return $info;
+    }
+
+    /**
+     * 获取uni-app路径
+     * @return mixed
+     */
+    public function getUrl()
+    {
+        $url = sys_data('uni_app_link');
+        if ($url) {
+            foreach ($url as &$link) {
+                $link['url'] = $link['link'];
+                $link['parameter'] = trim($link['param']);
+            }
+        } else {
+            /** @var CacheServices $cache */
+            $cache = app()->make(CacheServices::class);
+            $url = $cache->getDbCache('uni_app_url', null);
+        }
+        return app('json')->success(compact('url'));
+    }
+
+    /**
+     * 获取商品分类
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getCategory()
+    {
+        /** @var StoreCategoryServices $categoryService */
+        $categoryService = app()->make(StoreCategoryServices::class);
+        $list = $categoryService->cascaderList(1, 1);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 获取商品
+     * @return mixed
+     */
+    public function getProduct()
+    {
+        $where = $this->request->getMore([
+            ['id', 0],
+            ['salesOrder', ''],
+            ['priceOrder', ''],
+        ]);
+        $id = $where['id'];
+        unset($where['id']);
+        $where['is_show'] = 1;
+        /** @var StoreCategoryServices $storeCategoryServices */
+        $storeCategoryServices = app()->make(StoreCategoryServices::class);
+        if ($storeCategoryServices->value(['id' => $id], 'pid')) {
+            $where['sid'] = $id;
+        } else {
+            $where['cid'] = $id;
+        }
+        [$page, $limit] = $this->services->getPageValue();
+        /** @var StoreProductServices $productService */
+        $productService = app()->make(StoreProductServices::class);
+        $list = $productService->getSearchList($where, $page, $limit);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 获取提货点自提开启状态
+     * @return mixed
+     */
+    public function getStoreStatus()
+    {
+        $data['store_status'] = sys_config('store_self_mention', 0);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 还原模板数据
+     * @param $id
+     * @return mixed
+     */
+    public function Recovery($id)
+    {
+        if (!$id) throw new AdminException(100100);
+        $info = $this->services->get($id);
+        if ($info) {
+            $info->value = $info->default_value;
+            $info->update_time = time();
+            $info->save();
+            return app('json')->success(100014);
+        } else {
+            throw new AdminException(400351);
+        }
+    }
+
+    /**
+     * 获取二级分类
+     * @return mixed
+     */
+    public function getByCategory()
+    {
+        $where = $this->request->getMore([
+            ['pid', -1],
+            ['name', '']
+        ]);
+        /** @var StoreCategoryServices $categoryServices */
+        $categoryServices = app()->make(StoreCategoryServices::class);
+        return app('json')->success($categoryServices->getALlByIndex($where));
+    }
+
+    /**
+     * 添加页面
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->createForm());
+    }
+
+    /**
+     * 保存页面
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+        ]);
+        if (!$data['name']) app('json')->fail(400352);
+        $data['version'] = '1.0';
+        $data['add_time'] = time();
+        $data['type'] = 0;
+        $data['is_diy'] = 1;
+        $this->services->save($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 设置默认数据
+     * @param $id
+     * @return mixed
+     */
+    public function setRecovery($id)
+    {
+        if (!$id) throw new AdminException(100100);
+        $info = $this->services->get($id);
+        if ($info) {
+            $info->default_value = $info->value;
+            $info->update_time = time();
+            $info->save();
+            return app('json')->success(100014);
+        } else {
+            throw new AdminException(100026);
+        }
+    }
+
+    /**
+     * 获取商品列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getProductList()
+    {
+        $where = $this->request->getMore([
+            ['cate_id', ''],
+            ['store_name', ''],
+            ['type', 0],
+        ]);
+        $where['is_show'] = 1;
+        $where['is_del'] = 0;
+        /** @var StoreCategoryServices $storeCategoryServices */
+        $storeCategoryServices = app()->make(StoreCategoryServices::class);
+        if ($where['cate_id'] !== '') {
+            if ($storeCategoryServices->value(['id' => $where['cate_id']], 'pid')) {
+                $where['sid'] = $where['cate_id'];
+            } else {
+                $where['cid'] = $where['cate_id'];
+            }
+        }
+        unset($where['cate_id']);
+        $list = $this->services->ProductList($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 分类、个人中心、一键换色
+     * @param $type
+     * @return mixed
+     */
+    public function getColorChange($type)
+    {
+        $status = (int)$this->services->getColorChange((string)$type);
+        return app('json')->success(compact('status'));
+    }
+
+    /**
+     * 保存分类、个人中心、一键换色
+     * @param $status
+     * @param $type
+     * @return mixed
+     */
+    public function colorChange($status, $type)
+    {
+        if (!$status) throw new AdminException(100100);
+        $info = $this->services->get(['template_name' => $type, 'type' => 1]);
+        if ($info) {
+            $info->value = $status;
+            $info->update_time = time();
+            $info->save();
+            return app('json')->success(100014);
+        } else {
+            throw new AdminException(100026);
+        }
+    }
+
+    /**
+     * 获取个人中心数据
+     * @return mixed
+     */
+    public function getMember()
+    {
+        $data = $this->services->getMemberData();
+        return app('json')->success($data);
+    }
+
+    /**
+     * 保存个人中心数据
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function memberSaveData()
+    {
+        $data = $this->request->postMore([
+            ['status', 0],
+            ['order_status', 0],
+            ['my_banner_status', 0],
+            ['routine_my_banner', []],
+            ['routine_my_menus', []]
+        ]);
+        $this->services->memberSaveData($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 获取开屏广告
+     * @return mixed
+     */
+    public function getOpenAdv()
+    {
+        /** @var CacheServices $cacheServices */
+        $cacheServices = app()->make(CacheServices::class);
+        $data = $cacheServices->getDbCache('open_adv', '');
+        if ($data == '') {
+            $data = [
+                'status' => 0,
+                'time' => '',
+                'type' => 'pic',
+                'value' => [],
+                'video_link' => '',
+            ];
+        }
+        return app('json')->success($data);
+    }
+
+    /**
+     * 保存开屏广告
+     * @return mixed
+     */
+    public function openAdvAdd()
+    {
+        $data = $this->request->postMore([
+            ['status', 0],
+            ['time', 0],
+            ['type', ''],
+            ['value', []],
+            ['video_link', '']
+        ]);
+        if ($data['type'] == '') $data['type'] = 'pic';
+        /** @var CacheServices $cacheServices */
+        $cacheServices = app()->make(CacheServices::class);
+        $cacheServices->setDbCache('open_adv', $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 获取单个diy小程序预览二维码
+     * @param $id
+     * @return mixed
+     */
+    public function getRoutineCode($id)
+    {
+        $image = $this->services->getRoutineCode((int)$id);
+        return app('json')->success(compact('image'));
+    }
+}

+ 115 - 0
app/adminapi/controller/v1/diy/PageLink.php

@@ -0,0 +1,115 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\diy;
+
+use app\adminapi\controller\AuthController;
+use app\services\diy\DiyServices;
+use app\services\diy\PageCategoryServices;
+use app\services\diy\PageLinkServices;
+use app\services\product\product\StoreCategoryServices;
+use think\facade\App;
+
+/**
+ * Class PageLink
+ * @package app\controller\admin\v1\diy
+ */
+class PageLink extends AuthController
+{
+
+    /**
+     * PageLink constructor.
+     * @param App $app
+     * @param PageLinkServices $services
+     */
+    public function __construct(App $app, PageLinkServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取页面链接分类
+     * @return mixed
+     */
+    public function getCategory(PageCategoryServices $services)
+    {
+        return app('json')->success($services->getCategroyList());
+    }
+
+    /**
+     * 获取页面链接
+     * @param $cate_id
+     * @return mixed
+     */
+    public function getLinks($cate_id, PageCategoryServices $pageCategoryServices)
+    {
+        if (!$cate_id) return app('json')->fail(100100);
+        $category = $pageCategoryServices->get((int)$cate_id);
+        if (!$category) {
+            return app('json')->fail(400103);
+        }
+        switch ($category['type']) {
+            case 'special':
+                /** @var DiyServices $diyServices */
+                $diyServices = app()->make(DiyServices::class);
+                $data = $diyServices->getDiyList(['type' => 2]);
+                break;
+            case 'product_category':
+                /** @var StoreCategoryServices $storeCategoryServices */
+                $storeCategoryServices = app()->make(StoreCategoryServices::class);
+                $data = $storeCategoryServices->getList(['cate_name' => '', 'pid' => '', 'is_show' => '']);
+                break;
+            default:
+                $data = $this->services->getLinkList(['cate_id' => $cate_id]);
+                break;
+        }
+        return app('json')->success($data);
+    }
+
+    /**
+     * 保存链接
+     * @param $cate_id
+     * @param PageCategoryServices $pageCategoryServices
+     * @return mixed
+     */
+    public function saveLink($cate_id, PageCategoryServices $pageCategoryServices)
+    {
+        $data = $this->request->getMore([
+            ['name', ''],
+            ['url', '']
+        ]);
+        if (!$cate_id || !$data['name'] || !$data['url']) return app('json')->fail(100100);
+        $category = $pageCategoryServices->get((int)$cate_id);
+        if (!$category) {
+            return app('json')->fail(400103);
+        }
+        $data['cate_id'] = $cate_id;
+        $data['add_time'] = time();
+        if (!$this->services->save($data)) {
+            return app('json')->fail(100022);
+        }
+        return app('json')->success(100021);
+    }
+
+    /**
+     * 删除链接
+     * @param $id
+     * @return mixed
+     */
+    public function del($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->services->del($id);
+        return app('json')->success(100002);
+    }
+
+}

+ 446 - 0
app/adminapi/controller/v1/export/ExportExcel.php

@@ -0,0 +1,446 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\export;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\bargain\StoreBargainServices;
+use app\services\activity\combination\StoreCombinationServices;
+use app\services\activity\combination\StorePinkServices;
+use app\services\activity\seckill\StoreSeckillServices;
+use app\services\agent\AgentManageServices;
+use app\services\other\export\ExportServices;
+use app\services\order\StoreOrderServices;
+use app\services\product\product\StoreProductServices;
+use app\services\system\store\SystemStoreServices;
+use app\services\user\member\MemberCardServices;
+use app\services\user\UserBillServices;
+use app\services\user\UserRechargeServices;
+use app\services\wechat\WechatUserServices;
+use think\facade\App;
+
+/**
+ * 导出excel类
+ * Class ExportExcel
+ * @package app\adminapi\controller\v1\export
+ */
+class ExportExcel extends AuthController
+{
+    /**
+     * @var ExportServices
+     */
+    protected $service;
+
+    /**
+     * ExportExcel constructor.
+     * @param App $app
+     * @param ExportServices $services
+     */
+    public function __construct(App $app, ExportServices $services)
+    {
+        parent::__construct($app);
+        $this->service = $services;
+    }
+
+    public function userList()
+    {
+        $where = $this->request->getMore([
+            ['page', 1],
+            ['limit', 20],
+            ['nickname', ''],
+            ['status', ''],
+            ['pay_count', ''],
+            ['is_promoter', ''],
+            ['order', ''],
+            ['data', ''],
+            ['user_type', ''],
+            ['country', ''],
+            ['province', ''],
+            ['city', ''],
+            ['user_time_type', ''],
+            ['user_time', ''],
+            ['sex', ''],
+            [['level', 0], 0],
+            [['group_id', 'd'], 0],
+            ['label_id', ''],
+            ['now_money', 'normal'],
+            ['field_key', ''],
+            ['isMember', ''],
+            ['ids', []]
+        ]);
+        return app('json')->success($this->service->exportUserList($where));
+    }
+
+    /**
+     * 订单导出
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function orderList()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['real_name', ''],
+            ['is_del', ''],
+            ['data', '', '', 'time'],
+            ['type', ''],
+            ['pay_type', ''],
+            ['order', ''],
+            ['field_key', ''],
+            ['ids', []],
+        ]);
+        $where['is_system_del'] = 0;
+        $where['pid'] = 0;
+        return app('json')->success($this->service->exportOrderList($where));
+    }
+
+    /**
+     * 商品列表导出
+     * @return mixed
+     */
+    public function productList()
+    {
+        $where = $this->request->getMore([
+            ['store_name', ''],
+            ['cate_id', ''],
+            ['type', 1],
+            ['ids', []]
+        ]);
+        return app('json')->success($this->service->exportProductList($where));
+    }
+
+    /**
+     * 砍价商品列表导出
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function bargainList()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['store_name', ''],
+        ]);
+        $where['is_del'] = 0;
+        return app('json')->success($this->service->exportBargainList($where));
+    }
+
+    /**
+     * 拼团商品导出
+     * @return mixed
+     */
+    public function combinationList()
+    {
+        $where = $this->request->getMore([
+            ['is_show', ''],
+            ['store_name', '']
+        ]);
+        $where['is_del'] = 0;
+        return app('json')->success($this->service->exportCombinationList($where));
+    }
+
+    /**
+     * 秒杀商品导出
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function seckillList()
+    {
+        $where = $this->request->getMore([
+            [['status', 's'], ''],
+            [['store_name', 's'], '']
+        ]);
+        return app('json')->success($this->service->exportSeckillList($where));
+    }
+
+    /**
+     * 会员卡导出
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function memberCardList($id)
+    {
+        return app('json')->success($this->service->exportMemberCard($id));
+    }
+
+    /**
+     * 保存用户资金监控的excel表格
+     * @param UserBillServices $services
+     * @return mixed
+     */
+    public function userFinance(UserBillServices $services)
+    {
+        $where = $this->request->getMore([
+            ['start_time', ''],
+            ['end_time', ''],
+            ['nickname', ''],
+            ['type', ''],
+        ]);
+        $data = $services->getBillList($where, '*', false);
+        return app('json')->success($this->service->userFinance($data['data'] ?? []));
+    }
+
+    /**
+     * 用户佣金
+     * @param UserBillServices $services
+     * @return mixed
+     */
+    public function userCommission(UserBillServices $services)
+    {
+        $where = $this->request->getMore([
+            ['page', 1],
+            ['limit', 20],
+            ['nickname', ''],
+            ['price_max', ''],
+            ['price_min', ''],
+            ['excel', '1'],
+            ['time', ''],
+        ]);
+        $data = $services->getCommissionList($where, false);
+        return app('json')->success($this->service->userCommission($data['list'] ?? []));
+    }
+
+    /**
+     * 用户积分
+     * @param UserBillServices $services
+     * @return mixed
+     */
+    public function userPoint(UserBillServices $services)
+    {
+        $where = $this->request->getMore([
+            ['start_time', ''],
+            ['end_time', ''],
+            ['nickname', ''],
+            ['excel', '1'],
+        ]);
+        $data = $services->getPointList($where, '*', false);
+        return app('json')->success($this->service->userPoint($data['list'] ?? []));
+    }
+
+    /**
+     * 用户充值
+     * @param UserRechargeServices $services
+     * @return mixed
+     */
+    public function userRecharge(UserRechargeServices $services)
+    {
+        $where = $this->request->getMore([
+            ['data', ''],
+            ['paid', ''],
+            ['page', 1],
+            ['limit', 20],
+            ['nickname', ''],
+            ['excel', '1'],
+        ]);
+        $data = $services->getRechargeList($where, '*', false);
+        return app('json')->success($this->service->userRecharge($data['list'] ?? []));
+    }
+
+    /**
+     * 分销管理 用户推广
+     * @param AgentManageServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function userAgent(AgentManageServices $services)
+    {
+        $where = $this->request->getMore([
+            ['nickname', ''],
+            ['data', ''],
+            ['excel', '1'],
+        ]);
+        $data = $services->agentSystemPage($where, false);
+        return app('json')->success($this->service->userAgent($data['list']));
+    }
+
+    /**
+     * 微信用户导出(弃用)
+     * @param WechatUserServices $services
+     * @return mixed
+     */
+    public function wechatUser(WechatUserServices $services)
+    {
+        $where = $this->request->getMore([
+            ['page', 1],
+            ['limit', 20],
+            ['nickname', ''],
+            ['data', ''],
+            ['tagid_list', ''],
+            ['groupid', '-1'],
+            ['sex', ''],
+            ['export', '1'],
+            ['subscribe', '']
+        ]);
+        $tagidList = explode(',', $where['tagid_list']);
+        foreach ($tagidList as $k => $v) {
+            if (!$v) {
+                unset($tagidList[$k]);
+            }
+        }
+        $tagidList = array_unique($tagidList);
+        $where['tagid_list'] = implode(',', $tagidList);
+        $data = $services->exportData($where);
+        return app('json')->success($this->service->wechatUser($data));
+    }
+
+    /**
+     * 商铺砍价活动导出
+     * @param StoreBargainServices $services
+     * @return mixed
+     */
+    public function storeBargain(StoreBargainServices $services)
+    {
+        $where = $this->request->getMore([
+            ['start_status', ''],
+            ['status', ''],
+            ['store_name', ''],
+        ]);
+        $data = $services->getList($where);
+        return app('json')->success($this->service->storeBargain($data));
+    }
+
+    /**
+     * 拼团导出
+     * @param StoreCombinationServices $services
+     * @return mixed
+     */
+    public function storeCombination(StoreCombinationServices $services)
+    {
+        $where = $this->request->getMore([
+            ['start_status', ''],
+            ['is_show', ''],
+            ['store_name', ''],
+        ]);
+        $data = $services->getList($where);
+        /** @var StorePinkServices $storePinkServices */
+        $storePinkServices = app()->make(StorePinkServices::class);
+        $countAll = $storePinkServices->getPinkCount([]);
+        $countTeam = $storePinkServices->getPinkCount(['k_id' => 0, 'status' => 2]);
+        $countPeople = $storePinkServices->getPinkCount(['k_id' => 0]);
+        foreach ($data as &$item) {
+            $item['count_people'] = $countPeople[$item['id']] ?? 0;//拼团数量
+            $item['count_people_all'] = $countAll[$item['id']] ?? 0;//参与人数
+            $item['count_people_pink'] = $countTeam[$item['id']] ?? 0;//成团数量
+            $item['stop_status'] = $item['stop_time'] < time() ? 1 : 0;
+            if ($item['is_show']) {
+                if ($item['start_time'] > time())
+                    $item['start_name'] = '未开始';
+                else if ($item['stop_time'] < time())
+                    $item['start_name'] = '已结束';
+                else if ($item['stop_time'] > time() && $item['start_time'] < time()) {
+                    $item['start_name'] = '进行中';
+                }
+            } else $item['start_name'] = '已结束';
+        }
+        return app('json')->success($this->service->storeCombination($data));
+    }
+
+    /**
+     * 秒杀导出
+     * @param StoreSeckillServices $services
+     * @return mixed
+     */
+    public function storeSeckill(StoreSeckillServices $services)
+    {
+        $where = $this->request->getMore([
+            ['start_status', ''],
+            ['status', ''],
+            ['store_name', '']
+        ]);
+        $data = $services->getList($where);
+        return app('json')->success($this->service->storeSeckill($data));
+    }
+
+    /**
+     * 商品导出
+     * @param StoreProductServices $services
+     * @return mixed
+     */
+    public function storeProduct(StoreProductServices $services)
+    {
+        $where = $this->request->getMore([
+            ['store_name', ''],
+            ['cate_id', ''],
+            ['type', 1]
+        ]);
+        $data = $services->searchList($where, true, false);
+        return app('json')->success($this->service->storeProduct($data['list'] ?? []));
+    }
+
+    /**
+     * 订单列表导出
+     * @param StoreOrderServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function storeOrder(StoreOrderServices $services)
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['real_name', ''],
+            ['data', '', '', 'time']
+        ]);
+        $where['pid'] = 0;
+        $ids = $this->request->get('ids');
+        if ($ids) {
+            $idsArr = array_filter(explode(',', $ids));
+            if ($idsArr) {
+                $where['id'] = $idsArr;
+            }
+        }
+        $data = $services->getExportList($where);
+        return app('json')->success($this->service->storeOrder($data));
+    }
+
+    /**
+     * 获取提货点
+     * @param SystemStoreServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function storeMerchant(SystemStoreServices $services)
+    {
+        $where = $this->request->getMore([
+            [['keywords', 's'], ''],
+            [['type', 'd'], 0],
+        ]);
+        $data = $services->getExportData($where);
+        return app('json')->success($this->service->storeMerchant($data));
+    }
+
+    /**
+     * 会员卡导出
+     * @param int $id
+     * @param MemberCardServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function memberCard(int $id, MemberCardServices $services)
+    {
+        $data = $services->getExportData(['batch_card_id' => $id]);
+        return app('json')->success($this->service->memberCard($data));
+    }
+}

+ 138 - 0
app/adminapi/controller/v1/file/SystemAttachment.php

@@ -0,0 +1,138 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\file;
+
+use app\adminapi\controller\AuthController;
+use app\services\system\attachment\SystemAttachmentServices;
+use think\facade\App;
+
+/**
+ * 附件管理类
+ * Class SystemAttachment
+ * @package app\adminapi\controller\v1\file
+ */
+class SystemAttachment extends AuthController
+{
+    /**
+     * @var SystemAttachmentServices
+     */
+    protected $service;
+
+    /**
+     * @param App $app
+     * @param SystemAttachmentServices $service
+     */
+    public function __construct(App $app, SystemAttachmentServices $service)
+    {
+        parent::__construct($app);
+        $this->service = $service;
+    }
+
+    /**
+     * 显示列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['pid', 0]
+        ]);
+        return app('json')->success($this->service->getImageList($where));
+    }
+
+    /**
+     * 删除指定资源
+     * @return mixed
+     */
+    public function delete()
+    {
+        [$ids] = $this->request->postMore([
+            ['ids', '']
+        ], true);
+        $this->service->del($ids);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 图片上传
+     * @param int $upload_type
+     * @param int $type
+     * @return mixed
+     */
+    public function upload($upload_type = 0, $type = 0)
+    {
+        [$pid, $file, $menuName] = $this->request->postMore([
+            ['pid', 0],
+            ['file', 'file'],
+            ['menu_name', '']
+        ], true);
+        $res = $this->service->upload((int)$pid, $file, $upload_type, $type, $menuName);
+        return app('json')->success(100032, ['src' => $res]);
+    }
+
+    /**
+     * 移动图片
+     * @return mixed
+     */
+    public function moveImageCate()
+    {
+        $data = $this->request->postMore([
+            ['pid', 0],
+            ['images', '']
+        ]);
+        $this->service->move($data);
+        return app('json')->success(100034);
+    }
+
+    /**
+     * 修改文件名
+     * @param $id
+     * @return mixed
+     */
+    public function update($id)
+    {
+        $realName = $this->request->post('real_name', '');
+        if (!$realName) {
+            return app('json')->fail(400104);
+        }
+        $this->service->update($id, ['real_name' => $realName]);
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 获取上传类型
+     * @return mixed
+     */
+    public function uploadType()
+    {
+        $data['upload_type'] = (string)sys_config('upload_type', 1);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 视频分片上传
+     * @return mixed
+     */
+    public function videoUpload()
+    {
+        $data = $this->request->postMore([
+            ['chunkNumber', 0],//第几分片
+            ['currentChunkSize', 0],//分片大小
+            ['chunkSize', 0],//总大小
+            ['totalChunks', 0],//分片总数
+            ['file', 'file'],//文件
+            ['md5', ''],//MD5
+            ['filename', ''],//文件名称
+        ]);
+        $res = $this->service->videoUpload($data, $_FILES['file']);
+        return app('json')->success($res);
+    }
+}

+ 122 - 0
app/adminapi/controller/v1/file/SystemAttachmentCategory.php

@@ -0,0 +1,122 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\file;
+
+use app\adminapi\controller\AuthController;
+use app\services\system\attachment\SystemAttachmentCategoryServices;
+use think\facade\App;
+
+/**
+ * 图片分类管理类
+ * Class SystemAttachmentCategory
+ * @package app\adminapi\controller\v1\file
+ */
+class SystemAttachmentCategory extends AuthController
+{
+    /**
+     * @var SystemAttachmentCategoryServices
+     */
+    protected $service;
+
+    /**
+     * @param App $app
+     * @param SystemAttachmentCategoryServices $service
+     */
+    public function __construct(App $app, SystemAttachmentCategoryServices $service)
+    {
+        parent::__construct($app);
+        $this->service = $service;
+    }
+
+    /**
+     * 显示资源列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['name', ''],
+            ['pid', 0]
+        ]);
+        if ($where['name'] != '') $where['pid'] = '';
+        return app('json')->success($this->service->getAll($where));
+    }
+
+    /**
+     * 新增表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create($id)
+    {
+        return app('json')->success($this->service->createForm($id));
+    }
+
+    /**
+     * 保存新增
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['pid', 0],
+            ['name', '']
+        ]);
+        if (!$data['name']) {
+            return app('json')->fail(400100);
+        }
+        $this->service->save($data);
+        return app('json')->success(100021);
+    }
+
+    /**
+     * 编辑表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->service->editForm($id));
+    }
+
+    /**
+     * 保存更新的资源
+     * @param $id
+     * @return mixed
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['pid', 0],
+            ['name', '']
+        ]);
+        if (!$data['name']) {
+            return app('json')->fail(400100);
+        }
+        $info = $this->service->get($id);
+        $count = $this->service->count(['pid' => $id]);
+        if ($count && $info['pid'] != $data['pid']) return app('json')->fail(400105);
+        $this->service->update($id, $data);
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除指定资源
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id)
+    {
+        $this->service->del($id);
+        return app('json')->success(100002);
+    }
+}

+ 101 - 0
app/adminapi/controller/v1/finance/Finance.php

@@ -0,0 +1,101 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\finance;
+
+use app\services\user\UserBillServices;
+use think\facade\App;
+use app\adminapi\controller\AuthController;
+
+/**
+ * Class Finance
+ * @package app\adminapi\controller\v1\finance
+ */
+class Finance extends AuthController
+{
+    /**
+     * Finance constructor.
+     * @param App $app
+     * @param UserBillServices $services
+     */
+    public function __construct(App $app, UserBillServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 筛选类型
+     */
+    public function bill_type()
+    {
+        return app('json')->success($this->services->bill_type());
+    }
+
+    /**
+     * 资金记录
+     */
+    public function list()
+    {
+        $where = $this->request->getMore([
+            ['start_time', ''],
+            ['end_time', ''],
+            ['nickname', ''],
+            ['limit', 20],
+            ['page', 1],
+            ['type', ''],
+        ]);
+        return app('json')->success($this->services->getBillList($where));
+    }
+
+    /**
+     * 佣金记录
+     * @return mixed
+     */
+    public function get_commission_list()
+    {
+        $where = $this->request->getMore([
+            ['nickname', ''],
+            ['price_max', ''],
+            ['price_min', ''],
+            ['sum_number', 'normal'],
+            ['brokerage_price', 'normal'],
+            ['time', '']
+        ]);
+        return app('json')->success($this->services->getCommissionList($where));
+    }
+
+    /**
+     * 佣金详情用户信息
+     * @param $id
+     * @return mixed
+     */
+    public function user_info($id)
+    {
+        return app('json')->success($this->services->user_info((int)$id));
+    }
+
+    /**
+     * 佣金提现记录个人列表
+     */
+    public function get_extract_list($id = '')
+    {
+        if ($id == '') return app('json')->fail(100100);
+        $where = $this->request->getMore([
+            ['start_time', ''],
+            ['end_time', ''],
+            ['nickname', '']
+        ]);
+        $where['category'] = 'now_money';
+        $where['type'] = ['brokerage', 'brokerage_user'];
+        return app('json')->success($this->services->getBillOneList((int)$id, $where));
+    }
+
+}

+ 58 - 0
app/adminapi/controller/v1/finance/UserBalance.php

@@ -0,0 +1,58 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\finance;
+
+use app\adminapi\controller\AuthController;
+use app\services\user\UserMoneyServices;
+use think\facade\App;
+
+class UserBalance extends AuthController
+{
+    /**
+     * UserBalance constructor.
+     * @param App $app
+     * @param UserMoneyServices $services
+     */
+    public function __construct(App $app, UserMoneyServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 余额记录
+     * @return mixed
+     */
+    public function balanceList()
+    {
+        $where = $this->request->getMore([
+            ['time', ''],
+            ['trading_type', 0, '', 'type']
+        ]);
+        $date = $this->services->balanceList($where);
+        return app('json')->success($date);
+    }
+
+    /**
+     * 余额记录备注
+     * @return mixed
+     */
+    public function balanceRecordRemark($id = 0)
+    {
+        [$mark] = $this->request->postMore([
+            ['mark', '']
+        ], true);
+        if (!$id) return app('json')->fail(100100);
+        if ($mark === '') return app('json')->fail(400106);
+        $this->services->recordRemark($id, $mark);
+        return app('json')->success(100024);
+    }
+}

+ 140 - 0
app/adminapi/controller/v1/finance/UserExtract.php

@@ -0,0 +1,140 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\finance;
+
+use app\adminapi\controller\AuthController;
+use app\services\user\UserExtractServices;
+use think\facade\App;
+use think\Request;
+
+/**
+ * Class UserExtract
+ * @package app\adminapi\controller\v1\finance
+ */
+class UserExtract extends AuthController
+{
+    /**
+     * UserExtract constructor.
+     * @param App $app
+     * @param UserExtractServices $services
+     */
+    public function __construct(App $app, UserExtractServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['extract_type', ''],
+            ['nireid', '', '', 'like'],
+            ['data', '', '', 'time'],
+        ]);
+        if (isset($where['extract_type']) && $where['extract_type'] == 'wx') {
+            $where['extract_type'] = 'weixin';
+        }
+        return app('json')->success($this->services->index($where));
+    }
+
+    /**
+     * 显示编辑资源表单页
+     * @param $id
+     * @return mixed
+     */
+    public function edit($id)
+    {
+        if (!$id) return app('json')->fail(100026);
+        return app('json')->success($this->services->edit((int)$id));
+    }
+
+    /**
+     * 保存更新的资源
+     * @param Request $request
+     * @param $id
+     * @return mixed
+     */
+    public function update(Request $request, $id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $id = (int)$id;
+        $UserExtract = $this->services->getExtract($id);
+        if (!$UserExtract) app('json')->fail(100026);
+        if ($UserExtract['extract_type'] == 'alipay') {
+            $data = $this->request->postMore([
+                'real_name',
+                'mark',
+                'extract_price',
+                'alipay_code',
+            ]);
+            if (!$data['real_name']) return app('json')->fail(400107);
+            if ($data['extract_price'] <= -1) return app('json')->fail(400108);
+            if (!$data['alipay_code']) return app('json')->fail(400109);
+        } else if ($UserExtract['extract_type'] == 'weixin') {
+            $data = $this->request->postMore([
+                'real_name',
+                'mark',
+                'extract_price',
+                'wechat',
+            ]);
+            if ($data['extract_price'] <= -1) return app('json')->fail(400108);
+            if (!$data['wechat']) return app('json')->fail(400110);
+        } else {
+            $data = $this->request->postMore([
+                'real_name',
+                'extract_price',
+                'mark',
+                'bank_code',
+                'bank_address',
+            ]);
+            if (!$data['real_name']) return app('json')->fail(400107);
+            if ($data['extract_price'] <= -1) return app('json')->fail(400108);
+            if (!$data['bank_code']) return app('json')->fail(400111);
+            if (!$data['bank_address']) return app('json')->fail(400112);
+        }
+        return app('json')->success($this->services->update($id, $data) ? 100001 : 100007);
+    }
+
+    /**
+     * 拒绝
+     * @param $id
+     * @return mixed
+     */
+    public function refuse($id)
+    {
+        if (!$id) app('json')->fail(100100);
+        $data = $this->request->postMore([
+            ['message', '']
+        ]);
+        if ($data['message'] == '') return app('json')->fail(400113);
+        return app('json')->success($this->services->refuse((int)$id, $data['message']) ? 100014 : 100015);
+    }
+
+    /**
+     * 通过
+     * @param $id
+     * @return mixed
+     */
+    public function adopt($id)
+    {
+        if (!$id) app('json')->fail(100100);
+        return app('json')->success($this->services->adopt((int)$id) ? 100014 : 100015);
+    }
+}

+ 97 - 0
app/adminapi/controller/v1/finance/UserRecharge.php

@@ -0,0 +1,97 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\finance;
+
+use app\adminapi\controller\AuthController;
+use app\services\user\UserRechargeServices;
+use think\facade\App;
+
+/**
+ * Class UserRecharge
+ * @package app\adminapi\controller\v1\finance
+ */
+class UserRecharge extends AuthController
+{
+    /**
+     * UserRecharge constructor.
+     * @param App $app
+     * @param UserRechargeServices $services
+     */
+    public function __construct(App $app, UserRechargeServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     * @return \think\Response
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['data', ''],
+            ['paid', ''],
+            ['nickname', ''],
+        ]);
+        return app('json')->success($this->services->getRechargeList($where));
+    }
+
+    /**
+     * 删除指定资源
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($this->services->delRecharge((int)$id) ? 100002 : 100008);
+    }
+
+    /**
+     * 获取用户充值数据
+     * @return array
+     */
+    public function user_recharge()
+    {
+        $where = $this->request->getMore([
+            ['data', ''],
+            ['paid', ''],
+            ['nickname', ''],
+        ]);
+        return app('json')->success($this->services->user_recharge($where));
+    }
+
+    /**
+     * 退款表单
+     * @param $id
+     * @return mixed|void
+     */
+    public function refund_edit($id)
+    {
+        if (!$id) return app('json')->fail(100026);
+        return app('json')->success($this->services->refund_edit((int)$id));
+    }
+
+    /**
+     * 退款操作
+     * @param $id
+     * @return mixed
+     */
+    public function refund_update($id)
+    {
+        $data = $this->request->postMore([
+            'refund_price',
+        ]);
+        if (!$id) return app('json')->fail(100026);
+        return app('json')->success($this->services->refund_update((int)$id, $data['refund_price']) ? 100036 : 100037);
+    }
+}

+ 173 - 0
app/adminapi/controller/v1/freight/Express.php

@@ -0,0 +1,173 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\freight;
+
+use app\adminapi\controller\AuthController;
+use app\services\shipping\ExpressServices;
+use think\facade\App;
+
+/**
+ * 物流
+ * Class Express
+ * @package app\adminapi\controller\v1\freight
+ */
+class Express extends AuthController
+{
+    /**
+     * 构造方法
+     * Express constructor.
+     * @param App $app
+     * @param ExpressServices $services
+     */
+    public function __construct(App $app, ExpressServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取物流列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['keyword', '']
+        ]);
+        return app('json')->success($this->services->getExpressList($where));
+    }
+
+    /**
+     * 显示创建资源表单页
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->createForm());
+    }
+
+    /**
+     * 保存新建的资源
+     * @return \think\Response
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            'name',
+            'code',
+            ['sort', 0],
+            ['is_show', 0]]);
+        if (!$data['name']) return app('json')->fail(400400);
+        $this->services->save($data);
+        return app('json')->success(400401);
+    }
+
+    /**
+     * 显示编辑资源表单页
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->updateForm((int)$id));
+    }
+
+    /**
+     * 保存更新的资源
+     * @param $id
+     * @return mixed
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['account', ''],
+            ['key', ''],
+            ['net_name', ''],
+            ['courier_name', ''],
+            ['customer_name', ''],
+            ['code_name', ''],
+            ['sort', 0],
+            ['is_show', 0]]);
+        if (!$expressInfo = $this->services->get($id)) return app('json')->fail(100026);
+        if ($expressInfo['partner_id'] == 1 && !$data['account']) {
+            return app('json')->fail(400402);
+        }
+        if ($expressInfo['partner_key'] == 1 && !$data['key']) {
+            return app('json')->fail(400403);
+        }
+        if ($expressInfo['net'] == 1 && !$data['net_name']) {
+            return app('json')->fail(400404);
+        }
+        if ($expressInfo['check_man'] == 1 && !$data['courier_name']) {
+            return app('json')->fail(500001);
+        }
+        if ($expressInfo['partner_name'] == 1 && !$data['customer_name']) {
+            return app('json')->fail(500002);
+        }
+        if ($expressInfo['is_code'] == 1 && !$data['code_name']) {
+            return app('json')->fail(500003);
+        }
+        $expressInfo->account = $data['account'];
+        $expressInfo->key = $data['key'];
+        $expressInfo->net_name = $data['net_name'];
+        $expressInfo->courier_name = $data['courier_name'];
+        $expressInfo->customer_name = $data['customer_name'];
+        $expressInfo->code_name = $data['code_name'];
+        $expressInfo->sort = $data['sort'];
+        $expressInfo->is_show = $data['is_show'];
+        $expressInfo->status = 1;
+        $expressInfo->save();
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除指定资源
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $res = $this->services->delete($id);
+        if (!$res)
+            return app('json')->fail(100008);
+        else
+            return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param int $id
+     * @param string $status
+     * @return mixed
+     */
+    public function set_status($id = 0, $status = '')
+    {
+        if ($status == '' || $id == 0) return app('json')->fail(100100);
+        $this->services->update($id, ['is_show' => $status]);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 同步平台快递公司
+     * @return mixed
+     */
+    public function syncExpress()
+    {
+        $this->services->syncExpress();
+        return app('json')->success(100038);
+    }
+}

+ 313 - 0
app/adminapi/controller/v1/kefu/StoreService.php

@@ -0,0 +1,313 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\kefu;
+
+use app\adminapi\controller\AuthController;
+use app\services\kefu\LoginServices;
+use app\services\kefu\service\StoreServiceLogServices;
+use app\services\kefu\service\StoreServiceServices;
+use app\services\user\UserServices;
+use app\services\user\UserWechatuserServices;
+use crmeb\exceptions\AdminException;
+use crmeb\services\CacheService;
+use think\facade\App;
+
+/**
+ * 客服管理
+ * Class StoreService
+ * @package app\admin\controller\store
+ */
+class StoreService extends AuthController
+{
+    /**
+     * StoreService constructor.
+     * @param App $app
+     * @param StoreServiceServices $services
+     */
+    public function __construct(App $app, StoreServiceServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        return app('json')->success($this->services->getServiceList([]));
+    }
+
+    /**
+     * 显示创建资源表单页
+     * @param UserWechatuserServices $services
+     * @return mixed
+     */
+    public function create(UserWechatuserServices $services)
+    {
+        $where = $this->request->getMore([
+            ['nickname', ''],
+            ['data', '', '', 'time'],
+            ['type', '', '', 'user_type'],
+        ]);
+        $where['is_del'] = 0;
+        [$list, $count] = $services->getWhereUserList($where, 'u.nickname,u.uid,u.avatar as headimgurl,w.subscribe,w.province,w.country,w.city,w.sex,u.user_type,u.is_del');
+        return app('json')->success(compact('list', 'count'));
+    }
+
+    /**
+     * 添加客服表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function add()
+    {
+        return app('json')->success($this->services->create());
+    }
+
+    /**
+     * 保存新建的资源
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['image', ''],
+            ['uid', 0],
+            ['avatar', ''],
+            ['customer', ''],
+            ['notify', ''],
+            ['phone', ''],
+            ['account', ''],
+            ['password', ''],
+            ['true_password', ''],
+            ['phone', ''],
+            ['nickname', ''],
+            ['status', 1],
+        ]);
+        if ($data['image'] == '') return app('json')->fail(400250);
+        $data['uid'] = $data['image']['uid'];
+        /** @var UserServices $userService */
+        $userService = app()->make(UserServices::class);
+        $userInfo = $userService->get($data['uid']);
+        if ($data['phone'] == '') {
+            if (!$userInfo['phone']) {
+                throw new AdminException(400251);
+            } else {
+                $data['phone'] = $userInfo['phone'];
+            }
+        } else {
+            if (!check_phone($data['phone'])) {
+                throw new AdminException(400252);
+            }
+        }
+        if ($data['nickname'] == '') $data['nickname'] = $userInfo['nickname'];
+        $data['avatar'] = $data['image']['image'];
+        if ($this->services->count(['uid' => $data['uid']])) {
+            return app('json')->fail(400253);
+        }
+        unset($data['image']);
+        $data['add_time'] = time();
+        if (!$data['account']) {
+            return app('json')->fail(400254);
+        }
+        if (!preg_match('/^[a-zA-Z0-9]{4,30}$/', $data['account'])) {
+            return app('json')->fail(400255);
+        }
+        if (!$data['password']) {
+            return app('json')->fail(400256);
+        }
+        if (!preg_match('/^[0-9a-z_$]{6,20}$/i', $data['password'])) {
+            return app('json')->fail(400257);
+        }
+        if ($this->services->count(['phone' => $data['phone']])) {
+            return app('json')->fail(400258);
+        }
+        if ($this->services->count(['account' => $data['account']])) {
+            return app('json')->fail(400259);
+        }
+        $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
+        $res = $this->services->save($data);
+        if ($res) {
+            return app('json')->success(400260);
+        } else {
+            return app('json')->fail(400261);
+        }
+    }
+
+    /**
+     * 显示编辑资源表单页
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->edit((int)$id));
+    }
+
+    /**
+     * 保存新建的资源
+     * @param $id
+     * @return mixed
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['avatar', ''],
+            ['nickname', ''],
+            ['account', ''],
+            ['phone', ''],
+            ['status', 1],
+            ['notify', 1],
+            ['customer', 1],
+            ['password', ''],
+            ['true_password', ''],
+        ]);
+        $customer = $this->services->get((int)$id);
+        if (!$customer) {
+            return app('json')->fail(100026);
+        }
+        if ($data["nickname"] == '') {
+            return app('json')->fail(400262);
+        }
+        if (!check_phone($data['phone'])) {
+            return app('json')->fail(400252);
+        }
+        if ($customer['phone'] != $data['phone'] && $this->services->count(['phone' => $data['phone']])) {
+            return app('json')->fail(400258);
+        }
+        if ($data['password']) {
+            if (!preg_match('/^[0-9a-z_$]{6,16}$/i', $data['password'])) {
+                return app('json')->fail(400257);
+            }
+            if (!$data['true_password']) {
+                return app('json')->fail(400263);
+            }
+            if ($data['password'] != $data['true_password']) {
+                return app('json')->fail(400264);
+            }
+            $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
+        } else {
+            unset($data['password']);
+        }
+        $this->services->update($id, $data);
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除指定资源
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id)
+    {
+        if (!$this->services->delete($id))
+            return app('json')->fail(100008);
+        else
+            return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param UserServices $services
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status(UserServices $services, $id, $status)
+    {
+        if ($status == '' || $id == 0) return app('json')->fail(100100);
+        $info = $this->services->get($id, ['status', 'uid']);
+        if (!$services->count(['uid' => $info['uid']])) {
+            $info->status = 1;
+            $info->save();
+            return app('json')->fail(400265);
+        }
+        $info->status = $status;
+        $info->save();
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 聊天记录
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function chat_user($id)
+    {
+        $uid = $this->services->value(['id' => $id], 'uid');
+        if (!$uid) {
+            return app('json')->fail(100026);
+        }
+        return app('json')->success($this->services->getChatUser((int)$uid));
+    }
+
+
+    /**
+     * 聊天记录
+     * @param StoreServiceLogServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function chat_list(StoreServiceLogServices $services)
+    {
+        $data = $this->request->getMore([
+            ['uid', 0],
+            ['to_uid', 0],
+            ['id', 0]
+        ]);
+        if ($data['uid']) {
+            CacheService::set('admin_chat_list' . $this->adminId, $data);
+        }
+        $data = CacheService::get('admin_chat_list' . $this->adminId);
+        if ($data['uid']) {
+            $where = [
+                'chat' => [$data['uid'], $data['to_uid']],
+            ];
+        } else {
+            $where = [];
+        }
+        $list = $services->getChatLogList($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 客服登录
+     * @param LoginServices $services
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function keufLogin(LoginServices $services, $id)
+    {
+        $serviceInfo = $services->get($id);
+        if (!$serviceInfo) {
+            return app('json')->fail(400266);
+        }
+        if (!$serviceInfo->account || !$serviceInfo->password) {
+            return app('json')->fail(400267);
+        }
+        return app('json')->success($services->authLogin($serviceInfo->account));
+    }
+
+}

+ 111 - 0
app/adminapi/controller/v1/kefu/StoreServiceFeedback.php

@@ -0,0 +1,111 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\kefu;
+
+
+use app\adminapi\controller\AuthController;
+use app\services\kefu\service\StoreServiceFeedbackServices;
+use think\facade\App;
+
+/**
+ * 客服用户留言反馈
+ * Class StoreServiceFeedback
+ * @package app\adminapi\controller\v1\application\wechat
+ */
+class StoreServiceFeedback extends AuthController
+{
+
+    /**
+     * StoreServiceFeedback constructor.
+     * @param App $app
+     * @param StoreServiceFeedbackServices $services
+     */
+    public function __construct(App $app, StoreServiceFeedbackServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取留言列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['title', ''],
+            ['time', '']
+        ]);
+
+        return app('json')->success($this->services->getFeedbackList($where));
+    }
+
+    /**
+     * 获取修改表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function edit($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($this->services->editForm((int)$id));
+    }
+
+    /**
+     * 修改
+     * @param $id
+     * @return mixed
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['make', ''],
+            ['status', 0],
+        ]);
+        if (!$id || !($feedInfo = $this->services->get($id))) {
+            return app('json')->fail(400268);
+        }
+        $feedInfo->make = $data['make'];
+        if ($data['status']) {
+            $feedInfo->status = $data['status'];
+        }
+        $feedInfo->save();
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除反馈
+     * @param $id
+     * @return mixed
+     * @throws \Exception
+     */
+    public function delete($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        if ($this->services->delete($id)) {
+            return app('json')->success(100002);
+        } else {
+            return app('json')->fail(100008);
+        }
+    }
+}

+ 165 - 0
app/adminapi/controller/v1/kefu/StoreServiceSpeechcraft.php

@@ -0,0 +1,165 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\kefu;
+
+use app\Request;
+use think\facade\App;
+use app\adminapi\controller\AuthController;
+use app\services\kefu\service\StoreServiceSpeechcraftServices;
+use app\adminapi\validate\service\StoreServiceSpeechcraftValidata;
+
+/**
+ * 话术空控制器
+ * Class StoreServiceSpeechcraft
+ * @package app\adminapi\controller\v1\application\wechat
+ */
+class StoreServiceSpeechcraft extends AuthController
+{
+    /**
+     * StoreServiceSpeechcraft constructor.
+     * @param App $app
+     * @param StoreServiceSpeechcraftServices $services
+     */
+    public function __construct(App $app, StoreServiceSpeechcraftServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     * @param Request $request
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index(Request $request)
+    {
+        $where = $request->getMore([
+            ['title', ''],
+            ['message', ''],
+            [['cate_id', 'd'], ''],
+        ]);
+        $where['kefu_id'] = 0;
+        return app('json')->success($this->services->getSpeechcraftList($where));
+    }
+
+    /**
+     * 显示创建资源表单页
+     * @return mixed
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->createForm());
+    }
+
+    /**
+     * 保存新建的资源
+     * @param Request $request
+     * @return \think\Response
+     */
+    public function save(Request $request)
+    {
+        $data = $request->postMore([
+            ['title', ''],
+            ['message', ''],
+            [['cate_id', 'd'], 0],
+            ['sort', 0],
+        ]);
+
+        $this->validate($data, StoreServiceSpeechcraftValidata::class);
+        $data['add_time'] = time();
+        $data['kefu_id'] = 0;
+        if ($this->services->count(['message' => $data['message']])) {
+            return app('json')->fail(400269);
+        }
+        if ($this->services->save($data)) {
+            return app('json')->success(400270);
+        } else {
+            return app('json')->fail(400271);
+        }
+    }
+
+    /**
+     * 显示指定的资源
+     * @param int $id
+     * @return \think\Response
+     */
+    public function read($id)
+    {
+        $info = $this->services->get($id);
+        if (!$info) {
+            return app('json')->fail(100026);
+        }
+        return app('json')->success($info);
+    }
+
+    /**
+     * 显示编辑资源表单页
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->updateForm((int)$id));
+    }
+
+    /**
+     * 保存更新的资源
+     * @param Request $request
+     * @param int $id
+     * @return \think\Response
+     */
+    public function update(Request $request, $id)
+    {
+        $data = $request->postMore([
+            ['title', ''],
+            ['message', ''],
+            ['sort', 0],
+            [['cate_id', 'd'], 0],
+        ]);
+
+        $this->validate($data, StoreServiceSpeechcraftValidata::class);
+        $message = $this->services->get(['message' => $data['message']]);
+        if ($message && $message['id'] != $id) {
+            return app('json')->fail(400269);
+        }
+        if ($this->services->update($id, $data)) {
+            return app('json')->success(100001);
+        } else {
+            return app('json')->fail(100007);
+        }
+
+    }
+
+    /**
+     * 删除指定资源
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id)
+    {
+        if (!$id || !($info = $this->services->get($id))) {
+            return app('json')->fail(400272);
+        }
+        if ($info->delete()) {
+            return app('json')->success(100002);
+        } else {
+            return app('json')->fail(100008);
+        }
+    }
+}

+ 146 - 0
app/adminapi/controller/v1/kefu/StoreServiceSpeechcraftCate.php

@@ -0,0 +1,146 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\kefu;
+
+
+use app\Request;
+use think\facade\App;
+use app\adminapi\controller\AuthController;
+use app\services\kefu\service\StoreServiceSpeechcraftCateServices;
+
+/**
+ * Class StoreServiceSpeechcraftCate
+ * @package app\adminapi\controller\v1\application\wechat
+ */
+class StoreServiceSpeechcraftCate extends AuthController
+{
+
+    /**
+     * StoreServiceSpeechcraftCate constructor.
+     * @param App $app
+     * @param StoreServiceSpeechcraftCateServices $services
+     */
+    public function __construct(App $app, StoreServiceSpeechcraftCateServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['name', '']
+        ]);
+        $where['owner_id'] = 0;
+        $where['type'] = 1;
+        return app('json')->success($this->services->getCateList($where));
+    }
+
+    /**
+     * 获取创建表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->createForm());
+    }
+
+    /**
+     * 保存数据
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['sort', 0],
+        ]);
+
+        if (!$data['name']) {
+            return app('json')->fail(400100);
+        }
+
+        if ($this->services->count(['name' => $data['name'], 'type' => 1, 'owner_id' => 0])) {
+            return app('json')->fail(400101);
+        }
+
+        $data['add_time'] = time();
+        $data['type'] = 1;
+
+        $this->services->save($data);
+        return app('json')->success(100021);
+    }
+
+    /**
+     * 获取修改表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->editForm((int)$id));
+    }
+
+    /**
+     * 修改保存
+     * @param Request $request
+     * @param $id
+     * @return mixed
+     */
+    public function update(Request $request, $id)
+    {
+        $data = $request->postMore([
+            ['name', ''],
+            [['sort', 'd'], 0],
+        ]);
+        if (!$data['name']) {
+            return app('json')->fail(400100);
+        }
+
+        $cateInfo = $this->services->get($id);
+        if (!$cateInfo) {
+            return app('json')->fail(400103);
+        }
+        $cateInfo->name = $data['name'];
+        $cateInfo->sort = $data['sort'];
+        $cateInfo->save();
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if ($id == 0) return app('json')->fail(400273);
+        $cateInfo = $this->services->get($id);
+        if (!$cateInfo) {
+            return app('json')->fail(400103);
+        }
+        $cateInfo->delete();
+        return app('json')->success(100002);
+    }
+}

+ 149 - 0
app/adminapi/controller/v1/marketing/StoreAdvance.php

@@ -0,0 +1,149 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\marketing;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\advance\StoreAdvanceServices;
+use app\services\activity\bargain\StoreBargainServices;
+use app\services\activity\combination\StoreCombinationServices;
+use app\services\activity\seckill\StoreSeckillServices;
+use crmeb\exceptions\AdminException;
+use think\facade\App;
+
+/**
+ * 预售控制器
+ * Class StoreAdvance
+ * @package app\adminapi\controller\v1\marketing
+ */
+class StoreAdvance extends AuthController
+{
+    /**
+     * StoreAdvance constructor.
+     * @param App $app
+     * @param StoreAdvanceServices $services
+     */
+    public function __construct(App $app, StoreAdvanceServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 管理端预售列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['title', ''],
+            ['type', ''],
+            ['status', ''],
+            ['time_type', 0]
+        ]);
+        return app('json')->success($this->services->getList($where));
+    }
+
+    /**
+     * 添加/修改预售商品
+     * @param $id
+     * @return mixed
+     */
+    public function save($id)
+    {
+        $data = $this->request->postMore([
+            [['product_id', 'd'], 0],
+            [['title', 's'], ''],
+            [['info', 's'], ''],
+            [['unit_name', 's'], ''],
+            ['image', ''],
+            ['images', []],
+            [['description', 's'], ''],
+            [['temp_id', 'd'], 0],
+            [['status', 'd'], 0],
+            [['sort', 'd'], 0],
+            [['num', 'd'], 0],
+            [['once_num', 'd'], 1000],
+            ['section_time', []],
+            ['type', 0],
+            ['deposit', 0],
+            ['pay_time', []],
+            ['attrs', []],
+            ['items', []],
+            ['deliver_time', 0],
+            ['copy', 0]
+        ]);
+        if (!$id) {
+            /** @var StoreSeckillServices $storeSeckillService */
+            $storeSeckillService = app()->make(StoreSeckillServices::class);
+            $res1 = $storeSeckillService->count(['product_id' => $data['product_id'], 'is_del' => 0, 'status' => 1, 'seckill_time' => 1]);
+            if ($res1) {
+                throw new AdminException(400506);
+            }
+            /** @var StoreBargainServices $storeBargainService */
+            $storeBargainService = app()->make(StoreBargainServices::class);
+            $res2 = $storeBargainService->count(['product_id' => $data['product_id'], 'is_del' => 0, 'status' => 1, 'bargain_time' => 1]);
+            if ($res2) {
+                throw new AdminException(400506);
+            }
+            /** @var StoreCombinationServices $storeCombinationService */
+            $storeCombinationService = app()->make(StoreCombinationServices::class);
+            $res3 = $storeCombinationService->count(['product_id' => $data['product_id'], 'is_del' => 0, 'is_show' => 1, 'pinkIngTime' => 1]);
+            if ($res3) {
+                throw new AdminException(400506);
+            }
+        }
+        $this->services->saveData($id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 详情
+     * @param $id
+     * @return mixed
+     */
+    public function info($id)
+    {
+        $info = $this->services->getInfo($id);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 删除预售
+     * @param $id
+     * @return mixed
+     */
+    public function del($id)
+    {
+        $res = $this->services->update($id, ['is_del' => 1]);
+        if ($res) {
+            return app('json')->success(100002);
+        } else {
+            return app('json')->fail(100008);
+        }
+    }
+
+    /**
+     * 预售商品上下架
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function setStatus($id, $status)
+    {
+        $res = $this->services->update($id, ['status' => $status]);
+        if ($res) {
+            return app('json')->success(100014);
+        } else {
+            return app('json')->fail(100015);
+        }
+    }
+}

+ 226 - 0
app/adminapi/controller/v1/marketing/StoreBargain.php

@@ -0,0 +1,226 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\bargain\StoreBargainServices;
+use app\services\activity\bargain\StoreBargainUserHelpServices;
+use app\services\activity\bargain\StoreBargainUserServices;
+use think\facade\App;
+
+/**
+ * 砍价管理
+ * Class StoreBargain
+ * @package app\adminapi\controller\v1\marketing
+ */
+class StoreBargain extends AuthController
+{
+    /**
+     * StoreBargain constructor.
+     * @param App $app
+     * @param StoreBargainServices $services
+     */
+    public function __construct(App $app, StoreBargainServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 砍价列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['start_status', ''],
+            ['status', ''],
+            ['store_name', ''],
+        ]);
+        $where['is_del'] = 0;
+        $list = $this->services->getStoreBargainList($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 保存砍价商品
+     * @param $id
+     * @return mixed
+     */
+    public function save($id)
+    {
+        $data = $this->request->postMore([
+            ['title', ''],
+            ['info', ''],
+            ['unit_name', ''],
+            ['section_time', []],
+            ['images', []],
+            ['bargain_max_price', 0],
+            ['bargain_min_price', 0],
+            ['sort', 0],
+            ['give_integral', 0],
+            ['is_hot', 0],
+            ['status', 0],
+            ['product_id', 0],
+            ['description', ''],
+            ['attrs', []],
+            ['items', []],
+            ['temp_id', 0],
+            ['rule', ''],
+            ['num', 1],
+            ['copy', 0],
+            ['bargain_num', 1],
+            ['people_num', 1],
+            ['logistics', []],//物流方式
+            ['freight', 1],//运费设置
+            ['postage', 0],//邮费
+            ['custom_form', ''],
+            ['virtual_type', 0],
+        ]);
+        $this->validate($data, \app\adminapi\validate\marketing\StoreBargainValidate::class, 'save');
+        if ($data['section_time']) {
+            [$start_time, $end_time] = $data['section_time'];
+            if (strtotime($end_time) < time()) {
+                return app('json')->fail(400507);
+            }
+        }
+        $bragain = [];
+        if ($id) {
+            $bragain = $this->services->get((int)$id);
+            if (!$bragain) {
+                return app('json')->fail(100026);
+            }
+        }
+        //限制编辑
+        if ($data['copy'] == 0 && $bragain) {
+            if ($bragain['stop_time'] < time()) {
+                return app('json')->fail(400508);
+            }
+        }
+        if ($data['copy'] == 1) {
+            $id = 0;
+            unset($data['copy']);
+        }
+        $this->services->saveData($id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 获取详情
+     * @param $id
+     * @return mixed
+     */
+    public function read($id)
+    {
+        $info = $this->services->getInfo($id);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 删除砍价
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        $this->services->update($id, ['is_del' => 1]);
+        /** @var StoreBargainUserServices $bargainUserService */
+        $bargainUserService = app()->make(StoreBargainUserServices::class);
+        $bargainUserService->userBargainStatusFail($id, true);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        /** @var StoreBargainUserServices $bargainUserService */
+        $bargainUserService = app()->make(StoreBargainUserServices::class);
+        $bargainUserService->userBargainStatusFail($id, false);
+        $this->services->update($id, ['status' => $status]);
+        return app('json')->success($status == 0 ? 100001 : 100007);
+    }
+
+    /**
+     * 砍价列表
+     * @return mixed
+     */
+    public function bargainList()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['data', '', '', 'time'],
+        ]);
+        /** @var StoreBargainUserServices $bargainUserService */
+        $bargainUserService = app()->make(StoreBargainUserServices::class);
+        $list = $bargainUserService->bargainUserList($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 砍价信息
+     * @param $id
+     * @return mixed
+     */
+    public function bargainListInfo($id)
+    {
+        /** @var StoreBargainUserHelpServices $bargainUserHelpService */
+        $bargainUserHelpService = app()->make(StoreBargainUserHelpServices::class);
+        $list = $bargainUserHelpService->getHelpList($id);
+        return app('json')->success(compact('list'));
+    }
+
+    /**
+     * 砍价统计
+     * @param $id
+     * @return mixed
+     */
+    public function bargainStatistics($id)
+    {
+        $data = $this->services->bargainStatistics($id);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 砍价列表
+     * @param $id
+     * @return mixed
+     */
+    public function bargainStatisticsList($id)
+    {
+        $where = $this->request->getMore([
+            ['real_name', ''],
+        ]);
+        $data = $this->services->bargainStatisticsList($id, $where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 砍价订单
+     * @param $id
+     * @return mixed
+     */
+    public function bargainStatisticsOrder($id)
+    {
+        $where = $this->request->getMore([
+            ['real_name', ''],
+            ['status', '']
+        ]);
+        return app('json')->success($this->services->bargainStatisticsOrder($id, $where));
+    }
+}

+ 244 - 0
app/adminapi/controller/v1/marketing/StoreCombination.php

@@ -0,0 +1,244 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\combination\StoreCombinationServices;
+use app\services\activity\combination\StorePinkServices;
+use think\facade\App;
+
+/**
+ * 拼团管理
+ * Class StoreCombination
+ * @package app\admin\controller\store
+ */
+class StoreCombination extends AuthController
+{
+    /**
+     * StoreCombination constructor.
+     * @param App $app
+     * @param StoreCombinationServices $services
+     */
+    public function __construct(App $app, StoreCombinationServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 拼团列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['start_status', ''],
+            ['is_show', ''],
+            ['store_name', '']
+        ]);
+        $where['is_del'] = 0;
+        $list = $this->services->systemPage($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 拼团统计
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function statistics()
+    {
+        /** @var StorePinkServices $storePinkServices */
+        $storePinkServices = app()->make(StorePinkServices::class);
+        $info = $storePinkServices->getStatistics();
+        return app('json')->success($info);
+    }
+
+    /**
+     * 详情
+     * @param $id
+     * @return mixed
+     */
+    public function read($id)
+    {
+        $info = $info = $this->services->getInfo((int)$id);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 保存新建的资源
+     * @param int $id
+     */
+    public function save($id = 0)
+    {
+        $data = $this->request->postMore([
+            [['product_id', 'd'], 0],
+            [['title', 's'], ''],
+            [['info', 's'], ''],
+            [['unit_name', 's'], ''],
+            ['images', []],
+            ['section_time', []],
+            [['is_host', 'd'], 0],
+            [['is_show', 'd'], 0],
+            [['num', 'd'], 0],
+            [['temp_id', 'd'], 0],
+            [['effective_time', 'd'], 0],
+            [['people', 'd'], 0],
+            [['description', 's'], ''],
+            ['attrs', []],
+            ['items', []],
+            ['num', 1],
+            ['once_num', 1],
+            ['sort', 0],
+            ['copy', 0],
+            ['virtual', 100],
+            ['logistics', []],//物流方式
+            ['freight', 1],//运费设置
+            ['postage', 0],//邮费
+            ['custom_form', ''],
+            ['virtual_type', 0],
+            ['is_commission', 0],
+            ['head_commission', 0],
+        ]);
+        $this->validate($data, \app\adminapi\validate\marketing\StoreCombinationValidate::class, 'save');
+        if ($data['section_time']) {
+            [$start_time, $end_time] = $data['section_time'];
+            if (strtotime($end_time) < time()) {
+                return app('json')->fail(400507);
+            }
+        }
+        $combination = [];
+        if ($id) {
+            $combination = $this->services->get((int)$id);
+            if (!$combination) {
+                return app('json')->fail(100026);
+            }
+        }
+        //限制编辑
+        if ($data['copy'] == 0 && $combination) {
+            if ($combination['stop_time'] < time()) {
+                return app('json')->fail(400508);
+            }
+        }
+        if ($data['num'] < $data['once_num']) {
+            return app('json')->fail(400500);
+        }
+        if ($data['copy'] == 1) {
+            $id = 0;
+            unset($data['copy']);
+        }
+        $this->services->saveData($id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 删除拼团
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        $this->services->update($id, ['is_del' => 1]);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        $this->services->update($id, ['is_show' => $status]);
+        return app('json')->success($status == 0 ? 100014 : 100015);
+    }
+
+    /**
+     * 拼团列表
+     * @return mixed
+     */
+    public function combine_list()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['data', '', '', 'time'],
+        ]);
+        /** @var StorePinkServices $storePinkServices */
+        $storePinkServices = app()->make(StorePinkServices::class);
+        $list = $storePinkServices->systemPage($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 拼团人列表
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function order_pink($id)
+    {
+        /** @var StorePinkServices $storePinkServices */
+        $storePinkServices = app()->make(StorePinkServices::class);
+        $list = $storePinkServices->getPinkMember($id);
+        return app('json')->success(compact('list'));
+    }
+
+    /**
+     * 拼团统计
+     * @param $id
+     * @return mixed
+     */
+    public function combinationStatistics($id)
+    {
+        $data = $this->services->combinationStatistics($id);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 活动参与人
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function combinationStatisticsList($id)
+    {
+        $where = $this->request->getMore([
+            ['real_name', '', '', 'keyword'],
+            ['status', '']
+        ]);
+        $where['cid'] = $id;
+        /** @var StorePinkServices $storePinkServices */
+        $storePinkServices = app()->make(StorePinkServices::class);
+        $list = $storePinkServices->systemPage($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 拼团订单
+     * @param $id
+     * @return mixed
+     */
+    public function combinationStatisticsOrder($id)
+    {
+        $where = $this->request->getMore([
+            ['real_name', ''],
+            ['status', '']
+        ]);
+        return app('json')->success($this->services->combinationStatisticsOrder($id, $where));
+    }
+}

+ 159 - 0
app/adminapi/controller/v1/marketing/StoreCouponIssue.php

@@ -0,0 +1,159 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\coupon\StoreCouponIssueServices;
+use app\services\product\product\StoreProductCouponServices;
+use app\services\product\product\StoreProductServices;
+use think\facade\App;
+
+/**
+ * 已发布优惠券管理
+ * Class StoreCouponIssue
+ * @package app\adminapi\controller\v1\marketing
+ */
+class StoreCouponIssue extends AuthController
+{
+    public function __construct(App $app, StoreCouponIssueServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取优惠券列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['status', 1],
+            ['coupon_title', ''],
+            ['receive_type', ''],
+            ['type', ''],
+        ]);
+        $list = $this->services->getCouponIssueList($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 添加优惠券
+     * @return mixed
+     */
+    public function saveCoupon()
+    {
+        $data = $this->request->postMore([
+            ['coupon_title', ''],
+            ['coupon_price', 0.00],
+            ['use_min_price', 0.00],
+            ['coupon_time', 0],
+            ['start_use_time', 0],
+            ['end_use_time', 0],
+            ['start_time', 0],
+            ['end_time', 0],
+            ['receive_type', 0],
+            ['is_permanent', 0],
+            ['total_count', 0],
+            ['product_id', ''],
+            ['category_id', []],
+            ['type', 0],
+            ['sort', 0],
+            ['status', 0],
+            ['receive_limit', 1],
+        ]);
+        $res = $this->services->saveCoupon($data);
+        if ($res) return app('json')->success(100000);
+    }
+
+    /**
+     * 修改优惠券状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function status($id, $status)
+    {
+        $this->services->update($id, ['status' => $status]);
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 复制优惠券获取优惠券详情
+     * @param int $id
+     * @return mixed
+     */
+    public function copy($id = 0)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $info = $this->services->get($id);
+        if ($info) $info = $info->toArray();
+        if ($info['product_id'] != '') {
+            $productIds = explode(',', $info['product_id']);
+            /** @var StoreProductServices $product */
+            $product = app()->make(StoreProductServices::class);
+            $productImages = $product->getColumn([['id', 'in', $productIds]], 'image', 'id');
+            foreach ($productIds as $item) {
+                $info['productInfo'][] = [
+                    'product_id' => $item,
+                    'image' => $productImages[$item]
+                ];
+            }
+        }
+        if ($info['category_id'] != '') {
+            $info['category_id'] = explode(',', $info['category_id']);
+            foreach ($info['category_id'] as &$category_id) {
+                $category_id = (int)$category_id;
+            }
+        }
+        return app('json')->success($info);
+    }
+
+    /**
+     * 删除
+     * @param string $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        $this->services->update($id, ['is_del' => 1]);
+        /** @var StoreProductCouponServices $storeProductService */
+        $storeProductService = app()->make(StoreProductCouponServices::class);
+        //删除商品关联这个优惠券
+        $storeProductService->delete(['issue_coupon_id' => $id]);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->createForm($id));
+    }
+
+    /**
+     * 领取记录
+     * @param string $id
+     * @return mixed|string
+     */
+    public function issue_log($id)
+    {
+        $list = $this->services->issueLog($id);
+        return app('json')->success($list);
+    }
+}

+ 75 - 0
app/adminapi/controller/v1/marketing/StoreCouponUser.php

@@ -0,0 +1,75 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\coupon\StoreCouponIssueServices;
+use app\services\activity\coupon\StoreCouponUserServices;
+use think\facade\App;
+
+/**
+ * 优惠券发放记录控制器
+ * Class StoreCategory
+ * @package app\admin\controller\system
+ */
+class StoreCouponUser extends AuthController
+{
+    public function __construct(App $app, StoreCouponUserServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 用户领取记录
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['coupon_title', ''],
+            ['nickname', ''],
+        ]);
+        $list = $this->services->systemPage($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 发放优惠券到指定个人
+     * @return mixed
+     */
+    public function grant()
+    {
+        $data = $this->request->postMore([
+            ['id', 0],
+            ['uid', '']
+        ]);
+        if (!$data['id']) return app('json')->fail(100100);
+        /** @var StoreCouponIssueServices $issueService */
+        $issueService = app()->make(StoreCouponIssueServices::class);
+        $coupon = $issueService->get($data['id']);
+        if (!$coupon) {
+            return app('json')->fail(100026);
+        } else {
+            $coupon = $coupon->toArray();
+        }
+        $user = explode(',', $data['uid']);
+        if (!$issueService->setCoupon($coupon, $user))
+            return app('json')->fail(100031);
+        else
+            return app('json')->success(100030);
+
+    }
+}

+ 176 - 0
app/adminapi/controller/v1/marketing/StoreSeckill.php

@@ -0,0 +1,176 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\seckill\StoreSeckillServices;
+use app\services\product\sku\StoreProductAttrValueServices;
+use crmeb\services\CacheService;
+use think\facade\App;
+
+/**
+ * 限时秒杀  控制器
+ * Class StoreSeckill
+ * @package app\admin\controller\store
+ */
+class StoreSeckill extends AuthController
+{
+    public function __construct(App $app, StoreSeckillServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['start_status', ''],
+            [['status', 's'], ''],
+            [['store_name', 's'], '']
+        ]);
+        return app('json')->success($this->services->systemPage($where));
+    }
+
+    /**
+     * 详情
+     * @param $id
+     * @return mixed
+     */
+    public function read($id)
+    {
+        $info = $this->services->getInfo($id);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 保存秒杀商品
+     * @param int $id
+     */
+    public function save($id)
+    {
+        $data = $this->request->postMore([
+            [['product_id', 'd'], 0],
+            [['title', 's'], ''],
+            [['info', 's'], ''],
+            [['unit_name', 's'], ''],
+            ['images', []],
+            [['give_integral', 'd'], 0],
+            ['section_time', []],
+            [['is_hot', 'd'], 0],
+            [['status', 'd'], 0],
+            [['num', 'd'], 0],
+            [['once_num', 'd'], 0],
+            [['time_id', 'd'], 0],
+            [['temp_id', 'd'], 0],
+            [['sort', 'd'], 0],
+            [['description', 's'], ''],
+            ['attrs', []],
+            ['items', []],
+            ['copy', 0],
+            ['logistics', []],//物流方式
+            ['freight', 1],//运费设置
+            ['postage', 0],//邮费
+            ['custom_form', ''],
+            ['virtual_type', 0],
+        ]);
+        $this->validate($data, \app\adminapi\validate\marketing\StoreSeckillValidate::class, 'save');
+        $this->services->saveData($id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 删除秒杀
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->services->update($id, ['is_del' => 1]);
+        /** @var StoreProductAttrValueServices $storeProductAttrValueServices */
+        $storeProductAttrValueServices = app()->make(StoreProductAttrValueServices::class);
+        $unique = $storeProductAttrValueServices->value(['product_id' => $id, 'type' => 1], 'unique');
+        if ($unique) {
+            CacheService::delete('seckill_' . $unique . '_1');
+        }
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        $this->services->update($id, ['status' => $status]);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 秒杀时间段列表
+     * @return mixed
+     */
+    public function time_list()
+    {
+        $list['data'] = sys_data('routine_seckill_time');
+        return app('json')->success(compact('list'));
+    }
+
+    /**
+     * 秒杀统计
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function seckillStatistics($id)
+    {
+        $data = $this->services->seckillStatistics($id);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 秒杀参与人统计
+     * @param $id
+     * @return mixed
+     */
+    public function seckillPeople($id)
+    {
+        [$keyword] = $this->request->getMore([
+            ['real_name', '', '', 'keyword']
+        ], true);
+        return app('json')->success($this->services->seckillPeople($id, $keyword));
+    }
+
+    /**
+     * 秒杀订单统计
+     * @param $id
+     * @return mixed
+     */
+    public function seckillOrder($id)
+    {
+        $where = $this->request->getMore([
+            ['real_name', ''],
+            ['status', '']
+        ]);
+        return app('json')->success($this->services->seckillOrder($id, $where));
+    }
+}

+ 66 - 0
app/adminapi/controller/v1/marketing/UserPoint.php

@@ -0,0 +1,66 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing;
+
+use app\adminapi\controller\AuthController;
+use app\services\user\UserBillServices;
+use think\facade\App;
+
+/**
+ * 积分控制器
+ * Class StoreCategory
+ * @package app\admin\controller\system
+ */
+class UserPoint extends AuthController
+{
+
+    /**
+     * Finance constructor.
+     * @param App $app
+     * @param UserBillServices $services
+     */
+    public function __construct(App $app, UserBillServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 积分记录列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['start_time', ''],
+            ['end_time', ''],
+            ['nickname', ''],
+            ['page', 1],
+            ['limit', 10],
+        ]);
+        return app('json')->success($this->services->getPointList($where));
+    }
+
+    /**
+     * 获取积分日志头部信息
+     * @return mixed
+     */
+    public function integral_statistics()
+    {
+        $where = $this->request->getMore([
+            ['start_time', ''],
+            ['end_time', ''],
+            ['nickname', ''],
+        ]);
+        return app('json')->success(['res' => $this->services->getUserPointBadgelist($where)]);
+    }
+
+}

+ 138 - 0
app/adminapi/controller/v1/marketing/integral/StoreIntegral.php

@@ -0,0 +1,138 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing\integral;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\integral\StoreIntegralServices;
+use think\facade\App;
+
+/**
+ * 积分商城管理
+ * Class StoreCombination
+ * @package app\admin\controller\store
+ */
+class StoreIntegral extends AuthController
+{
+    /**
+     * StoreIntegral constructor.
+     * @param App $app
+     * @param StoreIntegralServices $services
+     */
+    public function __construct(App $app, StoreIntegralServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 积分商品列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['integral_time', ''],
+            ['is_show', ''],
+            ['store_name', '']
+        ]);
+        $where['is_del'] = 0;
+        $list = $this->services->systemPage($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 保存商品
+     * @param int $id
+     */
+    public function save($id = 0)
+    {
+        $data = $this->request->postMore([
+            [['product_id', 'd'], 0],
+            [['title', 's'], ''],
+            [['unit_name', 's'], ''],
+            ['image', ''],
+            ['images', []],
+            [['num', 'd'], 0],
+            [['is_host', 'd'], 0],
+            [['is_show', 'd'], 0],
+            [['once_num', 'd'], 0],
+            [['sort', 'd'], 0],
+            [['description', 's'], ''],
+            ['attrs', []],
+            ['items', []],
+            ['copy', 0]
+        ]);
+        $this->validate($data, \app\adminapi\validate\marketing\StoreIntegralValidate::class, 'save');
+        if ($id) {
+            $integral = $this->services->get((int)$id);
+            if (!$integral) {
+                return app('json')->fail(100026);
+            }
+        }
+        if ($data['copy'] == 1) {
+            $id = 0;
+            unset($data['copy']);
+        }
+        $this->services->saveData($id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 批量添加商品
+     * @return mixed
+     */
+    public function batch_add()
+    {
+        $data = $this->request->postMore([
+            ['attrs', []],
+            [['is_show', 'd'], 0]
+        ]);
+        $this->services->saveBatchData($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 详情
+     * @param $id
+     * @return mixed
+     */
+    public function read($id)
+    {
+        $info = $this->services->getInfo($id);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_show($id, $is_show)
+    {
+        $this->services->update($id, ['is_show' => $is_show]);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 删除指定资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->services->update($id, ['is_del' => 1]);
+        return app('json')->success(100002);
+    }
+
+}

+ 349 - 0
app/adminapi/controller/v1/marketing/integral/StoreIntegralOrder.php

@@ -0,0 +1,349 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing\integral;
+
+use app\adminapi\controller\AuthController;
+use app\services\serve\ServeServices;
+use app\services\activity\integral\{
+    StoreIntegralOrderServices,
+    StoreIntegralOrderStatusServices
+};
+use app\services\order\StoreOrderDeliveryServices;
+use app\services\shipping\ExpressServices;
+use app\services\user\UserServices;
+use think\facade\App;
+
+/**
+ * 订单管理
+ * Class StoreOrder
+ * @package app\controller\admin\v1\order
+ */
+class StoreIntegralOrder extends AuthController
+{
+    /**
+     * StoreIntegralOrder constructor.
+     * @param App $app
+     * @param StoreIntegralOrderServices $service
+     * @method temp
+     */
+    public function __construct(App $app, StoreIntegralOrderServices $service)
+    {
+        parent::__construct($app);
+        $this->services = $service;
+    }
+
+    /**
+     * 获取订单类型数量
+     * @return mixed
+     */
+    public function chart()
+    {
+        $where = $this->request->getMore([
+            ['data', '', '', 'time'],
+            ['product_id', '']
+        ]);
+        $data = $this->services->orderCount($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 获取订单列表
+     * @return mixed
+     */
+    public function lst()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['real_name', ''],
+            ['data', '', '', 'time'],
+            ['order', ''],
+            ['field_key', ''],
+            ['product_id', '']
+        ]);
+        $where['is_system_del'] = 0;
+        return app('json')->success($this->services->getOrderList($where, ['*']));
+    }
+
+    /**
+     * 获取快递公司
+     * @return mixed
+     */
+    public function express(ExpressServices $services)
+    {
+        [$status] = $this->request->getMore([
+            ['status', ''],
+        ], true);
+        if ($status != '') $data['status'] = $status;
+        $data['is_show'] = 1;
+        return app('json')->success($services->express($data));
+    }
+
+    /**
+     * 批量删除用户已经删除的订单
+     * @return mixed
+     */
+    public function del_orders()
+    {
+        [$ids, $all, $where] = $this->request->postMore([
+            ['ids', []],
+            ['where', []],
+        ], true);
+        if ($this->services->delOrders($ids)) {
+            return app('json')->success(100002);
+        } else {
+            return app('json')->fail(100008);
+        }
+    }
+
+    /**
+     * 删除订单
+     * @param $id
+     * @return mixed
+     */
+    public function del($id)
+    {
+        if ($this->services->delOrder($id)) {
+            return app('json')->success(100002);
+        } else {
+            return app('json')->fail(100008);
+        }
+    }
+
+    /**
+     * 订单发送货
+     * @param $id
+     * @return mixed
+     */
+    public function update_delivery($id)
+    {
+        $data = $this->request->postMore([
+            ['type', 1],
+            ['delivery_name', ''],//快递公司名称
+            ['delivery_id', ''],//快递单号
+            ['delivery_code', ''],//快递公司编码
+
+            ['express_record_type', 2],//发货记录类型
+            ['express_temp_id', ""],//电子面单模板
+            ['to_name', ''],//寄件人姓名
+            ['to_tel', ''],//寄件人电话
+            ['to_addr', ''],//寄件人地址
+
+            ['sh_delivery_name', ''],//送货人姓名
+            ['sh_delivery_id', ''],//送货人电话
+            ['sh_delivery_uid', ''],//送货人ID
+
+            ['fictitious_content', '']//虚拟发货内容
+        ]);
+        $this->services->delivery((int)$id, $data);
+        return app('json')->success(100010);
+    }
+
+    /**
+     * 确认收货
+     * @param $id
+     * @return mixed
+     */
+    public function take_delivery($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $order = $this->services->get($id);
+        if (!$order)
+            return app('json')->fail(100026);
+        if ($order['status'] == 3)
+            return app('json')->fail(400114);
+        if ($order['status'] == 2)
+            $data['status'] = 3;
+        else
+            return app('json')->fail(400115);
+
+        if (!$this->services->update($id, $data)) {
+            return app('json')->fail(400116);
+        } else {
+            //增加收货订单状态
+            /** @var StoreIntegralOrderStatusServices $statusService */
+            $statusService = app()->make(StoreIntegralOrderStatusServices::class);
+            $statusService->save([
+                'oid' => $order['id'],
+                'change_type' => 'take_delivery',
+                'change_message' => '已收货',
+                'change_time' => time()
+            ]);
+            return app('json')->success(400117);
+        }
+    }
+
+    /**
+     * 订单详情
+     * @param $id 订单id
+     * @return mixed
+     */
+    public function order_info($id)
+    {
+        if (!$id || !($orderInfo = $this->services->get($id))) {
+            return app('json')->fail(400118);
+        }
+        /** @var UserServices $services */
+        $services = app()->make(UserServices::class);
+        $userInfo = $services->get($orderInfo['uid']);
+        if (!$userInfo) return app('json')->fail(400119);
+        $userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
+        $orderInfo = $this->services->tidyOrder($orderInfo->toArray());
+        $userInfo = $userInfo->toArray();
+        return app('json')->success(compact('orderInfo', 'userInfo'));
+    }
+
+    /**
+     * 查询物流信息
+     * @param $id 订单id
+     * @return mixed
+     */
+    public function get_express($id, ExpressServices $services)
+    {
+        if (!$id || !($orderInfo = $this->services->get($id)))
+            return app('json')->fail(400118);
+        if ($orderInfo['delivery_type'] != 'express' || !$orderInfo['delivery_id'])
+            return app('json')->fail(400120);
+
+        $cacheName = 'integral' . $orderInfo['order_id'] . $orderInfo['delivery_id'];
+
+        $data['delivery_name'] = $orderInfo['delivery_name'];
+        $data['delivery_id'] = $orderInfo['delivery_id'];
+        $data['result'] = $services->query($cacheName, $orderInfo['delivery_id'], $orderInfo['delivery_code'] ?? null, $orderInfo['user_phone']);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 获取修改配送信息表单结构
+     * @param $id 订单id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function distribution($id)
+    {
+        if (!$id) {
+            return app('json')->fail(400118);
+        }
+        return app('json')->success($this->services->distributionForm((int)$id));
+    }
+
+    /**
+     * 修改配送信息
+     * @param $id  订单id
+     * @return mixed
+     */
+    public function update_distribution($id)
+    {
+        $data = $this->request->postMore([['delivery_name', ''], ['delivery_code', ''], ['delivery_id', '']]);
+        if (!$id) return app('json')->fail(100100);
+        $this->services->updateDistribution($id, $data);
+        return app('json')->success(100001);
+    }
+
+
+    /**
+     * 修改备注
+     * @param $id
+     * @return mixed
+     */
+    public function remark($id)
+    {
+        $data = $this->request->postMore([['remark', '']]);
+        if ($this->services->remark($id, $data['remark'])) {
+            return app('json')->success(100024);
+        } else {
+            return app('json')->fail(100025);
+        }
+    }
+
+    /**
+     * 获取订单状态列表并分页
+     * @param $id
+     * @return mixed
+     */
+    public function status(StoreIntegralOrderStatusServices $services, $id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($services->getStatusList(['oid' => $id])['list']);
+    }
+
+    /**
+     * 易联云打印机打印
+     * @param $id
+     * @return mixed
+     */
+    public function order_print($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $order = $this->services->get($id);
+        if (!$order) {
+            return app('json')->fail(400118);
+        }
+        $res = $this->services->orderPrint($order);
+        if ($res) {
+            return app('json')->success(400121);
+        } else {
+            return app('json')->fail(400122);
+        }
+    }
+
+    /**
+     * 电子面单模板
+     * @param $com
+     * @return mixed
+     */
+    public function expr_temp(ServeServices $services, $com)
+    {
+        if (!$com) {
+            return app('json')->fail(400123);
+        }
+        $list = $services->express()->temp($com);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 获取模板
+     */
+    public function express_temp(ServeServices $services)
+    {
+        $data = $this->request->getMore([['com', '']]);
+        $tpd = $services->express()->temp($data['com']);
+        return app('json')->success($tpd['data']);
+    }
+
+    /**
+     * 订单发货后打印电子面单
+     * @param $order_id
+     * @param StoreOrderDeliveryServices $storeOrderDeliveryServices
+     * @return mixed
+     */
+    public function order_dump($order_id, StoreOrderDeliveryServices $storeOrderDeliveryServices)
+    {
+        return app('json')->success($storeOrderDeliveryServices->orderDump($order_id));
+
+    }
+
+    /**
+     * 获取配置信息
+     * @return mixed
+     */
+    public function getDeliveryInfo()
+    {
+        return app('json')->success([
+            'express_temp_id' => sys_config('config_export_temp_id'),
+            'id' => sys_config('config_export_id'),
+            'to_name' => sys_config('config_export_to_name'),
+            'to_tel' => sys_config('config_export_to_tel'),
+            'to_add' => sys_config('config_export_to_address'),
+            'export_open' => (bool)((int)sys_config('config_export_open'))
+        ]);
+    }
+
+}

+ 110 - 0
app/adminapi/controller/v1/marketing/integral/StorePointRecord.php

@@ -0,0 +1,110 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing\integral;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\integral\StorePointRecordServices;
+use think\facade\App;
+
+/**
+ * 积分记录
+ */
+class StorePointRecord extends AuthController
+{
+    /**
+     * @param App $app
+     * @param StorePointRecordServices $services
+     */
+    public function __construct(App $app, StorePointRecordServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 积分记录
+     * @return mixed
+     */
+    public function pointRecord()
+    {
+        $where = $this->request->getMore([
+            ['time', ''],
+            ['trading_type', '']
+        ]);
+        $date = $this->services->pointRecord($where);
+        return app('json')->success($date);
+    }
+
+    /**
+     * 积分记录备注
+     * @return mixed
+     */
+    public function pointRecordRemark($id = 0)
+    {
+        [$mark] = $this->request->postMore([
+            ['mark', '']
+        ], true);
+        $this->services->recordRemark($id, $mark);
+        return app('json')->success(100024);
+    }
+
+    /**
+     * 积分统计基础信息
+     * @return mixed
+     */
+    public function getBasic()
+    {
+        $where = $this->request->getMore([
+            ['time', '']
+        ]);
+        $data = $this->services->getBasic($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 积分统计趋势图
+     * @return mixed
+     */
+    public function getTrend()
+    {
+        $where = $this->request->getMore([
+            ['time', '']
+        ]);
+        $data = $this->services->getTrend($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 积分来源
+     * @return mixed
+     */
+    public function getChannel()
+    {
+        $where = $this->request->getMore([
+            ['time', '']
+        ]);
+        $data = $this->services->getChannel($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 积分消耗
+     * @return mixed
+     */
+    public function getType()
+    {
+        $where = $this->request->getMore([
+            ['time', '']
+        ]);
+        $data = $this->services->getType($where);
+        return app('json')->success($data);
+    }
+}

+ 118 - 0
app/adminapi/controller/v1/marketing/live/LiveAnchor.php

@@ -0,0 +1,118 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing\live;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\live\LiveAnchorServices;
+use think\facade\App;
+
+/**
+ * 直播间主播
+ * Class LiveAnchor
+ * @package app\controller\admin\store
+ */
+class LiveAnchor extends AuthController
+{
+    /**
+     * LiveAnchor constructor.
+     * @param App $app
+     * @param LiveAnchorServices $services
+     */
+    public function __construct(App $app, LiveAnchorServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 列表
+     * @return mixed
+     */
+    public function list()
+    {
+        $where = $this->request->postMore([
+            ['kerword', ''],
+        ]);
+        return app('json')->success($this->services->getList($where));
+    }
+
+    /**
+     * 添加修改表单
+     * @return mixed
+     */
+    public function add()
+    {
+        list($id) = $this->request->getMore([
+            ['id', 0],
+        ], true);
+        return app('json')->success($this->services->add((int)$id));
+    }
+
+    /**
+     * 保存标签表单数据
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['id', 0],
+            ['name', ''],
+            ['wechat', ''],
+            ['phone', ''],
+            ['cover_img', '']
+        ]);
+        $this->validate($data, \app\adminapi\validate\marketing\LiveAnchorValidate::class, 'save');
+        $res = $this->services->save((int)$data['id'], $data);
+        if ($res === true) {
+            return app('json')->success(100000, ['auth' => false]);
+        }else{
+            return app('json')->fail(100006);
+        }
+    }
+
+    /**
+     * 删除
+     * @return mixed
+     * @throws \Exception
+     */
+    public function delete()
+    {
+        list($id) = $this->request->getMore([
+            ['id', 0],
+        ], true);
+        if (!$id) return app('json')->fail(100100);
+        $this->services->delAnchor((int)$id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 设置会员等级显示|隐藏
+     * @param string $id
+     * @param string $is_show
+     * @return mixed
+     */
+    public function setShow($id = '', $is_show = '')
+    {
+        if ($is_show == '' || $id == '') return app('json')->fail(100100);
+        $this->services->setShow((int)$id, (int)$is_show);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 同步主播
+     * @return mixed
+     */
+    public function syncAnchor()
+    {
+        $this->services->syncAnchor();
+        return app('json')->success(100038);
+    }
+}

+ 161 - 0
app/adminapi/controller/v1/marketing/live/LiveGoods.php

@@ -0,0 +1,161 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing\live;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\live\LiveGoodsServices;
+use think\facade\App;
+
+/**
+ * 直播间商品
+ * Class LiveGoods
+ * @package app\controller\admin\store
+ */
+class LiveGoods extends AuthController
+{
+    /**
+     * LiveGoods constructor.
+     * @param App $app
+     * @param LiveGoodsServices $services
+     */
+    public function __construct(App $app, LiveGoodsServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 直播间商品列表
+     * @return mixed
+     */
+    public function list()
+    {
+        $where = $this->request->postMore([
+            ['kerword', ''],
+            ['status', ''],
+            ['is_show', ''],
+            ['live_id', 0]
+        ]);
+        return app('json')->success($this->services->getList($where));
+    }
+
+    /**
+     * 生成直播商品
+     * @return mixed
+     */
+    public function create()
+    {
+        [$product_ids] = $this->request->postMore([
+            ['product_id', []]
+        ], true);
+        return app('json')->success($this->services->create($product_ids));
+    }
+
+    /**
+     * 上传直播商品
+     * @return mixed
+     * @throws \EasyWeChat\Core\Exceptions\InvalidArgumentException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function add()
+    {
+        [$goods_info] = $this->request->postMore([
+            ['goods_info', []]
+        ], true);
+        foreach ($goods_info as $goods) {
+            $this->validate($goods, \app\adminapi\validate\marketing\LiveGoodsValidate::class, 'save');
+        }
+        $this->services->add($goods_info);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 商品详情
+     * @param $id
+     * @return mixed
+     */
+    public function detail($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $goods = $this->services->get($id, ['*'], ['product']);
+        return app('json')->success($goods ? $goods->toArray() : []);
+    }
+
+    /**
+     * 同步直播商品
+     * @return mixed
+     */
+    public function syncGoods()
+    {
+        $this->services->syncGoodStatus();
+        return app('json')->success(100038);
+    }
+
+    /**
+     * 重新提交审核
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function audit($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->services->audit((int)$id);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 撤回审核
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function resetAudit($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->services->resetAudit((int)$id);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 设置状态
+     * @param int $id
+     * @param $is_show
+     * @return mixed
+     */
+    public function setShow(int $id, $is_show)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($this->services->isShow($id, $is_show));
+    }
+
+    /**
+     * 删除商品
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $this->services->delete($id);
+        return app('json')->success(100002);
+    }
+
+}

+ 154 - 0
app/adminapi/controller/v1/marketing/live/LiveRoom.php

@@ -0,0 +1,154 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\marketing\live;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\live\LiveRoomServices;
+use think\facade\App;
+
+/**
+ * 直播间
+ * Class LiveRoom
+ * @package app\adminapi\controller\v1\marketing\live
+ */
+class LiveRoom extends AuthController
+{
+    /**
+     * LiveRoom constructor.
+     * @param App $app
+     * @param LiveRoomServices $services
+     */
+    public function __construct(App $app, LiveRoomServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 直播间列表
+     * @return mixed
+     */
+    public function list()
+    {
+        $where = $this->request->postMore([
+            ['kerword', ''],
+            ['status', '']
+        ]);
+        return app('json')->success($this->services->getList($where));
+    }
+
+    /**
+     * 直播间详情
+     * @param $id
+     * @return mixed
+     */
+    public function detail($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($this->services->get((int)$id)->toArray());
+    }
+
+    /**
+     * 添加直播间
+     * @return mixed
+     */
+    public function add()
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['cover_img', ''],
+            ['share_img', ''],
+            ['anchor_name', ''],
+            ['anchor_wechat', ''],
+            ['phone', ''],
+            ['start_time', ['', '']],
+            ['type', 1],
+            ['screen_type', 1],
+            ['close_like', 0],
+            ['close_goods', 0],
+            ['close_comment', 0],
+            ['replay_status', 1],
+            ['sort', 0]
+        ]);
+        if (mb_strlen($data['name']) < 6 || mb_strlen($data['name']) > 17) {
+            return app('json')->fail(500030);
+        }
+        $this->validate($data, \app\adminapi\validate\marketing\LiveRoomValidate::class, 'save');
+        $this->services->add($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 添加直播间商品
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function addGoods()
+    {
+        [$room_id, $goods_ids] = $this->request->postMore([
+            ['room_id', 0],
+            ['goods_ids', []]
+        ], true);
+        $this->services->exportGoods((int)$room_id, $goods_ids);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 提交审核
+     * @param $id
+     * @return mixed
+     */
+    public function apply($id)
+    {
+        [$status, $msg] = $this->request->postMore([
+            ['status', ''],
+            ['msg', '']
+        ], true);
+        $this->services->apply((int)$id, $status, $msg);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 设置状态
+     * @param $id
+     * @param $is_show
+     * @return mixed
+     */
+    public function setShow($id, $is_show)
+    {
+        $this->services->isShow((int)$id, $is_show);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 删除直播间
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        $this->services->delete($id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 同步直播间
+     * @return mixed
+     */
+    public function syncRoom()
+    {
+        $this->services->syncRoomStatus();
+        return app('json')->success(100038);
+    }
+
+}

+ 225 - 0
app/adminapi/controller/v1/marketing/lottery/LuckLottery.php

@@ -0,0 +1,225 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+declare (strict_types=1);
+
+namespace app\adminapi\controller\v1\marketing\lottery;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\lottery\LuckLotteryServices;
+use think\facade\App;
+
+/**
+ * 抽奖活动
+ * Class LuckLottery
+ * @package app\controller\admin\v1\marketing\lottery
+ */
+class LuckLottery extends AuthController
+{
+
+    /**
+     * LuckLottery constructor.
+     * @param App $app
+     * @param LuckLotteryServices $services
+     */
+    public function __construct(App $app, LuckLotteryServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 抽奖列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->postMore([
+            ['start_status', '', '', 'start'],
+            ['status', ''],
+            ['factor', ''],
+            ['store_name', '', '', 'keyword'],
+        ]);
+        return app('json')->success($this->services->getList($where));
+    }
+
+    /**
+     * 抽奖活动详情
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function detail($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($this->services->getlotteryInfo((int)$id));
+    }
+
+    /**
+     * 根据类型获取详情
+     * @param $factor
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function factorInfo($factor)
+    {
+        if (!$factor) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($this->services->getlotteryFactorInfo((int)$factor));
+    }
+
+    /**
+     * 添加抽奖
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function add()
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['desc', ''],
+            ['image', ''],
+            ['factor', 1],
+            ['factor_num', 1],
+            ['attends_user', 1],
+            ['user_level', []],
+            ['user_label', []],
+            ['is_svip', 0],
+            ['period', [0, 0]],
+            ['lottery_num_term', 1],
+            ['lottery_num', 1],
+            ['spread_num', 1],
+            ['is_all_record', 1],
+            ['is_personal_record', 1],
+            ['is_content', 1],
+            ['content', ''],
+            ['status', 1],
+            ['prize', []]
+        ]);
+        if (!$data['name']) {
+            return app('json')->fail(400501);
+        }
+        if ($data['is_content'] && !$data['content']) {
+            return app('json')->fail(400502);
+        }
+        [$start, $end] = $data['period'];
+        unset($data['period']);
+        $data['start_time'] = $start ? strtotime($start) : 0;
+        $data['end_time'] = $end ? strtotime($end) : 0;
+        if ($data['start_time'] && $data['end_time'] && $data['end_time'] <= $data['start_time']) {
+            return app('json')->fail(400503);
+        }
+        if (!$data['prize']) {
+            return app('json')->fail(400504);
+        }
+        if (in_array($data['factor'], [1, 2]) && !$data['factor_num']) {
+            return app('json')->fail(400505);
+        }
+        return app('json')->success($this->services->add($data) ? 100000 : 100006);
+    }
+
+    /**
+     * 修改抽奖
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function edit($id)
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['desc', ''],
+            ['image', ''],
+            ['factor', 1],
+            ['factor_num', 1],
+            ['attends_user', 1],
+            ['user_level', []],
+            ['user_label', []],
+            ['is_svip', 0],
+            ['period', [0, 0]],
+            ['lottery_num_term', 1],
+            ['lottery_num', 1],
+            ['spread_num', 1],
+            ['is_all_record', 1],
+            ['is_personal_record', 1],
+            ['is_content', 1],
+            ['content', ''],
+            ['status', 1],
+            ['prize', []]
+        ]);
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        if (!$data['name']) {
+            return app('json')->fail(400501);
+        }
+        [$start, $end] = $data['period'];
+        unset($data['period']);
+        $data['start_time'] = $start ? strtotime($start) : 0;
+        $data['end_time'] = $end ? strtotime($end) : 0;
+        if ($data['start_time'] && $data['end_time'] && $data['end_time'] <= $data['start_time']) {
+            return app('json')->fail(400503);
+        }
+        if ($data['is_content'] && !$data['content']) {
+            return app('json')->fail(400502);
+        }
+        if (!$data['prize']) {
+            return app('json')->fail(400504);
+        }
+        if (in_array($data['factor'], [1, 2]) && !$data['factor_num']) {
+            return app('json')->fail(400505);
+        }
+        return app('json')->success($this->services->edit((int)$id, $data) ? 100001 : 100007);
+    }
+
+    /**
+     * 删除抽奖
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function delete()
+    {
+        list($id) = $this->request->getMore([
+            ['id', 0],
+        ], true);
+        if (!$id) return app('json')->fail(100026);
+        $this->services->delLottery((int)$id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 设置活动状态
+     * @param string $id
+     * @param string $status
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function setStatus($id = '', $status = '')
+    {
+        if ($status == '' || $id == '') return app('json')->fail(100100);
+        $this->services->setStatus((int)$id, (int)$status);
+        return app('json')->success(100014);
+    }
+}

+ 76 - 0
app/adminapi/controller/v1/marketing/lottery/LuckLotteryRecord.php

@@ -0,0 +1,76 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+declare (strict_types=1);
+
+namespace app\adminapi\controller\v1\marketing\lottery;
+
+use app\adminapi\controller\AuthController;
+use app\services\activity\lottery\LuckLotteryRecordServices;
+use think\facade\App;
+
+/**
+ * 抽奖中奖记录
+ * Class LuckLotteryRecord
+ * @package app\controller\admin\v1\marketing\lottery
+ */
+class LuckLotteryRecord extends AuthController
+{
+
+    /**
+     * LuckLotteryRecord constructor.
+     * @param App $app
+     * @param LuckLotteryRecordServices $services
+     */
+    public function __construct(App $app, LuckLotteryRecordServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 抽奖记录列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->postMore([
+            ['is_receive', ''],
+            ['is_deliver', ''],
+            ['type', ''],
+            ['keyword', ''],
+            ['data', '', '', 'time'],
+            ['factor', ''],
+        ]);
+        return app('json')->success($this->services->getList($where));
+    }
+
+    /**
+     * 中奖发货
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function deliver($id)
+    {
+        $data = $this->request->postMore([
+            ['deliver_name', ''],
+            ['deliver_number', ''],
+            ['mark', ''],
+        ]);
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        $this->services->setDeliver((int)$id, $data);
+        return app('json')->success($this->services->setDeliver((int)$id, $data) ? 100014 : 100015);
+    }
+}

+ 170 - 0
app/adminapi/controller/v1/merchant/SystemStore.php

@@ -0,0 +1,170 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\merchant;
+
+use think\facade\App;
+use app\adminapi\controller\AuthController;
+use app\services\system\store\SystemStoreServices;
+
+/**
+ * 门店管理控制器
+ * Class SystemAttachment
+ * @package app\admin\controller\system
+ *
+ */
+class SystemStore extends AuthController
+{
+    /**
+     * 构造方法
+     * SystemStore constructor.
+     * @param App $app
+     * @param SystemStoreServices $services
+     */
+    public function __construct(App $app, SystemStoreServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 门店列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            [['keywords', 's'], ''],
+            [['type', 'd'], 0]
+        ]);
+        return app('json')->success($this->services->getStoreList($where));
+    }
+
+    /**
+     * 获取门店头部
+     * @return mixed
+     */
+    public function get_header()
+    {
+        $count = $this->services->getStoreData();
+        return app('json')->success(compact('count'));
+    }
+
+    /**
+     * 门店设置
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function get_info()
+    {
+        [$id] = $this->request->getMore([
+            [['id', 'd'], 0],
+        ], true);
+        $info = $this->services->getStoreDispose($id);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 位置选择
+     * @return mixed
+     */
+    public function select_address()
+    {
+        $key = sys_config('tengxun_map_key');
+        if (!$key) return app('json')->fail(400124);
+        return app('json')->success(compact('key'));
+    }
+
+    /**
+     * 设置单个门店是否显示
+     * @param string $is_show
+     * @param string $id
+     * @return mixed
+     */
+    public function set_show($is_show = '', $id = '')
+    {
+        ($is_show == '' || $id == '') && app('json')->fail(100100);
+        $res = $this->services->update((int)$id, ['is_show' => (int)$is_show]);
+        if ($res) {
+            return app('json')->success(100014);
+        } else {
+            return app('json')->fail(100015);
+        }
+    }
+
+    /**
+     * 保存修改门店信息
+     * @param int $id
+     * @return mixed
+     */
+    public function save($id = 0)
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['introduction', ''],
+            ['image', ''],
+            ['oblong_image', ''],
+            ['phone', ''],
+            ['address', ''],
+            ['detailed_address', ''],
+            ['latlng', ''],
+            ['day_time', []],
+        ]);
+        $this->validate($data, \app\adminapi\validate\merchant\SystemStoreValidate::class, 'save');
+
+        $data['address'] = implode(',', $data['address']);
+        $data['latlng'] = explode(',', $data['latlng']);
+        if (!isset($data['latlng'][0]) || !isset($data['latlng'][1])) {
+            return app('json')->fail(400125);
+        }
+        $data['latitude'] = $data['latlng'][0];
+        $data['longitude'] = $data['latlng'][1];
+        $data['day_time'] = implode(' - ', $data['day_time']);
+        unset($data['latlng']);
+        if ($data['image'] && strstr($data['image'], 'http') === false) {
+            $site_url = sys_config('site_url');
+            $data['image'] = $site_url . $data['image'];
+        }
+        $this->services->saveStore((int)$id, $data);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 删除恢复门店
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $storeInfo = $this->services->get($id);
+        if (!$storeInfo) {
+            return app('json')->fail(100026);
+        }
+        if ($storeInfo->is_del == 1) {
+            $storeInfo->is_del = 0;
+            if (!$storeInfo->save())
+                return app('json')->fail(100041);
+            else
+                return app('json')->success(100040);
+        } else {
+            $storeInfo->is_del = 1;
+            if (!$storeInfo->save())
+                return app('json')->fail(100008);
+            else
+                return app('json')->success(100002);
+        }
+    }
+}

+ 186 - 0
app/adminapi/controller/v1/merchant/SystemStoreStaff.php

@@ -0,0 +1,186 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\merchant;
+
+use app\services\system\store\SystemStoreServices;
+use app\services\system\store\SystemStoreStaffServices;
+use think\facade\App;
+use app\adminapi\controller\AuthController;
+
+/**
+ * 店员
+ * Class SystemStoreStaff
+ * @package app\adminapi\controller\v1\merchant
+ */
+class SystemStoreStaff extends AuthController
+{
+    /**
+     * 构造方法
+     * SystemStoreStaff constructor.
+     * @param App $app
+     * @param SystemStoreStaffServices $services
+     */
+    public function __construct(App $app, SystemStoreStaffServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取店员列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            [['store_id', 'd'], 0],
+        ]);
+        return app('json')->success($this->services->getStoreStaffList($where));
+    }
+
+    /**
+     * 门店列表
+     * @param SystemStoreServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function store_list(SystemStoreServices $services)
+    {
+        return app('json')->success($services->getStore());
+    }
+
+    /**
+     * 店员新增表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->createForm());
+    }
+
+    /**
+     * 店员修改表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function edit()
+    {
+        [$id] = $this->request->getMore([
+            [['id', 'd'], 0],
+        ], true);
+        return app('json')->success($this->services->updateForm($id));
+    }
+
+    /**
+     * 保存店员信息
+     * @param int $id
+     * @return mixed
+     */
+    public function save($id = 0)
+    {
+        $data = $this->request->postMore([
+            ['image', ''],
+            ['uid', 0],
+            ['avatar', ''],
+            ['store_id', ''],
+            ['staff_name', ''],
+            ['phone', ''],
+            ['verify_status', 1],
+            ['status', 1],
+        ]);
+        if (!$id) {
+            if ($data['image'] == '') {
+                return app('json')->fail(400250);
+            }
+            if ($this->services->count(['uid' => $data['image']['uid']])) {
+                return app('json')->fail(400126);
+            }
+            $data['uid'] = $data['image']['uid'];
+            $data['avatar'] = $data['image']['image'];
+        } else {
+            $data['avatar'] = $data['image'];
+        }
+        if ($data['uid'] == 0) {
+            return app('json')->fail(400250);
+        }
+        if ($data['store_id'] == '') {
+            return app('json')->fail(400127);
+        }
+        if ($data['staff_name'] == ''){
+            return app('json')->fail(400128);
+        }
+        if ($data['phone'] == ''){
+            return app('json')->fail(400129);
+        }
+        unset($data['image']);
+        if ($id) {
+            $res = $this->services->update($id, $data);
+            if ($res) {
+                return app('json')->success(100001);
+            } else {
+                return app('json')->fail(100007);
+            }
+        } else {
+            $data['add_time'] = time();
+            $res = $this->services->save($data);
+            if ($res) {
+                return app('json')->success(400130);
+            } else {
+                return app('json')->fail(400131);
+            }
+        }
+    }
+
+    /**
+     * 设置单个店员是否开启
+     * @param string $is_show
+     * @param string $id
+     * @return mixed
+     */
+    public function set_show($is_show = '', $id = '')
+    {
+        if ($is_show == '' || $id == '') {
+            app('json')->fail(100100);
+        }
+        $res = $this->services->update($id, ['status' => (int)$is_show]);
+        if ($res) {
+            return app('json')->success(100014);
+        } else {
+            return app('json')->fail(100015);
+        }
+    }
+
+    /**
+     * 删除店员
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        if (!$this->services->delete($id))
+            return app('json')->fail(100008);
+        else
+            return app('json')->success(100002);
+    }
+}

+ 85 - 0
app/adminapi/controller/v1/merchant/SystemVerifyOrder.php

@@ -0,0 +1,85 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\merchant;
+
+use app\adminapi\controller\AuthController;
+use app\services\order\StoreOrderServices;
+use app\services\user\UserServices;
+use think\facade\App;
+
+/**
+ * 核销订单
+ * Class SystemVerifyOrder
+ * @package app\adminapi\controller\v1\merchant
+ */
+class SystemVerifyOrder extends AuthController
+{
+    /**
+     * 构造方法
+     * SystemVerifyOrder constructor.
+     * @param App $app
+     * @param StoreOrderServices $services
+     */
+    public function __construct(App $app, StoreOrderServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取核销订单列表
+     * return json
+     */
+    public function list()
+    {
+        $where = $this->request->getMore([
+            ['data', '', '', 'time'],
+            ['real_name', ''],
+            ['store_id', ''],
+            ['type', ''],
+            ['field_key', ''],
+        ]);
+        $data = $this->services->getOrderList($where + ['status' => 6], ['*'], ['store', 'staff']);
+        return app('json')->success(['count' => $data['count'], 'data' => $data['data']]);
+    }
+
+    /**
+     * 未使用,获取核销订单头部
+     * @return mixed
+     */
+    public function getVerifyBadge()
+    {
+        return app('json')->success([]);
+    }
+
+    /**
+     * 订单列表推荐人详细
+     * @param $uid
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function order_spread_user($uid)
+    {
+        /** @var UserServices $userServices */
+        $userServices = app()->make(UserServices::class);
+        $spread = [];
+        $spread = $userServices->getUserInfo((int)$uid);
+        if ($spread) {
+            $spread = $spread->toArray();
+            $spread['brokerage_pric'] = $spread['brokerage_price'];
+            $spread['birthday'] = $spread['birthday'] ? date('Y-m-d', $spread['birthday']) : '';
+            $spread['last_time'] = $spread['last_time'] ? date('Y-m-d H:i:s', $spread['last_time']) : '';
+        }
+        return app('json')->success(['spread' => $spread]);
+    }
+}

+ 76 - 0
app/adminapi/controller/v1/notification/sms/SmsAdmin.php

@@ -0,0 +1,76 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\notification\sms;
+
+use app\adminapi\controller\AuthController;
+use app\services\yihaotong\SmsAdminServices;
+use think\facade\App;
+
+/**
+ * 短信账号
+ * Class SmsAdmin
+ * @package app\adminapi\controller\v1\sms
+ */
+class SmsAdmin extends AuthController
+{
+    /**
+     * 构造方法
+     * SmsAdmin constructor.
+     * @param App $app
+     * @param SmsAdminServices $services
+     */
+    public function __construct(App $app, SmsAdminServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 发送验证码
+     * @return mixed
+     */
+    public function captcha()
+    {
+        if (!request()->isPost()) {
+            return app('json')->fail(100031);
+        }
+        $phone = request()->param('phone');
+        if (!trim($phone)) {
+            return app('json')->fail(400132);
+        }
+        return app('json')->success($this->services->captcha($phone));
+    }
+
+    /**
+     * 修改/注册短信平台账号
+     * @return mixed
+     */
+    public function save()
+    {
+        [$account, $password, $phone, $code, $url, $sign] = $this->request->postMore([
+            ['account', ''],
+            ['password', ''],
+            ['phone', ''],
+            ['code', ''],
+            ['url', ''],
+            ['sign', ''],
+        ], true);
+        $signLen = mb_strlen(trim($sign));
+        if (!strlen(trim($account))) return app('json')->fail(400133);
+        if (!strlen(trim($password))) return app('json')->fail(400134);
+        if (!$signLen) return app('json')->fail(400135);
+        if ($signLen > 8) return app('json')->fail(400136);
+        if (!strlen(trim($code))) return app('json')->fail(400137);
+        if (!strlen(trim($url))) return app('json')->fail(400138);
+        $status = $this->services->register($account, $password, $url, $phone, $code, $sign);
+        return app('json')->success($status['msg']);
+    }
+}

+ 135 - 0
app/adminapi/controller/v1/notification/sms/SmsConfig.php

@@ -0,0 +1,135 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\notification\sms;
+
+use app\services\yihaotong\SmsAdminServices;
+use app\services\serve\ServeServices;
+use crmeb\services\CacheService;
+use app\adminapi\controller\AuthController;
+use think\facade\App;
+
+/**
+ * 短信配置
+ * Class SmsConfig
+ * @package app\admin\controller\sms
+ */
+class SmsConfig extends AuthController
+{
+    /**
+     * 构造方法
+     * SmsConfig constructor.
+     * @param App $app
+     * @param SmsAdminServices $services
+     */
+    public function __construct(App $app, SmsAdminServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 保存短信配置
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function save_basics()
+    {
+        [$account, $token] = $this->request->postMore([
+            ['sms_account', ''],
+            ['sms_token', '']
+        ], true);
+
+        $this->validate(['sms_account' => $account, 'sms_token' => $token], \app\adminapi\validate\notification\SmsConfigValidate::class);
+
+        if ($this->services->login($account, $token)) {
+            return app('json')->success(400139);
+        } else {
+            return app('json')->fail(400140);
+        }
+    }
+
+    /**
+     * 检测登录
+     * @param ServeServices $services
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function is_login(ServeServices $services)
+    {
+        $sms_info = CacheService::get('sms_account');
+        $data = ['status' => false, 'info' => ''];
+        if ($sms_info) {
+            try {
+                $result = $services->user()->getUser();
+            } catch (\Throwable $e) {
+                $result = [];
+            }
+            if (!$result) {
+                $this->logout();
+            } else {
+                $data['status'] = true;
+                $data['info'] = $sms_info;
+            }
+            return app('json')->success($data);
+        } else {
+            CacheService::clear();
+            $account = sys_config('sms_account');
+            $password = sys_config('sms_token');
+            //没有退出登录 清空这两个数据 自动登录
+            if ($account && $password) {
+                $res = $services->user()->login($account, $password);
+                if ($res) {
+                    CacheService::set('sms_account', $account);
+                    $data['status'] = true;
+                    $data['info'] = $account;
+                }
+            }
+        }
+        return app('json')->success($data);
+    }
+
+    /**
+     * 退出
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function logout()
+    {
+        CacheService::delete('sms_account');
+        $this->services->updateSmsConfig('', '');
+        CacheService::clear();
+        return app('json')->success(100042);
+    }
+
+    /**
+     * 短信发送记录
+     * @param ServeServices $services
+     * @return mixed
+     */
+    public function record(ServeServices $services)
+    {
+        [$page, $limit, $status] = $this->request->getMore([
+            [['page', 'd'], 0],
+            [['limit', 'd'], 10],
+            ['type', '', '', 'status'],
+        ], true);
+        return app('json')->success($services->user()->record($page, $limit, 1, $status));
+    }
+
+    /**
+     * 获取当前登陆的短信账号信息
+     * @return mixed
+     */
+    public function data()
+    {
+        return app('json')->success($this->services->getSmsData());
+    }
+}

+ 88 - 0
app/adminapi/controller/v1/notification/sms/SmsPay.php

@@ -0,0 +1,88 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\notification\sms;
+
+use app\adminapi\controller\AuthController;
+use crmeb\services\{sms\Sms};
+
+/**
+ * 短信购买
+ * Class SmsPay
+ * @package app\admin\controller\sms
+ */
+class SmsPay extends AuthController
+{
+    /**
+     * @var Sms
+     */
+    protected $smsHandle;
+
+    /**
+     * @return mixed|void
+     */
+    public function initialize()
+    {
+        parent::initialize(); // TODO: Change the autogenerated stub
+        $this->smsHandle = new Sms('yihaotong', [
+            'sms_account' => sys_config('sms_account'),
+            'sms_token' => sys_config('sms_token'),
+            'site_url' => sys_config('site_url')
+        ]);
+        if (!$this->smsHandle->isLogin()) {
+            return app('json')->fail(400141);
+        }
+    }
+
+    /**
+     * 获取账号信息
+     * @return mixed
+     */
+    public function number()
+    {
+        $countInfo = $this->smsHandle->count();
+        if ($countInfo['status'] == 400) return app('json')->fail($countInfo['msg']);
+        $info['account'] = sys_config('sms_account');
+        $info['number'] = $countInfo['data']['number'];
+        $info['send_total'] = $countInfo['data']['send_total'];
+        return app('json')->success($info);
+    }
+
+    /**
+     * 获取支付套餐
+     * @return mixed
+     */
+    public function price()
+    {
+        list($page, $limit) = $this->request->getMore([
+            ['page', 1],
+            ['limit', 20],
+        ], true);
+        $mealInfo = $this->smsHandle->meal($page, $limit);
+        if ($mealInfo['status'] == 400) return app('json')->fail($mealInfo['msg']);
+        return app('json')->success($mealInfo['data']);
+    }
+
+    /**
+     * 获取支付码
+     * @return mixed
+     */
+    public function pay()
+    {
+        list($payType, $mealId, $price) = $this->request->postMore([
+            ['payType', 'weixin'],
+            ['mealId', 0],
+            ['price', 0],
+        ], true);
+        $payInfo = $this->smsHandle->pay($payType, $mealId, $price, $this->adminId);
+        if ($payInfo['status'] == 400) return app('json')->fail($payInfo['msg']);
+        return app('json')->success($payInfo['data']);
+    }
+}

+ 77 - 0
app/adminapi/controller/v1/notification/sms/SmsPublicTemp.php

@@ -0,0 +1,77 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\notification\sms;
+
+use app\adminapi\controller\AuthController;
+use crmeb\services\sms\Sms;
+
+/**
+ * 公共短信模板
+ * Class SmsPublicTemp
+ * @package app\admin\controller\sms
+ */
+class SmsPublicTemp extends AuthController
+{
+    /**
+     * @var Sms
+     */
+    protected $smsHandle;
+
+    /**
+     * @return mixed|void
+     */
+    public function initialize()
+    {
+        parent::initialize(); // TODO: Change the autogenerated stub
+        $this->smsHandle = new Sms('yihaotong', [
+            'sms_account' => sys_config('sms_account'),
+            'sms_token' => sys_config('sms_token'),
+            'site_url' => sys_config('site_url')
+        ]);
+        if (!$this->smsHandle->isLogin()) {
+            return app('json')->fail(400141);
+        }
+    }
+
+    /**
+     * 异步获取公共模板列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['is_have', ''],
+            ['page', 1],
+            ['limit', 20],
+        ]);
+        $templateList = $this->smsHandle->publictemp($where);
+        if ($templateList['status'] == 400) return app('json')->fail($templateList['msg']);
+        $arr = $templateList['data']['data'];
+        foreach ($arr as $key => $value) {
+            switch ($value['type']) {
+                case 1:
+                    $arr[$key]['type'] = '验证码';
+                    break;
+                case 2:
+                    $arr[$key]['type'] = '通知';
+                    break;
+                case 3:
+                    $arr[$key]['type'] = '推广';
+                    break;
+                default:
+                    $arr[$key]['type'] = '';
+                    break;
+            }
+        }
+        $templateList['data']['data'] = $arr;
+        return app('json')->success($templateList['data']);
+    }
+}

+ 97 - 0
app/adminapi/controller/v1/notification/sms/SmsTemplateApply.php

@@ -0,0 +1,97 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\notification\sms;
+
+use app\adminapi\controller\AuthController;
+use app\services\serve\ServeServices;
+use think\facade\App;
+
+/**
+ * 短信模板申请
+ * Class SmsTemplateApply
+ * @package app\admin\controller\sms
+ */
+class SmsTemplateApply extends AuthController
+{
+    /**
+     * @param App $app
+     * @param ServeServices $services
+     */
+    public function __construct(App $app, ServeServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 异步获取模板列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            [['type', 'd'], 0],
+            ['status', ''],
+            ['title', ''],
+            [['page', 'd'], 1],
+            [['limit', 'd'], 20],
+        ]);
+        $where['temp_type'] = $where['type'];
+        $templateList = $this->services->sms()->temps($where['page'], $where['limit'], $where['type']);
+        $templateList['data'] = $templateList['data'] ?? [];
+        foreach ($templateList['data'] as $key => &$item) {
+            $item['templateid'] = $item['temp_id'];
+            switch ((int)$item['temp_type']) {
+                case 1:
+                    $item['type'] = '验证码';
+                    break;
+                case 2:
+                    $item['type'] = '通知';
+                    break;
+                case 30:
+                    $item['type'] = '营销短信';
+                    break;
+            }
+        }
+        return app('json')->success($templateList);
+    }
+
+    /**
+     * 显示创建资源表单页
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->getSmsTemplateForm());
+    }
+
+    /**
+     * 保存新建的资源
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['title', ''],
+            ['content', ''],
+            ['type', 0]
+        ]);
+        if (!strlen(trim($data['title']))) {
+            return app('json')->fail(400142);
+        }
+        if (!strlen(trim($data['content']))) {
+            return app('json')->fail(400143);
+        }
+        $this->services->sms()->apply($data['title'], $data['content'], $data['type']);
+        return app('json')->success(100027);
+    }
+}

+ 142 - 0
app/adminapi/controller/v1/order/DeliveryService.php

@@ -0,0 +1,142 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\order;
+
+use app\adminapi\controller\AuthController;
+use app\services\order\DeliveryServiceServices;
+use app\services\user\UserWechatuserServices;
+use think\facade\App;
+
+/**
+ * 配送员管理
+ * Class StoreService
+ * @package app\admin\controller\store
+ */
+class DeliveryService extends AuthController
+{
+    /**
+     * DeliveryService constructor.
+     * @param App $app
+     * @param DeliveryServiceServices $services
+     */
+    public function __construct(App $app, DeliveryServiceServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 配送员列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        return app('json')->success($this->services->getServiceList([]));
+    }
+
+    /**
+     * 添加客服表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function add()
+    {
+        return app('json')->success($this->services->create());
+    }
+
+    /**
+     * 保存配送员
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['image', ''],
+            ['uid', 0],
+            ['avatar', ''],
+            ['phone', ''],
+            ['nickname', ''],
+            ['status', 1],
+        ]);
+
+        $this->services->saveDeliveryService($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 编辑表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->edit((int)$id));
+    }
+
+    /**
+     * 修改配送员
+     * @param $id
+     * @return mixed
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['avatar', ''],
+            ['nickname', ''],
+            ['phone', ''],
+            ['status', 1],
+        ]);
+
+        $this->services->updateDeliveryService((int)$id, $data);
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除配送员
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if (!$this->services->delete($id))
+            return app('json')->fail(100008);
+        else
+            return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        if ($status == '' || $id == 0) return app('json')->fail(100100);
+        $this->services->update($id, ['status' => $status]);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 获取所有配送员列表
+     * @return mixed
+     */
+    public function get_delivery_list()
+    {
+        $data = $this->services->getDeliveryList();
+        return app('json')->success($data);
+    }
+
+}

+ 100 - 0
app/adminapi/controller/v1/order/OtherOrder.php

@@ -0,0 +1,100 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\order;
+
+use app\adminapi\controller\AuthController;
+use app\services\order\OtherOrderServices;
+use app\services\other\QrcodeServices;
+use crmeb\utils\Canvas;
+use think\facade\App;
+
+/**
+ * 线下收银
+ * Class OtherOrder
+ * @package app\adminapi\controller\v1\order
+ */
+class OtherOrder extends AuthController
+{
+    /**
+     * OtherOrder constructor.
+     * @param App $app
+     * @param OtherOrderServices $service
+     */
+    public function __construct(App $app, OtherOrderServices $service)
+    {
+        parent::__construct($app);
+        $this->services = $service;
+    }
+
+    /**
+     * 线下收银订单列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function scan_list()
+    {
+        $where = $this->request->getMore([
+            ['order_id', ''],
+            ['add_time', ''],
+            ['name', ''],
+            ['page', 1],
+            ['limit', 20],
+        ]);
+        $data = $this->services->getScanOrderList($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 线下收银二维码
+     * @return mixed
+     * @throws \Exception
+     */
+    public function offline_scan()
+    {
+        [$type] = $this->request->getMore([
+            ['type', 1]
+        ], true);
+        //生成h5地址
+        $weixinPage = "/pages/annex/offline_pay/index";
+        $weixinFileName = "wechat_offline_scan.png";
+        /** @var QrcodeServices $QrcodeService */
+        $QrcodeService = app()->make(QrcodeServices::class);
+        $wechatQrcode = $QrcodeService->getWechatQrcodePath($weixinFileName, $weixinPage, false, false);
+        //生成小程序地址
+        $routineQrcode = $QrcodeService->getRoutineQrcodePath(4, 6, 3, [], false);
+        $qrcod = ['wechat' => $wechatQrcode, 'routine' => $routineQrcode];
+        $data = [];
+        if ($type) {
+            //生成画布
+            $canvas = Canvas::instance();
+            $path = 'uploads/offline/';
+            $imageType = 'jpg';
+            $siteUrl = sys_config('site_url');
+            $canvas->setImageUrl(public_path().'statics/qrcode/offlines.jpg')->setImageHeight(730)->setImageWidth(500)->pushImageValue();
+            foreach ($qrcod as $k => $v) {
+                if ($v) {
+                    $name = 'offline_' . $k;
+                    $canvas->setImageUrl($v)->setImageHeight(344)->setImageWidth(344)->setImageLeft(76)->setImageTop(120)->pushImageValue();
+                    $image = $canvas->setFileName($name)->setImageType($imageType)->setPath($path)->setBackgroundWidth(500)->setBackgroundHeight(720)->starDrawChart();
+                    $data[$k] = $image ? $siteUrl . '/' . $image : '';
+                } else {
+                    $data[$k] = "";
+                }
+
+            }
+        } else {
+            $data = ['wechat' => $wechatQrcode, 'routine' => $routineQrcode];
+        }
+        return app('json')->success($data);
+    }
+}

+ 231 - 0
app/adminapi/controller/v1/order/RefundOrder.php

@@ -0,0 +1,231 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\order;
+
+use app\adminapi\controller\AuthController;
+use app\Request;
+use app\services\order\StoreOrderRefundServices;
+use app\services\order\StoreOrderServices;
+use app\services\user\UserServices;
+use app\services\wechat\WechatUserServices;
+use think\facade\App;
+
+/**
+ * 退款订单
+ * Class RefundOrder
+ * @package app\adminapi\controller\v1\order
+ */
+class RefundOrder extends AuthController
+{
+
+    /**
+     * RefundOrder constructor.
+     * @param App $app
+     * @param StoreOrderRefundServices $service
+     * @method temp
+     */
+    public function __construct(App $app, StoreOrderRefundServices $service)
+    {
+        parent::__construct($app);
+        $this->services = $service;
+    }
+
+    /**
+     * 退款订单列表
+     * @return mixed
+     */
+    public function getRefundList()
+    {
+        $where = $this->request->getMore([
+            ['order_id', ''],
+            ['time', ''],
+            ['refund_type', 0]
+        ]);
+        $where['is_cancel'] = 0;
+        $where['is_system_del'] = 0;
+        return app('json')->success($this->services->refundList($where));
+    }
+
+    /**
+     * 订单详情
+     * @param $uni
+     * @return \think\Response
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @author 吴汐
+     * @email 442384644@qq.com
+     * @date 2023/03/02
+     */
+    public function getRefundInfo($uni)
+    {
+        $data['orderInfo'] = $this->services->refundDetail($uni);
+        /** @var UserServices $userServices */
+        $userServices = app()->make(UserServices::class);
+        $data['userInfo'] = $userServices->get($data['orderInfo']['uid']);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 商家同意退款
+     * @return mixed
+     */
+    public function agreeExpress($id)
+    {
+        $this->services->agreeExpress($id);
+        return app('json')->success(100010);
+    }
+
+    /**
+     * 修改备注
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function remark($id)
+    {
+        [$remark] = $this->request->postMore([['remark', '']], true);
+
+        $this->services->updateRemark((int)$id, $remark);
+        return app('json')->success(100024);
+    }
+
+    /**
+     * 退款表单生成
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function refund($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($this->services->refundOrderForm((int)$id));
+    }
+
+    /**
+     * 订单退款(产品)
+     * @param Request $request
+     * @param StoreOrderServices $services
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function refundPrice(Request $request, StoreOrderServices $services, $id)
+    {
+        $data = $request->postMore([
+            ['refund_price', 0],
+            ['type', 1]
+        ]);
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        $orderRefund = $this->services->get($id);
+        if (!$orderRefund) {
+            return app('json')->fail(100026);
+        }
+        if ($orderRefund['is_cancel'] == 1) {
+            return app('json')->fail(400118);
+        }
+        $order = $services->get((int)$orderRefund['store_order_id']);
+        if (!$order) {
+            return app('json')->fail(100026);
+        }
+        if (!in_array($orderRefund['refund_type'], [1, 5])) {
+            return app('json')->fail(400144);
+        }
+
+        if ($data['type'] == 1 || $data['type'] == 5) {
+            $data['refund_type'] = 6;
+        } else if ($data['type'] == 2) {
+            $data['refund_type'] = 3;
+        }
+        $data['refunded_time'] = time();
+        $type = $data['type'];
+        //拒绝退款
+        if ($type == 2) {
+            $this->services->refuseRefund((int)$id, $data, $orderRefund);
+            return app('json')->success(400145);
+        } else {
+            //0元退款
+            if ($orderRefund['refund_price'] == 0 && in_array($orderRefund['refund_type'], [1, 5])) {
+                $refund_price = 0;
+            } else {
+                if (!$data['refund_price']) {
+                    return app('json')->fail(400146);
+                }
+                if ($orderRefund['refund_price'] == $orderRefund['refunded_price']) {
+                    return app('json')->fail(400147);
+                }
+                $refund_price = $data['refund_price'];
+            }
+
+            $data['refunded_price'] = bcadd($data['refund_price'], $orderRefund['refunded_price'], 2);
+            $bj = bccomp((string)$orderRefund['refund_price'], (string)$data['refunded_price'], 2);
+            if ($bj < 0) {
+                return app('json')->fail(400148);
+            }
+
+            unset($data['type']);
+            $refund_data['pay_price'] = $order['pay_price'];
+            $refund_data['refund_price'] = $refund_price;
+            if ($order['refund_price'] > 0) {
+                mt_srand();
+                $refund_data['refund_id'] = $order['order_id'] . rand(100, 999);
+            }
+            ($order['pid'] > 0) ? $refund_data['order_id'] = $services->value(['id' => (int)$order['pid']], 'order_id') : $refund_data['order_id'] = $order['order_id'];
+            /** @var WechatUserServices $wechatUserServices */
+            $wechatUserServices = app()->make(WechatUserServices::class);
+            $refund_data['open_id'] = $wechatUserServices->uidToOpenid((int)$order['uid'], 'routine') ?? '';
+            $refund_data['refund_no'] = $orderRefund['order_id'];
+            //修改订单退款状态
+//            $data['refund_price'] = $data['refunded_price'];
+            unset($data['refund_price']);
+            if ($this->services->agreeRefund($id, $refund_data)) {
+                $this->services->update($id, $data);
+                return app('json')->success(400149);
+            } else {
+                $this->services->storeProductOrderRefundYFasle((int)$id, $refund_price);
+                return app('json')->fail(400150);
+            }
+        }
+    }
+
+    /**
+     * 不退款表单结构
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function noRefund($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($this->services->noRefundForm((int)$id));
+    }
+
+    /**
+     * 订单不退款
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function refuseRefund($id)
+    {
+        [$refund_reason] = $this->request->postMore([['refund_reason', '']], true);
+        $this->services->refuse($id, $refund_reason);
+        return app('json')->success(100010);
+    }
+}

+ 770 - 0
app/adminapi/controller/v1/order/StoreOrder.php

@@ -0,0 +1,770 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\order;
+
+use app\adminapi\controller\AuthController;
+use app\adminapi\validate\order\StoreOrderValidate;
+use app\services\serve\ServeServices;
+use app\services\order\{StoreOrderCartInfoServices,
+    StoreOrderDeliveryServices,
+    StoreOrderRefundServices,
+    StoreOrderStatusServices,
+    StoreOrderTakeServices,
+    StoreOrderWriteOffServices,
+    StoreOrderServices
+};
+use app\services\pay\OrderOfflineServices;
+use app\services\shipping\ExpressServices;
+use app\services\system\store\SystemStoreServices;
+use app\services\user\UserServices;
+use think\facade\App;
+
+/**
+ * 订单管理
+ * Class StoreOrder
+ * @package app\adminapi\controller\v1\order
+ */
+class StoreOrder extends AuthController
+{
+    /**
+     * StoreOrder constructor.
+     * @param App $app
+     * @param StoreOrderServices $service
+     * @method temp
+     */
+    public function __construct(App $app, StoreOrderServices $service)
+    {
+        parent::__construct($app);
+        $this->services = $service;
+    }
+
+    /**
+     * 获取订单类型数量
+     * @return mixed
+     */
+    public function chart()
+    {
+        $where = $this->request->getMore([
+            ['data', '', '', 'time'],
+            [['type', 'd'], 0],
+        ]);
+        $data = $this->services->orderCount($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 订单列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function lst()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['real_name', ''],
+            ['is_del', ''],
+            ['data', '', '', 'time'],
+            ['type', ''],
+            ['pay_type', ''],
+            ['order', ''],
+            ['field_key', ''],
+        ]);
+        $where['is_system_del'] = 0;
+        $where['pid'] = 0;
+        if ($where['status'] == 1) $where = $where + ['shipping_type' => 1];
+        return app('json')->success($this->services->getOrderList($where, ['*'], ['split' => function ($query) {
+            $query->field('id,pid');
+        }, 'pink', 'invoice', 'division']));
+    }
+
+    /**
+     * 核销码核销
+     * @param StoreOrderWriteOffServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function write_order(StoreOrderWriteOffServices $services)
+    {
+        [$code, $confirm] = $this->request->getMore([
+            ['code', ''],
+            ['confirm', 0]
+        ], true);
+        if (!$code) return app('json')->fail(100100);
+        $orderInfo = $services->writeOffOrder($code, (int)$confirm);
+        if ($confirm == 0) {
+            return app('json')->success(400151, $orderInfo);
+        }
+        return app('json')->success(400152);
+    }
+
+    /**
+     * 订单号核销
+     * @param StoreOrderWriteOffServices $services
+     * @param $order_id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function write_update(StoreOrderWriteOffServices $services, $order_id)
+    {
+        $orderInfo = $this->services->getOne(['order_id' => $order_id, 'is_del' => 0]);
+        if ($orderInfo->shipping_type != 2 && $orderInfo->delivery_type != 'send') {
+            return app('json')->fail(400153);
+        } else {
+            if (!$orderInfo->verify_code) {
+                return app('json')->fail(100100);
+            }
+            $orderInfo = $services->writeOffOrder($orderInfo->verify_code, 1);
+            if ($orderInfo) {
+                return app('json')->success(400151);
+            } else {
+                return app('json')->fail(400154);
+            }
+        }
+    }
+
+    /**
+     * 订单改价表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($this->services->updateForm($id));
+    }
+
+    /**
+     * 订单改价
+     * @param $id
+     * @return mixed
+     * @throws \Exception
+     */
+    public function update($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $data = $this->request->postMore([
+            ['order_id', ''],
+            ['total_price', 0],
+            ['total_postage', 0],
+            ['pay_price', 0],
+            ['pay_postage', 0],
+            ['gain_integral', 0],
+        ]);
+
+        $this->validate($data, StoreOrderValidate::class);
+
+        if ($data['total_price'] < 0) return app('json')->fail(400155);
+        if ($data['pay_price'] < 0) return app('json')->fail(400155);
+
+        $this->services->updateOrder((int)$id, $data);
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 获取快递公司
+     * @return mixed
+     */
+    public function express(ExpressServices $services)
+    {
+        [$status] = $this->request->getMore([
+            ['status', ''],
+        ], true);
+        if ($status != '') $data['status'] = $status;
+        $data['is_show'] = 1;
+        return app('json')->success($services->express($data));
+    }
+
+    /**
+     * 批量删除用户已经删除的订单
+     * @return mixed
+     */
+    public function del_orders()
+    {
+        [$ids] = $this->request->postMore([
+            ['ids', []],
+        ], true);
+        if (!count($ids)) return app('json')->fail(400156);
+        if ($this->services->getOrderIdsCount($ids))
+            return app('json')->fail(400157);
+        if ($this->services->batchUpdate($ids, ['is_system_del' => 1]))
+            return app('json')->success(100002);
+        else
+            return app('json')->fail(100008);
+    }
+
+    /**
+     * 删除订单
+     * @param $id
+     * @return mixed
+     */
+    public function del($id)
+    {
+        if (!$id || !($orderInfo = $this->services->get($id)))
+            return app('json')->fail(400118);
+        if (!$orderInfo->is_del)
+            return app('json')->fail(400157);
+        $orderInfo->is_system_del = 1;
+        if ($orderInfo->save()) {
+            /** @var StoreOrderRefundServices $refundServices */
+            $refundServices = app()->make(StoreOrderRefundServices::class);
+            $refundServices->update(['store_order_id' => $id], ['is_system_del' => 1]);
+            return app('json')->success(100002);
+        } else
+            return app('json')->fail(100008);
+    }
+
+    /**
+     * 订单发送货
+     * @param $id
+     * @param StoreOrderDeliveryServices $services
+     * @return mixed
+     */
+    public function update_delivery($id, StoreOrderDeliveryServices $services)
+    {
+        $data = $this->request->postMore([
+            ['type', 1],
+            ['delivery_name', ''],//快递公司名称
+            ['delivery_id', ''],//快递单号
+            ['delivery_code', ''],//快递公司编码
+
+            ['express_record_type', 2],//发货记录类型
+            ['express_temp_id', ""],//电子面单模板
+            ['to_name', ''],//寄件人姓名
+            ['to_tel', ''],//寄件人电话
+            ['to_addr', ''],//寄件人地址
+
+            ['sh_delivery_name', ''],//送货人姓名
+            ['sh_delivery_id', ''],//送货人电话
+            ['sh_delivery_uid', ''],//送货人ID
+
+            ['fictitious_content', '']//虚拟发货内容
+        ]);
+        $services->delivery((int)$id, $data);
+        return app('json')->success(100010);
+    }
+
+    /**
+     * 订单拆单发送货
+     * @param $id
+     * @param StoreOrderDeliveryServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function split_delivery($id, StoreOrderDeliveryServices $services)
+    {
+        $data = $this->request->postMore([
+            ['type', 1],
+            ['delivery_name', ''],//快递公司名称
+            ['delivery_id', ''],//快递单号
+            ['delivery_code', ''],//快递公司编码
+
+            ['express_record_type', 2],//发货记录类型
+            ['express_temp_id', ""],//电子面单模板
+            ['to_name', ''],//寄件人姓名
+            ['to_tel', ''],//寄件人电话
+            ['to_addr', ''],//寄件人地址
+
+            ['sh_delivery_name', ''],//送货人姓名
+            ['sh_delivery_id', ''],//送货人电话
+            ['sh_delivery_uid', ''],//送货人ID
+
+            ['fictitious_content', ''],//虚拟发货内容
+
+            ['cart_ids', []]
+        ]);
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        if (!$data['cart_ids']) {
+            return app('json')->fail(400158);
+        }
+        foreach ($data['cart_ids'] as $cart) {
+            if (!isset($cart['cart_id']) || !$cart['cart_id'] || !isset($cart['cart_num']) || !$cart['cart_num']) {
+                return app('json')->fail(400159);
+            }
+        }
+        $services->splitDelivery((int)$id, $data);
+        return app('json')->success(100010);
+    }
+
+    /**
+     * 获取订单可拆分发货商品列表
+     * @param $id
+     * @param StoreOrderCartInfoServices $services
+     * @return mixed
+     */
+    public function split_cart_info($id, StoreOrderCartInfoServices $services)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($services->getSplitCartList((int)$id));
+    }
+
+    /**
+     * 获取订单拆分子订单列表
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function split_order($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($this->services->getSplitOrderList(['pid' => $id, 'is_system_del' => 0], ['*'], ['split', 'pink', 'invoice']));
+    }
+
+
+    /**
+     * 确认收货
+     * @param $id 订单id
+     * @return mixed
+     * @throws \Exception
+     */
+    public function take_delivery(StoreOrderTakeServices $services, $id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $order = $this->services->get($id);
+        if (!$order)
+            return app('json')->fail(400118);
+        if ($order['status'] == 2)
+            return app('json')->fail(400114);
+        if ($order['paid'] == 1 && $order['status'] == 1)
+            $data['status'] = 2;
+        else if ($order['pay_type'] == 'offline')
+            $data['status'] = 2;
+        else
+            return app('json')->fail(400115);
+
+        if (!$this->services->update($id, $data)) {
+            return app('json')->fail(400116);
+        } else {
+            $services->storeProductOrderUserTakeDelivery($order);
+            return app('json')->success(400117);
+        }
+    }
+
+
+    /**
+     * 获取配置信息
+     * @return mixed
+     */
+    public function getDeliveryInfo()
+    {
+        return app('json')->success([
+            'express_temp_id' => sys_config('config_export_temp_id'),
+            'id' => sys_config('config_export_id'),
+            'to_name' => sys_config('config_export_to_name'),
+            'to_tel' => sys_config('config_export_to_tel'),
+            'to_add' => sys_config('config_export_to_address'),
+            'export_open' => (bool)((int)sys_config('config_export_open'))
+        ]);
+    }
+
+    /**
+     * 退款表单生成
+     * @param $id 订单id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function refund(StoreOrderRefundServices $services, $id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($services->refundOrderForm((int)$id));
+    }
+
+    /**
+     * 订单退款
+     * @param $id 订单id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function update_refund(StoreOrderRefundServices $services, $id)
+    {
+        $data = $this->request->postMore([
+            ['refund_price', 0],
+            ['type', 1]
+        ]);
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        $order = $this->services->get($id);
+        if (!$order) {
+            return app('json')->fail(400118);
+        }
+        //0元退款
+        if ($order['pay_price'] == 0 && in_array($order['refund_status'], [0, 1])) {
+            $refund_price = 0;
+        } else {
+            if ($order['pay_price'] == $order['refund_price']) {
+                return app('json')->fail(400147);
+            }
+            if (!$data['refund_price']) {
+                return app('json')->fail(400146);
+            }
+            $refund_price = $data['refund_price'];
+            $data['refund_price'] = bcadd($data['refund_price'], $order['refund_price'], 2);
+            $bj = bccomp((string)$order['pay_price'], (string)$data['refund_price'], 2);
+            if ($bj < 0) {
+                return app('json')->fail(400148);
+            }
+        }
+        if ($data['type'] == 1) {
+            $data['refund_status'] = 2;
+        } else if ($data['type'] == 2) {
+            $data['refund_status'] = 0;
+        }
+        $data['refund_type'] = 6;
+        $type = $data['type'];
+        unset($data['type']);
+        $refund_data['pay_price'] = $order['pay_price'];
+        $refund_data['refund_price'] = $refund_price;
+        if ($order['refund_price'] > 0) {
+            $refund_data['refund_id'] = $order['order_id'] . rand(100, 999);
+        }
+        //退款处理
+        $services->payOrderRefund($type, $order, $refund_data);
+        //修改订单退款状态
+        if ($this->services->update($id, $data)) {
+            $services->storeProductOrderRefundY($data, $order, $refund_price);
+            return app('json')->success(400149);
+        } else {
+            $services->storeProductOrderRefundYFasle((int)$id, $refund_price);
+            return app('json')->fail(400150);
+        }
+    }
+
+    /**
+     * 订单详情
+     * @param $id 订单id
+     * @return mixed
+     * @throws \ReflectionException
+     */
+    public function order_info($id)
+    {
+        if (!$id || !($orderInfo = $this->services->get($id, [], ['refund']))) {
+            return app('json')->fail(400118);
+        }
+        /** @var UserServices $services */
+        $services = app()->make(UserServices::class);
+        $userInfo = $services->get($orderInfo['uid']);
+        if (!$userInfo) return app('json')->fail(400119);
+        $userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
+        $userInfo['spread_name'] = '无';
+        if ($userInfo['spread_uid']) {
+            $spreadName = $services->value(['uid' => $userInfo['spread_uid']], 'nickname');
+            if ($spreadName) {
+                $userInfo['spread_name'] = $spreadName;
+            } else {
+                $userInfo['spread_uid'] = '';
+            }
+        } else {
+            $userInfo['spread_uid'] = '';
+        }
+
+        $orderInfo = $this->services->tidyOrder($orderInfo->toArray(), true, true);
+        //核算优惠金额
+        $vipTruePrice = $levelPrice = $memberPrice = 0;
+        foreach ($orderInfo['cartInfo'] as $cart) {
+            $vipTruePrice = bcadd((string)$vipTruePrice, (string)$cart['vip_sum_truePrice'], 2);
+            if ($cart['price_type'] == 'member') $memberPrice = bcadd((string)$memberPrice, (string)$cart['vip_sum_truePrice'], 2);
+            if ($cart['price_type'] == 'level') $levelPrice = bcadd((string)$levelPrice, (string)$cart['vip_sum_truePrice'], 2);
+        }
+        $orderInfo['vip_true_price'] = $vipTruePrice;
+        $orderInfo['levelPrice'] = $levelPrice;
+        $orderInfo['memberPrice'] = $memberPrice;
+        $orderInfo['total_price'] = bcadd($orderInfo['total_price'], $orderInfo['vip_true_price'], 2);
+        if ($orderInfo['store_id'] && $orderInfo['shipping_type'] == 2) {
+            /** @var  $storeServices */
+            $storeServices = app()->make(SystemStoreServices::class);
+            $orderInfo['_store_name'] = $storeServices->value(['id' => $orderInfo['store_id']], 'name');
+        } else
+            $orderInfo['_store_name'] = '';
+        $orderInfo['spread_name'] = $services->value(['uid' => $orderInfo['spread_uid']], 'nickname') ?? '无';
+        $orderInfo['_info'] = app()->make(StoreOrderCartInfoServices::class)->getOrderCartInfo((int)$orderInfo['id']);
+        $cart_num = 0;
+        $refund_num = array_sum(array_column($orderInfo['refund'], 'refund_num'));
+        foreach ($orderInfo['_info'] as $items) {
+            $cart_num += $items['cart_info']['cart_num'];
+        }
+        $orderInfo['is_all_refund'] = $refund_num == $cart_num;
+        $userInfo = $userInfo->toArray();
+        return app('json')->success(compact('orderInfo', 'userInfo'));
+    }
+
+    /**
+     * 查询物流信息
+     * @param $id 订单id
+     * @return mixed
+     */
+    public function get_express($id, ExpressServices $services)
+    {
+        if (!$id || !($orderInfo = $this->services->get($id)))
+            return app('json')->fail(400118);
+        if ($orderInfo['delivery_type'] != 'express' || !$orderInfo['delivery_id'])
+            return app('json')->fail(400120);
+
+        $cacheName = $orderInfo['order_id'] . $orderInfo['delivery_id'];
+
+        $data['delivery_name'] = $orderInfo['delivery_name'];
+        $data['delivery_id'] = $orderInfo['delivery_id'];
+        $data['result'] = $services->query($cacheName, $orderInfo['delivery_id'], $orderInfo['delivery_code'] ?? null, $orderInfo['user_phone']);
+        return app('json')->success($data);
+    }
+
+
+    /**
+     * 获取修改配送信息表单结构
+     * @param $id 订单id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function distribution(StoreOrderDeliveryServices $services, $id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($services->distributionForm((int)$id));
+    }
+
+    /**
+     * 修改配送信息
+     * @param $id  订单id
+     * @return mixed
+     */
+    public function update_distribution(StoreOrderDeliveryServices $services, $id)
+    {
+        $data = $this->request->postMore([['delivery_name', ''], ['delivery_code', ''], ['delivery_id', '']]);
+        if (!$id) return app('json')->fail(100100);
+        $services->updateDistribution($id, $data);
+        return app('json')->success(100010);
+    }
+
+    /**
+     * 不退款表单结构
+     * @param StoreOrderRefundServices $services
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function no_refund(StoreOrderRefundServices $services, $id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($services->noRefundForm((int)$id));
+    }
+
+    /**
+     * 订单不退款
+     * @param StoreOrderRefundServices $services
+     * @param $id
+     * @return mixed
+     */
+    public function update_un_refund(StoreOrderRefundServices $services, $id)
+    {
+        if (!$id || !($orderInfo = $this->services->get($id)))
+            return app('json')->fail(400118);
+        [$refund_reason] = $this->request->postMore([['refund_reason', '']], true);
+        if (!$refund_reason) {
+            return app('json')->fail(400113);
+        }
+        $orderInfo->refund_reason = $refund_reason;
+        $orderInfo->refund_status = 0;
+        $orderInfo->refund_type = 3;
+        $orderInfo->save();
+        if ($orderInfo->pid > 0) {
+            $res1 = $this->services->getCount([
+                ['pid', '=', $orderInfo->pid],
+                ['refund_type', '>', 0],
+                ['refund_type', '<>', 3],
+            ]);
+            if ($res1 == 0) {
+                $this->services->update($orderInfo->pid, ['refund_status' => 0]);
+            }
+        }
+        $services->storeProductOrderRefundNo((int)$id, $refund_reason);
+        //提醒推送
+        event('NoticeListener', [['orderInfo' => $orderInfo], 'send_order_refund_no_status']);
+        return app('json')->success(100010);
+    }
+
+    /**
+     * 线下支付
+     * @param $id 订单id
+     * @return mixed
+     */
+    public function pay_offline(OrderOfflineServices $services, $id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $res = $services->orderOffline((int)$id);
+        if ($res) {
+            return app('json')->success(100010);
+        } else {
+            return app('json')->fail(100005);
+        }
+    }
+
+    /**
+     * 退积分表单获取
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function refund_integral(StoreOrderRefundServices $services, $id)
+    {
+        if (!$id)
+            return app('json')->fail(100100);
+        return app('json')->success($services->refundIntegralForm((int)$id));
+    }
+
+    /**
+     * 退积分保存
+     * @param $id
+     * @return mixed
+     */
+    public function update_refund_integral(StoreOrderRefundServices $services, $id)
+    {
+        [$back_integral] = $this->request->postMore([['back_integral', 0]], true);
+        if (!$id || !($orderInfo = $this->services->get($id))) {
+            return app('json')->fail(400118);
+        }
+        if ($orderInfo->is_del) {
+            return app('json')->fail(400160);
+        }
+        if ($back_integral <= 0) {
+            return app('json')->fail(400161);
+        }
+        if ($orderInfo['use_integral'] == $orderInfo['back_integral']) {
+            return app('json')->fail(400162);
+        }
+
+        $data['back_integral'] = bcadd((string)$back_integral, (string)$orderInfo['back_integral'], 2);
+        $bj = bccomp((string)$orderInfo['use_integral'], (string)$data['back_integral'], 2);
+        if ($bj < 0) {
+            return app('json')->fail(400163);
+        }
+        //积分退款处理
+        $orderInfo->back_integral = $data['back_integral'];
+        if ($services->refundIntegral($orderInfo, $back_integral)) {
+            return app('json')->success(400164);
+        } else {
+            return app('json')->fail(400165);
+        }
+    }
+
+    /**
+     * 修改备注
+     * @param $id
+     * @return mixed
+     */
+    public function remark($id)
+    {
+        $data = $this->request->postMore([['remark', '']]);
+        if (!$data['remark'])
+            return app('json')->fail(400106);
+        if (!$id)
+            return app('json')->fail(100100);
+
+        if (!$order = $this->services->get($id)) {
+            return app('json')->fail(400118);
+        }
+        $order->remark = $data['remark'];
+        if ($order->save()) {
+            return app('json')->success(100024);
+        } else
+            return app('json')->fail(100025);
+    }
+
+    /**
+     * 获取订单状态列表并分页
+     * @param $id
+     * @return mixed
+     */
+    public function status(StoreOrderStatusServices $services, $id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        return app('json')->success($services->getStatusList(['oid' => $id])['list']);
+    }
+
+    /**
+     * 小票打印机打印
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function order_print($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        $res = $this->services->orderPrintTicket($id, true);
+        if ($res) {
+            return app('json')->success(100010);
+        } else {
+            return app('json')->fail(100005);
+        }
+    }
+
+    /**
+     * 电子面单模板
+     * @param $com
+     * @return mixed
+     */
+    public function expr_temp(ServeServices $services, $com)
+    {
+        if (!$com) {
+            return app('json')->fail(400123);
+        }
+        $list = $services->express()->temp($com);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 获取模板
+     */
+    public function express_temp(ServeServices $services)
+    {
+        $data = $this->request->getMore([['com', '']]);
+        if (!$data['com']) {
+            return app('json')->fail(400123);
+        }
+        $tpd = $services->express()->temp($data['com']);
+        return app('json')->success($tpd['data']);
+    }
+
+    /**
+     * 订单发货后打印电子面单
+     * @param $orderId
+     * @param StoreOrderDeliveryServices $storeOrderDeliveryServices
+     * @return mixed
+     */
+    public function order_dump($order_id, StoreOrderDeliveryServices $storeOrderDeliveryServices)
+    {
+        return app('json')->success($storeOrderDeliveryServices->orderDump($order_id));
+
+    }
+
+}

+ 140 - 0
app/adminapi/controller/v1/order/StoreOrderInvoice.php

@@ -0,0 +1,140 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\order;
+
+use app\adminapi\controller\AuthController;
+use app\services\order\StoreOrderInvoiceServices;
+use app\services\order\StoreOrderServices;
+use app\services\product\product\StoreProductServices;
+use app\services\system\store\SystemStoreServices;
+use app\services\user\UserServices;
+use think\facade\App;
+
+/**
+ * 发票管理
+ * Class StoreOrderInvoice
+ * @package app\adminapi\controller\v1\order
+ */
+class StoreOrderInvoice extends AuthController
+{
+
+    /**
+     * StoreOrderInvoice constructor.
+     * @param App $app
+     * @param StoreOrderInvoiceServices $services
+     */
+    public function __construct(App $app, StoreOrderInvoiceServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取订单类型数量
+     * @return mixed
+     */
+    public function chart()
+    {
+        $where = $this->request->getMore([
+            ['data', '', '', 'time'],
+            ['real_name', ''],
+            ['field_key', ''],
+            [['type', 'd'], 0],
+        ]);
+        $data = $this->services->chart($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 查询发票列表
+     * @return mixed
+     */
+    public function list()
+    {
+        $where = $this->request->getMore([
+            ['status', 0],
+            ['real_name', ''],
+            ['header_type', ''],
+            ['type', ''],
+            ['data', '', '', 'time'],
+            ['field_key', ''],
+        ]);
+        return app('json')->success($this->services->getList($where));
+    }
+
+
+    /**
+     * 设置发票状态
+     * @param string $id
+     * @return mixed
+     */
+    public function set_invoice($id = '')
+    {
+        if ($id == '') return app('json')->fail(100100);
+        $data = $this->request->postMore([
+            ['is_invoice', 0],
+            ['invoice_number', 0],
+            ['remark', '']
+        ]);
+        if ($data['is_invoice'] == 1 && !$data['invoice_number']) {
+            return app('json')->fail(400166);
+        }
+        if ($data['invoice_number'] && !preg_match('/^\d{8,10}$/', $data['invoice_number'])) {
+            return app('json')->fail(400167);
+        }
+        $this->services->setInvoice((int)$id, $data);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 订单详情
+     * @param $id 订单id
+     * @return mixed
+     */
+    public function orderInfo(StoreProductServices $productServices, StoreOrderServices $orderServices, $id)
+    {
+        if (!$id || !($orderInfo = $orderServices->get($id))) {
+            return app('json')->fail(400118);
+        }
+        /** @var UserServices $services */
+        $services = app()->make(UserServices::class);
+        $userInfo = $services->get($orderInfo['uid']);
+        if (!$userInfo) {
+            return app('json')->fail(400119);
+        }
+        $userInfo = $userInfo->hidden(['pwd', 'add_ip', 'last_ip', 'login_type']);
+        $userInfo['spread_name'] = '';
+        if ($userInfo['spread_uid'])
+            $userInfo['spread_name'] = $services->value(['uid' => $userInfo['spread_uid']], 'nickname');
+        $orderInfo = $orderServices->tidyOrder($orderInfo->toArray(), true, true);
+        //核算优惠金额
+        $vipTruePrice = array_column($orderInfo['cartInfo'], 'vip_sum_truePrice');
+        $vipTruePrice = array_sum($vipTruePrice);
+        $orderInfo['vip_true_price'] = $vipTruePrice ?: 0;
+
+        $orderInfo['add_time'] = $orderInfo['_add_time'] ?? '';
+        $productId = array_column($orderInfo['cartInfo'], 'product_id');
+        $cateData = $productServices->productIdByProductCateName($productId);
+        foreach ($orderInfo['cartInfo'] as &$item) {
+            $item['class_name'] = $cateData[$item['product_id']] ?? '';
+        }
+        if ($orderInfo['store_id'] && $orderInfo['shipping_type'] == 2) {
+            /** @var  $storeServices */
+            $storeServices = app()->make(SystemStoreServices::class);
+            $orderInfo['_store_name'] = $storeServices->value(['id' => $orderInfo['store_id']], 'name');
+        } else {
+            $orderInfo['_store_name'] = '';
+        }
+        $userInfo = $userInfo->toArray();
+        $invoice = $this->services->getOne(['order_id' => $id]);
+        return app('json')->success(compact('orderInfo', 'userInfo', 'invoice'));
+    }
+}

+ 114 - 0
app/adminapi/controller/v1/product/CopyTaobao.php

@@ -0,0 +1,114 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\product;
+
+use app\adminapi\controller\AuthController;
+use app\services\product\product\CopyTaobaoServices;
+use app\services\serve\ServeServices;
+use think\facade\App;
+
+
+/**
+ * Class CopyTaobao
+ * @package app\adminapi\controller\v1\product
+ */
+class CopyTaobao extends AuthController
+{
+    /**
+     * CopyTaobao constructor.
+     * @param App $app
+     * @param CopyTaobaoServices $services
+     */
+    public function __construct(App $app, CopyTaobaoServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取复制商品配置信息
+     * @return mixed
+     */
+    public function getConfig()
+    {
+        $data = [];
+        $copy = sys_config('system_product_copy_type', 1);
+        $data['copy_type'] = $copy;
+        $data['copy_num'] = 0;
+        if ($copy == 1) {//一号通
+            /** @var ServeServices $serverServices */
+            $serverServices = app()->make(ServeServices::class);
+            try {
+                $info = $serverServices->user()->getUser();
+            } catch (\Throwable $e) {
+                $info = [];
+            }
+            if ($info) {
+                $data['copy_num'] = $info['copy']['num'] ?? 0;
+            }
+        }
+        return app('json')->success($data);
+    }
+
+    /**
+     * 复制商品
+     * @return mixed
+     */
+    public function copyProduct()
+    {
+        list($type, $id, $shopid, $url) = $this->request->postMore([
+            ['type', ''],
+            ['id', ''],
+            ['shopid', ''],
+            ['url', '']
+        ], true);
+        $res = $this->services->copyProduct($type, $id, $shopid, $url);
+        return app('json')->success($res);
+    }
+
+    /**
+     * 保存图片保存商品信息
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function save_product()
+    {
+        $data = $this->request->postMore([
+            ['cate_id', ''],
+            ['store_name', ''],
+            ['store_info', ''],
+            ['keyword', ''],
+            ['unit_name', ''],
+            ['image', ''],
+            ['slider_image', []],
+            ['price', 0],
+            ['ot_price', 0],
+            ['give_integral', ''],
+            ['postage', ''],
+            ['sales', 0],
+            ['ficti', ''],
+            ['stock', 0],
+            ['cost', 0],
+            ['description_images', []],
+            ['description', ''],
+            ['is_show', 0],
+            ['soure_link', ''],
+            ['temp_id', 0],
+            ['spec_type', 0],
+            ['items', []],
+            ['attrs', []]
+        ]);
+        $this->services->save($data);
+        return app('json')->success(100000);
+    }
+}

+ 172 - 0
app/adminapi/controller/v1/product/StoreCategory.php

@@ -0,0 +1,172 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\product;
+
+use app\adminapi\controller\AuthController;
+use app\services\product\product\StoreCategoryServices;
+use think\facade\App;
+
+/**
+ * 商品分类控制器
+ * Class StoreCategory
+ * @package app\admin\controller\system
+ */
+class StoreCategory extends AuthController
+{
+    /**
+     * @var StoreCategoryServices
+     */
+    protected $service;
+
+    /**
+     * StoreCategory constructor.
+     * @param App $app
+     * @param StoreCategoryServices $service
+     */
+    public function __construct(App $app, StoreCategoryServices $service)
+    {
+        parent::__construct($app);
+        $this->service = $service;
+    }
+
+    /**
+     * 分类列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['is_show', ''],
+            ['pid', ''],
+            ['cate_name', ''],
+        ]);
+        $data = $this->service->getList($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 商品分类搜索
+     * @param $type
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function tree_list($type)
+    {
+        $list = $this->service->getTierList(1, $type);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 获取分类cascader格式数据
+     * @param $type
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function cascader_list($type = 1)
+    {
+        return app('json')->success($this->service->cascaderList(1, $type));
+    }
+
+    /**
+     * 修改状态
+     * @param string $is_show
+     * @param string $id
+     */
+    public function set_show($is_show = '', $id = '')
+    {
+        if ($is_show == '' || $id == '') return app('json')->fail(100100);
+        $this->service->setShow($id, $is_show);
+        return app('json')->success($is_show == 1 ? 100003 : 100004);
+    }
+
+    /**
+     * 生成新增表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create()
+    {
+        return app('json')->success($this->service->createForm());
+    }
+
+    /**
+     * 保存新增分类
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['pid', 0],
+            ['cate_name', ''],
+            ['pic', ''],
+            ['big_pic', ''],
+            ['sort', 0],
+            ['is_show', 0]
+        ]);
+        $this->service->createData($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 生成更新表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->service->editForm((int)$id));
+    }
+
+    /**
+     * 更新分类
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['pid', 0],
+            ['cate_name', ''],
+            ['pic', ''],
+            ['big_pic', ''],
+            ['sort', 0],
+            ['is_show', 0]
+        ]);
+
+        $this->service->editData($id, $data);
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除分类
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        $this->service->del((int)$id);
+        return app('json')->success(100002);
+    }
+}

+ 402 - 0
app/adminapi/controller/v1/product/StoreProduct.php

@@ -0,0 +1,402 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\product;
+
+
+use app\adminapi\controller\AuthController;
+use app\services\order\StoreCartServices;
+use app\services\other\CacheServices;
+use app\services\product\product\StoreCategoryServices;
+use app\services\product\product\StoreProductServices;
+use crmeb\services\FileService;
+use app\services\other\UploadService;
+use think\facade\App;
+
+/**
+ * Class StoreProduct
+ * @package app\adminapi\controller\v1\product
+ */
+class StoreProduct extends AuthController
+{
+    protected $service;
+
+    public function __construct(App $app, StoreProductServices $service)
+    {
+        parent::__construct($app);
+        $this->service = $service;
+    }
+
+    /**
+     * 显示资源列表头部
+     * @return mixed
+     */
+    public function type_header()
+    {
+        $list = $this->service->getHeader();
+        return app('json')->success(compact('list'));
+    }
+
+    /**
+     * 获取退出未保存的数据
+     * @param CacheServices $services
+     * @return mixed
+     */
+    public function getCacheData(CacheServices $services)
+    {
+        return app('json')->success(['info' => $services->getDbCache($this->adminId . '_product_data', [])]);
+    }
+
+    /**
+     * 1分钟保存一次产品数据
+     * @param CacheServices $services
+     * @return mixed
+     */
+    public function saveCacheData(CacheServices $services)
+    {
+        $data = $this->request->postMore([
+            ['cate_id', []],
+            ['store_name', ''],
+            ['store_info', ''],
+            ['keyword', ''],
+            ['unit_name', '件'],
+            ['image', []],
+            ['recommend_image', ''],
+            ['slider_image', []],
+            ['postage', 0],
+            ['is_sub', []],//佣金是单独还是默认
+            ['sort', 0],
+            ['sales', 0],
+            ['ficti', 100],
+            ['give_integral', 0],
+            ['is_show', 0],
+            ['temp_id', 0],
+            ['is_hot', 0],
+            ['is_benefit', 0],
+            ['is_best', 0],
+            ['is_new', 0],
+            ['mer_use', 0],
+            ['is_postage', 0],
+            ['is_good', 0],
+            ['description', ''],
+            ['spec_type', 0],
+            ['video_link', ''],
+            ['items', []],
+            ['attrs', []],
+            ['activity', []],
+            ['coupon_ids', []],
+            ['label_id', []],
+            ['command_word', ''],
+            ['tao_words', ''],
+            ['type', 0]
+        ]);
+        $services->setDbCache($this->adminId . '_product_data', $data, 68400);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 删除数据缓存
+     * @param CacheServices $services
+     * @return mixed
+     */
+    public function deleteCacheData(CacheServices $services)
+    {
+        $services->delectDbCache($this->adminId . '_product_data');
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 显示资源列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['store_name', ''],
+            ['cate_id', ''],
+            ['type', 1],
+            ['sales', 'normal']
+        ]);
+        $data = $this->service->getList($where);
+        return app('json')->success($data);
+    }
+
+    /**
+     * 修改状态
+     * @param string $is_show
+     * @param string $id
+     * @return mixed
+     */
+    public function set_show($is_show = '', $id = '')
+    {
+        $this->service->setShow([$id], $is_show);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 设置批量商品上架
+     * @return mixed
+     */
+    public function product_show()
+    {
+        [$ids] = $this->request->postMore([
+            ['ids', []]
+        ], true);
+        $this->service->setShow($ids, 1);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 设置批量商品下架
+     * @return mixed
+     */
+    public function product_unshow()
+    {
+        [$ids] = $this->request->postMore([
+            ['ids', []]
+        ], true);
+        $this->service->setShow($ids, 0);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 获取规格模板
+     * @return mixed
+     */
+    public function get_rule()
+    {
+        $list = $this->service->getRule();
+        return app('json')->success($list);
+    }
+
+    /**
+     * 获取商品详细信息
+     * @param int $id
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function get_product_info($id = 0)
+    {
+        return app('json')->success($this->service->getInfo((int)$id));
+    }
+
+    /**
+     * 保存新建或编辑
+     * @param $id
+     * @return mixed
+     * @throws \Exception
+     */
+    public function save($id)
+    {
+        $data = $this->request->postMore([
+            ['virtual_type', 0],// 商品类型
+            ['cate_id', []],//分类id
+            ['store_name', ''],//商品名称
+            ['keyword', ''],//关键字
+            ['unit_name', '件'],//单位
+            ['store_info', ''],//商品简介
+            ['slider_image', []],//轮播图
+            ['video_open', 0],//是否开启视频
+            ['video_link', ''],//视频链接
+            ['spec_type', 0],//单多规格
+            ['items', []],//规格
+            ['attrs', []],//规格
+            ['description', ''],//商品详情
+            ['description_images', []],//商品详情
+            ['logistics', []],//物流方式
+            ['freight', 1],//运费设置
+            ['postage', 0],//邮费
+            ['temp_id', 0],//运费模版id
+            ['give_integral', 0],//赠送积分
+            ['presale', 0],//预售商品开关
+            ['presale_time', 0],//预售时间
+            ['presale_day', 0],//预售发货日
+            ['vip_product', 0],//是否付费会员商品
+            ['is_sub', []],//佣金是单独还是默认
+            ['recommend', []],//商品推荐
+            ['activity', []],//活动优先级
+            ['recommend_list', []],//优品推荐商品
+            ['coupon_ids', []],//优惠券
+            ['label_id', []],//用户标签
+            ['command_word', ''],//商品口令
+            ['is_show', 0],//是否上架
+            ['ficti', 0],//虚拟销量
+            ['sort', 0],//排序
+            ['recommend_image', ''],//商品推荐图
+            ['sales', 0],//销量
+            ['custom_form', []],//自定义表单
+            ['type', 0],
+            ['is_copy', 0],//是否是复制商品
+            ['is_limit', 0],//是否限购
+            ['limit_type', 0],//限购类型
+            ['limit_num', 0]//限购数量
+        ]);
+        $this->service->save((int)$id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 删除指定资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id)
+    {
+        //删除商品检测是否有参与活动
+        $this->service->checkActivity($id);
+        $res = $this->service->del($id);
+        /** @var StoreCartServices $cartService */
+        $cartService = app()->make(StoreCartServices::class);
+        $cartService->changeStatus($id, 0);
+        return app('json')->success($res);
+    }
+
+    /**
+     * 生成规格列表
+     * @param int $id
+     * @param int $type
+     * @return mixed
+     */
+    public function is_format_attr($id = 0, $type = 0)
+    {
+        $data = $this->request->postMore([
+            ['attrs', []],
+            ['items', []],
+            ['is_virtual', 0],
+            ['virtual_type', 0]
+        ]);
+        if ($id > 0 && $type == 1) $this->service->checkActivity($id);
+        $info = $this->service->getAttr($data, $id, $type);
+        return app('json')->success(compact('info'));
+    }
+
+
+    /**
+     * 获取选择的商品列表
+     * @return mixed
+     */
+    public function search_list()
+    {
+        $where = $this->request->getMore([
+            ['cate_id', ''],
+            ['store_name', ''],
+            ['type', 1],
+            ['is_live', 0],
+            ['is_new', ''],
+            ['is_virtual', -1],
+            ['is_presale', -1]
+        ]);
+        $where['is_show'] = 1;
+        $where['is_del'] = 0;
+        /** @var StoreCategoryServices $storeCategoryServices */
+        $storeCategoryServices = app()->make(StoreCategoryServices::class);
+        if ($where['cate_id'] !== '') {
+            if ($storeCategoryServices->value(['id' => $where['cate_id']], 'pid')) {
+                $where['sid'] = $where['cate_id'];
+            } else {
+                $where['cid'] = $where['cate_id'];
+            }
+        }
+        unset($where['cate_id']);
+        $list = $this->service->searchList($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 获取某个商品规格
+     * @return mixed
+     */
+    public function get_attrs()
+    {
+        [$id, $type] = $this->request->getMore([
+            [['id', 'd'], 0],
+            [['type', 'd'], 0],
+        ], true);
+        $info = $this->service->getProductRules($id, $type);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 获取运费模板列表
+     * @return mixed
+     */
+    public function get_template()
+    {
+        return app('json')->success($this->service->getTemp());
+    }
+
+    /**
+     * 获取视频上传token
+     * @return mixed
+     * @throws \Exception
+     */
+    public function getTempKeys()
+    {
+        $upload = UploadService::init();
+        $re = $upload->getTempKeys();
+        return $re ? app('json')->success($re) : app('json')->fail(100016);
+    }
+
+    /**
+     * 检测商品是否开活动
+     * @param $id
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function check_activity($id)
+    {
+        $this->service->checkActivity($id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 导入卡密
+     * @return mixed
+     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
+     */
+    public function import_card()
+    {
+        $data = $this->request->getMore([
+            ['file', ""]
+        ]);
+        if (!$data['file']) return app('json')->fail(400168);
+        $file = public_path() . substr($data['file'], 1);
+        /** @var FileService $readExcelService */
+        $readExcelService = app()->make(FileService::class);
+        $cardData = $readExcelService->readExcel($file);
+        return app('json')->success($cardData);
+    }
+
+    /**
+     * 商品批量设置
+     * @return mixed
+     */
+    public function batchSetting()
+    {
+        $data = $this->request->postMore([
+            ['ids', []],
+            ['cate_id', []],
+            ['logistics', []],
+            ['freight', 2],
+            ['postage', 0],
+            ['temp_id', 1],
+            ['give_integral', 0],
+            ['coupon_ids', []],
+            ['label_id', []],
+            ['recommend', []],
+            ['type', 0]
+        ]);
+        $this->service->batchSetting($data);
+        return app('json')->success(100014);
+    }
+}

+ 112 - 0
app/adminapi/controller/v1/product/StoreProductReply.php

@@ -0,0 +1,112 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\product;
+
+use app\adminapi\controller\AuthController;
+use app\services\product\product\StoreProductReplyServices;
+use think\facade\App;
+
+/**
+ * 评论管理 控制器
+ * Class StoreProductReply
+ * @package app\admin\controller\store
+ */
+class StoreProductReply extends AuthController
+{
+    public function __construct(App $app, StoreProductReplyServices $service)
+    {
+        parent::__construct($app);
+        $this->services = $service;
+    }
+
+    /**
+     * 显示资源列表
+     *
+     * @return \think\Response
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['is_reply', ''],
+            ['store_name', ''],
+            ['account', ''],
+            ['data', ''],
+            ['product_id', 0],
+            ['key', ''],
+            ['order', '']
+        ]);
+        $list = $this->services->sysPage($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 删除评论
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        $this->services->del($id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 回复评论
+     * @param $id
+     * @return mixed
+     */
+    public function set_reply($id)
+    {
+        [$content] = $this->request->postMore([
+            ['content', '']
+        ], true);
+        $this->services->setReply($id, $content);
+        return app('json')->success(400169);
+    }
+
+    /**
+     * 创建虚拟评论表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function fictitious_reply()
+    {
+        list($product_id) = $this->request->postMore([
+            ['product_id', 0],
+        ], true);
+        return app('json')->success($this->services->createForm($product_id));
+    }
+
+    /**
+     * 保存虚拟评论
+     * @return mixed
+     */
+    public function save_fictitious_reply()
+    {
+        $data = $this->request->postMore([
+            ['image', ''],
+            ['nickname', ''],
+            ['avatar', ''],
+            ['comment', ''],
+            ['pics', []],
+            ['product_score', 0],
+            ['service_score', 0],
+            ['product_id', 0],
+            ['add_time', 0]
+        ]);
+        if (!$data['product_id']) {
+            $data['product_id'] = $data['image']['product_id'] ?? '';
+        }
+        $this->validate(['product_id' => $data['product_id'], 'nickname' => $data['nickname'], 'avatar' => $data['avatar'], 'comment' => $data['comment'], 'product_score' => $data['product_score'], 'service_score' => $data['service_score']], \app\adminapi\validate\product\StoreProductReplyValidate::class, 'save');
+        $this->services->saveReply($data);
+        return app('json')->success(100000);
+    }
+}

+ 87 - 0
app/adminapi/controller/v1/product/StoreProductRule.php

@@ -0,0 +1,87 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\product;
+
+use app\adminapi\controller\AuthController;
+use app\services\product\sku\StoreProductRuleServices;
+use think\facade\App;
+
+/**
+ * 规则管理
+ * Class StoreProductRule
+ * @package app\adminapi\controller\v1\product
+ */
+class StoreProductRule extends AuthController
+{
+
+    public function __construct(App $app, StoreProductRuleServices $service)
+    {
+        parent::__construct($app);
+        $this->services = $service;
+    }
+
+    /**
+     * 规格列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['rule_name', '']
+        ]);
+        $list = $this->services->getList($where);
+        return app('json')->success($list);
+    }
+
+    /**
+     * 保存规格
+     * @param $id
+     * @return mixed
+     */
+    public function save($id)
+    {
+        $data = $this->request->postMore([
+            ['rule_name', ''],
+            ['spec', []]
+        ]);
+        $this->services->save($id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 获取规格信息
+     * @param $id
+     * @return mixed
+     */
+    public function read($id)
+    {
+        $info = $this->services->getInfo($id);
+        return app('json')->success($info);
+    }
+
+    /**
+     * 删除指定资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete()
+    {
+        [$ids] = $this->request->postMore([
+            ['ids', '']
+        ], true);
+        $this->services->del((string)$ids);
+        return app('json')->success(100002);
+    }
+}

+ 83 - 0
app/adminapi/controller/v1/serve/Export.php

@@ -0,0 +1,83 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\serve;
+
+
+use app\adminapi\controller\AuthController;
+use app\services\serve\ServeServices;
+use app\services\shipping\ExpressServices;
+use think\facade\App;
+
+/**
+ * 一号通平台物流服务
+ * Class Export
+ * @package app\adminapi\controller\v1\serve
+ */
+class Export extends AuthController
+{
+
+    /**
+     * Export constructor.
+     * @param App $app
+     * @param ExpressServices $services
+     */
+    public function __construct(App $app, ExpressServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 物流公司
+     * @return mixed
+     */
+    public function getExportAll()
+    {
+        return app('json')->success($this->services->expressList());
+    }
+
+    /**
+     *
+     * 获取面单信息
+     * @param string $com
+     * @return mixed
+     */
+    public function getExportTemp(ServeServices $services)
+    {
+        [$com] = $this->request->getMore([
+            ['com', ''],
+        ], true);
+        return app('json')->success($services->express()->temp($com));
+    }
+
+    /**
+     * 打印电子面单是否开启
+     * @return mixed
+     */
+    public function dumpIsOpen(ServeServices $services)
+    {
+        $userInfo = $services->user()->getUser();
+        $res = false;
+        if ($userInfo['dump']['open']) {
+            $res = true;
+            if (!sys_config('config_export_siid')
+                && !sys_config('config_export_com')
+                && !sys_config('config_export_to_name')
+                && !sys_config('config_export_to_tel')
+                && !sys_config('config_export_to_address')
+            ) {
+                $res = false;
+            }
+        }
+        return app('json')->success(['isOpen' => $res]);
+    }
+}

+ 117 - 0
app/adminapi/controller/v1/serve/Login.php

@@ -0,0 +1,117 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\serve;
+
+
+use app\adminapi\controller\AuthController;
+use app\adminapi\validate\serve\ServeValidata;
+use app\Request;
+use app\services\yihaotong\SmsAdminServices;
+use crmeb\services\CacheService;
+use app\services\serve\ServeServices;
+use think\facade\App;
+
+/**
+ * 服务登录
+ * Class Login
+ * @package app\adminapi\controller\v1\serve
+ */
+class Login extends AuthController
+{
+
+    public function __construct(App $app, ServeServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 发送验证码
+     * @param string $phone
+     * @return mixed
+     */
+    public function captcha(string $phone)
+    {
+        $this->validate(['phone' => $phone], ServeValidata::class, 'phone');
+        return app('json')->success('发送成功', $this->services->user()->code($phone));
+    }
+
+    /**
+     * 验证验证码
+     * @param string $phone
+     * @param $code
+     * @return mixed
+     */
+    public function checkCode()
+    {
+        [$phone, $verify_code] = $this->request->postMore([
+            ['phone', ''],
+            ['verify_code', ''],
+        ], true);
+        $this->validate(['phone' => $phone], ServeValidata::class, 'phone');
+        return app('json')->success('success', $this->services->user()->checkCode($phone, $verify_code));
+    }
+
+    /**
+     * 注册服务
+     * @param Request $request
+     * @param SmsAdminServices $services
+     * @return mixed
+     */
+    public function register(Request $request, SmsAdminServices $services)
+    {
+        $data = $request->postMore([
+            ['phone', ''],
+            ['account', ''],
+            ['password', ''],
+            ['verify_code', ''],
+        ]);
+
+        $data['account'] = $data['phone'];
+        $this->validate($data, ServeValidata::class);
+        $data['password'] = md5($data['password']);
+        $res = $this->services->user()->register($data);
+        if ($res) {
+            $services->updateSmsConfig($data['account'], md5($data['account'] . md5($data['password'])));
+            return app('json')->success(400170);
+        } else {
+            return app('json')->fail(400171);
+        }
+    }
+
+    /**
+     * 平台登录
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function login(SmsAdminServices $services)
+    {
+        [$account, $password] = $this->request->postMore([
+            ['account', ''],
+            ['password', '']
+        ], true);
+
+        $this->validate(['account' => $account, 'password' => $password], ServeValidata::class, 'login');
+
+        $password = md5($account . md5($password));
+
+        $res = $this->services->user()->login($account, $password);
+        if ($res) {
+            CacheService::clear();
+            CacheService::set('sms_account', $account);
+            $services->updateSmsConfig($account, $password);
+            return app('json')->success(400139, $res);
+        } else {
+            return app('json')->fail(400172);
+        }
+    }
+}

+ 213 - 0
app/adminapi/controller/v1/serve/Serve.php

@@ -0,0 +1,213 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\serve;
+
+
+use app\adminapi\controller\AuthController;
+use app\adminapi\validate\serve\ExpressValidata;
+use app\adminapi\validate\serve\MealValidata;
+use app\adminapi\validate\serve\ServeValidata;
+use app\services\system\config\SystemConfigServices;
+use crmeb\services\CacheService;
+use app\services\serve\ServeServices;
+use think\facade\App;
+
+/**
+ * Class Serve
+ * @package app\adminapi\controller\v1\serve
+ */
+class Serve extends AuthController
+{
+    /**
+     * Serve constructor.
+     * @param App $app
+     * @param ServeServices $services
+     */
+    public function __construct(App $app, ServeServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 检测登录
+     * @return mixed
+     */
+    public function is_login()
+    {
+        $sms_info = CacheService::get('sms_account');
+        if ($sms_info) {
+            return app('json')->success(['status' => true, 'info' => $sms_info]);
+        } else {
+            return app('json')->success(['status' => false]);
+        }
+    }
+
+    /**
+     * 获取套餐列表
+     * @param string $type
+     * @return mixed
+     */
+    public function mealList(string $type)
+    {
+        $res = $this->services->user()->mealList($type);
+        if ($res) {
+            return app('json')->success($res);
+        } else {
+            return app('json')->fail(400173);
+        }
+    }
+
+    /**
+     * 获取支付码
+     * @return mixed
+     */
+    public function payMeal()
+    {
+        $data = $this->request->postMore([
+            ['meal_id', ''],
+            ['price', ''],
+            ['num', ''],
+            ['type', ''],
+            ['pay_type', ''],
+        ]);
+        $openInfo = $this->services->user()->getUser();
+        if (!$openInfo) app('json')->fail(400174);
+        switch ($data['type']) {
+            case "sms" :
+                if (!$openInfo['sms']['open']) return app('json')->fail(400175);
+                break;
+            case "query" :
+                if (!$openInfo['query']['open']) return app('json')->fail(400176);
+                break;
+            case "dump" :
+                if (!$openInfo['dump']['open']) return app('json')->fail(400177);
+                break;
+            case "copy" :
+                if (!$openInfo['copy']['open']) return app('json')->fail(400178);
+                break;
+        }
+        $this->validate($data, MealValidata::class);
+
+        $res = $this->services->user()->payMeal($data);
+        if ($res) {
+            return app('json')->success($res);
+        } else {
+            return app('json')->fail(400174);
+        }
+    }
+
+    /**
+     * 开通打印电子面单
+     * @return mixed
+     */
+    public function openExpress()
+    {
+        $data = $this->request->postMore([
+            ['com', ''],
+            ['temp_id', ''],
+            ['to_name', ''],
+            ['to_tel', ''],
+            ['to_address', ''],
+            ['siid', ''],
+        ]);
+
+        $this->validate($data, ExpressValidata::class);
+
+        /** @var SystemConfigServices $systemConfigService */
+        $systemConfigService = app()->make(SystemConfigServices::class);
+        $systemConfigService->saveExpressInfo($data);
+        $this->services->express()->open();
+        return app('json')->success(100044);
+
+    }
+
+    /**
+     * 获取用户信息,用户信息内包含是否开通服务字段
+     * @return mixed
+     */
+    public function getUserInfo()
+    {
+        return app('json')->success($this->services->user()->getUser());
+    }
+
+    /**
+     * 查询记录
+     * @return mixed
+     */
+    public function getRecord()
+    {
+        [$page, $limit, $type] = $this->request->getMore([
+            [['page', 'd'], 0],
+            [['limit', 'd'], 10],
+            [['type', 'd'], 0],
+        ], true);
+
+        return app('json')->success($this->services->user()->record($page, $limit, $type));
+    }
+
+    /**
+     * 开通服务
+     * @param int $type
+     * @return mixed
+     */
+    public function openServe($type = 0)
+    {
+        if ($type) {
+            $this->services->copy()->open();
+        } else {
+            $this->services->express()->open();
+        }
+
+        return app('json')->success(100044);
+    }
+
+    /**
+     * 修改密码
+     * @return mixed
+     */
+    public function modify()
+    {
+        $data = $this->request->postMore([
+            ['account', ''],
+            ['password', ''],
+            ['phone', ''],
+            ['verify_code', ''],
+        ]);
+
+        $this->validate($data, ServeValidata::class);
+
+        $data['password'] = md5($data['password']);
+        $this->services->user()->modify($data);
+        CacheService::delete('sms_account');
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 修改手机号
+     * @return mixed
+     */
+    public function updatePhone()
+    {
+        $data = $this->request->postMore([
+            ['account', ''],
+            ['phone', ''],
+            ['verify_code', ''],
+        ]);
+
+        $this->validate($data, ServeValidata::class, 'phone');
+
+        $this->services->user()->modifyPhone($data);
+        CacheService::delete('sms_account');
+        return app('json')->success(100001);
+    }
+}

+ 121 - 0
app/adminapi/controller/v1/serve/Sms.php

@@ -0,0 +1,121 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+
+namespace app\adminapi\controller\v1\serve;
+
+
+use app\adminapi\controller\AuthController;
+use app\adminapi\validate\serve\ServeValidata;
+use app\services\serve\ServeServices;
+use think\facade\App;
+
+/**
+ * Class Sms
+ * @package app\adminapi\controller\v1\serve
+ */
+class Sms extends AuthController
+{
+    /**
+     * Sms constructor.
+     * @param App $app
+     * @param ServeServices $services
+     */
+    public function __construct(App $app, ServeServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+
+    /**
+     * 开通服务
+     * @param string $sign
+     * @return mixed
+     */
+    public function openServe(string $sign)
+    {
+        if (!$sign) {
+            return app('json')->fail(400179);
+        }
+        $this->services->sms()->setSign($sign)->open();
+        return app('json')->success(100044);
+    }
+
+    /**
+     * 修改短信签名
+     * @param string $sign
+     * @return mixed
+     */
+    public function editSign(string $sign)
+    {
+        [$sign, $phone, $code] = $this->request->postMore([
+            ['sign', ''],
+            ['phone', ''],
+            ['code', ''],
+        ], true);
+
+        $this->validate(['phone' => $phone], ServeValidata::class, 'phone');
+
+        if (!$sign) {
+            return app('json')->fail(400179);
+        }
+        $this->services->sms()->modify($sign, $phone, $code);
+        return app('json')->success(400180);
+    }
+
+    /**
+     * 获取短信模板
+     * @return mixed
+     */
+    public function temps()
+    {
+        [$page, $limit, $type] = $this->request->getMore([
+            ['page', 1],
+            ['limit', 10],
+            ['temp_type', 0],
+        ], true);
+
+        return app('json')->success($this->services->getSmsTempsList((int)$page, (int)$limit, (int)$type));
+    }
+
+    /**
+     * 申请模板
+     * @return mixed
+     */
+    public function apply()
+    {
+        [$title, $content, $type] = $this->request->postMore([
+            ['title', ''],
+            ['content', ''],
+            ['type', 0]
+        ], true);
+
+        if (!$title || !$content || !$type) {
+            return app('json')->success(400143);
+        }
+        return app('json')->success($this->services->sms()->apply($title, $content, (int)$type));
+    }
+
+    /**
+     * 获取申请记录
+     * @return mixed
+     */
+    public function applyRecord()
+    {
+        [$page, $limit, $tempType] = $this->request->getMore([
+            [['page', 'd'], 1],
+            [['limit', 'd'], 10],
+            [['temp_type', 'd'], 0],
+        ], true);
+
+        return app('json')->success($this->services->sms()->applys($tempType, $page, $limit));
+    }
+}

+ 105 - 0
app/adminapi/controller/v1/setting/LangCode.php

@@ -0,0 +1,105 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\system\lang\LangCodeServices;
+use think\facade\App;
+
+class LangCode extends AuthController
+{
+    /**
+     * @param App $app
+     * @param LangCodeServices $services
+     */
+    public function __construct(App $app, LangCodeServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取语言列表
+     * @return mixed
+     * @throws \ReflectionException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function langCodeList()
+    {
+        $where = $this->request->getMore([
+            ['is_admin', 0],
+            ['type_id', 0],
+            ['code', ''],
+            ['remarks', '']
+        ]);
+        return app('json')->success($this->services->langCodeList($where));
+    }
+
+    /**
+     * 获取语言详情
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function langCodeInfo()
+    {
+        [$code] = $this->request->getMore([
+            ['code', ''],
+        ], true);
+        return app('json')->success($this->services->langCodeInfo($code));
+    }
+
+    /**
+     * 新增编辑语言
+     * @return mixed
+     * @throws \Exception
+     */
+    public function langCodeSave()
+    {
+        $data = $this->request->postMore([
+            ['is_admin', 0],
+            ['code', ''],
+            ['remarks', ''],
+            ['edit', 0],
+            ['list', []]
+        ]);
+        $this->services->langCodeSave($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 删除语言
+     * @param $id
+     * @return mixed
+     */
+    public function langCodeDel($id)
+    {
+        $this->services->langCodeDel($id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 机器翻译
+     * @return mixed
+     * @throws \Throwable
+     */
+    public function langCodeTranslate()
+    {
+        [$text] = $this->request->postMore([
+            ['text', '']
+        ], true);
+        if ($text == '') return app('json')->fail(100100);
+        return app('json')->success($this->services->langCodeTranslate($text));
+    }
+}

+ 79 - 0
app/adminapi/controller/v1/setting/LangCountry.php

@@ -0,0 +1,79 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\system\lang\LangCountryServices;
+use think\facade\App;
+
+class LangCountry extends AuthController
+{
+    /**
+     * @param App $app
+     * @param LangCountryServices $services
+     */
+    public function __construct(App $app, LangCountryServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 国家语言列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function langCountryList()
+    {
+        $where = $this->request->getMore([
+            ['keyword', ''],
+        ]);
+        return app('json')->success($this->services->langCountryList($where));
+    }
+
+    /**
+     * 设置国家语言类型表单
+     * @param $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function langCountryForm($id)
+    {
+        return app('json')->success($this->services->langCountryForm($id));
+    }
+
+    /**
+     * 地区语言修改
+     * @param $id
+     * @return mixed
+     */
+    public function langCountrySave($id)
+    {
+        $data = $this->request->postMore([
+            ['name', ''],
+            ['code', ''],
+            ['type_id', 0],
+        ]);
+        $this->services->langCountrySave($id, $data);
+        return app('json')->success(100000);
+    }
+
+    public function langCountryDel($id)
+    {
+        $this->services->langCountryDel($id);
+        return app('json')->success(100002);
+    }
+}

+ 95 - 0
app/adminapi/controller/v1/setting/LangType.php

@@ -0,0 +1,95 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\system\lang\LangTypeServices;
+use crmeb\services\CacheService;
+use think\facade\App;
+
+class LangType extends AuthController
+{
+    /**
+     * @param App $app
+     * @param LangTypeServices $services
+     */
+    public function __construct(App $app, LangTypeServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取语言类型列表
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function langTypeList()
+    {
+        $where['is_del'] = 0;
+        return app('json')->success($this->services->langTypeList($where));
+    }
+
+    /**
+     * 添加语言类型表单
+     * @param int $id
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function langTypeForm(int $id = 0)
+    {
+        return app('json')->success($this->services->langTypeForm($id));
+    }
+
+    /**
+     * 保存语言类型
+     * @return mixed
+     */
+    public function langTypeSave()
+    {
+        $data = $this->request->postMore([
+            ['id', 0],
+            ['language_name', ''],
+            ['file_name', ''],
+            ['is_default', 0],
+            ['status', 0]
+        ]);
+        $this->services->langTypeSave($data);
+        CacheService::delete('lang_type_data');
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 修改语言类型状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function langTypeStatus($id, $status)
+    {
+        $this->services->langTypeStatus($id, $status);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 删除语言类型
+     * @param int $id
+     * @return mixed
+     */
+    public function langTypeDel(int $id = 0)
+    {
+        $this->services->langTypeDel($id);
+        CacheService::delete('lang_type_data');
+        return app('json')->success(100002);
+    }
+}

+ 113 - 0
app/adminapi/controller/v1/setting/ShippingTemplates.php

@@ -0,0 +1,113 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\shipping\ShippingTemplatesServices;
+use app\services\shipping\SystemCityServices;
+use think\facade\App;
+
+/**
+ * 运费模板
+ * Class ShippingTemplates
+ * @package app\adminapi\controller\v1\setting
+ */
+class ShippingTemplates extends AuthController
+{
+    /**
+     * 构造方法
+     * ShippingTemplates constructor.
+     * @param App $app
+     * @param ShippingTemplatesServices $services
+     */
+    public function __construct(App $app, ShippingTemplatesServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 运费模板列表
+     * @return mixed
+     */
+    public function temp_list()
+    {
+        $where = $this->request->getMore([
+            [['name', 's'], '']
+        ]);
+        return app('json')->success($this->services->getShippingList($where));
+    }
+
+    /**
+     * 修改
+     * @return string
+     * @throws \Exception
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->getShipping((int)$id));
+    }
+
+    /**
+     * 保存或者修改
+     * @param int $id
+     */
+    public function save($id = 0)
+    {
+        $data = $this->request->postMore([
+            [['region_info', 'a'], []],
+            [['appoint_info', 'a'], []],
+            [['no_delivery_info', 'a'], []],
+            [['sort', 'd'], 0],
+            [['type', 'd'], 0],
+            [['name', 's'], ''],
+            [['appoint', 'd'], 0],
+            [['no_delivery', 'd'], 0]
+        ]);
+        $this->validate($data, \app\adminapi\validate\setting\ShippingTemplatesValidate::class, 'save');
+        $temp['name'] = $data['name'];
+        $temp['type'] = $data['type'];
+        $temp['appoint'] = $data['appoint'] && $data['appoint_info'] ? 1 : 0;
+        $temp['no_delivery'] = $data['no_delivery'] && $data['no_delivery_info'] ? 1 : 0;
+        $temp['sort'] = $data['sort'];
+        $temp['add_time'] = time();
+        $this->services->save((int)$id, $temp, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 删除运费模板
+     */
+    public function delete()
+    {
+        [$id] = $this->request->getMore([
+            [['id', 'd'], 0],
+        ], true);
+        if ($id == 1) {
+            return app('json')->fail(400181);
+        } else {
+            $this->services->detete($id);
+            return app('json')->success(100002);
+        }
+    }
+
+    /**
+     * 城市数据
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function city_list(SystemCityServices $services)
+    {
+        return app('json')->success($services->getShippingCity());
+    }
+}

+ 210 - 0
app/adminapi/controller/v1/setting/SystemAdmin.php

@@ -0,0 +1,210 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\system\admin\SystemAdminServices;
+use crmeb\services\CacheService;
+use think\facade\{App, Config};
+
+/**
+ * Class SystemAdmin
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemAdmin extends AuthController
+{
+    /**
+     * SystemAdmin constructor.
+     * @param App $app
+     * @param SystemAdminServices $services
+     */
+    public function __construct(App $app, SystemAdminServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示管理员资源列表
+     *
+     * @return \think\Response
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['name', '', '', 'account_like'],
+            ['roles', ''],
+            ['is_del', 1],
+            ['status', '']
+        ]);
+        $where['level'] = $this->adminInfo['level'] + 1;
+        return app('json')->success($this->services->getAdminList($where));
+    }
+
+    /**
+     * 创建表单
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->createForm($this->adminInfo['level'] + 1));
+    }
+
+    /**
+     * 保存管理员
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['account', ''],
+            ['conf_pwd', ''],
+            ['pwd', ''],
+            ['real_name', ''],
+            ['roles', []],
+            ['status', 0],
+        ]);
+
+        $this->validate($data, \app\adminapi\validate\setting\SystemAdminValidata::class);
+
+        $data['level'] = $this->adminInfo['level'] + 1;
+        $this->services->create($data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 显示编辑资源表单页.
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function edit($id)
+    {
+        if (!$id) {
+            return app('json')->fail(400182);
+        }
+
+        return app('json')->success($this->services->updateForm($this->adminInfo['level'] + 1, (int)$id));
+    }
+
+    /**
+     * 修改管理员信息
+     * @param $id
+     * @return mixed
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            ['account', ''],
+            ['conf_pwd', ''],
+            ['pwd', ''],
+            ['real_name', ''],
+            ['roles', []],
+            ['status', 0],
+        ]);
+
+        $this->validate($data, \app\adminapi\validate\setting\SystemAdminValidata::class, 'update');
+
+        if ($this->services->save((int)$id, $data)) {
+            return app('json')->success(100001);
+        } else {
+            return app('json')->fail(100007);
+        }
+    }
+
+    /**
+     * 删除管理员
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if (!$id) return app('json')->fail(100100);
+        if ($this->services->update((int)$id, ['is_del' => 1, 'status' => 0]))
+            return app('json')->success(100002);
+        else
+            return app('json')->fail(100008);
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        $this->services->update((int)$id, ['status' => $status]);
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 获取当前登陆管理员的信息
+     * @return mixed
+     */
+    public function info()
+    {
+        return app('json')->success($this->adminInfo);
+    }
+
+    /**
+     * 修改当前登陆admin信息
+     * @return mixed
+     */
+    public function update_admin()
+    {
+        $data = $this->request->postMore([
+            ['real_name', ''],
+            ['head_pic', ''],
+            ['pwd', ''],
+            ['new_pwd', ''],
+            ['conf_pwd', ''],
+        ]);
+        if (!preg_match('/^(?![^a-zA-Z]+$)(?!\D+$).{6,}$/', $data['new_pwd'])) {
+            return app('json')->fail(400183);
+        }
+        if ($this->services->updateAdmin($this->adminId, $data))
+            return app('json')->success(100001);
+        else
+            return app('json')->fail(100007);
+    }
+
+    /**
+     * 修改当前登陆admin的文件管理密码
+     * @return mixed
+     */
+    public function set_file_password()
+    {
+        $data = $this->request->postMore([
+            ['file_pwd', ''],
+            ['conf_file_pwd', ''],
+        ]);
+        if (!preg_match('/^(?![^a-zA-Z]+$)(?!\D+$).{6,}$/', $data['file_pwd'])) {
+            return app('json')->fail(400183);
+        }
+        if ($this->services->setFilePassword($this->adminId, $data))
+            return app('json')->success(100001);
+        else
+            return app('json')->fail(100007);
+    }
+
+    /**
+     * 退出登陆
+     * @return mixed
+     */
+    public function logout()
+    {
+        $key = trim(ltrim($this->request->header(Config::get('cookie.token_name')), 'Bearer'));
+        CacheService::delete(md5($key));
+        return app('json')->success();
+    }
+}

+ 54 - 0
app/adminapi/controller/v1/setting/SystemAgreement.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\other\AgreementServices;
+use think\facade\App;
+
+class SystemAgreement extends AuthController
+{
+    /**
+     * 构造方法
+     * SystemCity constructor.
+     * @param App $app
+     * @param AgreementServices $services
+     */
+    public function __construct(App $app, AgreementServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取协议内容
+     * @param $type
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getAgreement($type)
+    {
+        if (!$type) return app('json')->fail(400184);
+        $info = $this->services->getAgreementBytype($type);
+        return app('json')->success($info);
+    }
+
+    /**
+     * 保存协议内容
+     * @return mixed
+     */
+    public function saveAgreement()
+    {
+        $data = $this->request->postMore([
+            ['id', 0],
+            ['type', 0],
+            ['title', ''],
+            ['content', ''],
+        ]);
+        $data['status'] = 1;
+        $this->services->saveAgreement($data, $data['id']);
+        return app('json')->success(100000);
+    }
+}

+ 143 - 0
app/adminapi/controller/v1/setting/SystemCity.php

@@ -0,0 +1,143 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\shipping\SystemCityServices;
+use think\facade\App;
+use crmeb\services\{CacheService};
+
+
+/**
+ * 城市数据
+ * Class SystemCity
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemCity extends AuthController
+{
+    /**
+     * 构造方法
+     * SystemCity constructor.
+     * @param App $app
+     * @param SystemCityServices $services
+     */
+    public function __construct(App $app, SystemCityServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 城市列表
+     * @return string
+     * @throws \Exception
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            [['parent_id', 'd'], 0]
+        ]);
+        return app('json')->success($this->services->getCityList($where));
+    }
+
+    /**
+     * 添加城市
+     * @return mixed
+     * @throws \FormBuilder\Exception\FormBuilderException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function add()
+    {
+        [$parentId] = $this->request->getMore([
+            [['parent_id', 'd'], 0]
+        ], true);
+        return app('json')->success($this->services->createCityForm($parentId));
+    }
+
+    /**
+     * 保存
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            [['id', 'd'], 0],
+            [['name', 's'], ''],
+            [['merger_name', 's'], ''],
+            [['area_code', 's'], ''],
+            [['lng', 's'], ''],
+            [['lat', 's'], ''],
+            [['level', 'd'], 0],
+            [['parent_id', 'd'], 0],
+        ]);
+        $this->validate($data, \app\adminapi\validate\setting\SystemCityValidate::class, 'save');
+        if ($data['parent_id'] == 0) {
+            $data['merger_name'] = $data['name'];
+        } else {
+            $data['merger_name'] = $this->services->value(['id' => $data['parent_id']], 'name') . ',' . $data['name'];
+        }
+        if ($data['id'] == 0) {
+            unset($data['id']);
+            $data['level'] = $data['level'] + 1;
+            $data['city_id'] = intval($this->services->getCityIdMax() + 1);
+            $this->services->save($data);
+            return app('json')->success(100000);
+        } else {
+            unset($data['level']);
+            unset($data['parent_id']);
+            $this->services->update($data['id'], $data);
+            return app('json')->success(100001);
+        }
+    }
+
+    /**
+     * 修改城市
+     * @return string
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function edit()
+    {
+        [$id] = $this->request->getMore([
+            [['id', 'd'], 0]
+        ], true);
+        return app('json')->success($this->services->updateCityForm($id));
+    }
+
+    /**
+     * 删除城市
+     * @throws \Exception
+     */
+    public function delete()
+    {
+        [$id] = $this->request->getMore([
+            [['city_id', 'd'], 0]
+        ], true);
+        $this->services->deleteCity($id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 清除城市缓存
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function clean_cache()
+    {
+        $res = CacheService::delete('CITY_LIST');
+        if ($res) {
+            return app('json')->success(400185);
+        } else {
+            return app('json')->fail(400186);
+        }
+    }
+}

+ 413 - 0
app/adminapi/controller/v1/setting/SystemConfig.php

@@ -0,0 +1,413 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\Request;
+use app\services\order\StoreOrderServices;
+use app\services\system\config\SystemConfigServices;
+use app\services\system\config\SystemConfigTabServices;
+use think\facade\App;
+
+/**
+ * 系统配置
+ * Class SystemConfig
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemConfig extends AuthController
+{
+
+    /**
+     * SystemConfig constructor.
+     * @param App $app
+     * @param SystemConfigServices $services
+     */
+    public function __construct(App $app, SystemConfigServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     *
+     * @return \think\Response
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['tab_id', 0],
+            ['status', -1]
+        ]);
+        if (!$where['tab_id']) {
+            return app('json')->fail(100100);
+        }
+        if ($where['status'] == -1) {
+            unset($where['status']);
+        }
+        return app('json')->success($this->services->getConfigList($where));
+    }
+
+    /**
+     * 显示创建资源表单页.
+     * @param $type
+     * @return \think\Response
+     */
+    public function create()
+    {
+        [$type, $tabId] = $this->request->getMore([
+            [['type', 'd'], ''],
+            [['tab_id', 'd'], 1]
+        ], true);
+        return app('json')->success($this->services->createFormRule($type, $tabId));
+    }
+
+    /**
+     * 保存新建的资源
+     *
+     * @return \think\Response
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['menu_name', ''],
+            ['type', ''],
+            ['input_type', 'input'],
+            ['config_tab_id', 0],
+            ['parameter', ''],
+            ['upload_type', 1],
+            ['required', ''],
+            ['width', 0],
+            ['high', 0],
+            ['value', ''],
+            ['info', ''],
+            ['desc', ''],
+            ['sort', 0],
+            ['status', 0]
+        ]);
+        if (!$data['info']) return app('json')->fail(400274);
+        if (!$data['menu_name']) return app('json')->fail(400275);
+        if (!$data['desc']) return app('json')->fail(400276);
+        if ($data['sort'] < 0) {
+            $data['sort'] = 0;
+        }
+        if ($data['type'] == 'text') {
+            if (!$data['width']) return app('json')->fail(400277);
+            if ($data['width'] <= 0) return app('json')->fail(400278);
+        }
+        if ($data['type'] == 'textarea') {
+            if (!$data['width']) return app('json')->fail(400279);
+            if (!$data['high']) return app('json')->fail(400280);
+            if ($data['width'] < 0) return app('json')->fail(400281);
+            if ($data['high'] < 0) return app('json')->fail(400282);
+        }
+        if ($data['type'] == 'radio' || $data['type'] == 'checkbox') {
+            if (!$data['parameter']) return app('json')->fail(400283);
+            $this->services->valiDateRadioAndCheckbox($data);
+        }
+        $data['value'] = json_encode($data['value']);
+        $config = $this->services->getOne(['menu_name' => $data['menu_name']]);
+        if ($config) {
+            $this->services->update($config['id'], $data, 'id');
+        } else {
+            $this->services->save($data);
+        }
+        \crmeb\services\CacheService::clear();
+        return app('json')->success(400284);
+    }
+
+    /**
+     * 显示指定的资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function read($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        $info = $this->services->getReadList((int)$id);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 显示编辑资源表单页.
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->editConfigForm((int)$id));
+    }
+
+    /**
+     * 保存更新的资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function update($id)
+    {
+        $type = request()->post('type');
+        if ($type == 'text' || $type == 'textarea' || $type == 'radio' || ($type == 'upload' && (request()->post('upload_type') == 1 || request()->post('upload_type') == 3))) {
+            $value = request()->post('value');
+        } else {
+            $value = request()->post('value/a');
+        }
+        if (!$value) $value = request()->post(request()->post('menu_name'));
+        $data = $this->request->postMore([
+            ['menu_name', ''],
+            ['type', ''],
+            ['input_type', 'input'],
+            ['config_tab_id', 0],
+            ['parameter', ''],
+            ['upload_type', 1],
+            ['required', ''],
+            ['width', 0],
+            ['high', 0],
+            ['value', $value],
+            ['info', ''],
+            ['desc', ''],
+            ['sort', 0],
+            ['status', 0]
+        ]);
+        if (!$this->services->get($id)) {
+            return app('json')->fail(100026);
+        }
+        $data['value'] = json_encode($data['value']);
+        $this->services->update($id, $data);
+        \crmeb\services\CacheService::clear();
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除指定资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id)
+    {
+        if (!$this->services->delete($id))
+            return app('json')->fail(100008);
+        else {
+            \crmeb\services\CacheService::clear();
+            return app('json')->success(100002);
+        }
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        if ($status == '' || $id == 0) {
+            return app('json')->fail(100100);
+        }
+        $this->services->update($id, ['status' => $status]);
+        \crmeb\services\CacheService::clear();
+        return app('json')->success(100014);
+    }
+
+    /**
+     * 基础配置
+     * */
+    public function edit_basics(Request $request)
+    {
+        $tabId = $this->request->param('tab_id', 1);
+        if (!$tabId) {
+            return app('json')->fail(100100);
+        }
+        $url = $request->baseUrl();
+        return app('json')->success($this->services->getConfigForm($url, $tabId));
+    }
+
+    /**
+     * 保存数据    true
+     * */
+    public function save_basics(Request $request)
+    {
+        $post = $this->request->post();
+        foreach ($post as $k => $v) {
+            if (is_array($v)) {
+                $res = $this->services->getUploadTypeList($k);
+                foreach ($res as $kk => $vv) {
+                    if ($kk == 'upload') {
+                        if ($vv == 1 || $vv == 3) {
+                            $post[$k] = $v[0];
+                        }
+                    }
+                }
+            }
+        }
+        $this->validate($post, \app\adminapi\validate\setting\SystemConfigValidata::class);
+        if (isset($post['upload_type'])) {
+            $this->services->checkThumbParam($post);
+        }
+        if (isset($post['extract_type']) && !count($post['extract_type'])) {
+            return app('json')->fail(400753);
+        }
+        if (isset($post['store_brokerage_binding_status'])) {
+            $this->services->checkBrokerageBinding($post);
+        }
+        if (isset($post['store_brokerage_ratio']) && isset($post['store_brokerage_two'])) {
+            $num = $post['store_brokerage_ratio'] + $post['store_brokerage_two'];
+            if ($num > 100) {
+                return app('json')->fail(400285);
+            }
+        }
+        if (isset($post['spread_banner'])) {
+            $num = count($post['spread_banner']);
+            if ($num > 5) {
+                return app('json')->fail(400286);
+            }
+        }
+        if (isset($post['user_extract_min_price'])) {
+            if (!preg_match('/[0-9]$/', $post['user_extract_min_price'])) {
+                return app('json')->fail(400287);
+            }
+        }
+        if (isset($post['wss_open'])) {
+            $this->services->saveSslFilePath((int)$post['wss_open'], $post['wss_local_pk'] ?? '', $post['wss_local_cert'] ?? '');
+        }
+        if (isset($post['store_brokerage_price']) && $post['store_brokerage_statu'] == 3) {
+            if ($post['store_brokerage_price'] === '') {
+                return app('json')->fail(400288);
+            }
+            if ($post['store_brokerage_price'] < 0) {
+                return app('json')->fail(400289);
+            }
+        }
+        if (isset($post['store_brokerage_binding_time']) && $post['store_brokerage_binding_status'] == 2) {
+            if (!preg_match("/^[0-9][0-9]*$/", $post['store_brokerage_binding_time'])) {
+                return app('json')->fail(400290);
+            }
+        }
+        if (isset($post['uni_brokerage_price']) && $post['uni_brokerage_price'] < 0) {
+            return app('json')->fail(400756);
+        }
+        if (isset($post['day_brokerage_price_upper']) && $post['day_brokerage_price_upper'] < -1) {
+            return app('json')->fail(400757);
+        }
+        if (isset($post['pay_new_weixin_open']) && (bool)$post['pay_new_weixin_open']) {
+            if (empty($post['pay_new_weixin_mchid'])) {
+                return app('json')->fail(400763);
+            }
+        }
+        if (isset($post['uni_brokerage_price']) && preg_match('/\.[0-9]{2,}[1-9][0-9]*$/', (string)$post['uni_brokerage_price']) > 0) {
+            return app('json')->fail(500029);
+        }
+
+        //支付接口类型选择,如果有订单就不能再进行切换
+//        if (isset($post['pay_wechat_type'])) {
+//            /** @var StoreOrderServices $orderServices */
+//            $orderServices = app()->make(StoreOrderServices::class);
+//            if ($post['pay_wechat_type'] != -1 && $orderServices->count()) {
+//                return app('json')->fail('支付接口类型已经选择,不能再次进行切换,切换后会导致无法退款等问题。');
+//            }
+//        }
+
+        if (isset($post['weixin_ckeck_file'])) {
+            $from = public_path() . $post['weixin_ckeck_file'];
+            $to = public_path() . array_reverse(explode('/', $post['weixin_ckeck_file']))[0];
+            @copy($from, $to);
+        }
+        if (isset($post['ico_path'])) {
+            $from = public_path() . $post['ico_path'];
+            $toAdmin = public_path('admin') . 'favicon.ico';
+            $toHome = public_path('home') . 'favicon.ico';
+            $toPublic = public_path() . 'favicon.ico';
+            @copy($from, $toAdmin);
+            @copy($from, $toHome);
+            @copy($from, $toPublic);
+        }
+        if(isset($post['reward_integral']) || isset($post['reward_money'])) {
+            if($post['reward_integral'] < 0 || $post['reward_money'] < 0) return app('json')->fail(400558);
+        }
+        foreach ($post as $k => $v) {
+            $config_one = $this->services->getOne(['menu_name' => $k]);
+            if ($config_one) {
+                $config_one['value'] = $v;
+                $this->services->valiDateValue($config_one);
+                $this->services->update($k, ['value' => json_encode($v)], 'menu_name');
+            }
+        }
+        \crmeb\services\CacheService::clear();
+        return app('json')->success(100001);
+
+    }
+
+    /**
+     * 获取系统设置头部分类
+     * @param SystemConfigTabServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function header_basics(SystemConfigTabServices $services)
+    {
+        [$type, $pid] = $this->request->getMore([
+            [['type', 'd'], 0],
+            [['pid', 'd'], 0]
+        ], true);
+        if ($type == 3) {//其它分类
+            $config_tab = [];
+        } else {
+            $config_tab = $services->getConfigTab($pid);
+        }
+        return app('json')->success(compact('config_tab'));
+    }
+
+    /**
+     * 获取单个配置的值
+     * @param $name
+     * @return mixed
+     */
+    public function get_system($name)
+    {
+        $value = sys_config($name);
+        return app('json')->success(compact('value'));
+    }
+
+    /**
+     * 获取某个分类下的所有配置
+     * @param $tabId
+     * @return mixed
+     */
+    public function get_config_list($tabId)
+    {
+        $list = $this->services->getConfigTabAllList($tabId);
+        $data = [];
+        foreach ($list as $item) {
+            $data[$item['menu_name']] = json_decode($item['value']);
+        }
+        return app('json')->success($data);
+    }
+
+    /**
+     * 获取版本号信息
+     * @return mixed
+     */
+    public function getVersion()
+    {
+        $version = get_crmeb_version();
+        return app('json')->success([
+            'version' => $version,
+            'label' => 19
+        ]);
+    }
+}

+ 159 - 0
app/adminapi/controller/v1/setting/SystemConfigTab.php

@@ -0,0 +1,159 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\system\config\SystemConfigServices;
+use app\services\system\config\SystemConfigTabServices;
+use think\facade\App;
+
+
+/**
+ * 配置分类
+ * Class SystemConfigTab
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemConfigTab extends AuthController
+{
+    /**
+     * g构造方法
+     * SystemConfigTab constructor.
+     * @param App $app
+     * @param SystemConfigTabServices $services
+     */
+    public function __construct(App $app, SystemConfigTabServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     *
+     * @return \think\Response
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['title', '']
+        ]);
+        return app('json')->success($this->services->getConfgTabList($where));
+    }
+
+    /**
+     * 显示创建资源表单页.
+     *
+     * @return \think\Response
+     */
+    public function create()
+    {
+        return app('json')->success($this->services->createForm());
+    }
+
+    /**
+     * 保存新建的资源
+     *
+     * @return \think\Response
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            'eng_title',
+            'status',
+            'title',
+            'icon',
+            ['type', 0],
+            ['sort', 0],
+            ['pid', 0],
+        ]);
+        if (!$data['title']) return app('json')->fail(400291);
+        $this->services->save($data);
+        return app('json')->success(400292);
+    }
+
+    /**
+     * 显示指定的资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function read($id)
+    {
+        //
+    }
+
+    /**
+     * 显示编辑资源表单页.
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function edit($id)
+    {
+        return app('json')->success($this->services->updateForm((int)$id));
+    }
+
+    /**
+     * 保存更新的资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function update($id)
+    {
+        $data = $this->request->postMore([
+            'title',
+            'status',
+            'eng_title',
+            'icon',
+            ['type', 0],
+            ['sort', 0],
+            ['pid', 0],
+        ]);
+        if (!$data['title']) return app('json')->fail(400291);
+        if (!$data['eng_title']) return app('json')->fail(400275);
+        $this->services->update($id, $data);
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除指定资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete(SystemConfigServices $services, $id)
+    {
+        if ($services->count(['tab_id' => $id])) {
+            return app('json')->fail(400293);
+        }
+        if (!$this->services->delete($id))
+            return app('json')->fail(100008);
+        else
+            return app('json')->success(100002);
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        if ($status == '' || $id == 0) {
+            return app('json')->fail(100100);
+        }
+        $this->services->update($id, ['status' => $status]);
+        return app('json')->success(100014);
+    }
+}

+ 215 - 0
app/adminapi/controller/v1/setting/SystemGroup.php

@@ -0,0 +1,215 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\services\system\config\SystemGroupDataServices;
+use think\facade\App;
+use app\adminapi\controller\AuthController;
+use app\services\system\config\SystemGroupServices;
+
+/**
+ * 组合数据
+ * Class SystemGroup
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemGroup extends AuthController
+{
+    /**
+     * 构造方法
+     * SystemGroup constructor.
+     * @param App $app
+     * @param SystemGroupServices $services
+     */
+    public function __construct(App $app, SystemGroupServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     *
+     * @return \think\Response
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['title', '']
+        ]);
+        return app('json')->success($this->services->getGroupList($where));
+    }
+
+    /**
+     * 显示创建资源表单页.
+     *
+     * @return \think\Response
+     */
+    public function create()
+    {
+        //
+    }
+
+    /**
+     * 保存新建的资源
+     *
+     * @return \think\Response
+     */
+    public function save()
+    {
+        $params = $this->request->postMore([
+            ['name', ''],
+            ['config_name', ''],
+            [['cate_id', 'd'], 0],
+            ['info', ''],
+            ['typelist', []],
+        ]);
+
+        //数据组名称判断
+        if (!$params['name']) {
+            return app('json')->fail(400187);
+        }
+        if (!$params['config_name']) {
+            return app('json')->fail(400274);
+        }
+        $data["name"] = $params['name'];
+        $data["config_name"] = $params['config_name'];
+        $data["info"] = $params['info'];
+        $data["cate_id"] = $params['cate_id'];
+        //字段信息判断
+        if (!count($params['typelist']))
+            return app('json')->fail(400294);
+        else {
+            $validate = ["name", "type", "title", "description"];
+            foreach ($params["typelist"] as $key => $value) {
+                foreach ($value as $name => $field) {
+                    if (empty($field["value"]) && in_array($name, $validate))
+                        return app('json')->fail("字段" . ($key + 1) . ":" . $field["placeholder"] . "不能为空!");
+                    else
+                        $data["fields"][$key][$name] = $field["value"];
+                }
+            }
+        }
+        $data["fields"] = json_encode($data["fields"]);
+        $this->services->save($data);
+        \crmeb\services\CacheService::clear();
+        return app('json')->success(400295);
+    }
+
+    /**
+     * 显示指定的资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function read($id)
+    {
+        $info = $this->services->get($id);
+        $fields = json_decode($info['fields'], true);
+        $type_list = [];
+        foreach ($fields as $key => $v) {
+            $type_list[$key]['name']['value'] = $v['name'];
+            $type_list[$key]['title']['value'] = $v['title'];
+            $type_list[$key]['type']['value'] = $v['type'];
+            $type_list[$key]['param']['value'] = $v['param'];
+        }
+        $info['typelist'] = $type_list;
+        unset($info['fields']);
+        return app('json')->success(compact('info'));
+    }
+
+    /**
+     * 显示编辑资源表单页.
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function edit($id)
+    {
+        //
+    }
+
+    /**
+     * 保存更新的资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function update($id)
+    {
+        $params = $this->request->postMore([
+            ['name', ''],
+            ['config_name', ''],
+            [['cate_id', 'd'], 0],
+            ['info', ''],
+            ['typelist', []],
+        ]);
+
+        //数据组名称判断
+        if (!$params['name']) return app('json')->fail(400187);
+        if (!$params['config_name']) return app('json')->fail(400274);
+        //判断ID是否存在,存在就是编辑,不存在就是添加
+        if (!$id) {
+            if ($this->services->count(['config_name' => $params['config_name']])) {
+                return app('json')->fail(400296);
+            }
+        }
+        $data["name"] = $params['name'];
+        $data["config_name"] = $params['config_name'];
+        $data["info"] = $params['info'];
+        $data["cate_id"] = $params['cate_id'];
+        //字段信息判断
+        if (!count($params['typelist']))
+            return app('json')->fail(400294);
+        else {
+            $validate = ["name", "type", "title", "description"];
+            foreach ($params["typelist"] as $key => $value) {
+                foreach ($value as $name => $field) {
+                    if (empty($field["value"]) && in_array($name, $validate))
+                        return app('json')->fail(400297);
+                    else
+                        $data["fields"][$key][$name] = $field["value"];
+                }
+            }
+        }
+        $data["fields"] = json_encode($data["fields"]);
+        $this->services->update($id, $data);
+        \crmeb\services\CacheService::clear();
+        return app('json')->success(400295);
+    }
+
+    /**
+     * 删除指定资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id, SystemGroupDataServices $services)
+    {
+        if (!$this->services->delete($id))
+            return app('json')->fail(100008);
+        else {
+            $services->delete($id, 'gid');
+            return app('json')->success(100002);
+        }
+    }
+
+    /**
+     * 获取组合数据
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getGroup()
+    {
+        return app('json')->success($this->services->getGroupList(['cate_id' => 1], ['id', 'name', 'config_name'])['list']);
+    }
+}

+ 316 - 0
app/adminapi/controller/v1/setting/SystemGroupData.php

@@ -0,0 +1,316 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use crmeb\exceptions\AdminException;
+use app\services\other\CacheServices;
+use think\facade\App;
+use app\adminapi\controller\AuthController;
+use app\services\system\config\SystemGroupDataServices;
+use app\services\system\config\SystemGroupServices;
+
+/**
+ * 数据管理
+ * Class SystemGroupData
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemGroupData extends AuthController
+{
+    /**
+     * 构造方法
+     * SystemGroupData constructor.
+     * @param App $app
+     * @param SystemGroupDataServices $services
+     */
+    public function __construct(App $app, SystemGroupDataServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 获取数据列表头
+     * @return mixed
+     */
+    public function header(SystemGroupServices $services)
+    {
+        [$gid, $config_name] = $this->request->getMore([
+            ['gid', 0],
+            ['config_name', '']
+        ], true);
+        if (!$gid && !$config_name) return app('json')->fail(100100);
+        if (!$gid) {
+            $gid = $services->value(['config_name' => $config_name], 'id');
+        }
+        return app('json')->success($services->getGroupDataTabHeader($gid));
+    }
+
+    /**
+     * 显示资源列表
+     *
+     * @return \think\Response
+     */
+    public function index(SystemGroupServices $group)
+    {
+        $where = $this->request->getMore([
+            ['gid', 0],
+            ['status', ''],
+            ['config_name', '']
+        ]);
+        if (!$where['gid'] && !$where['config_name']) return app('json')->fail(100100);
+        if (!$where['gid']) {
+            $where['gid'] = $group->value(['config_name' => $where['config_name']], 'id');
+        }
+        unset($where['config_name']);
+        return app('json')->success($this->services->getGroupDataList($where));
+    }
+
+    /**
+     * 显示创建资源表单页.
+     *
+     * @return \think\Response
+     */
+    public function create()
+    {
+        $gid = $this->request->param('gid/d');
+        if ($this->services->isGroupGidSave($gid, 4, 'index_categy_images')) {
+            return app('json')->fail(400298);
+        }
+        if ($this->services->isGroupGidSave($gid, 7, 'sign_day_num')) {
+            return app('json')->fail(400299);
+        }
+        return app('json')->success($this->services->createForm($gid));
+    }
+
+    /**
+     * 保存新建的资源
+     *
+     * @return \think\Response
+     */
+    public function save(SystemGroupServices $services)
+    {
+        $params = request()->post();
+        $gid = (int)$params['gid'];
+        $group = $services->getOne(['id' => $gid], 'id,config_name,fields');
+        if ($group && $group['config_name'] == 'order_details_images') {
+            $groupDatas = $this->services->getColumn(['gid' => $gid], 'value', 'id');
+            foreach ($groupDatas as $groupData) {
+                $groupData = json_decode($groupData, true);
+                if (isset($groupData['order_status']['value']) && $groupData['order_status']['value'] == $params['order_status']) {
+                    return app('json')->fail(400188);
+                }
+            }
+        }
+        $this->services->checkSeckillTime($services, $gid, $params);
+        $this->checkSign($services, $gid, $params);
+        $fields = json_decode($group['fields'], true) ?? [];
+        $value = [];
+        foreach ($params as $key => $param) {
+            foreach ($fields as $index => $field) {
+                if ($key == $field["title"]) {
+                    if ($param == "")
+                        return app('json')->fail(400297);
+                    else {
+                        $value[$key]["type"] = $field["type"];
+                        $value[$key]["value"] = $param;
+                    }
+                }
+            }
+        }
+        $data = [
+            "gid" => $params['gid'],
+            "add_time" => time(),
+            "value" => json_encode($value),
+            "sort" => $params["sort"] ?: 0,
+            "status" => $params["status"]
+        ];
+        $this->services->save($data);
+        \crmeb\services\CacheService::clear();
+        return app('json')->success(400189);
+    }
+
+    /**
+     * 显示指定的资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function read($id)
+    {
+        //
+    }
+
+    /**
+     * 显示编辑资源表单页.
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function edit($id)
+    {
+        $gid = $this->request->param('gid/d');
+        if (!$gid) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($this->services->updateForm((int)$gid, (int)$id));
+    }
+
+    /**
+     * 保存更新的资源
+     *
+     * @param \think\Request $request
+     * @param int $id
+     * @return \think\Response
+     */
+    public function update(SystemGroupServices $services, $id)
+    {
+        $groupData = $this->services->get($id);
+        $fields = $services->getValueFields((int)$groupData["gid"]);
+        $params = request()->post();
+        $this->services->checkSeckillTime($services, $groupData["gid"], $params, $id);
+        $this->checkSign($services, $groupData["gid"], $params);
+        $value = [];
+        foreach ($params as $key => $param) {
+            foreach ($fields as $index => $field) {
+                if ($key == $field["title"]) {
+                    if ($param == '')
+                        return app('json')->fail(400297);
+                    else {
+                        $value[$key]["type"] = $field["type"];
+                        $value[$key]["value"] = $param;
+                    }
+                }
+            }
+        }
+        $data = [
+            "value" => json_encode($value),
+            "sort" => $params["sort"],
+            "status" => $params["status"]
+        ];
+        $this->services->update($id, $data);
+        \crmeb\services\CacheService::clear();
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除指定资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id)
+    {
+        if (!$this->services->delete($id))
+            return app('json')->fail(100008);
+        else {
+            \crmeb\services\CacheService::clear();
+            return app('json')->success(100002);
+        }
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        if ($status == '' || $id == 0) return app('json')->fail(100100);
+        $this->services->update($id, ['status' => $status]);
+        \crmeb\services\CacheService::clear();
+        return app('json')->success(100014);
+    }
+
+
+
+    /**
+     * 检查签到配置
+     * @param SystemGroupServices $services
+     * @param $gid
+     * @param $params
+     * @param int $id
+     * @return mixed
+     */
+    public function checkSign(SystemGroupServices $services, $gid, $params, $id = 0)
+    {
+        $name = $services->value(['id' => $gid], 'config_name');
+        if ($name == 'sign_day_num') {
+            if (!$params['sign_num']) {
+                throw new AdminException(400196);
+            }
+            if (!preg_match('/^\+?[1-9]\d*$/', $params['sign_num'])) {
+                throw new AdminException(400197);
+            }
+        }
+    }
+
+    /**
+     * 获取客服页面广告内容
+     * @return mixed
+     */
+    public function getKfAdv()
+    {
+        /** @var CacheServices $cache */
+        $cache = app()->make(CacheServices::class);
+        $content = $cache->getDbCache('kf_adv', '');
+        return app('json')->success(compact('content'));
+    }
+
+    /**
+     * 设置客服页面广告内容
+     * @return mixed
+     */
+    public function setKfAdv()
+    {
+        $content = $this->request->post('content');
+        /** @var CacheServices $cache */
+        $cache = app()->make(CacheServices::class);
+        $cache->setDbCache('kf_adv', $content);
+        return app('json')->success(100014);
+    }
+
+    public function saveAll()
+    {
+        $params = request()->post();
+        if (!isset($params['config_name']) || !isset($params['data'])) {
+            return app('json')->fail(100100);
+        }
+        $this->services->saveAllData($params['data'], $params['config_name']);
+        return app('json')->success(400295);
+    }
+
+
+    /**
+     * 获取用户协议内容
+     * @return mixed
+     */
+    public function getUserAgreement()
+    {
+        /** @var CacheServices $cache */
+        $cache = app()->make(CacheServices::class);
+        $content = $cache->getDbCache('user_agreement', '');
+        return app('json')->success(compact('content'));
+    }
+
+    /**
+     * 设置用户协议内容
+     * @return mixed
+     */
+    public function setUserAgreement()
+    {
+        $content = $this->request->post('content');
+        /** @var CacheServices $cache */
+        $cache = app()->make(CacheServices::class);
+        $cache->setDbCache('user_agreement', $content);
+        return app('json')->success(100014);
+    }
+}

+ 240 - 0
app/adminapi/controller/v1/setting/SystemMenus.php

@@ -0,0 +1,240 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+
+use app\adminapi\controller\AuthController;
+use app\services\system\SystemMenusServices;
+use think\facade\App;
+use think\facade\Route;
+
+/**
+ * 菜单权限
+ * Class SystemMenus
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemMenus extends AuthController
+{
+    /**
+     * SystemMenus constructor.
+     * @param App $app
+     * @param SystemMenusServices $services
+     */
+    public function __construct(App $app, SystemMenusServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+        $this->request->filter(['addslashes', 'trim']);
+    }
+
+    /**
+     * 菜单展示列表
+     * @return \think\Response
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['is_show', ''],
+            ['keyword', ''],
+        ]);
+        return app('json')->success($this->services->getList($where));
+    }
+
+    /**
+     * 显示创建资源表单页.
+     *
+     * @return \think\Response
+     */
+    public function create()
+    {
+
+        return app('json')->success($this->services->createMenus());
+    }
+
+    /**
+     * 保存菜单权限
+     * @return mixed
+     */
+    public function save()
+    {
+        $data = $this->request->getMore([
+            ['menu_name', ''],
+            ['controller', ''],
+            ['module', 'admin'],
+            ['action', ''],
+            ['icon', ''],
+            ['params', ''],
+            ['path', []],
+            ['menu_path', ''],
+            ['api_url', ''],
+            ['methods', ''],
+            ['unique_auth', ''],
+            ['header', ''],
+            ['is_header', 0],
+            ['pid', 0],
+            ['sort', 0],
+            ['auth_type', 0],
+            ['access', 1],
+            ['is_show', 0],
+            ['is_show_path', 0],
+        ]);
+
+        if (!$data['menu_name'])
+            return app('json')->fail(400198);
+        $data['path'] = implode('/', $data['path']);
+        if ($this->services->save($data)) {
+            return app('json')->success(100021);
+        } else {
+            return app('json')->fail(100022);
+        }
+    }
+
+    /**
+     * 获取一条菜单权限信息
+     * @param int $id
+     * @return \think\Response
+     */
+    public function read($id)
+    {
+
+        if (!$id) {
+            return app('json')->fail(100026);
+        }
+        return app('json')->success($this->services->find((int)$id));
+    }
+
+    /**
+     * 修改菜单权限表单获取
+     * @param int $id
+     * @return \think\Response
+     */
+    public function edit($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        return app('json')->success($this->services->updateMenus((int)$id));
+    }
+
+    /**
+     * 修改菜单
+     * @param $id
+     * @return mixed
+     */
+    public function update($id)
+    {
+        if (!$id || !($menu = $this->services->get($id)))
+            return app('json')->fail(100026);
+        $data = $this->request->postMore([
+            'menu_name',
+            'controller',
+            ['module', 'admin'],
+            'action',
+            'params',
+            ['icon', ''],
+            ['menu_path', ''],
+            ['api_url', ''],
+            ['methods', ''],
+            ['unique_auth', ''],
+            ['path', []],
+            ['sort', 0],
+            ['pid', 0],
+            ['is_header', 0],
+            ['header', ''],
+            ['auth_type', 0],
+            ['access', 1],
+            ['is_show', 0],
+            ['is_show_path', 0],
+        ]);
+        if (!$data['menu_name'])
+            return app('json')->fail(400198);
+        $data['path'] = implode('/', $data['path']);
+        if ($this->services->update($id, $data))
+            return app('json')->success(100001);
+        else
+            return app('json')->fail(100007);
+    }
+
+    /**
+     * 删除指定资源
+     *
+     * @param int $id
+     * @return \think\Response
+     */
+    public function delete($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+
+        if (!$this->services->delete((int)$id)) {
+            return app('json')->fail(100008);
+        } else {
+            return app('json')->success(100002);
+        }
+    }
+
+    /**
+     * 显示和隐藏
+     * @param $id
+     * @return mixed
+     */
+    public function show($id)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+
+        [$show] = $this->request->postMore([['is_show', 0]], true);
+
+        if ($this->services->update($id, ['is_show' => $show])) {
+            return app('json')->success(100001);
+        } else {
+            return app('json')->fail(100007);
+        }
+    }
+
+    /**
+     * 获取菜单数据
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function menus()
+    {
+        [$menus, $unique] = $this->services->getMenusList($this->adminInfo['roles'], (int)$this->adminInfo['level']);
+        return app('json')->success(['menus' => $menus, 'unique' => $unique]);
+    }
+
+    /**
+     * 获取接口列表
+     * @return array
+     */
+    public function ruleList()
+    {
+        //获取所有的路由
+        $ruleList = Route::getRuleList();
+        $menuApiList = $this->services->getColumn(['auth_type' => 2, 'is_del' => 0], "concat(`api_url`,'_',lower(`methods`)) as rule");
+        if ($menuApiList) $menuApiList = array_column($menuApiList, 'rule');
+        $list = [];
+        foreach ($ruleList as $item) {
+            $item['rule'] = str_replace('adminapi/', '', $item['rule']);
+            if (!in_array($item['rule'] . '_' . $item['method'], $menuApiList)) {
+                $item['real_name'] = $item['option']['real_name'] ?? '';
+                unset($item['option']);
+                $item['method'] = strtoupper($item['method']);
+                $list[] = $item;
+            }
+        }
+        return app('json')->success($list);
+    }
+}

+ 124 - 0
app/adminapi/controller/v1/setting/SystemNotification.php

@@ -0,0 +1,124 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\message\SystemNotificationServices;
+use crmeb\services\CacheService;
+use think\facade\App;
+
+/**
+ * Class SystemRole
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemNotification extends AuthController
+{
+    /**
+     * SystemRole constructor.
+     * @param App $app
+     * @param SystemNotificationServices $services
+     */
+    public function __construct(App $app, SystemNotificationServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     * @return \think\Response
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['type', ''],
+        ]);
+        return app('json')->success($this->services->getNotList($where));
+    }
+
+    /**
+     * 显示编辑
+     * @return \think\Response
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function info()
+    {
+        $where = $this->request->getMore([
+            ['type', ''],
+            ['id', 0]
+        ]);
+        if (!$where['id']) return app('json')->fail(100100);
+        return app('json')->success($this->services->getNotInfo($where));
+    }
+
+    /**
+     * 保存新建的资源
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            ['id', 0],
+            ['type', ''],
+            ['name', ''],
+            ['title', ''],
+            ['is_system', 0],
+            ['is_app', 0],
+            ['is_wechat', 0],
+            ['is_routine', 0],
+            ['is_sms', 0],
+            ['is_ent_wechat', 0],
+            ['system_title', ''],
+            ['system_text', ''],
+            ['tempid', ''],
+            ['ent_wechat_text', ''],
+            ['url', ''],
+            ['wechat_id', ''],
+            ['routine_id', ''],
+            ['mark', ''],
+            ['sms_id', ''],
+        ]);
+        if ($data['mark'] == 'verify_code') $data['type'] = 'is_sms';
+        if (!$data['id']) return app('json')->fail(100100);
+        if ($this->services->saveData($data)) {
+            CacheService::clear();
+            return app('json')->success(100001);
+        } else {
+            return app('json')->fail(100007);
+        }
+    }
+
+    /**
+     * 修改消息状态
+     * @param $type
+     * @param $status
+     * @param $id
+     * @return mixed
+     * @throws \Psr\SimpleCache\InvalidArgumentException
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function set_status($type, $status, $id)
+    {
+        if ($type == '' || $status == '' || $id == 0) return app('json')->fail(100100);
+        $this->services->update($id, [$type => $status]);
+        $res = $this->services->getOneNotce(['id' => $id]);
+        CacheService::clear();
+        return app('json')->success(100014);
+    }
+}

+ 261 - 0
app/adminapi/controller/v1/setting/SystemOutAccount.php

@@ -0,0 +1,261 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\outapi\validate\StoreOutAccountValidate;
+use app\services\out\OutAccountServices;
+use app\services\out\OutInterfaceServices;
+use think\facade\App;
+
+/**
+ * 对外接口账户
+ * Class SystemOutAccount
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemOutAccount extends AuthController
+{
+    /**
+     * 构造方法
+     * SystemOut constructor.
+     * @param App $app
+     * @param OutAccountServices $services
+     */
+    public function __construct(App $app, OutAccountServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 账号信息
+     * @return string
+     * @throws \Exception
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['name', '', ''],
+            ['status', ''],
+        ]);
+        return app('json')->success($this->services->getList($where));
+    }
+
+    /**
+     * 修改状态
+     * @param string $status
+     * @param string $id
+     * @return mixed
+     */
+    public function set_status($id = '', $status = '')
+    {
+        if ($status == '' || $id == '') return app('json')->fail(100100);
+        $this->services->update($id, ['status' => $status]);
+        return app('json')->success($status == 1 ? 100012 : 100013);
+    }
+
+    /**
+     * 删除
+     * @param $id
+     * @return mixed
+     */
+    public function delete($id)
+    {
+        if ($id == '') return app('json')->fail(100100);
+        $this->services->update($id, ['is_del' => 1]);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 保存
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function save()
+    {
+        $data = $this->request->postMore([
+            [['appid', 's'], ''],
+            [['appsecret', 's'], ''],
+            [['title', 's'], ''],
+            ['rules', []],
+        ]);
+        $this->validate($data, StoreOutAccountValidate::class, 'save');
+        if ($this->services->getOne(['appid' => $data['appid']])) return app('json')->fail('账号重复');
+        if (!$data['appsecret']) {
+            unset($data['appsecret']);
+        } else {
+            $data['appsecret'] = password_hash($data['appsecret'], PASSWORD_DEFAULT);
+        }
+        $data['add_time'] = time();
+        $data['rules'] = implode(',', $data['rules']);
+        if (!$this->services->save($data)) {
+            return app('json')->fail(100006);
+        } else {
+            return app('json')->success(100000);
+        }
+    }
+
+    /**
+     * 修改
+     * @param string $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function update($id = '')
+    {
+        $data = $this->request->postMore([
+            [['appsecret', 's'], ''],
+            [['title', 's'], ''],
+            ['rules', []],
+        ]);
+
+        $this->validate($data, StoreOutAccountValidate::class, 'update');
+        if (!$data['appsecret']) {
+            unset($data['appsecret']);
+        } else {
+            $data['appsecret'] = password_hash($data['appsecret'], PASSWORD_DEFAULT);
+        }
+        if (!$this->services->getOne(['id' => $id])) return app('json')->fail('没有此账号');
+        $data['rules'] = implode(',', $data['rules']);
+        $res = $this->services->update($id, $data);
+        if (!$res) {
+            return app('json')->fail(100006);
+        } else {
+            return app('json')->success(100000);
+        }
+    }
+
+    /**
+     * 设置账号推送接口
+     * @param $id
+     * @return mixed
+     */
+    public function outSetUpSave($id)
+    {
+        $data = $this->request->postMore([
+            ['push_open', 0],
+            ['push_account', ''],
+            ['push_password', ''],
+            ['push_token_url', ''],
+            ['user_update_push', ''],
+            ['order_create_push', ''],
+            ['order_pay_push', ''],
+            ['refund_create_push', ''],
+            ['refund_cancel_push', ''],
+        ]);
+        $this->services->outSetUpSave($id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 对外接口列表
+     * @param OutInterfaceServices $service
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function outInterfaceList(OutInterfaceServices $service)
+    {
+        return app('json')->success($service->outInterfaceList());
+    }
+
+    /**
+     * 保存接口文档
+     * @param $id
+     * @param OutInterfaceServices $service
+     * @return mixed
+     */
+    public function saveInterface($id, OutInterfaceServices $service)
+    {
+        $data = $this->request->postMore([
+            ['pid', 0], //上级id
+            ['type', 0], //类型 0菜单 1接口
+            ['name', ''], //名称
+            ['describe', ''], //说明
+            ['method', ''], //方法
+            ['url', ''], //链接地址
+            ['request_params', []], //请求参数
+            ['return_params', []], //返回参数
+            ['request_example', ''], //请求示例
+            ['return_example', ''], //返回示例
+            ['error_code', []] //错误码
+        ]);
+        $service->saveInterface((int)$id, $data);
+        return app('json')->success(100000);
+    }
+
+    /**
+     * 对外接口文档
+     * @param $id
+     * @param OutInterfaceServices $service
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function interfaceInfo($id, OutInterfaceServices $service)
+    {
+        return app('json')->success($service->interfaceInfo($id));
+    }
+
+    /**
+     * 修改接口名称
+     * @param OutInterfaceServices $service
+     * @return mixed
+     */
+    public function editInterfaceName(OutInterfaceServices $service)
+    {
+        $data = $this->request->postMore([
+            ['id', 0], //上级id
+            ['name', ''], //名称
+        ]);
+        if (!$data['id'] || !$data['name']) {
+            return app('json')->success(100100);
+        }
+        $service->editInterfaceName($data);
+        return app('json')->success(100001);
+    }
+
+    /**
+     * 删除接口
+     * @param $id
+     * @param OutInterfaceServices $service
+     * @return mixed
+     */
+    public function delInterface($id, OutInterfaceServices $service)
+    {
+        if (!$id) return app('json')->success(100100);
+        $service->delInterface($id);
+        return app('json')->success(100002);
+    }
+
+    /**
+     * 测试获取token接口
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function textOutUrl()
+    {
+        $data = $this->request->postMore([
+            ['push_account', 0],
+            ['push_password', 0],
+            ['push_token_url', '']
+        ]);
+        return app('json')->success('100014',$this->services->textOutUrl($data));
+    }
+}

+ 154 - 0
app/adminapi/controller/v1/setting/SystemRole.php

@@ -0,0 +1,154 @@
+<?php
+// +----------------------------------------------------------------------
+// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
+// +----------------------------------------------------------------------
+// | Author: CRMEB Team <admin@crmeb.com>
+// +----------------------------------------------------------------------
+namespace app\adminapi\controller\v1\setting;
+
+use app\adminapi\controller\AuthController;
+use app\services\system\admin\SystemAdminServices;
+use app\services\system\admin\SystemRoleServices;
+use app\services\system\SystemMenusServices;
+use crmeb\services\CacheService;
+use think\facade\App;
+
+/**
+ * Class SystemRole
+ * @package app\adminapi\controller\v1\setting
+ */
+class SystemRole extends AuthController
+{
+    /**
+     * SystemRole constructor.
+     * @param App $app
+     * @param SystemRoleServices $services
+     */
+    public function __construct(App $app, SystemRoleServices $services)
+    {
+        parent::__construct($app);
+        $this->services = $services;
+    }
+
+    /**
+     * 显示资源列表
+     * @return mixed
+     */
+    public function index()
+    {
+        $where = $this->request->getMore([
+            ['status', ''],
+            ['role_name', ''],
+        ]);
+        $where['level'] = $this->adminInfo['level'] + 1;
+        return app('json')->success($this->services->getRoleList($where));
+    }
+
+    /**
+     * 显示创建资源表单页
+     * @param SystemMenusServices $services
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function create(SystemMenusServices $services)
+    {
+        $menus = $services->getmenus($this->adminInfo['level'] == 0 ? [] : $this->adminInfo['roles']);
+        return app('json')->success(compact('menus'));
+    }
+
+    /**
+     * 保存新建的资源
+     *
+     * @return \think\Response
+     */
+    public function save($id)
+    {
+        $data = $this->request->postMore([
+            'role_name',
+            ['status', 0],
+            ['checked_menus', [], '', 'rules']
+        ]);
+        if (!$data['role_name']) return app('json')->fail(400220);
+        if (!is_array($data['rules']) || !count($data['rules']))
+            return app('json')->fail(400221);
+        $data['rules'] = implode(',', $data['rules']);
+        if ($id) {
+            if (!$this->services->update($id, $data)) return app('json')->fail(100007);
+            $this->services->cacheDriver()->clear();
+            return app('json')->success(100001);
+        } else {
+            $data['level'] = $this->adminInfo['level'] + 1;
+            if (!$this->services->save($data)) return app('json')->fail(400223);
+            $this->services->cacheDriver()->clear();
+            return app('json')->success(400222);
+        }
+    }
+
+    /**
+     * 显示编辑资源表单页
+     * @param SystemMenusServices $services
+     * @param $id
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function edit(SystemMenusServices $services, $id)
+    {
+        $role = $this->services->get($id);
+        if (!$role) {
+            return app('json')->fail(100100);
+        }
+        $menus = $services->getMenus($this->adminInfo['level'] == 0 ? [] : $this->adminInfo['roles']);
+        return app('json')->success(['role' => $role->toArray(), 'menus' => $menus]);
+    }
+
+    /**
+     * 删除指定资源
+     * @param SystemAdminServices $adminServices
+     * @param $id
+     * @return mixed
+     */
+    public function delete(SystemAdminServices $adminServices, $id)
+    {
+        if ($adminServices->checkRoleUse($id)) {
+            return app('json')->fail(400754);
+        }
+        if (!$this->services->delete($id))
+            return app('json')->fail(100008);
+        else {
+            $this->services->cacheDriver()->clear();
+            return app('json')->success(100002);
+        }
+    }
+
+    /**
+     * 修改状态
+     * @param $id
+     * @param $status
+     * @return mixed
+     */
+    public function set_status($id, $status)
+    {
+        if (!$id) {
+            return app('json')->fail(100100);
+        }
+        $role = $this->services->get($id);
+        if (!$role) {
+            return app('json')->fail(400199);
+        }
+        $role->status = $status;
+        if ($role->save()) {
+            $this->services->cacheDriver()->clear();
+            return app('json')->success(100001);
+        } else {
+            return app('json')->fail(100007);
+        }
+    }
+}

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