wupengfei 2 년 전
부모
커밋
7fbec4bd81
100개의 변경된 파일19489개의 추가작업 그리고 0개의 파일을 삭제
  1. 11 0
      .bowerrc
  2. 11 0
      .env.sample
  3. 14 0
      .gitignore
  4. 1 0
      .htaccess
  5. 7 0
      404.html
  6. 191 0
      LICENSE
  7. 1 0
      addons/.gitkeep
  8. 1 0
      addons/.htaccess
  9. 1 0
      addons/alisms/.addonrc
  10. 86 0
      addons/alisms/Alisms.php
  11. 73 0
      addons/alisms/config.php
  12. 73 0
      addons/alisms/controller/Index.php
  13. 10 0
      addons/alisms/info.ini
  14. 170 0
      addons/alisms/library/Alisms.php
  15. 62 0
      addons/alisms/view/index/index.html
  16. 1 0
      addons/qcloudsms/.addonrc
  17. 197 0
      addons/qcloudsms/Qcloudsms.php
  18. 139 0
      addons/qcloudsms/config.php
  19. 15 0
      addons/qcloudsms/controller/Index.php
  20. 10 0
      addons/qcloudsms/info.ini
  21. 69 0
      addons/qcloudsms/library/FileVoiceSender.php
  22. 91 0
      addons/qcloudsms/library/SmsMobileStatusPuller.php
  23. 99 0
      addons/qcloudsms/library/SmsMultiSender.php
  24. 211 0
      addons/qcloudsms/library/SmsSenderUtil.php
  25. 107 0
      addons/qcloudsms/library/SmsSingleSender.php
  26. 75 0
      addons/qcloudsms/library/SmsStatusPuller.php
  27. 71 0
      addons/qcloudsms/library/SmsVoicePromptSender.php
  28. 67 0
      addons/qcloudsms/library/SmsVoiceVerifyCodeSender.php
  29. 77 0
      addons/qcloudsms/library/TtsVoiceSender.php
  30. 0 0
      addons/shopro/.addonrc
  31. 134 0
      addons/shopro/Shopro.php
  32. 67 0
      addons/shopro/bootstrap.js
  33. 79 0
      addons/shopro/command/Chat.php
  34. 5966 0
      addons/shopro/config/menu.php
  35. 38 0
      addons/shopro/controller/ActivityGroupon.php
  36. 63 0
      addons/shopro/controller/Address.php
  37. 32 0
      addons/shopro/controller/Base.php
  38. 40 0
      addons/shopro/controller/Cart.php
  39. 64 0
      addons/shopro/controller/Category.php
  40. 52 0
      addons/shopro/controller/Coupons.php
  41. 64 0
      addons/shopro/controller/Express.php
  42. 26 0
      addons/shopro/controller/Faq.php
  43. 28 0
      addons/shopro/controller/Feedback.php
  44. 125 0
      addons/shopro/controller/Goods.php
  45. 40 0
      addons/shopro/controller/GoodsComment.php
  46. 302 0
      addons/shopro/controller/Index.php
  47. 60 0
      addons/shopro/controller/Kefu.php
  48. 53 0
      addons/shopro/controller/Live.php
  49. 38 0
      addons/shopro/controller/Notification.php
  50. 130 0
      addons/shopro/controller/Order.php
  51. 69 0
      addons/shopro/controller/OrderAftersale.php
  52. 27 0
      addons/shopro/controller/OrderExpress.php
  53. 422 0
      addons/shopro/controller/Pay.php
  54. 27 0
      addons/shopro/controller/ScoreGoodsSkuPrice.php
  55. 51 0
      addons/shopro/controller/Share.php
  56. 101 0
      addons/shopro/controller/Sms.php
  57. 31 0
      addons/shopro/controller/Store.php
  58. 38 0
      addons/shopro/controller/TradeOrder.php
  59. 727 0
      addons/shopro/controller/User.php
  60. 38 0
      addons/shopro/controller/UserBank.php
  61. 28 0
      addons/shopro/controller/UserSign.php
  62. 60 0
      addons/shopro/controller/UserWalletApply.php
  63. 26 0
      addons/shopro/controller/UserWalletLog.php
  64. 199 0
      addons/shopro/controller/Wechat.php
  65. 39 0
      addons/shopro/controller/chat/Index.php
  66. 34 0
      addons/shopro/controller/store/Apply.php
  67. 48 0
      addons/shopro/controller/store/Base.php
  68. 39 0
      addons/shopro/controller/store/Order.php
  69. 26 0
      addons/shopro/controller/store/Store.php
  70. 30 0
      addons/shopro/exception/Exception.php
  71. 142 0
      addons/shopro/helper.php
  72. 122 0
      addons/shopro/hooks.php
  73. 11 0
      addons/shopro/info.ini
  74. 5319 0
      addons/shopro/install.sql
  75. 57 0
      addons/shopro/job/ActivityAutoOper.php
  76. 57 0
      addons/shopro/job/ActivityGrouponAutoOper.php
  77. 25 0
      addons/shopro/job/BaseJob.php
  78. 40 0
      addons/shopro/job/Notification.php
  79. 142 0
      addons/shopro/job/OrderAutoOper.php
  80. 87 0
      addons/shopro/job/OrderPayed.php
  81. 42 0
      addons/shopro/job/TradeOrderAutoOper.php
  82. 74 0
      addons/shopro/job/Wechat.php
  83. 84 0
      addons/shopro/lang/zh-cn.php
  84. 8 0
      addons/shopro/lang/zh-cn/common.php
  85. 39 0
      addons/shopro/lang/zh-cn/user.php
  86. 116 0
      addons/shopro/library/Export.php
  87. 230 0
      addons/shopro/library/Express.php
  88. 25 0
      addons/shopro/library/Hook.php
  89. 0 0
      addons/shopro/library/Oauth.php
  90. 71 0
      addons/shopro/library/Oper.php
  91. 272 0
      addons/shopro/library/PayService.php
  92. 68 0
      addons/shopro/library/Redis.php
  93. 327 0
      addons/shopro/library/Wechat.php
  94. 138 0
      addons/shopro/library/apple-signin/ASDecoder.php
  95. 7 0
      addons/shopro/library/apple-signin/LICENSE
  96. 8 0
      addons/shopro/library/apple-signin/Vendor/BeforeValidException.php
  97. 8 0
      addons/shopro/library/apple-signin/Vendor/ExpiredException.php
  98. 158 0
      addons/shopro/library/apple-signin/Vendor/JWK.php
  99. 380 0
      addons/shopro/library/apple-signin/Vendor/JWT.php
  100. 30 0
      addons/shopro/library/apple-signin/Vendor/LICENSE

+ 11 - 0
.bowerrc

@@ -0,0 +1,11 @@
+{
+  "directory": "public/assets/libs",
+  "ignoredDependencies": [
+    "es6-promise",
+    "file-saver",
+    "html2canvas",
+    "jspdf",
+    "jspdf-autotable",
+    "pdfmake"
+  ]
+}

+ 11 - 0
.env.sample

@@ -0,0 +1,11 @@
+[app]
+debug = false
+trace = false
+
+[database]
+hostname = 127.0.0.1
+database = fastadmin
+username = root
+password = root
+hostport = 3306
+prefix = fa_

+ 14 - 0
.gitignore

@@ -0,0 +1,14 @@
+/nbproject/
+/runtime/*
+/application/admin/command/Install/*.lock
+/public/assets/libs/
+/public/uploads/*
+.idea
+composer.lock
+*.log
+*.css.map
+!.gitkeep
+.env
+.svn
+.vscode
+node_modules

+ 1 - 0
.htaccess

@@ -0,0 +1 @@
+ 

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

+ 191 - 0
LICENSE

@@ -0,0 +1,191 @@
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities
+that control, are controlled by, or are under common control with that entity.
+For the purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether by
+contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
+outstanding shares, or (iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included
+in or attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that
+is based on (or derived from) the Work and for which the editorial revisions,
+annotations, elaborations, or other modifications represent, as a whole, an
+original work of authorship. For the purposes of this License, Derivative Works
+shall not include works that remain separable from, or merely link (or bind by
+name) to the interfaces of, the Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version
+of the Work and any modifications or additions to that Work or Derivative Works
+thereof, that is intentionally submitted to Licensor for inclusion in the Work
+by the copyright owner or by an individual or Legal Entity authorized to submit
+on behalf of the copyright owner. For the purposes of this definition,
+"submitted" means any form of electronic, verbal, or written communication sent
+to the Licensor or its representatives, including but not limited to
+communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for
+the purpose of discussing and improving the Work, but excluding communication
+that is conspicuously marked or otherwise designated in writing by the copyright
+owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
+of whom a Contribution has been received by Licensor and subsequently
+incorporated within the Work.
+
+2. Grant of Copyright License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License.
+
+Subject to the terms and conditions of this License, each Contributor hereby
+grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+irrevocable (except as stated in this section) patent license to make, have
+made, use, offer to sell, sell, import, and otherwise transfer the Work, where
+such license applies only to those patent claims licensable by such Contributor
+that are necessarily infringed by their Contribution(s) alone or by combination
+of their Contribution(s) with the Work to which such Contribution(s) was
+submitted. If You institute patent litigation against any entity (including a
+cross-claim or counterclaim in a lawsuit) alleging that the Work or a
+Contribution incorporated within the Work constitutes direct or contributory
+patent infringement, then any patent licenses granted to You under this License
+for that Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.
+
+You may reproduce and distribute copies of the Work or Derivative Works thereof
+in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of
+this License; and
+You must cause any modified files to carry prominent notices stating that You
+changed the files; and
+You must retain, in the Source form of any Derivative Works that You distribute,
+all copyright, patent, trademark, and attribution notices from the Source form
+of the Work, excluding those notices that do not pertain to any part of the
+Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the
+attribution notices contained within such NOTICE file, excluding those notices
+that do not pertain to any part of the Derivative Works, in at least one of the
+following places: within a NOTICE text file distributed as part of the
+Derivative Works; within the Source form or documentation, if provided along
+with the Derivative Works; or, within a display generated by the Derivative
+Works, if and wherever such third-party notices normally appear. The contents of
+the NOTICE file are for informational purposes only and do not modify the
+License. You may add Your own attribution notices within Derivative Works that
+You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as
+modifying the License.
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies
+with the conditions stated in this License.
+
+5. Submission of Contributions.
+
+Unless You explicitly state otherwise, any Contribution intentionally submitted
+for inclusion in the Work by You to the Licensor shall be under the terms and
+conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of
+any separate license agreement you may have executed with Licensor regarding
+such Contributions.
+
+6. Trademarks.
+
+This License does not grant permission to use the trade names, trademarks,
+service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and
+reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty.
+
+Unless required by applicable law or agreed to in writing, Licensor provides the
+Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+including, without limitation, any warranties or conditions of TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
+solely responsible for determining the appropriateness of using or
+redistributing the Work and assume any risks associated with Your exercise of
+permissions under this License.
+
+8. Limitation of Liability.
+
+In no event and under no legal theory, whether in tort (including negligence),
+contract, or otherwise, unless required by applicable law (such as deliberate
+and grossly negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License or
+out of the use or inability to use the Work (including but not limited to
+damages for loss of goodwill, work stoppage, computer failure or malfunction, or
+any and all other commercial damages or losses), even if such Contributor has
+been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability.
+
+While redistributing the Work or Derivative Works thereof, You may choose to
+offer, and charge a fee for, acceptance of support, warranty, indemnity, or
+other liability obligations and/or rights consistent with this License. However,
+in accepting such obligations, You may act only on Your own behalf and on Your
+sole responsibility, not on behalf of any other Contributor, and only if You
+agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your
+accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work
+
+To apply the Apache License to your work, attach the following boilerplate
+notice, with the fields enclosed by brackets "{}" replaced with your own
+identifying information. (Don't include the brackets!) The text should be
+enclosed in the appropriate comment syntax for the file format. We also
+recommend that a file or class name and description of purpose be included on
+the same "printed page" as the copyright notice for easier identification within
+third-party archives.
+
+   Copyright 2017 Karson
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 1 - 0
addons/.gitkeep

@@ -0,0 +1 @@
+

+ 1 - 0
addons/.htaccess

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

+ 1 - 0
addons/alisms/.addonrc

@@ -0,0 +1 @@
+{"files":[],"license":"regular","licenseto":"46647","licensekey":"1kdMw4mQfUPc8zlr QNaU3jelHf8g6Oxi4btUwA==","domains":["hdlkeji.com"],"licensecodes":[],"validations":["629b583abe0e6955e04ae79d8a2c42db"]}

+ 86 - 0
addons/alisms/Alisms.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace addons\alisms;
+
+use think\Addons;
+
+/**
+ * Alisms
+ */
+class Alisms extends Addons
+{
+
+    /**
+     * 插件安装方法
+     * @return bool
+     */
+    public function install()
+    {
+        return true;
+    }
+
+    /**
+     * 插件卸载方法
+     * @return bool
+     */
+    public function uninstall()
+    {
+        return true;
+    }
+
+    /**
+     * 短信发送行为
+     * @param array $params 必须包含mobile,event,code
+     * @return  boolean
+     */
+    public function smsSend(&$params)
+    {
+        $config = get_addon_config('alisms');
+        if (!isset($config['template'][$params['event']])) {
+            return false;
+        }
+        $alisms = new \addons\alisms\library\Alisms();
+        $result = $alisms->mobile($params['mobile'])
+            ->template($config['template'][$params['event']])
+            ->param(['code' => $params['code']])
+            ->send();
+        return $result;
+    }
+
+    /**
+     * 短信发送通知
+     * @param array $params 必须包含 mobile,event,msg
+     * @return  boolean
+     */
+    public function smsNotice(&$params)
+    {
+        $config = get_addon_config('alisms');
+        $alisms = \addons\alisms\library\Alisms::instance();
+        if (isset($params['msg'])) {
+            if (is_array($params['msg'])) {
+                $param = $params['msg'];
+            } else {
+                parse_str($params['msg'], $param);
+            }
+        } else {
+            $param = [];
+        }
+        $param = $param ? $param : [];
+        $params['template'] = isset($params['template']) ? $params['template'] : (isset($params['event']) && isset($config['template'][$params['event']]) ? $config['template'][$params['event']] : '');
+        $result = $alisms->mobile($params['mobile'])
+            ->template($params['template'])
+            ->param($param)
+            ->send();
+        return $result;
+    }
+
+    /**
+     * 检测验证是否正确
+     * @param   $params
+     * @return  boolean
+     */
+    public function smsCheck(&$params)
+    {
+        return true;
+    }
+}

+ 73 - 0
addons/alisms/config.php

@@ -0,0 +1,73 @@
+<?php
+
+return [
+    [
+        'name'    => 'key',
+        'title'   => '应用key',
+        'type'    => 'string',
+        'content' => [],
+        'value'   => 'your key',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ],
+    [
+        'name'    => 'secret',
+        'title'   => '密钥secret',
+        'type'    => 'string',
+        'content' => [],
+        'value'   => 'your secret',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ],
+    [
+        'name'    => 'sign',
+        'title'   => '签名',
+        'type'    => 'string',
+        'content' => [],
+        'value'   => 'your sign',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ],
+    [
+        'name'    => 'template',
+        'title'   => '短信模板',
+        'type'    => 'array',
+        'content' => [],
+        'value'   => [
+            'register'           => 'SMS_114000000',
+            'resetpwd'           => 'SMS_114000000',
+            'changepwd'          => 'SMS_114000000',
+            'changemobile'       => 'SMS_114000000',
+            'profile'            => 'SMS_114000000',
+            'notice'             => 'SMS_114000000',
+            'mobilelogin'        => 'SMS_114000000',
+            'bind'               => 'SMS_114000000',
+        ],
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ],
+    [
+        'name'    => '__tips__',
+        'title'   => '温馨提示',
+        'type'    => 'string',
+        'content' => [],
+        'value'   => '应用key和密钥你可以通过 https://ak-console.aliyun.com/?spm=a2c4g.11186623.2.13.fd315777PX3tjy#/accesskey 获取',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ],
+];

+ 73 - 0
addons/alisms/controller/Index.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace addons\alisms\controller;
+
+use think\addons\Controller;
+
+/**
+ * 阿里短信
+ */
+class Index extends Controller
+{
+
+    protected $model = null;
+    protected $templateList = [
+        'register'     => '注册',
+        'resetpwd'     => '重置密码',
+        'changepwd'    => '修改密码',
+        'changemobile' => '修改手机号',
+        'profile'      => '修改个人信息',
+        'notice'       => '通知',
+        'mobilelogin'  => '移动端登录',
+        'bind'         => '绑定账号',
+    ];
+
+    public function _initialize()
+    {
+        if (!\app\admin\library\Auth::instance()->id) {
+            $this->error('暂无权限浏览');
+        }
+        parent::_initialize();
+    }
+
+    //首页
+    public function index()
+    {
+        $this->view->assign('templateList', $this->templateList);
+        return $this->view->fetch();
+    }
+
+    //发送测试短信
+    public function send()
+    {
+        $config = get_addon_config('alisms');
+        $mobile = $this->request->post('mobile');
+        $template = $this->request->post('template');
+        $sign = $this->request->post('sign', '');
+
+        if (!$mobile) {
+            $this->error('手机号不能为空');
+        }
+
+        $templateArr = $config['template'] ?? [];
+        if (!isset($templateArr[$template]) || !$templateArr[$template]) {
+            $this->error('后台未配置对应的模板CODE');
+        }
+        $template = $templateArr[$template];
+        $sign = $sign ? $sign : $config['sign'];
+        $param = (array)json_decode($this->request->post('param', '', 'trim'));
+        $param = ['code' => mt_rand(1000, 9999)];
+        $alisms = new \addons\alisms\library\Alisms();
+        $ret = $alisms->mobile($mobile)
+            ->template($template)
+            ->sign($sign)
+            ->param($param)
+            ->send();
+        if ($ret) {
+            $this->success("发送成功");
+        } else {
+            $this->error("发送失败!失败原因:" . $alisms->getError());
+        }
+    }
+
+}

+ 10 - 0
addons/alisms/info.ini

@@ -0,0 +1,10 @@
+name = alisms
+title = 阿里云短信发送
+intro = 阿里云短信发送插件
+author = FastAdmin
+website = https://www.fastadmin.net
+version = 1.0.10
+state = 1
+url = /addons/alisms
+license = regular
+licenseto = 46647

+ 170 - 0
addons/alisms/library/Alisms.php

@@ -0,0 +1,170 @@
+<?php
+
+namespace addons\alisms\library;
+
+/**
+ * 阿里大于SMS短信发送
+ */
+class Alisms
+{
+    private $_params = [];
+    public $error = '';
+    protected $config = [];
+    protected static $instance;
+
+    public function __construct($options = [])
+    {
+        if ($config = get_addon_config('alisms')) {
+            $this->config = array_merge($this->config, $config);
+        }
+        $this->config = array_merge($this->config, is_array($options) ? $options : []);
+    }
+
+    /**
+     * 单例
+     * @param array $options 参数
+     * @return Alisms
+     */
+    public static function instance($options = [])
+    {
+        if (is_null(self::$instance)) {
+            self::$instance = new static($options);
+        }
+
+        return self::$instance;
+    }
+
+    /**
+     * 设置签名
+     * @param string $sign
+     * @return Alisms
+     */
+    public function sign($sign = '')
+    {
+        $this->_params['SignName'] = $sign;
+        return $this;
+    }
+
+    /**
+     * 设置参数
+     * @param array $param
+     * @return Alisms
+     */
+    public function param(array $param = [])
+    {
+        foreach ($param as $k => &$v) {
+            $v = (string)$v;
+        }
+        unset($v);
+        $param = array_filter($param);
+        $this->_params['TemplateParam'] = $param ? json_encode($param) : '{}';
+        return $this;
+    }
+
+    /**
+     * 设置模板
+     * @param string $code 短信模板
+     * @return Alisms
+     */
+    public function template($code = '')
+    {
+        $this->_params['TemplateCode'] = $code;
+        return $this;
+    }
+
+    /**
+     * 接收手机
+     * @param string $mobile 手机号码
+     * @return Alisms
+     */
+    public function mobile($mobile = '')
+    {
+        $this->_params['PhoneNumbers'] = $mobile;
+        return $this;
+    }
+
+    /**
+     * 立即发送
+     * @return boolean
+     */
+    public function send()
+    {
+        $this->error = '';
+        $params = $this->_params();
+        $params['Signature'] = $this->_signed($params);
+        $response = $this->_curl($params);
+        if ($response !== false) {
+            $res = (array)json_decode($response, true);
+            if (isset($res['Code']) && $res['Code'] == 'OK') {
+                return true;
+            }
+            $this->error = isset($res['Message']) ? $res['Message'] : 'InvalidResult';
+        } else {
+            $this->error = 'InvalidResult';
+        }
+        return false;
+    }
+
+    /**
+     * 获取错误信息
+     * @return string
+     */
+    public function getError()
+    {
+        return $this->error;
+    }
+
+    private function _params()
+    {
+        return array_merge([
+            'AccessKeyId'      => $this->config['key'],
+            'SignName'         => isset($this->config['sign']) ? $this->config['sign'] : '',
+            'Action'           => 'SendSms',
+            'Format'           => 'JSON',
+            'Version'          => '2017-05-25',
+            'SignatureVersion' => '1.0',
+            'SignatureMethod'  => 'HMAC-SHA1',
+            'SignatureNonce'   => uniqid(),
+            'Timestamp'        => gmdate('Y-m-d\TH:i:s\Z'),
+        ], $this->_params);
+    }
+
+    private function percentEncode($string)
+    {
+        $string = urlencode($string);
+        $string = preg_replace('/\+/', '%20', $string);
+        $string = preg_replace('/\*/', '%2A', $string);
+        $string = preg_replace('/%7E/', '~', $string);
+        return $string;
+    }
+
+    private function _signed($params)
+    {
+        $sign = $this->config['secret'];
+        ksort($params);
+        $canonicalizedQueryString = '';
+        foreach ($params as $key => $value) {
+            $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
+        }
+        $stringToSign = 'GET&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
+        $signature = base64_encode(hash_hmac('sha1', $stringToSign, $sign . '&', true));
+        return $signature;
+    }
+
+    private function _curl($params)
+    {
+        $uri = 'http://dysmsapi.aliyuncs.com/?' . http_build_query($params);
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($ch, CURLOPT_URL, $uri);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
+        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.98 Safari/537.36");
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        $reponse = curl_exec($ch);
+        curl_close($ch);
+        return $reponse;
+    }
+}

+ 62 - 0
addons/alisms/view/index/index.html

@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
+    <title>阿里云短信发送示例 - {$site.name}</title>
+
+    <!-- Bootstrap Core CSS -->
+    <link href="__CDN__/assets/libs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
+
+    <!-- Custom CSS -->
+    <link href="__CDN__/assets/css/frontend.min.css" rel="stylesheet">
+
+    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
+    <!--[if lt IE 9]>
+    <script src="https://cdn.staticfile.org/html5shiv/3.7.3/html5shiv.min.js"></script>
+    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
+    <![endif]-->
+</head>
+<body>
+<div class="container">
+    <div class="well" style="margin-top:30px;">
+        <div class="alert alert-danger-light">温馨提示:仅用于测试插件是否能正常发送短信</div>
+        <form class="form-horizontal" action="{:addon_url('alisms/index/send')}" method="POST">
+            <fieldset>
+                <legend>阿里云短信发送测试</legend>
+                <div class="form-group">
+                    <label class="col-lg-2 control-label">手机号</label>
+                    <div class="col-lg-10">
+                        <input type="text" class="form-control" name="mobile" placeholder="手机号">
+                    </div>
+                </div>
+                <div class="form-group">
+                    <label class="col-lg-2 control-label">消息模板</label>
+                    <div class="col-lg-10">
+                        <select name="template" class="form-control">
+                            {foreach name="templateList" id="item"}
+                            <option value="{$key}">{$item} ({$key})</option>
+                            {/foreach}
+                        </select>
+                    </div>
+                </div>
+                <div class="form-group">
+                    <div class="col-lg-10 col-lg-offset-2">
+                        <button type="submit" class="btn btn-primary">发送</button>
+                        <button type="reset" class="btn btn-default">重置</button>
+                    </div>
+                </div>
+            </fieldset>
+        </form>
+    </div>
+</div>
+
+<script src="__CDN__/assets/libs/jquery/dist/jquery.min.js"></script>
+<script src="__CDN__/assets/libs/bootstrap/dist/js/bootstrap.min.js"></script>
+
+<script type="text/javascript">
+    $(function () {
+
+    });
+</script>
+</body>
+</html>

+ 1 - 0
addons/qcloudsms/.addonrc

@@ -0,0 +1 @@
+{"files":[],"license":"regular","licenseto":"46647","licensekey":"eZraf5HEgpCJXIvV EL\/2zgalpkT5iB22iJTc8LaSnj\/trCsVMOz4zRnT3v4=","domains":["hdlkeji.com"],"licensecodes":[],"validations":["629b583abe0e6955e04ae79d8a2c42db"]}

+ 197 - 0
addons/qcloudsms/Qcloudsms.php

@@ -0,0 +1,197 @@
+<?php
+
+namespace addons\qcloudsms;
+
+use addons\qcloudsms\library\SmsSingleSender;
+use addons\qcloudsms\library\SmsVoicePromptSender;
+use addons\qcloudsms\library\SmsVoiceverifyCodeSender;
+use addons\qcloudsms\library\TtsVoiceSender;
+use think\Addons;
+use think\Config;
+
+/**
+ * 插件
+ */
+class Qcloudsms extends Addons
+{
+    private $appid = null;
+    private $appkey = null;
+    private $config = null;
+    private $sender = null;
+    private $sendError = '';
+
+    public function ConfigInit()
+    {
+        $this->config = $this->getConfig();
+        //如果使用语音短信  更换成语音短信模板
+        if ($this->config['isVoice'] == 1) {
+            $this->config['template'] = $this->config['voiceTemplate'];
+            //语音短信 需要另行设置Aappid 与Appkey
+            $this->appid = $this->config['voiceAppid'];
+            $this->appkey = $this->config['voiceAppkey'];
+        } else {
+            $this->appid = $this->config['appid'];
+            $this->appkey = $this->config['appkey'];
+        }
+    }
+
+    /**
+     * 短信发送行为
+     * @param Sms $params
+     * @return  boolean
+     */
+    public function smsSend(&$params)
+    {
+        $this->ConfigInit();
+        try {
+            if ($this->config['isTemplateSender'] == 1) {
+                $templateID = $this->config['template'][$params->event];
+                if ($this->config['isVoice'] != 1) {
+                    //普通短信发送
+                    $this->sender = new SmsSingleSender($this->appid, $this->appkey);
+                    $result = $this->sender->sendWithParam("86", $params['mobile'], $templateID, ["{$params->code}"], $this->config['sign'], "", "");
+                } else {
+                    //语音短信发送
+                    $this->sender = new TtsVoiceSender($this->appid, $this->appkey);
+                    //参数: 国家码,手机号、模板ID、模板参数、播放次数(可选字段)、用户的session内容,服务器端原样返回(可选字段)
+                    $result = $this->sender->send("86", $params['mobile'], $templateID, [$params->code]);
+                }
+            } else {
+                //判断是否是语音短信
+                if ($this->config['isVoice'] != 1) {
+                    $this->sender = new SmsSingleSender($this->appid, $this->appkey);
+                    //参数:短信类型{1营销短信,0普通短信 }、国家码、手机号、短信内容、扩展码(可留空)、服务的原样返回的参数
+                    $result = $this->sender->send($params['type'], '86', $params['mobile'], $params['msg'], "", "");
+                } else {
+                    $this->sender = new SmsVoiceVerifyCodeSender($this->appid, $this->appkey);
+                    //参数:国家码、手机号、短信内容、播放次数(默认2次)、服务的原样返回的参数
+                    $result = $this->sender->send('86', $params['mobile'], $params['msg']);
+                }
+            }
+
+            $rsp = json_decode($result, true);
+            if ($rsp['result'] == 0 && $rsp['errmsg'] == 'OK') {
+                return true;
+            } else {
+                //记录错误信息
+                $this->setError($rsp);
+                return false;
+            }
+        } catch (\Exception $e) {
+            $this->setError($e->getMessage());
+        }
+        return false;
+    }
+
+    /**
+     * 短信发送通知
+     * @param array $params
+     * @return  boolean
+     */
+    public function smsNotice(&$params)
+    {
+        $this->ConfigInit();
+        try {
+            if ($this->config['isTemplateSender'] == 1) {
+                $templateID = $this->config['template'][$params['template']];
+
+                if ($this->config['isVoice'] != 1) {
+                    //普通短信发送
+                    $this->sender = new SmsSingleSender($this->appid, $this->appkey);
+                    $result = $this->sender->sendWithParam("86", $params['mobile'], $templateID, ["{$params['msg']}"], $this->config['sign'], "", "");
+                } else {
+                    //语音短信发送
+                    $this->sender = new TtsVoiceSender($this->appid, $this->appkey);
+                    //参数: 国家码,手机号、模板ID、模板参数、播放次数(可选字段)、用户的session内容,服务器端原样返回(可选字段)
+                    $result = $this->sender->send("86", $params['mobile'], $templateID, [$params['msg']]);
+                }
+            } else {
+                //判断是否是语音短信
+                if ($this->config['isVoice'] != 1) {
+                    $this->sender = new SmsSingleSender($this->appid, $this->appkey);
+                    //参数:短信类型{1营销短信,0普通短信 }、国家码、手机号、短信内容、扩展码(可留空)、服务的原样返回的参数
+                    $result = $this->sender->send($params['type'], '86', $params['mobile'], $params['msg'], "", "");
+                } else {
+                    $this->sender = new SmsVoicePromptSender($this->appid, $this->appkey);
+                    //参数:国家码、手机号、语音类型(目前固定为2)、短信内容、播放次数(默认2次)、服务的原样返回的参数
+                    $result = $this->sender->send('86', $params['mobile'], 2, $params['msg']);
+                }
+            }
+            $rsp = (array)json_decode($result, true);
+            if ($rsp['result'] == 0 && $rsp['errmsg'] == 'OK') {
+                return true;
+            } else {
+                //记录错误信息
+                $this->setError($rsp);
+                return false;
+            }
+        } catch (\Exception $e) {
+            var_dump($e);
+            exit();
+        }
+    }
+
+    /**
+     * 记录失败信息
+     * @param [type] $err [description]
+     */
+    private function setError($err)
+    {
+        $this->sendError = $err;
+    }
+
+    /**
+     * 获取失败信息
+     * @return [type] [description]
+     */
+    public function getError()
+    {
+        return $this->sendError;
+    }
+
+    /**
+     * 检测验证是否正确
+     * @param Sms $params
+     * @return  boolean
+     */
+    public function smsCheck(&$params)
+    {
+        return true;
+    }
+
+    /**
+     * 插件安装方法
+     * @return bool
+     */
+    public function install()
+    {
+        return true;
+    }
+
+    /**
+     * 插件卸载方法
+     * @return bool
+     */
+    public function uninstall()
+    {
+        return true;
+    }
+
+    /**
+     * 插件启用方法
+     * @return bool
+     */
+    public function enable()
+    {
+        return true;
+    }
+
+    /**
+     * 插件禁用方法
+     * @return bool
+     */
+    public function disable()
+    {
+        return true;
+    }
+}

+ 139 - 0
addons/qcloudsms/config.php

@@ -0,0 +1,139 @@
+<?php
+
+return array(
+    array(
+        'name'    => 'appid',
+        'title'   => '应用AppID',
+        'type'    => 'string',
+        'content' =>
+            array(),
+        'value'   => '',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ),
+    array(
+        'name'    => 'appkey',
+        'title'   => '应用AppKEY',
+        'type'    => 'string',
+        'content' =>
+            array(),
+        'value'   => '',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ),
+    array(
+        'name'    => 'voiceAppid',
+        'title'   => '语音短信AppID',
+        'type'    => 'string',
+        'content' =>
+            array(),
+        'value'   => '',
+        'rule'    => 'required',
+        'msg'     => '使用语音短信必须设置',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ),
+    array(
+        'name'    => 'voiceAppkey',
+        'title'   => '语音短信AppKEY',
+        'type'    => 'string',
+        'content' =>
+            array(),
+        'value'   => '',
+        'rule'    => 'required',
+        'msg'     => '使用语音短信必须设置',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ),
+    array(
+        'name'    => 'sign',
+        'title'   => '签名',
+        'type'    => 'string',
+        'content' =>
+            array(),
+        'value'   => 'your sign',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ),
+    array(
+        'name'    => 'isVoice',
+        'title'   => '是否使用语音短信',
+        'type'    => 'radio',
+        'content' =>
+            array(
+                0 => '否',
+                1 => '是',
+            ),
+        'value'   => '0',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ),
+    array(
+        'name'    => 'isTemplateSender',
+        'title'   => '是否使用短信模板发送',
+        'type'    => 'radio',
+        'content' =>
+            array(
+                0 => '否',
+                1 => '是',
+            ),
+        'value'   => '1',
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ),
+    array(
+        'name'    => 'template',
+        'title'   => '短信模板',
+        'type'    => 'array',
+        'content' =>
+            array(),
+        'value'   =>
+            array(
+                'register'  => '',
+                'resetpwd'  => '',
+                'changepwd' => '',
+                'profile'   => '',
+            ),
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ),
+    array(
+        'name'    => 'voiceTemplate',
+        'title'   => '语音短信模板',
+        'type'    => 'array',
+        'content' =>
+            array(),
+        'value'   =>
+            array(
+                'register'  => '',
+                'resetpwd'  => '',
+                'changepwd' => '',
+                'profile'   => '',
+            ),
+        'rule'    => 'required',
+        'msg'     => '',
+        'tip'     => '',
+        'ok'      => '',
+        'extend'  => '',
+    ),
+);

+ 15 - 0
addons/qcloudsms/controller/Index.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace addons\qcloudsms\controller;
+
+use think\addons\Controller;
+
+class Index extends Controller
+{
+
+    public function index()
+    {
+        $this->error("当前插件暂无前台页面");
+    }
+
+}

+ 10 - 0
addons/qcloudsms/info.ini

@@ -0,0 +1,10 @@
+name = qcloudsms
+title = 腾讯云短信发送插件
+intro = 腾讯云短信发送插件
+author = Seacent
+website = https://www.seacent.com
+version = 1.0.3
+state = 1
+url = /addons/qcloudsms
+license = regular
+licenseto = 46647

+ 69 - 0
addons/qcloudsms/library/FileVoiceSender.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace addons\qcloudsms\library;
+
+use addons\qcloudsms\library\SmsSenderUtil;
+
+
+/**
+ * 按语音文件fid发送语音通知类
+ *
+ */
+class FileVoiceSender
+{
+    private $url;
+    private $appid;
+    private $appkey;
+    private $util;
+
+    /**
+     * 构造函数
+     *
+     * @param string $appid  sdkappid
+     * @param string $appkey sdkappid对应的appkey
+     */
+    public function __construct($appid, $appkey)
+    {
+        $this->url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendfvoice";
+        $this->appid =  $appid;
+        $this->appkey = $appkey;
+        $this->util = new SmsSenderUtil();
+    }
+
+    /**
+     *
+     * 按语音文件fid发送语音通知
+     *
+     * @param string $nationCode  国家码,如 86 为中国
+     * @param string $phoneNumber 不带国家码的手机号
+     * @param string $fid         语音文件fid
+     * @param string $playtimes   播放次数,可选,最多3次,默认2次
+     * @param string $ext         用户的session内容,服务端原样返回,可选字段,不需要可填空串
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function send($nationCode, $phoneNumber, $fid, $playtimes = 2, $ext = "")
+    {
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        // 按照协议组织 post 包体
+        $data = new \stdClass();
+        $tel = new \stdClass();
+        $tel->nationcode = "".$nationCode;
+        $tel->mobile = "".$phoneNumber;
+        $data->tel = $tel;
+        $data->fid = $fid;
+        $data->playtimes = $playtimes;
+
+        // app凭证
+        $data->sig = $this->util->calculateSig($this->appkey, $random,
+            $curTime, array($phoneNumber));
+
+        // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
+        $data->time = $curTime;
+        $data->ext = $ext;
+
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+}

+ 91 - 0
addons/qcloudsms/library/SmsMobileStatusPuller.php

@@ -0,0 +1,91 @@
+<?php
+
+namespace addons\qcloudsms\library;
+
+use addons\qcloudsms\library\SmsSenderUtil;
+
+/**
+ * 拉取单个手机短信状态类
+ *
+ */
+class SmsMobileStatusPuller
+{
+    private $url;
+    private $appid;
+    private $appkey;
+    private $util;
+
+    /**
+     * 构造函数
+     *
+     * @param string $appid  sdkappid
+     * @param string $appkey sdkappid对应的appkey
+     */
+    public function __construct($appid, $appkey)
+    {
+        $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus4mobile";
+        $this->appid =  $appid;
+        $this->appkey = $appkey;
+        $this->util = new SmsSenderUtil();
+    }
+
+    /**
+     * 拉取回执结果
+     *
+     * @param int    $type         拉取类型,0表示回执结果,1表示回复信息
+     * @param string $nationCode   国家码,如 86 为中国
+     * @param string $mobile       不带国家码的手机号
+     * @param int    $beginTime    开始时间(unix timestamp)
+     * @param int    $endTime      结束时间(unix timestamp)
+     * @param int    $max          拉取最大条数,最多100
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    private function pull($type, $nationCode, $mobile, $beginTime, $endTime, $max)
+    {
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        $data = new \stdClass();
+        $data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
+        $data->time = $curTime;
+        $data->type = $type;
+        $data->max = $max;
+        $data->begin_time = $beginTime;
+        $data->end_time = $endTime;
+        $data->nationcode = $nationCode;
+        $data->mobile = $mobile;
+
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+
+    /**
+     * 拉取回执结果
+     *
+     * @param string $nationCode   国家码,如 86 为中国
+     * @param string $mobile       不带国家码的手机号
+     * @param int    $beginTime    开始时间(unix timestamp)
+     * @param int    $endTime      结束时间(unix timestamp)
+     * @param int    $max          拉取最大条数,最多100
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function pullCallback($nationCode, $mobile, $beginTime, $endTime, $max)
+    {
+        return $this->pull(0, $nationCode, $mobile, $beginTime, $endTime, $max);
+    }
+
+    /**
+     * 拉取回复信息
+     *
+     * @param string $nationCode   国家码,如 86 为中国
+     * @param string $mobile       不带国家码的手机号
+     * @param int    $beginTime    开始时间(unix timestamp)
+     * @param int    $endTime      结束时间(unix timestamp)
+     * @param int    $max          拉取最大条数,最多100
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function pullReply($nationCode, $mobile, $beginTime, $endTime, $max)
+    {
+        return $this->pull(1, $nationCode, $mobile, $beginTime, $endTime, $max);
+    }
+}

+ 99 - 0
addons/qcloudsms/library/SmsMultiSender.php

@@ -0,0 +1,99 @@
+<?php
+
+namespace addons\qcloudsms\library;
+
+use addons\qcloudsms\library\SmsSenderUtil;
+
+/**
+ * 群发短信类
+ *
+ */
+class SmsMultiSender
+{
+    private $url;
+    private $appid;
+    private $appkey;
+    private $util;
+
+    /**
+     * 构造函数
+     *
+     * @param string $appid  sdkappid
+     * @param string $appkey sdkappid对应的appkey
+     */
+    public function __construct($appid, $appkey)
+    {
+        $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/sendmultisms2";
+        $this->appid =  $appid;
+        $this->appkey = $appkey;
+        $this->util = new SmsSenderUtil();
+    }
+
+    /**
+     * 普通群发
+     *
+     * 普通群发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,
+     * 否则系统将使用默认签名。
+     *
+     *
+     * @param int    $type         短信类型,0 为普通短信,1 营销短信
+     * @param string $nationCode   国家码,如 86 为中国
+     * @param array  $phoneNumbers 不带国家码的手机号列表
+     * @param string $msg          信息内容,必须与申请的模板格式一致,否则将返回错误
+     * @param string $extend       扩展码,可填空串
+     * @param string $ext          服务端原样返回的参数,可填空串
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function send($type, $nationCode, $phoneNumbers, $msg, $extend = "", $ext = "")
+    {
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        $data = new \stdClass();
+        $data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
+        $data->type = $type;
+        $data->msg = $msg;
+        $data->sig = $this->util->calculateSig($this->appkey, $random,
+            $curTime, $phoneNumbers);
+        $data->time = $curTime;
+        $data->extend = $extend;
+        $data->ext = $ext;
+
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+
+    /**
+     * 指定模板群发
+     *
+     *
+     * @param  string $nationCode   国家码,如 86 为中国
+     * @param  array  $phoneNumbers 不带国家码的手机号列表
+     * @param  int    $templId      模板id
+     * @param  array  $params       模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
+     * @param  string $sign         签名,如果填空串,系统会使用默认签名
+     * @param  string $extend       扩展码,可填空串
+     * @param  string $ext          服务端原样返回的参数,可填空串
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function sendWithParam($nationCode, $phoneNumbers, $templId, $params,
+        $sign = "", $extend = "", $ext = "")
+    {
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        $data = new \stdClass();
+        $data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
+        $data->sign = $sign;
+        $data->tpl_id = $templId;
+        $data->params = $params;
+        $data->sig = $this->util->calculateSigForTemplAndPhoneNumbers(
+            $this->appkey, $random, $curTime, $phoneNumbers);
+        $data->time = $curTime;
+        $data->extend = $extend;
+        $data->ext = $ext;
+
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+}

+ 211 - 0
addons/qcloudsms/library/SmsSenderUtil.php

@@ -0,0 +1,211 @@
+<?php
+
+namespace addons\qcloudsms\library;
+
+/**
+ * 发送Util类
+ *
+ */
+class SmsSenderUtil
+{
+    /**
+     * 生成随机数
+     *
+     * @return int 随机数结果
+     */
+    public function getRandom()
+    {
+        return rand(100000, 999999);
+    }
+
+    /**
+     * 生成签名
+     *
+     * @param string $appkey        sdkappid对应的appkey
+     * @param string $random        随机正整数
+     * @param string $curTime       当前时间
+     * @param array  $phoneNumbers  手机号码
+     * @return string  签名结果
+     */
+    public function calculateSig($appkey, $random, $curTime, $phoneNumbers)
+    {
+        $phoneNumbersString = $phoneNumbers[0];
+        for ($i = 1; $i < count($phoneNumbers); $i++) {
+            $phoneNumbersString .= ("," . $phoneNumbers[$i]);
+        }
+
+        return hash("sha256", "appkey=".$appkey."&random=".$random
+            ."&time=".$curTime."&mobile=".$phoneNumbersString);
+    }
+
+    /**
+     * 生成签名
+     *
+     * @param string $appkey        sdkappid对应的appkey
+     * @param string $random        随机正整数
+     * @param string $curTime       当前时间
+     * @param array  $phoneNumbers  手机号码
+     * @return string  签名结果
+     */
+    public function calculateSigForTemplAndPhoneNumbers($appkey, $random,
+        $curTime, $phoneNumbers)
+    {
+        $phoneNumbersString = $phoneNumbers[0];
+        for ($i = 1; $i < count($phoneNumbers); $i++) {
+            $phoneNumbersString .= ("," . $phoneNumbers[$i]);
+        }
+
+        return hash("sha256", "appkey=".$appkey."&random=".$random
+            ."&time=".$curTime."&mobile=".$phoneNumbersString);
+    }
+
+    public function phoneNumbersToArray($nationCode, $phoneNumbers)
+    {
+        $i = 0;
+        $tel = array();
+        do {
+            $telElement = new \stdClass();
+            $telElement->nationcode = $nationCode;
+            $telElement->mobile = $phoneNumbers[$i];
+            array_push($tel, $telElement);
+        } while (++$i < count($phoneNumbers));
+
+        return $tel;
+    }
+
+    /**
+     * 生成签名
+     *
+     * @param string $appkey        sdkappid对应的appkey
+     * @param string $random        随机正整数
+     * @param string $curTime       当前时间
+     * @param array  $phoneNumber   手机号码
+     * @return string  签名结果
+     */
+    public function calculateSigForTempl($appkey, $random, $curTime, $phoneNumber)
+    {
+        $phoneNumbers = array($phoneNumber);
+
+        return $this->calculateSigForTemplAndPhoneNumbers($appkey, $random,
+            $curTime, $phoneNumbers);
+    }
+
+    /**
+     * 生成签名
+     *
+     * @param string $appkey        sdkappid对应的appkey
+     * @param string $random        随机正整数
+     * @param string $curTime       当前时间
+     * @return string 签名结果
+     */
+    public function calculateSigForPuller($appkey, $random, $curTime)
+    {
+        return hash("sha256", "appkey=".$appkey."&random=".$random
+            ."&time=".$curTime);
+    }
+
+    /**
+     * 生成上传文件授权
+     *
+     * @param string $appkey        sdkappid对应的appkey
+     * @param string $random        随机正整数
+     * @param string $curTime       当前时间
+     * @param array  $fileSha1Sum   文件sha1sum
+     * @return string  授权结果
+     */
+    public function calculateAuth($appkey, $random, $curTime, $fileSha1Sum)
+    {
+        return hash("sha256", "appkey=".$appkey."&random=".$random
+            ."&time=".$curTime."&content-sha1=".$fileSha1Sum);
+    }
+
+    /**
+     * 生成sha1sum
+     *
+     * @param string $content  内容
+     * @return string  内容sha1散列值
+     */
+    public function sha1sum($content)
+    {
+        return hash("sha1", $content);
+    }
+
+    /**
+     * 发送请求
+     *
+     * @param string $url      请求地址
+     * @param array  $dataObj  请求内容
+     * @return string 应答json字符串
+     */
+    public function sendCurlPost($url, $dataObj)
+    {
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_URL, $url);
+        curl_setopt($curl, CURLOPT_HEADER, 0);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($curl, CURLOPT_POST, 1);
+        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
+        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($dataObj));
+        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
+        'Content-Type: application/json; charset=utf-8',
+        'Content-Length: ' . strlen(json_encode($dataObj)))
+    );
+        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+
+        $ret = curl_exec($curl);
+        if (false == $ret) {
+            // curl_exec failed
+            $result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
+        } else {
+            $rsp = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+            if (200 != $rsp) {
+                $result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
+                        . " " . curl_error($curl) ."\"}";
+            } else {
+                $result = $ret;
+            }
+        }
+
+        curl_close($curl);
+
+        return $result;
+    }
+
+    /**
+     * 发送请求
+     *
+     * @param string $req  请求对象
+     * @return string 应答json字符串
+     */
+    public function fetch($req)
+    {
+        $curl = curl_init();
+
+        curl_setopt($curl, CURLOPT_URL, $req->url);
+        curl_setopt($curl, CURLOPT_HTTPHEADER, $req->headers);
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $req->body);
+        curl_setopt($curl, CURLOPT_HEADER, 0);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($curl, CURLOPT_POST, 1);
+        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+
+        $result = curl_exec($curl);
+
+        if (false == $result) {
+            // curl_exec failed
+            $result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
+        } else {
+            $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+            if (200 != $code) {
+                $result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
+                    . " " . curl_error($curl) ."\"}";
+            }
+        }
+        curl_close($curl);
+
+        return $result;
+    }
+}

+ 107 - 0
addons/qcloudsms/library/SmsSingleSender.php

@@ -0,0 +1,107 @@
+<?php
+
+namespace addons\qcloudsms\library;
+
+use addons\qcloudsms\library\SmsSenderUtil;
+
+/**
+ * 单发短信类
+ *
+ */
+class SmsSingleSender
+{
+    private $url;
+    private $appid;
+    private $appkey;
+    private $util;
+
+    /**
+     * 构造函数
+     *
+     * @param string $appid  sdkappid
+     * @param string $appkey sdkappid对应的appkey
+     */
+    public function __construct($appid, $appkey)
+    {
+        $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms";
+        $this->appid =  $appid;
+        $this->appkey = $appkey;
+        $this->util = new SmsSenderUtil();
+    }
+
+    /**
+     * 普通单发
+     *
+     * 普通单发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名。
+     *
+     * @param int    $type        短信类型,0 为普通短信,1 营销短信
+     * @param string $nationCode  国家码,如 86 为中国
+     * @param string $phoneNumber 不带国家码的手机号
+     * @param string $msg         信息内容,必须与申请的模板格式一致,否则将返回错误
+     * @param string $extend      扩展码,可填空串
+     * @param string $ext         服务端原样返回的参数,可填空串
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function send($type, $nationCode, $phoneNumber, $msg, $extend = "", $ext = "")
+    {
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        // 按照协议组织 post 包体
+        $data = new \stdClass();
+        $tel = new \stdClass();
+        $tel->nationcode = "".$nationCode;
+        $tel->mobile = "".$phoneNumber;
+
+        $data->tel = $tel;
+        $data->type = (int)$type;
+        $data->msg = $msg;
+        $data->sig = hash("sha256",
+            "appkey=".$this->appkey."&random=".$random."&time="
+            .$curTime."&mobile=".$phoneNumber, FALSE);
+        $data->time = $curTime;
+        $data->extend = $extend;
+        $data->ext = $ext;
+
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+
+    /**
+     * 指定模板单发
+     *
+     * @param string $nationCode  国家码,如 86 为中国
+     * @param string $phoneNumber 不带国家码的手机号
+     * @param int    $templId     模板 id
+     * @param array  $params      模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
+     * @param string $sign        签名,如果填空串,系统会使用默认签名
+     * @param string $extend      扩展码,可填空串
+     * @param string $ext         服务端原样返回的参数,可填空串
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function sendWithParam($nationCode, $phoneNumber, $templId = 0, $params,
+        $sign = "", $extend = "", $ext = "")
+    {
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        // 按照协议组织 post 包体
+        $data = new \stdClass();
+        $tel = new \stdClass();
+        $tel->nationcode = "".$nationCode;
+        $tel->mobile = "".$phoneNumber;
+
+        $data->tel = $tel;
+        $data->sig = $this->util->calculateSigForTempl($this->appkey, $random,
+            $curTime, $phoneNumber);
+        $data->tpl_id = $templId;
+        $data->params = $params;
+        $data->sign = $sign;
+        $data->time = $curTime;
+        $data->extend = $extend;
+        $data->ext = $ext;
+
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+}

+ 75 - 0
addons/qcloudsms/library/SmsStatusPuller.php

@@ -0,0 +1,75 @@
+<?php
+
+namespace addons\qcloudsms\library;
+
+use addons\qcloudsms\library\SmsSenderUtil;
+
+/**
+ * 拉取短信状态类
+ *
+ */
+class SmsStatusPuller
+{
+    private $url;
+    private $appid;
+    private $appkey;
+    private $util;
+
+    /**
+     * 构造函数
+     *
+     * @param string $appid  sdkappid
+     * @param string $appkey sdkappid对应的appkey
+     */
+    public function __construct($appid, $appkey)
+    {
+        $this->url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus";
+        $this->appid =  $appid;
+        $this->appkey = $appkey;
+        $this->util = new SmsSenderUtil();
+    }
+
+    /**
+     * 拉取回执结果
+     *
+     * @param int $type 拉取类型,0表示回执结果,1表示回复信息
+     * @param int $max  最大条数,最多100
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    private function pull($type, $max)
+    {
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        $data = new \stdClass();
+        $data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
+        $data->time = $curTime;
+        $data->type = $type;
+        $data->max = $max;
+
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+
+    /**
+     * 拉取回执结果
+     *
+     * @param int $max 拉取最大条数,最多100
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function pullCallback($max)
+    {
+        return $this->pull(0, $max);
+    }
+
+    /**
+     * 拉取回复信息
+     *
+     * @param int $max 拉取最大条数,最多100
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function pullReply($max)
+    {
+        return $this->pull(1, $max);
+    }
+}

+ 71 - 0
addons/qcloudsms/library/SmsVoicePromptSender.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace addons\qcloudsms\library;
+
+use addons\qcloudsms\library\SmsSenderUtil;
+
+/**
+ * 发送语音通知类
+ *
+ */
+class SmsVoicePromptSender
+{
+    private $url;
+    private $appid;
+    private $appkey;
+    private $util;
+
+    /**
+     * 构造函数
+     *
+     * @param string $appid  sdkappid
+     * @param string $appkey sdkappid对应的appkey
+     */
+    public function __construct($appid, $appkey)
+    {
+        $this->url = "https://yun.tim.qq.com/v5/tlsvoicesvr/sendvoiceprompt";
+        $this->appid =  $appid;
+        $this->appkey = $appkey;
+        $this->util = new SmsSenderUtil();
+    }
+
+    /**
+     *
+     * 发送语音通知
+     *
+     * @param string $nationCode  国家码,如 86 为中国
+     * @param string $phoneNumber 不带国家码的手机号
+     * @param string $prompttype  语音类型,目前固定为2
+     * @param string $msg         信息内容,必须与申请的模板格式一致,否则将返回错误
+     * @param string $playtimes   播放次数,可选,最多3次,默认2次
+     * @param string $ext         用户的session内容,服务端原样返回,可选字段,不需要可填空串
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function send($nationCode, $phoneNumber, $prompttype, $msg, $playtimes = 2, $ext = "")
+    {
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        // 按照协议组织 post 包体
+        $data = new \stdClass();
+        $tel = new \stdClass();
+        $tel->nationcode = "".$nationCode;
+        $tel->mobile = "".$phoneNumber;
+
+        $data->tel = $tel;
+        // 通知内容,utf8编码,支持中文英文、数字及组合,需要和语音内容模版相匹配
+        $data->promptfile = $msg;
+        // 固定值 2
+        $data->prompttype = $prompttype;
+        $data->playtimes = $playtimes;
+        // app凭证
+        $data->sig = hash("sha256",
+            "appkey=".$this->appkey."&random=".$random."&time="
+            .$curTime."&mobile=".$phoneNumber, FALSE);
+        // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
+        $data->time = $curTime;
+        $data->ext = $ext;
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+}

+ 67 - 0
addons/qcloudsms/library/SmsVoiceVerifyCodeSender.php

@@ -0,0 +1,67 @@
+<?php
+
+namespace addons\qcloudsms\library;
+
+use addons\qcloudsms\library\SmsSenderUtil;
+
+/**
+ * 发送语音验证码类
+ *
+ */
+class SmsVoiceVerifyCodeSender
+{
+    private $url;
+    private $appid;
+    private $appkey;
+    private $util;
+
+    /**
+     * 构造函数
+     *
+     * @param string $appid  sdkappid
+     * @param string $appkey sdkappid对应的appkey
+     */
+    public function __construct($appid, $appkey)
+    {
+        $this->url = "https://yun.tim.qq.com/v5/tlsvoicesvr/sendvoice";
+        $this->appid =  $appid;
+        $this->appkey = $appkey;
+        $this->util = new SmsSenderUtil();
+    }
+
+    /**
+     * 发送语音验证码
+     *
+     * @param string $nationCode  国家码,如 86 为中国
+     * @param string $phoneNumber 不带国家码的手机号
+     * @param string $msg         信息内容,必须与申请的模板格式一致,否则将返回错误
+     * @param int    $playtimes   播放次数,可选,最多3次,默认2次
+     * @param string $ext         用户的session内容,服务端原样返回,可选字段,不需要可填空串
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function send($nationCode, $phoneNumber, $msg, $playtimes = 2, $ext = "")
+    {
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        // 按照协议组织 post 包体
+        $data = new \stdClass();
+        $tel = new \stdClass();
+        $tel->nationcode = "".$nationCode;
+        $tel->mobile = "".$phoneNumber;
+
+        $data->tel = $tel;
+        $data->msg = $msg;
+        $data->playtimes = $playtimes;
+        // app凭证
+        $data->sig = hash("sha256",
+            "appkey=".$this->appkey."&random=".$random."&time="
+            .$curTime."&mobile=".$phoneNumber, FALSE);
+        // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
+        $data->time = $curTime;
+        $data->ext = $ext;
+
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+}

+ 77 - 0
addons/qcloudsms/library/TtsVoiceSender.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace addons\qcloudsms\library;
+
+use addons\qcloudsms\library\SmsSenderUtil;
+
+
+/**
+ * 指定模板发送语音通知类
+ *
+ */
+class TtsVoiceSender
+{
+    private $url;
+    private $appid;
+    private $appkey;
+    private $util;
+
+    /**
+     * 构造函数
+     *
+     * @param string $appid  sdkappid
+     * @param string $appkey sdkappid对应的appkey
+     */
+    public function __construct($appid, $appkey)
+    {
+        $this->url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendtvoice";
+        $this->appid =  $appid;
+        $this->appkey = $appkey;
+        $this->util = new SmsSenderUtil();
+    }
+
+    /**
+     *
+     * 指定模板发送语音短信
+     *
+     * @param string $nationCode  国家码,如 86 为中国
+     * @param string $phoneNumber 不带国家码的手机号
+     * @param int    $templId     模板 id
+     * @param array  $params      模板参数列表,如模板 {1}...{2}...{3},需要带三个参数
+     * @param string $playtimes   播放次数,可选,最多3次,默认2次
+     * @param string $ext         用户的session内容,服务端原样返回,可选字段,不需要可填空串
+     * @return string 应答json字符串,详细内容参见腾讯云协议文档
+     */
+    public function send($nationCode, $phoneNumber, $templId, $params, $playtimes = 2, $ext = "")
+    {
+        /*var_dump($nationCode);
+        var_dump($phoneNumber);
+        var_dump($templId);
+        var_dump($params);
+        var_dump($playtimes);
+        exit();*/
+        $random = $this->util->getRandom();
+        $curTime = time();
+        $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+        // 按照协议组织 post 包体
+        $data = new \stdClass();
+        $tel = new \stdClass();
+        $tel->nationcode = "".$nationCode;
+        $tel->mobile = "".$phoneNumber;
+        $data->tel = $tel;
+        $data->tpl_id = $templId;
+        $data->params = $params;
+        $data->playtimes = $playtimes;
+
+        // app凭证
+        $data->sig = $this->util->calculateSig($this->appkey, $random,
+            $curTime, array($phoneNumber));
+
+        // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
+        $data->time = $curTime;
+        $data->ext = $ext;
+        //var_dump($data);exit();
+        return $this->util->sendCurlPost($wholeUrl, $data);
+    }
+}

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
addons/shopro/.addonrc


+ 134 - 0
addons/shopro/Shopro.php

@@ -0,0 +1,134 @@
+<?php
+
+namespace addons\shopro;
+
+use think\Addons;
+use app\common\library\Menu;
+use app\admin\model\AuthRule;
+use addons\shopro\library\Hook;
+use think\Exception;
+use think\exception\PDOException;
+
+/**
+ * Shopro插件 v1.0.7
+ */
+class Shopro extends Addons
+{
+
+    /**
+     * 插件安装方法
+     * @return bool
+     */
+    public function install()
+    { 
+        $menu = self::getMenu();
+        Menu::create($menu['new']);
+        return true;
+    }
+
+    /**
+     * 插件卸载方法
+     * @return bool
+     */
+    public function uninstall()
+    {
+        Menu::delete('shopro');
+        return true;
+    }
+
+    /**
+     * 插件启用方法
+     */
+    public function enable()
+    {
+        Menu::enable('shopro');
+        return true;
+    }
+
+    /**
+     * 插件更新方法
+     */
+    public function upgrade()
+    {
+        $menu = self::getMenu();
+        if(method_exists(Menu::class, 'upgrade')){
+            Menu::upgrade('shopro', $menu['new']);
+        }else {
+            //使用Shopro自带的更新操作
+            self::menuCreateOrUpdate($menu['new'], $menu['old']);
+        }
+
+        return true;
+    }
+
+    /**
+     * 插件禁用方法
+     */
+    public function disable()
+    {
+        Menu::disable('shopro');
+         return true;
+    }
+
+
+    /**
+     * 应用初始化
+     */
+    public function appInit()
+    {
+        // 公共方法
+        require_once __DIR__ . '/helper.php';
+
+        // 全局注册行为事件
+        Hook::register();
+
+        if (request()->isCli()) {
+            \think\Console::addDefaultCommands([
+                'addons\shopro\command\Chat'
+            ]);
+        }
+    }
+
+    private static function getMenu()
+    {
+        $newMenu = [];
+        $config_file = ADDON_PATH . "shopro" . DS . 'config' . DS . "menu.php";
+        if (is_file($config_file)) {
+            $newMenu = include $config_file;
+        }
+        $oldMenu = AuthRule::where('name','like',"shopro%")->select();
+        $oldMenu = array_column($oldMenu, null, 'name');
+        return ['new' => $newMenu, 'old' => $oldMenu];
+    }
+
+    private static function menuCreateOrUpdate($newMenu, $oldMenu, $parent = 0)
+    {
+        if (!is_numeric($parent)) {
+            $parentRule = AuthRule::getByName($parent);
+            $pid = $parentRule ? $parentRule['id'] : 0;
+        } else {
+            $pid = $parent;
+        }
+        $allow = array_flip(['file', 'name', 'title', 'icon', 'condition', 'remark', 'ismenu', 'weigh']);
+        foreach ($newMenu as $k => $v) {
+            $hasChild = isset($v['sublist']) && $v['sublist'] ? true : false;
+            $data = array_intersect_key($v, $allow);
+            $data['ismenu'] = isset($data['ismenu']) ? $data['ismenu'] : ($hasChild ? 1 : 0);
+            $data['icon'] = isset($data['icon']) ? $data['icon'] : ($hasChild ? 'fa fa-list' : 'fa fa-circle-o');
+            $data['pid'] = $pid;
+            $data['status'] = 'normal';
+            try {
+                if (!isset($oldMenu[$data['name']])) {
+                    $menu = AuthRule::create($data);
+                }else{
+                    $menu = $oldMenu[$data['name']];
+                }
+                if ($hasChild) {
+                    self::menuCreateOrUpdate($v['sublist'], $oldMenu, $menu['id']);
+                }
+            } catch (PDOException $e) {
+                new Exception($e->getMessage());
+            }
+        }
+    }
+}

+ 67 - 0
addons/shopro/bootstrap.js

@@ -0,0 +1,67 @@
+if (Config.modulename == 'admin' && Config.controllername == 'index' && Config.actionname == 'index') {
+    require.config({
+        paths: {
+            'vue': "../addons/shopro/libs/vue",
+            'moment': "../addons/shopro/libs/moment",
+            'text': "../addons/shopro/libs/require-text",
+            'chat': '../addons/shopro/libs/chat',
+            'ELEMENT': '../addons/shopro/libs/element/element',
+        },
+        shim: {
+            'ELEMENT': {
+                deps: ['css!../addons/shopro/libs/element/element.css']
+            },
+        },
+    });
+    require(['vue', 'jquery', 'chat', 'text!../addons/shopro/chat.html', 'ELEMENT', 'moment'], function (Vue, $, Chat, ChatTemp, ELEMENT, Moment) {
+
+        Vue.use(ELEMENT);
+
+        var wsUri;
+        Fast.api.ajax({
+            url: 'shopro/chat/index/init',
+            loading: false,
+            type: 'GET'
+        }, function (ret, res) {
+            if (res.data.config.type == 'shopro') {
+
+                let wg = 'ws';
+                if (res.data.config.system.is_ssl == 1) {
+                    wg = 'wss';
+                }
+                wsUri = wg + '://' + window.location.hostname + ':' + res.data.config.system.gateway_port;
+                // 反向代理
+                if (res.data.config.system.is_ssl == 1 && res.data.config.system.ssl_type == 'reverse_proxy') {
+                    wsUri = wg + '://' + window.location.hostname + '/websocket/';
+                }
+                $("body").append(`<div id="chatTemplateContainer" style="display:none"></div>
+                    <div id="chatService"><Chat :passvalue="obj"></Chat></div>`);
+
+                $("#chatTemplateContainer").append(ChatTemp);
+
+                new Vue({
+                    el: "#chatService",
+                    data() {
+                        return {
+                            obj: {
+                                commonWordsList: res.data.fast_reply,
+                                token: res.data.token,
+                                wsUri: wsUri,
+                                expire_time: res.data.expire_time,
+                                customer_service_id: res.data.customer_service.id,
+                                adminData: res.data,
+                                emoji_list: res.data.emoji
+                            }
+                        }
+                    }
+                });
+
+            }
+            return false;
+        }, function (ret, res) {
+            if (res.msg == '') {
+                return false;
+            }
+        })
+    });
+}

+ 79 - 0
addons/shopro/command/Chat.php

@@ -0,0 +1,79 @@
+<?php
+/**
+ * run with command
+ * php start.php start
+ */
+
+namespace addons\shopro\command;
+
+use think\console\Command;
+use think\console\Input;
+use think\console\input\Argument;
+use think\console\Output;
+use Workerman\Worker;
+use addons\shopro\library\chat\Start;
+
+/**
+ *
+ */
+class Chat extends Command
+{
+
+    protected function configure()
+    {
+        $this->setName('shopro:chat')
+            ->addArgument('action', Argument::OPTIONAL, "action start [d]|stop|restart|status")
+            ->addArgument('type', Argument::OPTIONAL, "d -d")
+            ->setHelp('此命令是用来启动 shopro 商城的客服服务端进程')
+            ->setDescription('shopro 客服');
+    }
+
+    protected function execute(Input $input, Output $output)
+    {
+        global $argv;
+        $action = trim($input->getArgument('action'));
+        $type   = trim($input->getArgument('type')) ? '-d' : '';
+
+        $argv[0] = 'shopro:chat';
+        $argv[1] = $action;
+        $argv[2] = $type ? '-d' : '';
+        $this->start($input, $output);
+    }
+
+    private function start($input, $output)
+    {
+        if (strpos(strtolower(PHP_OS), 'win') === 0) {
+            $output->writeln("<error>GatewayWorker Not Support On Windows.</error>");
+            exit(1);
+        }
+
+        // 检查扩展
+        if (!extension_loaded('pcntl')) {
+            $output->writeln("<error>Please install pcntl extension.</error>");
+            exit(1);
+        }
+
+        if (!extension_loaded('posix')) {
+            $output->writeln("<error>Please install posix extension.</error>");
+            exit(1);
+        }
+
+        // 实例化启动类
+        $startServer = new Start();
+
+        // 启动 register
+        $startServer->register();
+
+        // 启动 businessWorker
+        $startServer->businessWorker();
+
+        // 启动 gateway
+        $startServer->gateway();
+
+        // 设置日志
+        $startServer->setLog(__DIR__ . '/../');
+
+        // 运行所有服务
+        Worker::runAll();
+    }
+}

+ 5966 - 0
addons/shopro/config/menu.php

@@ -0,0 +1,5966 @@
+<?php
+/**
+ * 菜单配置文件
+ */
+
+return array (
+  0 => 
+  array (
+    'type' => 'file',
+    'name' => 'shopro',
+    'title' => 'Shopro商城',
+    'icon' => 'fa fa-home',
+    'url' => '',
+    'condition' => '',
+    'remark' => '',
+    'ismenu' => 1,
+    'menutype' => NULL,
+    'extend' => '',
+    'weigh' => 0,
+    'sublist' => 
+    array (
+      0 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/config',
+        'title' => '商城配置',
+        'icon' => 'fa fa-sliders',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/config/index',
+            'title' => '查看',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/config/add',
+            'title' => '添加',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/config/edit',
+            'title' => '编辑',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/config/del',
+            'title' => '删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/config/multi',
+            'title' => '批量更新',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          5 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/config/platform',
+            'title' => '平台配置',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+        ),
+      ),
+      1 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/decorate',
+        'title' => '店铺装修',
+        'icon' => 'fa fa-paint-brush',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/lists',
+            'title' => '模版管理',
+            'icon' => 'fa fa-cubes',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/add',
+            'title' => '添加',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/edit',
+            'title' => '编辑',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/del',
+            'title' => '删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/multi',
+            'title' => '批量更新',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          5 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/recyclebin',
+            'title' => '回收站',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          6 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/destroy',
+            'title' => '真实删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          7 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/restore',
+            'title' => '还原',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          8 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/dodecorate',
+            'title' => '装修',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          9 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/preview',
+            'title' => '预览页面',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          10 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/designer',
+            'title' => '设计师模板',
+            'icon' => 'fa fa-cube',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/decorate/use_designer_template',
+                'title' => '使用',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          11 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/custom',
+            'title' => '自定义页面',
+            'icon' => 'fa fa-clone',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/decorate/select',
+                'title' => '自定义选择',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          12 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/publish',
+            'title' => '发布',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          13 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/dodecorate_save',
+            'title' => '装修保存',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          14 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/copy',
+            'title' => '复制模板',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          15 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/index',
+            'title' => '查看',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          16 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/decorate/down',
+            'title' => '模板下架',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+        ),
+      ),
+      2 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/coupons',
+        'title' => '优惠券',
+        'icon' => 'fa fa-money',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/coupons/index',
+            'title' => '查看',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/coupons/recyclebin',
+            'title' => '回收站',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/coupons/add',
+            'title' => '添加',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/coupons/edit',
+            'title' => '编辑',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/coupons/del',
+            'title' => '删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          5 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/coupons/destroy',
+            'title' => '真实删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          6 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/coupons/restore',
+            'title' => '还原',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          7 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/coupons/multi',
+            'title' => '批量更新',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          8 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/coupons/select',
+            'title' => '选择优惠券',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+        ),
+      ),
+      3 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/dispatch',
+        'title' => '配送设置',
+        'icon' => 'fa fa-gears',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dispatch/dispatch',
+            'title' => '发货模板',
+            'icon' => 'fa fa-ambulance',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/dispatch/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/dispatch/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/dispatch/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/dispatch/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/dispatch/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/dispatch/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/dispatch/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/dispatch/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/dispatch/select',
+                'title' => '选择模板',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dispatch/selfetch',
+            'title' => '到店/自提',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/selfetch/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/selfetch/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/selfetch/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/selfetch/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/selfetch/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/selfetch/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/selfetch/destroy',
+                'title' => '销毁',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dispatch/express',
+            'title' => '物流快递',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/express/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/express/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/express/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/express/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/express/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/express/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/express/destroy',
+                'title' => '销毁',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dispatch/store',
+            'title' => '商家配送',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/store/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/store/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/store/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/store/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/store/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/store/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/store/destroy',
+                'title' => '销毁',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dispatch/autosend',
+            'title' => '自动发货',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/autosend/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/autosend/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/autosend/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/autosend/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/autosend/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/autosend/destroy',
+                'title' => '销毁',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/dispatch/autosend/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          5 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/express',
+            'title' => '快递公司',
+            'icon' => 'fa fa-automobile',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/express/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/express/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/express/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/express/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/express/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/express/select',
+                'title' => '选择',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+        ),
+      ),
+      4 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/product',
+        'title' => '商品管理',
+        'icon' => 'fa fa-archive',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/category',
+            'title' => '商品分类',
+            'icon' => 'fa fa-sitemap',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/category/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/category/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/category/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/category/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/category/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/category/select',
+                'title' => '选择商品组',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/category/update',
+                'title' => '保存更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/goods/goods',
+            'title' => '商品管理',
+            'icon' => 'fa fa-shopping-bag',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/select',
+                'title' => '选择商品',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              9 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/detail',
+                'title' => '查看详情',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              10 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/goods/setstatus',
+                'title' => '商品状态',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/goods/service',
+            'title' => '服务标签',
+            'icon' => 'fa fa-tags',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/service/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/service/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/service/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/service/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/service/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/service/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/service/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/service/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/goods/comment',
+            'title' => '商品评价',
+            'icon' => 'fa fa-pencil-square',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/comment/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/comment/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/comment/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/comment/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/comment/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/comment/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/comment/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/comment/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/comment/setstatus',
+                'title' => '设置状态',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => 'addtabs',
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/goods/stock_warning',
+            'title' => '库存预警',
+            'icon' => 'fa fa-warning',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/stock_warning/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/stock_warning/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/stock_warning/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/stock_warning/destroy',
+                'title' => '销毁',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/goods/stock_warning/addstock',
+                'title' => '补货',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+        ),
+      ),
+      5 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/material',
+        'title' => '资料管理',
+        'icon' => 'fa fa-file-text',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/richtext',
+            'title' => '富文本',
+            'icon' => 'fa fa-language',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/richtext/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/richtext/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/richtext/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/richtext/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/richtext/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/richtext/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/richtext/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/richtext/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/richtext/select',
+                'title' => '选择富文本',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/link',
+            'title' => '页面链接',
+            'icon' => 'fa fa-unlink',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/link/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/link/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/link/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/link/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/link/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/link/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/link/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/link/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/link/select',
+                'title' => '选择链接',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/area',
+            'title' => '省市区数据',
+            'icon' => 'fa fa-percent',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/area/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/area/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/area/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/area/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/area/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/area/select',
+                'title' => '选择省市区',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/faq',
+            'title' => '常见问题',
+            'icon' => 'fa fa-info-circle',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/faq/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/faq/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/faq/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/faq/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/faq/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/faq/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/faq/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/faq/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_fake',
+            'title' => '虚拟用户',
+            'icon' => 'fa fa-user-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user_fake/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user_fake/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user_fake/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user_fake/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user_fake/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user_fake/random_user',
+                'title' => '添加虚拟用户',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+        ),
+      ),
+      6 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/activity',
+        'title' => '活动中心',
+        'icon' => 'fa fa-font-awesome',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/activity/activity',
+            'title' => '营销活动',
+            'icon' => 'fa fa-star',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/createorupdatesku',
+                'title' => '编辑活动规格',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              9 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/select',
+                'title' => '选择活动',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              10 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/sku',
+                'title' => '活动规格',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              11 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/detail',
+                'title' => '活动详情',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              12 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/all',
+                'title' => '活动记录',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              13 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity/gettype',
+                'title' => '活动类型',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/activity/activity_sku_price',
+            'title' => '商品规格',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity_sku_price/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity_sku_price/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity_sku_price/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity_sku_price/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity_sku_price/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity_sku_price/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity_sku_price/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/activity_sku_price/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/activity/groupon',
+            'title' => '拼团列表',
+            'icon' => 'fa fa-modx',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/groupon/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/groupon/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/groupon/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/groupon/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/groupon/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/groupon/detail',
+                'title' => '详情',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/activity/groupon/addfictitious',
+                'title' => '确定拼团虚拟人',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+        ),
+      ),
+      7 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/app',
+        'title' => '应用',
+        'icon' => 'fa fa-suitcase',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/app/score_shop',
+            'title' => '积分商城',
+            'icon' => 'fa fa-database',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/select',
+                'title' => '选择积分产品',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/createorupdatesku',
+                'title' => '更编辑积分规格',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/sku',
+                'title' => '积分规格',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              9 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              10 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/score_shop/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/app/live',
+            'title' => '小程序直播',
+            'icon' => 'fa fa-video-camera',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/select',
+                'title' => '直播间选择',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/detail',
+                'title' => '直播详情',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/synclive',
+                'title' => '同步直播间',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              9 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              10 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/app/live/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+        ),
+      ),
+      8 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/user_wallet_apply',
+        'title' => '用户提现',
+        'icon' => 'fa fa-jpy',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/index',
+            'title' => '查看',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/recyclebin',
+            'title' => '回收站',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/add',
+            'title' => '添加',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/edit',
+            'title' => '编辑',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/del',
+            'title' => '删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          5 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/destroy',
+            'title' => '真实删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          6 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/restore',
+            'title' => '还原',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          7 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/multi',
+            'title' => '批量更新',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          8 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/gettype',
+            'title' => '获取type',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          9 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/handle',
+            'title' => '提现操作',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          10 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/log',
+            'title' => '操作日志',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          11 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user_wallet_apply/export',
+            'title' => '导出',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+        ),
+      ),
+      9 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/order',
+        'title' => '订单中心',
+        'icon' => 'fa fa-file',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/order/order',
+            'title' => '订单管理',
+            'icon' => 'fa fa-file-text',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/detail',
+                'title' => '详情',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              9 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/send',
+                'title' => '发货',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              10 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/aftersalefinish',
+                'title' => '售后',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              11 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/refund',
+                'title' => '退款',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              12 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/editmemo',
+                'title' => '备注',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              13 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/gettype',
+                'title' => '订单筛选',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              14 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/refundrefuse',
+                'title' => '拒绝退款',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              15 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/export',
+                'title' => '订单导出',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              16 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/actions',
+                'title' => '操作记录',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              17 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/editconsignee',
+                'title' => '修改收货信息',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              18 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/sendstore',
+                'title' => '备货',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              19 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/deliverbyapi',
+                'title' => 'api发货',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              20 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/deliverbyinput',
+                'title' => '手动发货',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              21 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/deliverbyuploadtemplate',
+                'title' => '模板发货',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              22 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/exportdelivery',
+                'title' => '导出发货单',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              23 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order/changefee',
+                'title' => '改价',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => 'addtabs',
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/order/order_item',
+            'title' => '订单商品明细',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order_item/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order_item/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order_item/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order_item/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order_item/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order_item/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order_item/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/order_item/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/order/aftersale',
+            'title' => '售后/退款',
+            'icon' => 'fa fa-handshake-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/destroy',
+                'title' => '真实删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/restore',
+                'title' => '还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/detail',
+                'title' => '详情',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              9 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/addlog',
+                'title' => '售后反馈',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              10 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/refuse',
+                'title' => '拒绝申请',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              11 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/refund',
+                'title' => '同意退款',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              12 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/aftersale/finish',
+                'title' => '售后完成',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/order/invoice',
+            'title' => '订单发票',
+            'icon' => 'fa fa-sticky-note-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => 'addtabs',
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/invoice/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => 'addtabs',
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/invoice/confirm',
+                'title' => '确认开具',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => 'addtabs',
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/order/trade_order',
+            'title' => '充值订单',
+            'icon' => 'fa fa-paypal',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => 'addtabs',
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/order/trade_order/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => 'addtabs',
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+        ),
+      ),
+      10 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/feedback',
+        'title' => '意见反馈',
+        'icon' => 'fa fa-question-circle-o',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/feedback/index',
+            'title' => '查看',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/feedback/recyclebin',
+            'title' => '回收站',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/feedback/add',
+            'title' => '添加',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/feedback/edit',
+            'title' => '编辑',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/feedback/del',
+            'title' => '删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          5 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/feedback/destroy',
+            'title' => '真实删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          6 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/feedback/restore',
+            'title' => '还原',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          7 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/feedback/multi',
+            'title' => '批量更新',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          8 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/feedback/detail',
+            'title' => '详情',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+        ),
+      ),
+      11 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/dashboard',
+        'title' => '数据中心',
+        'icon' => 'fa fa-dashboard',
+        'url' => '',
+        'condition' => '',
+        'remark' => '用于展示当前系统中的统计数据、统计报表及重要实时数据',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dashboard/index',
+            'title' => '查看',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dashboard/add',
+            'title' => '添加',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dashboard/edit',
+            'title' => '编辑',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dashboard/del',
+            'title' => '删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/dashboard/multi',
+            'title' => '批量更新',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+        ),
+      ),
+      12 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/wechat',
+        'title' => '微信管理',
+        'icon' => 'fa fa-wechat',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/wechat/menu/index',
+            'title' => '菜单管理',
+            'icon' => 'fa fa-server',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/menu/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/menu/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/menu/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/menu/publish',
+                'title' => '发布',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/menu/copy',
+                'title' => '复制',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/wechat/auto_reply/index',
+            'title' => '自动回复',
+            'icon' => 'fa fa-send',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/auto_reply/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/auto_reply/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/auto_reply/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/wechat/material/index',
+            'title' => '素材管理',
+            'icon' => 'fa fa-folder-open',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/material/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/material/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/material/detail',
+                'title' => '音频播放',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/material/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/wechat/material/select',
+                'title' => '选择',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+        ),
+      ),
+      13 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/notification',
+        'title' => '消息通知',
+        'icon' => 'fa fa-bullhorn',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/index',
+            'title' => '查看列表',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/recyclebin',
+            'title' => '回收站',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/add',
+            'title' => '添加',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/edit',
+            'title' => '编辑',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/del',
+            'title' => '删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          5 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/destroy',
+            'title' => '真实删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          6 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/restore',
+            'title' => '还原',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          7 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/config',
+            'title' => '消息配置',
+            'icon' => 'fa fa-cogs',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          8 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/set_template',
+            'title' => '配置模板',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          9 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/notification/set_status',
+            'title' => '切换状态',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+        ),
+      ),
+      14 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/store',
+        'title' => '门店管理',
+        'icon' => 'fa fa-bank',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/store/store',
+            'title' => '门店列表',
+            'icon' => 'fa fa-building',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/recyclebin',
+                'title' => '回收站',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/setstatus',
+                'title' => '是否禁用',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/select',
+                'title' => '选择',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              6 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              7 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/all',
+                'title' => '全部门店',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              8 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/restore',
+                'title' => '单个还原',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              9 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/store/destroy',
+                'title' => '单个销毁',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/store/apply',
+            'title' => '门店审核',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/apply/applyoper',
+                'title' => '操作',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/apply/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/apply/detail',
+                'title' => '详情',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/store/dashboard',
+            'title' => '门店统计',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/store/dashboard/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+        ),
+      ),
+      15 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/user/user',
+        'title' => '用户管理',
+        'icon' => 'fa fa-user',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/index',
+            'title' => '用户列表',
+            'icon' => 'fa fa-list-ul',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user/user/change_parent_user',
+                'title' => '修改用户推荐人',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/select',
+            'title' => '选择',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/profile',
+            'title' => '编辑',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          3 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/del',
+            'title' => '删除',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          4 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/order_log',
+            'title' => '订单记录',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          5 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/login_log',
+            'title' => '登录记录',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          6 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/money_log',
+            'title' => '余额明细',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          7 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/score_log',
+            'title' => '积分明细',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          8 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/share_log',
+            'title' => '分享记录',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          9 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/goods_favorite',
+            'title' => '收藏商品',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          10 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/coupon_log',
+            'title' => '优惠券',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          11 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/goods_view',
+            'title' => '浏览足迹',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          12 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/recyclebin',
+            'title' => '回收站',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          13 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/update',
+            'title' => '更新',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          14 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/money_recharge',
+            'title' => '余额充值',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          15 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/score_recharge',
+            'title' => '积分充值',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+          16 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/group',
+            'title' => '用户分组',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user/group/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user/group/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user/group/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/user/group/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          17 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/user/user/batchrecharge',
+            'title' => '批量充值',
+            'icon' => 'fa fa-circle-o',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 0,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+          ),
+        ),
+      ),
+      16 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/commission',
+        'title' => '分销中心',
+        'icon' => 'fa fa-users',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/commission/config',
+            'title' => '分销设置',
+            'icon' => 'fa fa-cog',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/commission/config/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/commission/config/save',
+                'title' => '保存',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          )
+        ),
+      ),
+      17 => 
+      array (
+        'type' => 'file',
+        'name' => 'shopro/chat',
+        'title' => '客服管理',
+        'icon' => 'fa fa-list',
+        'url' => '',
+        'condition' => '',
+        'remark' => '',
+        'ismenu' => 1,
+        'menutype' => NULL,
+        'extend' => '',
+        'weigh' => 0,
+        'sublist' => 
+        array (
+          0 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/chat/fast_reply',
+            'title' => '快捷回复',
+            'icon' => 'fa fa-commenting',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/fast_reply/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/fast_reply/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/fast_reply/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/fast_reply/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/fast_reply/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          1 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/chat/question',
+            'title' => '常见问题',
+            'icon' => 'fa fa-envelope-open',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/question/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/question/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/question/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/question/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/question/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+          2 => 
+          array (
+            'type' => 'file',
+            'name' => 'shopro/chat/customer_service',
+            'title' => '客服管理',
+            'icon' => 'fa fa-user-circle',
+            'url' => '',
+            'condition' => '',
+            'remark' => '',
+            'ismenu' => 1,
+            'menutype' => NULL,
+            'extend' => '',
+            'weigh' => 0,
+            'sublist' => 
+            array (
+              0 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/customer_service/index',
+                'title' => '查看',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              1 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/customer_service/add',
+                'title' => '添加',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              2 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/customer_service/edit',
+                'title' => '编辑',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              3 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/customer_service/del',
+                'title' => '删除',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              4 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/chat/customer_service/multi',
+                'title' => '批量更新',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+              5 => 
+              array (
+                'type' => 'file',
+                'name' => 'shopro/admin/index',
+                'title' => '管理员列表',
+                'icon' => 'fa fa-circle-o',
+                'url' => '',
+                'condition' => '',
+                'remark' => '',
+                'ismenu' => 0,
+                'menutype' => NULL,
+                'extend' => '',
+                'weigh' => 0,
+              ),
+            ),
+          ),
+        ),
+      ),
+    ),
+  ),
+);

+ 38 - 0
addons/shopro/controller/ActivityGroupon.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace addons\shopro\controller;
+
+/**
+ * 拼团开的团
+ *
+ */
+
+class ActivityGroupon extends Base
+{
+    protected $noNeedLogin = ['index', 'detail'];
+    protected $noNeedRight = ['*'];
+
+
+    /**
+     * 根据商品 id 获取正在拼的团
+     */
+    public function index() {
+        $params = $this->request->get();
+
+        $this->success('团列表', \addons\shopro\model\ActivityGroupon::getActivityGroupon($params));
+    }
+
+
+    public function detail () {
+        $id = $this->request->get('id');
+
+        $this->success('团详情', \addons\shopro\model\ActivityGroupon::getActivityGrouponDetail($id));
+    }
+
+
+    public function myGroupon () {
+        $type = $this->request->get('type', 'all');
+
+        $this->success('我的拼团', \addons\shopro\model\ActivityGroupon::getMyGroupon($type));
+    }
+}

+ 63 - 0
addons/shopro/controller/Address.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\exception\Exception;
+use addons\shopro\model\UserAddress;
+use addons\shopro\model\Area;
+
+class Address extends Base
+{
+
+    protected $noNeedLogin = ['area'];
+    protected $noNeedRight = ['*'];
+
+    public function index()
+    {
+        $this->success('收货地址', UserAddress::getUserAddress());
+    }
+
+    public function defaults()
+    {
+        $this->success('默认收货地址', UserAddress::getUserDefaultAddress());
+    }
+
+    public function area()
+    {
+        $data['provinceData'] = Area::where('level', 1)->order('id asc')->field('id as value, name as label, pid, level')->select();
+        foreach ($data['provinceData'] as $k => $p) {
+            $data['cityData'][$k] = Area::where(['level' => 2, 'pid' => $p->value])->order('id asc')->field('id as value, name as label, pid, level')->select();
+            foreach ($data['cityData'][$k] as $i => $c) {
+                $data['areaData'][$k][$i] = Area::where(['level' => 3, 'pid' => $c->value])->order('id asc')->field('id as value, name as label, pid, level')->select();
+            }
+        }
+
+        $this->success('省市区', $data);
+
+    }
+
+    public function edit()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'edit');
+
+        $this->success('编辑地址', UserAddress::edit($params));
+    }
+
+    public function info()
+    {
+        $params = $this->request->get();
+        $this->success('地址详情', UserAddress::info($params));
+    }
+
+    public function del()
+    {
+        $params = $this->request->post();
+        $this->success('地址详情', UserAddress::del($params));
+
+    }
+
+
+}

+ 32 - 0
addons/shopro/controller/Base.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\exception\Exception;
+use app\common\controller\Api;
+use think\Lang;
+
+class Base extends Api
+{
+    public function _initialize()
+    {
+
+        parent::_initialize();
+        $controllername = strtolower($this->request->controller());
+        $this->loadlang($controllername);
+
+    }
+
+    protected function loadlang($name)
+    {
+        Lang::load(ADDON_PATH  . 'shopro/lang/' . $this->request->langset() . '/' . str_replace('.', '/', $name) . '.php');
+    }
+
+
+    protected function shoproValidate($params, $class, $scene, $rules = []) {
+        $validate = validate(str_replace('controller', 'validate', $class));
+        if (!$validate->check($params, $rules, $scene)) {
+            $this->error($validate->getError());
+        }
+    }
+}

+ 40 - 0
addons/shopro/controller/Cart.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\model\Cart as CartModel;
+
+class Cart extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+    public function index()
+    {
+        $data = CartModel::info();
+        $this->success('我的购物车', $data);
+    }
+
+    public function add()
+    {
+        $params = $this->request->post();
+        
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'add');
+
+        $goodsList = $params['goods_list'];
+        $this->success('已添加', CartModel::add($goodsList));
+    }
+
+    public function edit()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'edit');
+
+        $this->success('', CartModel::edit($params));
+    }
+
+}

+ 64 - 0
addons/shopro/controller/Category.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\model\Category as CategoryModel;
+use addons\shopro\model\Goods;
+
+/**
+ * 分类管理
+ *
+ * @icon   fa fa-list
+ * @remark 用于统一管理网站的所有分类,分类可进行无限级分类,分类类型请在常规管理->系统配置->字典配置中添加
+ */
+
+class Category extends Base
+{
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+
+
+    public function detail () {
+        $id = $this->request->get('id');
+
+        $data = CategoryModel::getCategoryDetail($id);
+        $this->success('商城分类', $data);
+    }
+
+    public function index()
+    {
+        $id = $this->request->get('id');
+        $data = CategoryModel::getCategoryList($id);
+        $this->success('商城分类', $data);
+
+    }
+
+
+    public function goods() {
+        $params = $this->request->get();
+        $category_id = $params['category_id'];
+
+        $categories = CategoryModel::where('pid', $category_id)->where('status', 'normal')->select();
+
+        // 获取这个分类下面的所有商品
+        $goodsList = Goods::getGoodsList(array_merge($params, ['no_activity' => false]), false);
+
+        foreach($categories as $key => $category) {
+            $categoryIds = ',' . $category['id'] . ',';
+
+            $currentCategoryGoods = [];
+            foreach ($goodsList as $k => $goods) {
+                $goodsCategoryIds = ',' . $goods['category_ids'] . ',';
+
+                if (strpos($goodsCategoryIds, $categoryIds) !== false) {
+                    $currentCategoryGoods[] = $goods;
+                }
+            }
+
+            $categories[$key]['goods'] = $currentCategoryGoods;
+        }
+
+        $this->success('商城分类商品', $categories);
+    }
+}

+ 52 - 0
addons/shopro/controller/Coupons.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class Coupons extends Base
+{
+
+    protected $noNeedLogin = ['lists', 'detail', 'goods'];
+    protected $noNeedRight = ['*'];
+
+    // 领券中心,自己的优惠券
+    public function index()
+    {
+        $type = $this->request->get('type');
+        $this->success('优惠券中心', \addons\shopro\model\Coupons::getCouponsList($type));
+    }
+
+    public function lists()
+    {
+        $ids = $this->request->get('ids');
+        $this->success('优惠券列表', \addons\shopro\model\Coupons::getCouponsListByIds($ids));
+
+    }
+
+    public function get()
+    {
+        $id = $this->request->get('id');
+        $this->success('领取成功', \addons\shopro\model\Coupons::getCoupon($id));
+    }
+
+    public function detail()
+    {
+        $id = $this->request->get('id');
+        $user_coupons_id = $this->request->get('user_coupons_id', 0);
+        $detail = \addons\shopro\model\Coupons::getCouponsDetail($id, $user_coupons_id);
+
+        $this->success('优惠券详情', $detail);
+    }
+
+    public function goods()
+    {
+        $id = $this->request->get('id');
+        $detail = \addons\shopro\model\Coupons::getGoodsByCoupons($id);
+
+        $this->success('优惠券详情', $detail);
+    }
+
+
+
+
+}

+ 64 - 0
addons/shopro/controller/Express.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\exception\Exception;
+use addons\shopro\model\Order;
+use addons\shopro\model\User;
+use think\Db;
+use think\Log;
+
+class Express extends Base
+{
+
+    protected $noNeedLogin = ['callback'];
+    protected $noNeedRight = ['*'];
+
+
+    /**
+     * 物流信息订阅回调接口
+     */
+    public function callback()
+    {
+        $requestData = $this->request->post();
+
+        $expressLib = new \addons\shopro\library\Express();
+
+        // 信息记录日志
+        // \think\Log::write('expresscallback:'. json_encode($requestData));
+
+        $data = json_decode(html_entity_decode($requestData['RequestData']), true);
+        $expressData = $data['Data'];
+
+        foreach ($expressData as $key => $express) {
+            // 查找包裹
+            $orderExpress = \addons\shopro\model\OrderExpress::with('order')->where('express_code', $express['ShipperCode'])
+                ->where('express_no', $express['LogisticCode'])
+                ->find();
+
+            if (!$orderExpress) {
+                // 包裹不存在,记录日志信息,然后继续下一个
+                \think\Log::write('orderExpressNotFound:' . json_encode($express));
+                continue;
+            }
+
+            if (!$express['Success']) {
+                // 失败了
+                if (isset($express['Reason']) && ($express['Reason'] == '三天无轨迹' || $express['Reason'] == '七天无轨迹')) {
+                    // 需要重新订阅
+                    $expressLib->subscribe([
+                        'express_code' => $express['ShipperCode'],
+                        'express_no' => $express['LogisticCode']
+                    ], $orderExpress, $orderExpress->order);
+                }
+
+                \think\Log::write('orderExpressReason:' . json_encode($express));
+                continue;
+            }
+
+            $expressLib->checkAndAddTraces($orderExpress, $express);
+        }
+
+        return $expressLib->setPushResult(true);
+    }
+}

+ 26 - 0
addons/shopro/controller/Faq.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class Faq extends Base
+{
+
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+
+    // faq 列表
+    public function index()
+    {
+        $this->success('获取成功', \addons\shopro\model\Faq::order('id', 'DESC')->paginate(10));
+    }
+
+
+    public function detail () {
+        $id = $this->request->get('id');
+
+        $this->success('签到成功', \addons\shopro\model\Faq::where('id', $id)->find());
+    }
+
+}

+ 28 - 0
addons/shopro/controller/Feedback.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class Feedback extends Base
+{
+
+    protected $noNeedLogin = ['type'];
+    protected $noNeedRight = ['*'];
+
+
+    public function type()
+    {
+        $this->success('反馈类型', array_values(\addons\shopro\model\Feedback::$typeAll));
+    }
+
+
+    public function add() {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'add');
+
+        $this->success('反馈成功', \addons\shopro\model\Feedback::add($params));
+    }
+
+}

+ 125 - 0
addons/shopro/controller/Goods.php

@@ -0,0 +1,125 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\exception\Exception;
+
+class Goods extends Base
+{
+
+    protected $noNeedLogin = ['index', 'detail', 'lists', 'activity', 'seckillList', 'grouponList', 'store'];
+    protected $noNeedRight = ['*'];
+
+    public function index()
+    {
+        // 测试腾讯云短信
+        $user = \addons\shopro\model\User::get(10011);
+        $walletLog = \addons\shopro\model\UserWalletLog::get(61);
+
+        $user && $user->notify(
+            new \addons\shopro\notifications\Wallet([
+                'walletLog' => $walletLog,
+                'event' => 'wallet_change'
+            ])
+        );
+    }
+
+    public function detail()
+    {
+        $id = $this->request->get('id');
+        $detail = \addons\shopro\model\Goods::getGoodsDetail($id);
+        
+        // 记录足记
+        \addons\shopro\model\UserView::addView($detail);
+
+        $sku_price = $detail['sku_price'];      // 处理过的规格
+        // tp bug json_encode 或者 toArray 的时候 sku_price 会重新查询数据库,导致被处理过的规格又还原回去了
+        $detail = json_decode(json_encode($detail), true);
+        $detail['sku_price'] = $sku_price;
+
+        $this->success('商品详情', $detail);
+    }
+
+    public function lists()
+    {
+        $params = $this->request->get();
+        $data = \addons\shopro\model\Goods::getGoodsList($params);
+
+        $this->success('商品列表', $data);
+
+    }
+
+
+    /**
+     * 获取商品支持的 自提点
+     */
+    public function store()
+    {
+        $params = $this->request->get();
+        $data = \addons\shopro\model\Goods::getGoodsStore($params);
+
+        $this->success('自提列表', $data);
+    }
+
+
+    // 秒杀列表
+    public function seckillList() {
+        $params = $this->request->get();
+
+        $this->success('秒杀商品列表', \addons\shopro\model\Goods::getSeckillGoodsList($params));
+    }
+
+
+    // 拼团列表
+    public function grouponList() {
+        $params = $this->request->get();
+
+        $this->success('拼团商品列表', \addons\shopro\model\Goods::getGrouponGoodsList($params));
+    }
+
+
+    public function activity()
+    {
+        $activity_id = $this->request->get('activity_id');
+        $activity = \addons\shopro\model\Activity::get($activity_id);
+        if (!$activity) {
+            $this->error('活动不存在', null, -1);
+        }
+        
+        $goods = \addons\shopro\model\Goods::getGoodsList(['goods_ids' => $activity->goods_ids]);
+        $activity->goods = $goods;
+        
+        $this->success('活动列表', $activity);
+    }
+
+    public function favorite()
+    {
+        $params = $this->request->post();
+        $result = \addons\shopro\model\UserFavorite::edit($params);
+        $this->success($result ? '收藏成功' : '取消收藏', $result);
+    }
+
+    public function favoriteList()
+    {
+        $data = \addons\shopro\model\UserFavorite::getGoodsList();
+        $this->success('商品收藏列表', $data);
+    }
+
+
+    public function viewDelete()
+    {
+        $params = $this->request->post();
+        $result = \addons\shopro\model\UserView::del($params);
+        $this->success('删除成功', $result);
+    }
+
+
+    public function viewList()
+    {
+        $data = \addons\shopro\model\UserView::getGoodsList();
+        $this->success('商品浏览列表', $data);
+    }
+
+
+
+}

+ 40 - 0
addons/shopro/controller/GoodsComment.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class GoodsComment extends Base
+{
+
+    protected $noNeedLogin = ['index', 'type'];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $params = $this->request->get();
+        
+        $goodsComments = \addons\shopro\model\GoodsComment::getList($params);
+        
+        $this->success('评价详情', $goodsComments);
+    }
+
+
+    public function type() {
+        $goods_id = $this->request->get('goods_id', 0);
+
+        $type = array_values(\addons\shopro\model\GoodsComment::$typeAll);
+
+        foreach ($type as $key => $val) {
+            // 只查询 count 比查出来所有评论,在判断状态要快
+            $comment = \addons\shopro\model\GoodsComment::where('goods_id', $goods_id);
+            if ($val['code'] != 'all') {
+                $comment = $comment->{$val['code']}();
+            }
+            $comment = $comment->count();
+            $type[$key]['num'] = $comment;
+        }
+
+        $this->success('筛选类型', $type);
+    }
+}

+ 302 - 0
addons/shopro/controller/Index.php

@@ -0,0 +1,302 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\model\Config;
+use think\Db;
+use think\Config as FaConfig;
+use fast\Random;
+use think\exception\HttpResponseException;
+use addons\shopro\library\commission\Agent as AgentLibrary;
+use addons\shopro\library\commission\Commission as CommissionLibrary;
+use addons\shopro\library\commission\Reward as RewardLibrary;
+use addons\shopro\model\Order;
+
+class Index extends Base
+{
+
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+    public function index()
+    {
+    }
+
+    // 初始化商城数据 服务器压力大可以把最后的data数据存入cache缓存中来调用,防止多次查sql
+    public function init()
+    {
+        $platform = $this->request->header('platform'); // 获取平台标识
+        if (!in_array($platform, ['H5', 'App', 'wxMiniProgram', 'wxOfficialAccount'])) {
+            $this->error('请使用正确客户端访问');
+        }
+        $data = [];     // 设置信息
+        $configFields = ['shopro', 'share', 'chat', 'store', 'withdraw', $platform];    // 定义设置字段
+        $configModel = new \addons\shopro\model\Config;
+        $config = $configModel->where('name', 'in', $configFields)->column('value', 'name');
+
+        // 商城基本设置
+        $shoproConfig = json_decode($config['shopro'], true);
+        $shoproConfig['logo'] = cdnurl($shoproConfig['logo'], true);
+        $data['shop'] = $shoproConfig;
+
+        // 支付设置
+        $payment = $configModel->where('group', 'payment')->select();
+        $paymentConfig = [];
+        foreach ($payment as $key => $v) {
+            $val = json_decode($v->value, true);
+            if ($val && in_array($platform, $val['platform'])) {
+                $paymentConfig[] = $v->name;
+            }
+        }
+        $data['payment'] = $paymentConfig;        // 平台支持的支付方式
+
+        // 平台设置
+        $platformConfig = json_decode($config[$platform], true);
+        if (in_array($platform, ['wxOfficialAccount', 'wxMiniProgram'])) {
+            if (isset($platformConfig['auto_login']) && $platformConfig['auto_login'] == 1) {
+                $autologin = true;
+            } else {
+                $autologin = false;
+            }
+            $data['wechat'] = [
+                'appid' => isset($platformConfig['app_id']) ? $platformConfig['app_id'] : '',
+                'autologin' => $autologin,
+            ];
+        }
+
+        // 分享设置
+        $shareConfig = json_decode($config['share'], true);
+        $data['share'] = [
+            'title' => $shareConfig['title'],
+            'image' => isset($shareConfig['image']) ? cdnurl($shareConfig['image'], true) : '',
+            'goods_poster_bg' => isset($shareConfig['goods_poster_bg']) ? cdnurl($shareConfig['goods_poster_bg'], true) : '',
+            'user_poster_bg' => isset($shareConfig['user_poster_bg']) ? cdnurl($shareConfig['user_poster_bg'], true) : '',
+            'groupon_poster_bg' => isset($shareConfig['groupon_poster_bg']) ? cdnurl($shareConfig['groupon_poster_bg'], true) : '',
+        ];
+
+        $withdrawConfig = json_decode($config['withdraw'], true);
+        $recharge = $withdrawConfig['recharge'] ?? [];
+        $data['recharge'] = [
+            'enable' => $recharge['enable'] ?? 0,
+            'methods' => $recharge['methods'] ?? [],
+            'moneys' => $recharge['moneys'] ?? [],
+        ];
+        
+        // 插件设置
+        $data['addons'] = array_keys(get_addon_list());
+
+        // 客服设置
+        $data['chat'] =  isset($config['chat']) ? json_decode($config['chat'], true) : [];
+        // 门店配置
+        $data['store'] = isset($config['store']) ? json_decode($config['store'], true) : [];
+        $this->success('初始化数据', $data);
+    }
+
+    // 商城模板数据
+    public function template()
+    {
+        $get = $this->request->get();
+        $platform = $this->request->header('platform');
+        if (isset($get['shop_id']) && $get['shop_id'] != 0) {
+            $template = \addons\shopro\model\Decorate::getCurrentPlatformDecorate('preview', $get['shop_id']);
+        } else {
+            $template = \addons\shopro\model\Decorate::getCurrentPlatformDecorate($platform);
+        }
+        $this->success('模板数据', $template);
+    }
+
+    // 自定义页面
+    public function custom()
+    {
+        $get = $this->request->get();
+        $decorate = \addons\shopro\model\Decorate::get($get['custom_id']);
+        if (!$decorate) {
+            $this->error('未找到自定义页面');
+        }
+        $decorate->template = \addons\shopro\model\Decorate::getCustomDecorate($get['custom_id']);
+        $this->success('自定义模板数据', $decorate);
+    }
+
+    // 富文本详情
+    public function richtext()
+    {
+        $id = $this->request->get('id');
+        $data = \addons\shopro\model\Richtext::get(['id' => $id]);
+        $this->success($data->title, $data);
+    }
+
+    // 同步前端所有页面链接
+    public function asyncPages()
+    {
+        $post = $this->request->post();
+        $newLink = $post['data'];
+        $existLink = (array)Db::name('shopro_link')->select();
+        $newLinkPath = array_column($newLink, 'path');
+        $existLinkPath = array_flip(array_column($existLink, 'path'));
+        $insertData = [];
+        $count = 1;
+        foreach ($newLinkPath as $key => $item) {
+            if (!isset($existLinkPath[$item]) && isset($newLink[$key]['meta']['async']) && $newLink[$key]['meta']['async']) {
+                $insertData[] = [
+                    'name' => isset($newLink[$key]['meta']['title']) ? $newLink[$key]['meta']['title'] : '新链接' . $count,
+                    'path' => $item,
+                    'group' => isset($newLink[$key]['meta']['group']) ? $newLink[$key]['meta']['group'] : '其它',
+                    'createtime' => time(),
+                    'updatetime' => time()
+                ];
+                $count++;
+            }
+        }
+        if ($insertData !== []) {
+            Db::name('shopro_link')->insertAll($insertData);
+        }
+    }
+
+
+    /**
+     * 上传文件
+     * @ApiMethod (POST)
+     * @param File $file 文件流
+     */
+    public function upload()
+    {
+        $file = $this->request->file('file');
+        if (empty($file)) {
+            $this->error(__('No file upload or server upload limit exceeded'));
+        }
+
+        //判断是否已经存在附件
+        $sha1 = $file->hash();
+
+        $upload = FaConfig::get('upload');
+
+        preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
+        $type = strtolower($matches[2]);
+        $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
+        $size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
+        $fileInfo = $file->getInfo();
+        $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
+        $suffix = $suffix && preg_match("/^[a-zA-Z0-9]+$/", $suffix) ? $suffix : 'file';
+
+        $mimetypeArr = explode(',', strtolower($upload['mimetype']));
+        $typeArr = explode('/', $fileInfo['type']);
+
+        //禁止上传PHP和HTML文件
+        if (in_array($fileInfo['type'], ['text/x-php', 'text/html']) || in_array($suffix, ['php', 'html', 'htm'])) {
+            $this->error(__('Uploaded file format is limited'));
+        }
+        //验证文件后缀
+        if (
+            $upload['mimetype'] !== '*' &&
+            (!in_array($suffix, $mimetypeArr)
+                || (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr))))
+        ) {
+            $this->error(__('Uploaded file format is limited'));
+        }
+        //验证是否为图片文件
+        $imagewidth = $imageheight = 0;
+        if (in_array($fileInfo['type'], ['image/gif', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/png', 'image/webp']) || in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'webp'])) {
+            $imgInfo = getimagesize($fileInfo['tmp_name']);
+            if (!$imgInfo || !isset($imgInfo[0]) || !isset($imgInfo[1])) {
+                $this->error(__('Uploaded file is not a valid image'));
+            }
+            $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
+            $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
+        }
+
+        // 文件 md5
+        $fileMd5 = md5_file($fileInfo['tmp_name']);
+
+        $replaceArr = [
+            '{year}' => date("Y"),
+            '{mon}' => date("m"),
+            '{day}' => date("d"),
+            '{hour}' => date("H"),
+            '{min}' => date("i"),
+            '{sec}' => date("s"),
+            '{random}' => Random::alnum(16),
+            '{random32}' => Random::alnum(32),
+            '{filename}' => $suffix ? substr($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
+            '{suffix}' => $suffix,
+            '{.suffix}' => $suffix ? '.' . $suffix : '',
+            '{filemd5}' => $fileMd5,
+        ];
+        $savekey = $upload['savekey'];
+        $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
+
+        $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
+        $fileName = substr($savekey, strripos($savekey, '/') + 1);
+        //
+
+        if (in_array($upload['storage'], ['cos', 'alioss', 'qiniu'])) {     // upyun:又拍云 ,bos:百度BOS,ucloud: Ucloud, 如果要使用这三种,请自行安装插件配置,并将标示填入前面数组,进行测试
+            $token_name = $upload['storage'] . 'token';     // costoken, aliosstoken, qiniutoken
+            $controller_name = '\\addons\\' . $upload['storage'] . '\\controller\\Index';
+
+            $storageToken[$token_name] = $upload['multipart'] && $upload['multipart'][$token_name] ? $upload['multipart'][$token_name] : '';
+            $domain = request()->domain();
+
+            try {
+                $uploadCreate = \think\Request::create('foo', 'POST', array_merge([
+                    'name' => $fileInfo['name'],
+                    'md5' => $fileMd5,
+                    'chunk' => 0,
+                ], $storageToken));
+
+                // 重新设置跨域允许域名
+                $cors = config('fastadmin.cors_request_domain');
+                config('fastadmin.cors_request_domain', $cors . ',' . $domain);
+
+                $uploadController = new $controller_name($uploadCreate);
+                $uploadController->upload();
+            } catch (HttpResponseException $e) {
+                $result = $e->getResponse()->getData();
+                if (isset($result['code']) && $result['code'] == 0) {
+                    $this->error($result['msg']);
+                }
+
+                $resultData = $result['data'];
+            }
+        } else {
+            $splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
+
+            if ($splInfo) {
+                $resultData = [
+                    'url' => $uploadDir . $splInfo->getSaveName(),
+                    'fullurl' => request()->domain() . $uploadDir . $splInfo->getSaveName()
+                ];
+            } else {
+                // 上传失败获取错误信息
+                $this->error($file->getError());
+            }
+        }
+
+        $params = array(
+            'admin_id' => 0,
+            'user_id' => (int)$this->auth->id,
+            'filename'    => substr(htmlspecialchars(strip_tags($fileInfo['name'])), 0, 100),
+            'filesize' => $fileInfo['size'],
+            'imagewidth' => $imagewidth,
+            'imageheight' => $imageheight,
+            'imagetype' => $suffix,
+            'imageframes' => 0,
+            'mimetype' => $fileInfo['type'] == 'application/octet-stream' && in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'webp']) ? 'image/' . $suffix : $fileInfo['type'],
+            'url' => $resultData['url'],
+            'uploadtime' => time(),
+            'storage' => $upload['storage'],
+            'sha1' => $sha1,
+        );
+        $attachment = new \app\common\model\Attachment;
+        $attachment->data(array_filter($params));
+        $attachment->save();
+        \think\Hook::listen("upload_after", $attachment);
+        $this->success(__('Upload successful'), $resultData);
+    }
+
+
+    public function debugLog()
+    {
+        $params = $this->request->post();
+        \think\Log::write($params, 'Frontend-Debug');
+    }
+
+}

+ 60 - 0
addons/shopro/controller/Kefu.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace addons\shopro\controller;
+
+/**
+ * 客服接口
+ */
+class Kefu extends Base
+{
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+    /**
+     * 对接Fastadmin插件市场WorkerMan客服插件
+     */
+    public function historyGoods()
+    {
+        $viewList = \addons\shopro\model\UserView::getGoodsList();
+        if(!empty($viewList)) {
+            foreach($viewList as $k => &$v) {
+                $v->id = $v->goods_id;
+                $v->logo = $v->goods->image;
+                $v->subject = $v->goods->title;
+                $v->note = $v->goods->subtitle;
+                $v->price = $v->goods->price;
+
+                unset($v['goods']);
+                unset($v['goods_id']);
+                unset($v['user_id']);
+            }
+        }
+        $this->success('浏览历史', $viewList);
+    }
+
+    public function historyOrder()
+    {
+        $orderList = \addons\shopro\model\Order::getList(['type' => 'all']);
+        if(!empty($orderList)) {
+            foreach($orderList['data'] as $k => &$v) {
+                $order = [];
+                $order['id'] = $v['id'];
+                $order['subject'] = $v['item'][0]['goods_title'];
+                $order['logo'] = $v['item'][0]['goods_image'];
+                $order['note'] = "订单编号:{$v['order_sn']}";
+                $order['price'] = $v['total_amount'];
+                $order['number'] = 23;
+                $itemNumber = count($v['item']);
+
+                if($itemNumber == 1) {
+                    $order['subject'] = "{$order['subject']}...等{$itemNumber}个产品";
+                }
+            
+                $v = $order;
+            }
+        }
+        $this->success('order', $orderList);
+    }
+
+
+}

+ 53 - 0
addons/shopro/controller/Live.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\library\Wechat;
+use addons\shopro\exception\Exception;
+use think\Cache;
+
+class Live extends Base
+{
+
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $params = $this->request->get();
+        
+        $type = $params['type'] ?? 'all';
+        $ids = array_filter(isset($params['ids']) ? explode(',', $params['ids']) : []);
+
+        if (!in_array($type, ['all', 'notice', 'living', 'lived'])) {
+            $this->error('参数错误');
+        }
+
+        // 同步直播
+        \addons\shopro\model\Live::autoSyncLive();
+        
+        if ($type != 'all') {
+            $lives = \addons\shopro\model\Live::{$type}()
+                        ->with('goods')
+                        ->order('id', 'desc')
+                        ->paginate(10);
+        } else {
+            $lives = \addons\shopro\model\Live::order('live_status', 'asc')
+                        ->with('goods')
+                        ->order('id', 'desc');
+
+            if (isset($params['ids'])) {
+                // 首页根据 id 获取
+                $lives = $lives->where('id', 'in', $ids)->select();
+            } else {
+                // 直播列表
+                $lives = $lives->paginate(10);
+            }
+        }
+
+        $this->success('获取成功', $lives);
+    }
+
+
+}

+ 38 - 0
addons/shopro/controller/Notification.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\exception\Exception;
+use addons\shopro\model\NotificationConfig;
+use think\Cache;
+
+
+class Notification extends Base
+{
+
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+
+    public function template()
+    {
+        $platform = request()->header('platform');
+
+        $templates = [];
+        if (in_array($platform, ['wxMiniProgram', 'wxOfficialAccount'])) {
+            $platform = $platform == 'wxOfficialAccount' ? 'wxOfficialAccountBizsend' : $platform;
+            // 获取订阅消息模板
+            $notificationConfig = NotificationConfig::cache(300)->where('platform', $platform)->select();
+            
+            foreach ($notificationConfig as $k => $config) {
+                if ($config['status'] && $config['content_arr'] && $config['content_arr']['template_id']) {
+                    $templates[$config['event']] = $config['content_arr']['template_id'];
+                }
+            }
+        }
+
+        $this->success('获取成功', $templates);
+    }
+
+
+}

+ 130 - 0
addons/shopro/controller/Order.php

@@ -0,0 +1,130 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class Order extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $params = $this->request->get();
+
+        $this->success('订单列表', \addons\shopro\model\Order::getList($params));
+    }
+
+
+
+    public function detail()
+    {
+        $params = $this->request->get();
+        $this->success('订单详情', \addons\shopro\model\Order::detail($params));
+    }
+
+
+    public function itemDetail()
+    {
+        $params = $this->request->get();
+        $this->success('订单商品', \addons\shopro\model\Order::itemDetail($params));
+    }
+
+
+    // 即将废弃
+    public function statusNum()
+    {
+        $this->success('订单数量', \addons\shopro\model\Order::statusNum());
+    }
+
+
+    // 取消订单
+    public function cancel()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'cancel');
+
+        $this->success('取消成功', \addons\shopro\model\Order::operCancel($params));
+    }
+
+    // 删除订单
+    public function delete()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'delete');
+
+        $this->success('删除成功', \addons\shopro\model\Order::operDelete($params));
+    }
+
+    // 确认收货
+    public function confirm()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'confirm');
+
+        $this->success('收货成功', \addons\shopro\model\Order::operConfirm($params));
+    }
+
+
+    public function comment()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'comment');
+
+        $this->success('评价成功', \addons\shopro\model\Order::operComment($params));
+    }
+
+
+    public function pre()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'pre');
+
+        $result = \addons\shopro\model\Order::pre($params);
+
+        if (isset($result['msg']) && $result['msg']) {
+            $this->error($result['msg'], $result);
+        } else {
+            $this->success('计算成功', $result);
+        }
+    }
+
+
+    public function createOrder()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'createOrder');
+
+        $order = \addons\shopro\model\Order::createOrder($params);
+
+        $this->success('订单添加成功', $order);
+    }
+
+
+    // 获取可用优惠券列表
+    public function coupons()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'coupons');
+
+        $coupons = \addons\shopro\model\Order::coupons($params);
+
+        $this->success('获取成功', $coupons);
+    }
+}

+ 69 - 0
addons/shopro/controller/OrderAftersale.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class OrderAftersale extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $params = $this->request->get();
+
+        $this->success('售后列表', \addons\shopro\model\OrderAftersale::getList($params));
+    }
+
+
+    /**
+     * 详情
+     */
+    public function detail()
+    {
+        $params = $this->request->get();
+
+        $this->shoproValidate($params, get_class(), 'detail');
+
+        $this->success('售后详情', \addons\shopro\model\OrderAftersale::detail($params));
+    }
+
+
+
+    // 申请售后
+    public function aftersale()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'aftersale');
+
+        $this->success('申请成功', \addons\shopro\model\OrderAftersale::aftersale($params));
+    }
+
+
+    // 取消售后单
+    public function cancel()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'cancel');
+
+        $this->success('取消成功', \addons\shopro\model\OrderAftersale::operCancel($params));
+    }
+
+    // 删除售后单
+    public function delete()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'delete');
+
+        $this->success('删除成功', \addons\shopro\model\OrderAftersale::operDelete($params));
+    }
+
+}

+ 27 - 0
addons/shopro/controller/OrderExpress.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class OrderExpress extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $params = $this->request->get();
+
+        $this->success('包裹列表', \addons\shopro\model\OrderExpress::getList($params));
+    }
+
+
+    public function detail()
+    {
+        $params = $this->request->get();
+
+        $this->success('包裹详情', \addons\shopro\model\OrderExpress::detail($params));
+    }
+}

+ 422 - 0
addons/shopro/controller/Pay.php

@@ -0,0 +1,422 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\epay\library\Service;
+use fast\Random;
+use think\addons\Controller;
+use addons\shopro\exception\Exception;
+use addons\shopro\model\Order;
+use addons\shopro\model\User;
+use addons\shopro\model\TradeOrder;
+use think\Db;
+use think\Log;
+
+class Pay extends Base
+{
+
+    protected $noNeedLogin = ['prepay', 'notifyx', 'notifyr', 'alipay'];
+    protected $noNeedRight = ['*'];
+
+
+    /**
+     * 支付宝网页支付
+     */
+    public function alipay()
+    {
+        $order_sn = $this->request->get('order_sn');
+
+        list($order, $prepay_type) = $this->getOrderInstance($order_sn);
+        $order = $order->where('order_sn', $order_sn)->find();
+
+        try {
+            if (!$order) {
+                throw new \Exception("订单不存在");
+            }
+            if ($order->status > 0) {
+                throw new \Exception("订单已支付");
+            }
+            if ($order->status < 0) {
+                throw new \Exception("订单已失效");
+            }
+    
+            $notify_url = $this->request->root(true) . '/addons/shopro/pay/notifyx/payment/alipay/platform/H5';
+            $pay = new \addons\shopro\library\PayService('alipay', 'url', $notify_url);
+    
+            $order_data = [
+                'order_id' => $order->id,
+                'out_trade_no' => $order->order_sn,
+                'total_fee' => $order->total_fee,
+                'subject' => '商城订单支付',
+            ];
+    
+            $result = $pay->create($order_data);
+
+            $result = $result->getContent();
+            
+	        echo $result;
+        } catch (\Exception $e) {
+            echo $e->getMessage();
+        }
+
+        // $this->assign('result', $result);
+
+        // return $this->view->fetch();
+    }
+
+
+    /**
+     * 拉起支付
+     */
+    public function prepay()
+    {
+        checkEnv('yansongda');
+
+        $order_sn = $this->request->post('order_sn');
+        $payment = $this->request->post('payment');
+        $openid = $this->request->post('openid', '');
+        $platform = request()->header('platform');
+
+        list($order, $prepay_type) = $this->getOrderInstance($order_sn);
+        $order = $order->nopay()->where('order_sn', $order_sn)->find();
+
+        if (!$order) {
+            $this->error("订单不存在");
+        }
+
+        if (!$payment || !in_array($payment, ['wechat', 'alipay', 'wallet'])) {
+            $this->error("支付类型不能为空");
+        }
+
+        if ($payment == 'wallet' && $prepay_type == 'order') {
+            // 余额支付
+            $this->walletPay($order, $payment, $platform);
+        }
+
+        $order_data = [
+            'order_id' => $order->id,
+            'out_trade_no' => $order->order_sn,
+            'total_fee' => $order->total_fee,
+        ];
+
+        // 微信公众号,小程序支付,必须有 openid
+        if ($payment == 'wechat') {
+            if (in_array($platform, ['wxOfficialAccount', 'wxMiniProgram'])) {
+                if (isset($openid) && $openid) {
+                    // 如果传的有 openid
+                    $order_data['openid'] = $openid;
+                } else {
+                    // 没有 openid 默认拿下单人的 openid
+                    $oauth = \addons\shopro\model\UserOauth::where([
+                        'user_id' => $order->user_id,
+                        'provider' => 'Wechat',
+                        'platform' => $platform
+                    ])->find();
+        
+                    $order_data['openid'] = $oauth ? $oauth->openid : '';
+                }
+    
+                if (empty($order_data['openid'])) {
+                    // 缺少 openid
+                    return $this->success('缺少 openid', 'no_openid');
+                }
+            }
+
+            $order_data['body'] = '商城订单支付';
+        } else {
+            $order_data['subject'] = '商城订单支付';
+        }
+
+        $notify_url = $this->request->root(true) . '/addons/shopro/pay/notifyx/payment/' . $payment . '/platform/' . $platform;
+        $pay = new \addons\shopro\library\PayService($payment, $platform, $notify_url);
+
+        try {
+            $result = $pay->create($order_data);
+        } catch (\Yansongda\Pay\Exceptions\Exception $e) {
+            $this->error("支付配置错误:" . $e->getMessage());
+        }
+        
+        if ($platform == 'App') {
+            $result = $result->getContent();
+        }
+        if ($platform == 'H5' && $payment == 'wechat') {
+            $result = $result->getContent();
+        }
+
+        return $this->success('获取预付款成功', [
+            'pay_data' => $result,
+            'pay_action' => $pay->method,
+        ]);
+    }
+
+
+
+    // 余额支付
+    public function walletPay ($order, $type, $method) {
+        $order = Db::transaction(function () use ($order, $type, $method) {
+            // 重新加锁读,防止连点问题
+            $order = Order::nopay()->where('order_sn', $order->order_sn)->lock(true)->find();
+            if (!$order) {
+                $this->error("订单已支付");
+            }
+            $total_fee = $order->total_fee;
+
+            // 扣除余额
+            $user = User::info();
+
+            if (is_null($user)) {
+                // 没有登录,请登录
+                $this->error(__('Please login first'), null, 401);
+            }
+
+            User::money(-$total_fee, $user->id, 'wallet_pay', $order->id, '',[
+                'order_id' => $order->id,
+                'order_sn' => $order->order_sn,
+            ]);
+
+            // 支付后流程
+            $notify = [
+                'order_sn' => $order['order_sn'],
+                'transaction_id' => '',
+                'notify_time' => date('Y-m-d H:i:s'),
+                'buyer_email' => $user->id,
+                'pay_fee' => $order->total_fee,
+                'pay_type' => 'wallet'             // 支付方式
+            ];
+            $notify['payment_json'] = json_encode($notify);
+            $order->paymentProcess($order, $notify);
+
+            return $order;
+        });
+
+        $this->success('支付成功', $order);
+    }
+
+
+    /**
+     * 支付成功回调
+     */
+    public function notifyx()
+    {
+        Log::write('notifyx-comein:');
+
+        $payment = $this->request->param('payment');
+        $platform = $this->request->param('platform');
+
+        $pay = new \addons\shopro\library\PayService($payment, $platform);
+
+        $result = $pay->notify(function ($data, $pay) use ($payment, $platform) {
+            Log::write('notifyx-result:'. json_encode($data));
+            // {    // 微信回调参数
+            //     "appid":"wx39cd0799d4567dd0",
+            //     "bank_type":"OTHERS",
+            //     "cash_fee":"1",
+            //     "fee_type":"CNY",
+            //     "is_subscribe":"N",
+            //     "mch_id":"1481069012",
+            //     "nonce_str":"dPpcZ6AzCDU8daNC",
+            //     "openid":"oD9ko4x7QMDQPZEuN8V5jtZjie3g",
+            //     "out_trade_no":"202010240834057843002700",
+            //     "result_code":"SUCCESS",
+            //     "return_code":"SUCCESS",
+            //     "sign":"3103B6D06F13D2B3959C5B3F7F1FD61C",
+            //     "time_end":"20200407102424",
+            //     "total_fee":"1",
+            //     "trade_type":"JSAPI",
+            //     "transaction_id":"4200000479202004070804485027"
+            // }
+
+            // {    // 支付宝支付成功回调参数
+            //     "gmt_create":"2020-04-10 19:15:00",
+            //     "charset":"utf-8",
+            //     "seller_email":"xptech@qq.com",
+            //     "subject":"\u5546\u57ce\u8ba2\u5355\u652f\u4ed8",
+            //     "sign":"AOiYZ1a2mEMOuIbHFCi6V6A0LJ97UMiHsCWgNdSU9dlzKFl15Ts8b0mL\/tN+Hhskl+94S3OUiNTBD3dD0Kv923SqaTWxNdj533PCdo2GDKsZIZgKbavnOvaccSKUdmQRE9KtmePPq9V9lFzEQvdUkKq1M8KAWO5K9LTy2iT2y5CUynpiu\/04GVzsTL9PqY+LDwqj6K+w7MgceWm1BWaFWg27AXIRw7wvsFckr3k9GGajgE2fufhoCYGYtGFbhGOp6ExtqS5RXBuPODOyRhBLpD8mwpOX38Oy0X+R4YQIrOi02dhqwPpvw79YjnvgXY3qZEQ66EdUsrT7EBdcPHK0Gw==",
+            //     "buyer_id":"2088902485164146",
+            //     "invoice_amount":"0.01",
+            //     "notify_id":"2020041000222191501064141414240102",
+            //     "fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]",
+            //     "notify_type":"trade_status_sync",
+            //     "trade_status":"TRADE_SUCCESS",
+            //     "receipt_amount":"0.01",
+            //     "buyer_pay_amount":"0.01",
+            //     "app_id":"2021001114666742",
+            //     "sign_type":"RSA2",
+            //     "seller_id":"2088721922277739",
+            //     "gmt_payment":"2020-04-10 19:15:00",
+            //     "notify_time":"2020-04-10 19:15:01",
+            //     "version":"1.0",
+            //     "out_trade_no":"202007144778322770017000",
+            //     "total_amount":"0.01",
+            //     "trade_no":"2020041022001464141443020240",
+            //     "auth_app_id":"2021001114666742",
+            //     "buyer_logon_id":"157***@163.com",
+            //     "point_amount":"0.00"
+            // }
+
+            // {   // 支付宝退款成功(交易关闭)回调参数
+            //     "gmt_create": "2020-08-15 14:48:32",
+            //     "charset": "utf-8",
+            //     "seller_email": "xptech@qq.com",
+            //     "gmt_payment": "2020-08-15 14:48:32",
+            //     "notify_time": "2020-08-15 16:11:45",
+            //     "subject": "商城订单支付",
+            //     "gmt_refund": "2020-08-15 16:11:45.140",
+            //     "sign": "b6ArkgzLIRteRL9FMGC6i\/jf6VwFYQbaGDGRx002W+pdmN5q9+O4edZ3ALF74fYaijSl9ksNr0dKdvanu3uYxBTcd\/GIS4N1CWzmCOv6pzgx5rO\/YvGoHLM3Yop0GKKuMxmnNsZ6jhYKEY7SYD3Y0L6PU9ZMdHV7yIiVj+zZmbKzUgK9MPDCEXs+nzpNAiSM8GTqYRSUvKobAK68hswG2k1QIcqr5z+ZmVYa\/nHHkoC9qXt5zwyGi4P+2eOsr6V2PjA3x8qqe7TN5aI1DeoZD5KqHPYYaYF17J2q6YPlgl3WUl1RhE7H86bivB1fIuYEv\/3+JR74WN\/o7krGw1RPHg==",
+            //     "out_biz_no": "R202004114414846255015300",
+            //     "buyer_id": "2088902485164146",
+            //     "version": "1.0",
+            //     "notify_id": "2020081500222161145064141453349793",
+            //     "notify_type": "trade_status_sync",
+            //     "out_trade_no": "202002460317545607015300",
+            //     "total_amount": "0.01",
+            //     "trade_status": "TRADE_CLOSED",
+            //     "refund_fee": "0.01",
+            //     "trade_no": "2020081522001464141438570535",
+            //     "auth_app_id": "2021001114666742",
+            //     "buyer_logon_id": "157***@163.com",
+            //     "gmt_close": "2020-08-15 16:11:45",
+            //     "app_id": "2021001114666742",
+            //     "sign_type": "RSA2",
+            //     "seller_id": "2088721922277739"
+            // }
+
+            try {
+                $out_trade_no = $data['out_trade_no'];
+                $out_refund_no = $data['out_biz_no'] ?? '';
+
+                list($order, $prepay_type) = $this->getOrderInstance($out_trade_no);
+                
+                // 判断是否是支付宝退款(支付宝退款成功会通知该接口)
+                if ($payment == 'alipay'    // 支付宝支付
+                    && $data['notify_type'] == 'trade_status_sync'      // 同步交易状态
+                    && $data['trade_status'] == 'TRADE_CLOSED'          // 交易关闭
+                    && $out_refund_no                                   // 退款单号
+                ) {
+                    // 退款回调
+                    if ($prepay_type == 'order') {
+                        // 退款回调
+                        $this->refundFinish($out_trade_no, $out_refund_no);
+                    } else {
+                        // 其他订单如果支持退款,逻辑这里补充
+                    }
+
+                    return $pay->success()->send();
+                }
+
+
+                // 判断支付宝微信是否是支付成功状态,如果不是,直接返回响应
+                if ($payment == 'alipay' && $data['trade_status'] != 'TRADE_SUCCESS') {
+                    // 不是交易成功的通知,直接返回成功
+                    return $pay->success()->send();
+                }
+                if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) {
+                    // 微信交易未成功,返回 false,让微信再次通知
+                    return false;
+                }
+
+                // 支付成功流程
+                $pay_fee = $payment == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
+
+                //你可以在此编写订单逻辑
+                $order = $order->where('order_sn', $out_trade_no)->find();
+
+                if (!$order || $order->status > 0) {
+                    // 订单不存在,或者订单已支付
+                    return $pay->success()->send();
+                }
+
+                Db::transaction(function () use ($order, $data, $payment, $platform, $pay_fee, $prepay_type) {
+                    $notify = [
+                        'order_sn' => $data['out_trade_no'],
+                        'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'],
+                        'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])),
+                        'buyer_email' => $payment == 'alipay' ? $data['buyer_logon_id'] : $data['openid'],
+                        'payment_json' => json_encode($data->all()),
+                        'pay_fee' => $pay_fee,
+                        'pay_type' => $payment              // 支付方式
+                    ];
+                    $order->paymentProcess($order, $notify);
+                });
+
+                return $pay->success()->send();
+            } catch (\Exception $e) {
+                Log::write('notifyx-error:' . json_encode($e->getMessage()));
+            }
+        });
+
+        return $result;
+    }
+
+
+    /**
+     * 退款成功回调
+     */
+    public function notifyr()
+    {
+        Log::write('notifyreturn-comein:');
+
+        $payment = $this->request->param('payment');
+        $platform = $this->request->param('platform');
+
+        $pay = new \addons\shopro\library\PayService($payment, $platform);
+
+        $result = $pay->notifyRefund(function ($data, $pay) use ($payment, $platform) {
+            Log::write('notifyr-result:' . json_encode($data));
+            try {
+                $out_refund_no = $data['out_refund_no'];
+                $out_trade_no = $data['out_trade_no'];
+
+                // 退款
+                $this->refundFinish($out_trade_no, $out_refund_no);
+                
+                return $pay->success()->send();
+            } catch (\Exception $e) {
+                Log::write('notifyreturn-error:' . json_encode($e->getMessage()));
+            }
+        });
+
+        return $result;
+    }
+
+    
+    private function refundFinish($out_trade_no, $out_refund_no) {
+        $order = Order::where('order_sn', $out_trade_no)->find();
+        $refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find();
+
+        if (!$order || !$refundLog || $refundLog->status != 0) {
+            // 订单不存在,或者订单已退款
+            return true;
+        }
+
+        $item = \app\admin\model\shopro\order\OrderItem::where('id', $refundLog->order_item_id)->find();
+
+        Db::transaction(function () use ($order, $item, $refundLog) {
+            \app\admin\model\shopro\order\Order::refundFinish($order, $item, $refundLog);
+        });
+
+        return true;
+    }
+
+
+    /**
+     * 根据订单号获取订单实例
+     *
+     * @param [type] $order_sn
+     * @return void
+     */
+    private function getOrderInstance($order_sn) 
+    {
+        $prepay_type = 'order';
+        if (strpos($order_sn, 'TO') === 0) {
+            // 充值订单
+            $prepay_type = 'recharge';
+            $order = new TradeOrder();
+        } else {
+            // 订单
+            $order = new Order();
+        }
+
+        return [$order, $prepay_type];
+    }
+}

+ 27 - 0
addons/shopro/controller/ScoreGoodsSkuPrice.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class ScoreGoodsSkuPrice extends Base
+{
+
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+    public function index()
+    {
+        $params = $this->request->get();
+        $goods = \addons\shopro\model\ScoreGoodsSkuPrice::getGoodsList($params);
+        
+        $this->success('积分商城列表', $goods);
+    }
+
+    public function detail()
+    {
+        $id = $this->request->get('id');
+        $detail = \addons\shopro\model\ScoreGoodsSkuPrice::getGoodsDetail($id);
+
+        $this->success('商品详情', $detail);
+    }
+}

+ 51 - 0
addons/shopro/controller/Share.php

@@ -0,0 +1,51 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\model\Share as ShareModel;
+
+class Share extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    /**
+     * 获取分享记录
+     *
+     * @return void
+     */
+    public function index()
+    {
+        $params = $this->request->get();
+
+        $shares = ShareModel::getList($params);
+        return $this->success('获取成功', $shares);
+    }
+
+
+    public function add()
+    {
+
+        $spm = $this->request->post('spm');
+        $share = false;
+        if (!empty($spm)) {
+            $share = \think\Db::transaction(function () use ($spm) {
+                try {
+                    $shareLog = ShareModel::add($spm);
+                    if ($shareLog) {
+                        \think\Hook::listen('share_after', $shareLog);
+                        return true;
+                    }
+                } catch (\Exception $e) {
+                    $this->error($e->getMessage());
+                }
+                return false;
+            });
+        }
+        if($share) {
+            $this->success('识别成功'); // 使用 success 前端不提示
+        }
+    }
+}

+ 101 - 0
addons/shopro/controller/Sms.php

@@ -0,0 +1,101 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use app\common\library\Sms as Smslib;
+use addons\shopro\model\User;
+use think\Hook;
+
+/**
+ * 手机短信接口
+ */
+class Sms extends Base
+{
+    protected $noNeedLogin = '*';
+    protected $noNeedRight = '*';
+
+    /**
+     * 发送验证码
+     *
+     * @param string $mobile 手机号
+     * @param string $event 事件名称
+     */
+    public function send()
+    {
+        $mobile = $this->request->post("mobile");
+        $event = $this->request->post("event");
+        $event = $event ? $event : 'register';
+
+        if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
+            $this->error(__('手机号不正确'));
+        }
+        $last = Smslib::get($mobile, $event);
+        if ($last && time() - $last['createtime'] < 60) {
+            $this->error(__('发送频繁'));
+        }
+        $ipSendTotal = \app\common\model\Sms::where(['ip' => $this->request->ip()])->whereTime('createtime', '-1 hours')->count();
+        if ($ipSendTotal >= 5) {
+            $this->error(__('发送频繁'));
+        }
+        if ($event) {
+            $userinfo = User::getByMobile($mobile);
+            if ($event == 'register' && $userinfo) {
+                //已被注册
+                $this->error(__('已被注册'));
+            } elseif (in_array($event, ['changemobile']) && $userinfo) {
+                //被占用
+                $this->error(__('已被占用'));
+            } elseif (in_array($event, ['changepwd', 'resetpwd', 'mobilelogin']) && !$userinfo) {
+                //未注册
+                $this->error(__('未注册'));
+            }
+        }
+        if (!Hook::get('sms_send')) {
+            $this->error(__('请在后台插件管理安装短信验证插件'));
+        }
+        $ret = Smslib::send($mobile, null, $event);
+        if ($ret) {
+            $this->success(__('发送成功'));
+        } else {
+            $this->error(__('发送失败,请检查短信配置是否正确'));
+        }
+    }
+
+    /**
+     * 检测验证码
+     *
+     * @param string $mobile 手机号
+     * @param string $event 事件名称
+     * @param string $captcha 验证码
+     */
+    public function check()
+    {
+        $mobile = $this->request->post("mobile");
+        $event = $this->request->post("event");
+        $event = $event ? $event : 'register';
+        $captcha = $this->request->post("captcha");
+
+        if (!$mobile || !\think\Validate::regex($mobile, "^1\d{10}$")) {
+            $this->error(__('手机号不正确'));
+        }
+        if ($event) {
+            $userinfo = User::getByMobile($mobile);
+            if ($event == 'register' && $userinfo) {
+                //已被注册
+                $this->error(__('已被注册'));
+            } elseif (in_array($event, ['changemobile']) && $userinfo) {
+                //被占用
+                $this->error(__('已被占用'));
+            } elseif (in_array($event, ['changepwd', 'resetpwd']) && !$userinfo) {
+                //未注册
+                $this->error(__('未注册'));
+            }
+        }
+        $ret = Smslib::check($mobile, $captcha, $event);
+        if ($ret) {
+            $this->success(__('成功'));
+        } else {
+            $this->error(__('验证码不正确'));
+        }
+    }
+}

+ 31 - 0
addons/shopro/controller/Store.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\exception\Exception;
+use addons\shopro\model\Store as ModelStore;
+use addons\shopro\model\User;
+use addons\shopro\model\UserStore;
+
+class Store extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $user = User::info();
+        $userStore = UserStore::where('user_id', $user->id)->select();
+        $store_id_arr = array_column($userStore, 'store_id');
+
+        $stores = [];
+        if ($store_id_arr) {
+            $stores = ModelStore::show()->where('id', 'in', $store_id_arr)->select();
+        }
+        
+        $this->success('获取门店列表', $stores);
+    }
+    
+}

+ 38 - 0
addons/shopro/controller/TradeOrder.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class TradeOrder extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $params = $this->request->get();
+
+        $this->success('充值记录', \addons\shopro\model\TradeOrder::getList($params));
+    }
+
+    public function detail()
+    {
+        $params = $this->request->get();
+        $this->success('订单详情', \addons\shopro\model\TradeOrder::detail($params));
+    }
+
+
+    public function recharge()
+    {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'recharge');
+
+        $order = \addons\shopro\model\TradeOrder::recharge($params);
+
+        $this->success('订单添加成功', $order);
+    }
+}

+ 727 - 0
addons/shopro/controller/User.php

@@ -0,0 +1,727 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use think\Db;
+use app\common\library\Sms;
+use fast\Random;
+use think\Validate;
+use addons\shopro\library\Wechat;
+use addons\shopro\model\UserOauth;
+use addons\shopro\model\User as UserModel;
+use addons\shopro\model\UserStore;
+
+/**
+ * 会员接口
+ */
+class User extends Base
+{
+    protected $noNeedLogin = ['accountLogin', 'smsLogin', 'register', 'forgotPwd', 'wxMiniProgramOauth', 'getWxMiniProgramSessionKey', 'wxOfficialAccountOauth', 'wxOfficialAccountBaseLogin', 'wxOpenPlatformOauth', 'appleIdOauth', 'logout'];
+    protected $noNeedRight = '*';
+
+    public function _initialize()
+    {
+        return parent::_initialize();
+    }
+
+    /**
+     * 会员中心
+     */
+    public function index()
+    {
+        $auth = \app\common\library\Auth::instance();
+        $auth->setAllowFields(['id', 'username', 'nickname', 'mobile', 'avatar', 'score', 'birthday', 'money', 'group', 'group_id', 'verification', 'child_user_count', 'child_user_count_1', 'child_user_count_2', 'total_consume']);
+        $data = $auth->getUserinfo();
+        $data['avatar'] = $data['avatar'] ? cdnurl($data['avatar'], true) : '';
+        if (!isset($data['group'])) {
+            $data['group'] = \addons\shopro\model\UserGroup::get($data['group_id']);
+        }
+
+        $this->success('用户信息', $data);
+    }
+
+
+    /**
+     * 获取用户数据
+     *
+     * @return void
+     */
+    public function userData()
+    {
+        $user = $this->auth->getUserinfo();
+        // 查询用户优惠券数量
+        $userCoupons = \addons\shopro\model\Coupons::getCouponsList(1);
+        $data['coupons_num'] = count($userCoupons);
+
+        // 查询用户是否是门店管理员
+        $userStores = UserStore::where('user_id', $user['id'])->select();
+        $data['is_store'] = $userStores ? 1 : 0;
+        $data['store_id'] = 0;
+        if (count($userStores) == 1) {
+            // 只有一个店铺 直接进入店铺
+            $data['store_id'] = $userStores[0]['store_id'];
+        }
+
+        // 订单数量
+        $data['order_num'] = \addons\shopro\model\Order::statusNum();
+
+        $this->success('用户数据', $data);
+    }
+
+    /**
+     * 1.账号登录
+     *
+     * @param string $account 账号
+     * @param string $password 密码
+     */
+    public function accountLogin()
+    {
+        $account = $this->request->post('account');
+        $password = $this->request->post('password');
+        if (!$account || !$password) {
+            $this->error(__('Invalid parameters'));
+        }
+        $ret = $this->auth->login($account, $password);
+        if ($ret) {
+            $data = ['token' => $this->auth->getToken()];
+            $this->success(__('Logged in successful'), $data);
+        } else {
+            $this->error($this->auth->getError());
+        }
+    }
+
+    /**
+     * 2.短信登录
+     *
+     * @param string $mobile 手机号
+     * @param string $code 验证码
+     */
+    public function smsLogin()
+    {
+        $mobile = $this->request->post('mobile');
+        $code = $this->request->post('code');
+        if (!$mobile || !$code) {
+            $this->error(__('Invalid parameters'));
+        }
+        if (!Validate::regex($mobile, "^1\d{10}$")) {
+            $this->error(__('Mobile is incorrect'));
+        }
+        if (!Sms::check($mobile, $code, 'mobilelogin')) {
+            $this->error(__('Captcha is incorrect'));
+        }
+        $user = \app\common\model\User::getByMobile($mobile);
+        if ($user) {
+            if ($user->status != 'normal') {
+                $this->error(__('Account is locked'));
+            }
+            //如果已经有账号则直接登录
+            $ret = $this->auth->direct($user->id);
+        }
+        if ($ret) {
+            Sms::flush($mobile, 'mobilelogin');
+            $data = ['token' => $this->auth->getToken()];
+            $this->success(__('Logged in successful'), $data);
+        } else {
+            $this->error($this->auth->getError());
+        }
+    }
+
+    /**
+     * 3.注册会员
+     *
+     * @param string $mobile 手机号
+     * @param string $password 密码
+     * @param string $code 验证码
+     */
+    public function register()
+    {
+        $username = $this->request->post('mobile');
+        $password = $this->request->post('password');
+        $email = $this->request->post('mobile') . '@' . request()->host();
+
+        $mobile = $this->request->post('mobile');
+        $code = $this->request->post('code');
+        if (!$password) {
+            $this->error(__('请填写密码')); //TODO:密码规则校验
+        }
+        if (strlen($password) < 6 || strlen($password) > 16) {
+            $this->error(__('密码长度 6-16 位')); //TODO:密码规则校验
+        }
+        if ($email && !Validate::is($email, "email")) {
+            $this->error(__('邮箱填写错误'));
+        }
+        if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
+            $this->error(__('手机号填写错误'));
+        }
+        $ret = Sms::check($mobile, $code, 'register');
+        if (!$ret) {
+            $this->error(__('Captcha is incorrect'));
+        }
+        $extend = $this->getUserDefaultFields();
+        $ret = $this->auth->register($username, $password, $email, $mobile, $extend);
+        if ($ret) {
+            $user = $this->auth->getUser();
+            $user->nickname = $user->nickname . $user->id;
+            $verification = $user->verification;
+            $verification->mobile = 1;
+            $user->verification = $verification;
+            $user->save();
+            $data = ['token' => $this->auth->getToken()];
+            $this->success(__('注册成功'), $data);
+        } else {
+            $this->error($this->auth->getError());
+        }
+    }
+
+    /**
+     * 4.忘记密码
+     *
+     * @param string $mobile 手机号
+     * @param string $password 新密码
+     * @param string $code 验证码
+     */
+    public function forgotPwd()
+    {
+        $mobile = $this->request->post("mobile");
+        $newpassword = $this->request->post("password");
+        $captcha = $this->request->post("code");
+        if (!$newpassword || !$captcha) {
+            $this->error(__('Invalid parameters'));
+        }
+        if (strlen($newpassword) < 6 || strlen($newpassword) > 16) {
+            $this->error(__('密码长度 6-16 位')); //TODO:密码规则校验
+        }
+        if (!Validate::regex($mobile, "^1\d{10}$")) {
+            $this->error(__('Mobile is incorrect'));
+        }
+        $user = \app\common\model\User::getByMobile($mobile);
+        if (!$user) {
+            $this->error(__('User not found'));
+        }
+        $ret = Sms::check($mobile, $captcha, 'resetpwd');
+        if (!$ret) {
+            $this->error(__('Captcha is incorrect'));
+        }
+        Sms::flush($mobile, 'resetpwd');
+        //模拟一次登录
+        $this->auth->direct($user->id);
+        $ret = $this->auth->changepwd($newpassword, '', true);
+        if ($ret) {
+            $this->success(__('Reset password successful'));
+        } else {
+            $this->error($this->auth->getError());
+        }
+    }
+
+    /**
+     * 5.绑定手机号
+     *
+     * @param string $mobile 手机号
+     * @param string $code 验证码
+     */
+    public function bindMobile()
+    {
+        $user = $this->auth->getUser();
+        $mobile = $this->request->post('mobile');
+        $captcha = $this->request->post('code');
+        if (!$mobile || !$captcha) {
+            $this->error(__('Invalid parameters'));
+        }
+        if (!Validate::regex($mobile, "^1\d{10}$")) {
+            $this->error(__('Mobile is incorrect'));
+        }
+        if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find()) {
+            $this->error(__('Mobile already exists'));
+        }
+        $result = Sms::check($mobile, $captcha, 'changemobile');
+        if (!$result) {
+            $this->error(__('Captcha is incorrect'));
+        }
+        $verification = $user->verification;
+        $verification->mobile = 1;
+        $user->verification = $verification;
+        $user->mobile = $mobile;
+        $user->save();
+
+        Sms::flush($mobile, 'changemobile');
+        $this->success(__('Mobile is binded'));
+    }
+
+
+    /**
+     * 6.修改密码
+     *
+     * @param string $oldpassword 手机号
+     * @param string $newpassword 验证码
+     */
+    public function changePwd()
+    {
+        $user = $this->auth->getUser();
+
+        $oldpassword = $this->request->post("oldpassword");
+        $newpassword = $this->request->post("newpassword");
+
+        if (!$newpassword || !$oldpassword) {
+            $this->error(__('Invalid parameters'));
+        }
+        if (strlen($newpassword) < 6 || strlen($newpassword) > 16) {
+            $this->error(__('密码长度 6-16 位')); //TODO:密码规则校验
+        }
+
+        $ret = $this->auth->changepwd($newpassword, $oldpassword);
+
+        if ($ret) {
+            $this->auth->direct($user->id);
+            $data = ['userinfo' => $this->auth->getUserinfo()];
+
+            $this->success(__('Change password successful'), $data);
+        } else {
+            $this->error($this->auth->getError());
+        }
+    }
+
+    /**
+     * 获取微信小程序session_key
+     *
+     * @param string  $code       加密code
+     * @param boolean $autoLogin  是否自动登录(需已注册会员)
+     */
+    public function getWxMiniProgramSessionKey()
+    {
+        $post = $this->request->post();
+        $autoLogin = $post['autoLogin'];
+        $wechat = new Wechat('wxMiniProgram');
+        $decryptSession = $wechat->code($post['code']);
+        if (!isset($decryptSession['session_key'])) {
+            $this->error('未获取session_key,请重启应用');
+        }
+        \think\Cache::set($decryptSession['session_key'], $decryptSession, 24 * 3600 * 31); // 强制31天过期
+        $userOauth = UserOauth::get([
+            'provider' => 'Wechat',
+            'platform' => 'wxMiniProgram',
+            'openid' => $decryptSession['openid'],
+            'user_id' => ['neq', 0]
+        ]);
+        if ($userOauth) {
+            $userOauth->save(['session_key' => $decryptSession['session_key']]);
+        }
+        if ($autoLogin && $userOauth) {
+            $ret = $this->auth->direct($userOauth->user_id);
+            if ($ret) {
+                $token = $this->auth->getToken();
+                $this->success(__('Logged in successful'), ['token' => $token, 'session_key' => $decryptSession['session_key'], 'openid' => $decryptSession['openid']]);
+            } else {
+                $this->error($this->auth->getError());
+            }
+        }
+
+        $this->success('', $decryptSession);
+    }
+    /**
+     * 微信小程序登录
+     *
+     * @param string  $session_key      session_key
+     * @param string  $signature        校验签名
+     * @param string  $iv               解密向量
+     * @param string  $encryptedData    需解密完整用户信息
+     * @param boolean $refresh          重新获取或刷新最新的用户信息 (用户头像失效或微信客户端修改昵称等情况)
+     */
+    public function wxMiniProgramOauth()
+    {
+        $post = $this->request->post();
+
+        $token = Db::transaction(function () use ($post) {
+            try {
+                $wechat = new Wechat('wxMiniProgram');
+                $decryptSession = \think\Cache::get($post['session_key']);
+                if (!$decryptSession || !isset($decryptSession['openid'])) {
+                    throw \Exception('未获取到登录态,请重试');
+                }
+                $decryptUserInfo = $wechat->decryptData($post['session_key'], $post['iv'], $post['encryptedData']); // 客户端传值数据都不可信,需服务端解密用户信息
+                $decryptUserInfo = array_merge($decryptUserInfo, $decryptSession);
+                //组装decryptData
+                $decryptData = array_change_key_case($decryptUserInfo, CASE_LOWER);
+                if (empty($decryptData['openid'])) {
+                    throw \Exception('code错误,请重试');
+                }
+                $decryptData['headimgurl'] = $decryptData['avatarurl'];
+                $decryptData['sex'] = $decryptData['gender'];
+                $decryptData['session_key'] = $post['session_key'];
+                return $this->oauthLoginOrRegisterOrBindOrRefresh($post['event'], $decryptData, 'wxMiniProgram', 'Wechat');
+            } catch (\Exception $e) {
+                $this->error($e->getMessage());
+            }
+        });
+
+        if ($token) {
+            $this->success(__('Logged in successful'), ['token' => $token]);
+        } else {
+            $this->error($this->auth->getError());
+        }
+    }
+
+    /**
+     * 微信APP登录
+     *
+     * @param string $authResult 授权信息
+     */
+    public function wxOpenPlatformOauth()
+    {
+        $post = $this->request->post();
+
+        $token = Db::transaction(function () use ($post) {
+            try {
+                //组装decryptData
+                $authResult = $post['authResult'];
+                $res = \fast\Http::get('https://api.weixin.qq.com/sns/userinfo?access_token=' . $authResult['access_token'] . '&openid=' . $authResult['openid']);
+                $userInfo = json_decode($res, true);
+                if (isset($userInfo['errmsg'])) {
+                    throw \Exception($userInfo['errmsg']);
+                }
+                $decryptData = array_merge($userInfo, $authResult);
+                return $this->oauthLoginOrRegisterOrBindOrRefresh($post['event'], $decryptData, 'App', 'Wechat');
+            } catch (\Exception $e) {
+                $this->error($e->getMessage());
+            }
+        });
+
+        if ($token) {
+            $this->success(__('Logged in successful'), ['token' => $token]);
+        } else {
+            $this->error($this->auth->getError());
+        }
+    }
+
+
+    /**
+     * 微信公众号登录、更新信息、绑定(授权页 非api)
+     *
+     * @param string $code 加密code
+     */
+    public function wxOfficialAccountOauth()
+    {
+        $token = '';
+        $params = $this->request->get();
+
+        $payload = json_decode(htmlspecialchars_decode($params['payload']), true);
+        // 解析前端主机
+        if ($payload['event'] !== 'login' && $payload['token'] !== '') {
+            $this->auth->init($payload['token']);
+        }
+
+        $wechat = new Wechat('wxOfficialAccount');
+        $oauth = $wechat->oauth();
+        $decryptData = $oauth->user()->getOriginal();
+        $token = Db::transaction(function () use ($payload, $decryptData) {
+            try {
+                $token = $this->oauthLoginOrRegisterOrBindOrRefresh($payload['event'], $decryptData, 'wxOfficialAccount', 'Wechat');
+                return $token;
+            } catch (\Exception $e) {
+                $this->error($e->getMessage());
+            }
+        });
+        // 跳转回前端
+        if ($token) {
+            header('Location: ' . $payload['host']  . 'pages/public/loading/?token=' . $token);
+        } else {
+            header('Location: ' . $payload['host']);
+        }
+        exit;
+    }
+
+    /**
+     * 苹果ID授权
+     *
+     * @param string $authResult 授权信息
+     * @param string $userInfo 用户信息
+     */
+    public function appleIdOauth()
+    {
+        $post = $this->request->post();
+        $userInfo = $post['userInfo'];
+        $token = '';
+        $platform = request()->header('platform');
+
+        try {
+            \think\Loader::addNamespace('AppleSignIn', ADDON_PATH . 'shopro' . DS . 'library' . DS . 'apple-signin' . DS);
+            $identityToken = $userInfo['identityToken'];
+            $clientUser = $userInfo['openId'];
+            $appleSignInPayload = \AppleSignIn\ASDecoder::getAppleSignInPayload($identityToken);
+            $isValid = $appleSignInPayload->verifyUser($clientUser);
+            if ($isValid) {
+                $nickname = '';
+                $headimgurl = '';
+                if (isset($userInfo['fullName']['familyName'])) {
+                    $nickname = $userInfo['fullName']['familyName'] . ' ' . $userInfo['fullName']['giveName'];
+                } else {
+                    $nickname = '';
+                }
+                $decryptData = [
+                    'openid' => $userInfo['openId'],
+                    'nickname' => $nickname,
+                    'access_token' => $userInfo['authorizationCode'],
+                    'headimgurl' => $headimgurl
+                ];
+                $token = $this->oauthLoginOrRegisterOrBindOrRefresh($post['event'], $decryptData, $platform, 'Apple');
+            }
+        } catch (\Exception $e) {
+            $this->error('登录失败:' . $e->getMessage());
+        }
+
+        if ($token) {
+            $this->success(__('Logged in successful'), ['token' => $token]);
+        } else {
+            $this->error($this->auth->getError());
+        }
+    }
+
+    /**
+     * 微信公众号静默登录
+     *
+     * @param string $code 加密code
+     */
+    public function wxOfficialAccountBaseLogin()
+    {
+        $wechat = new Wechat('wxOfficialAccount');
+        $oauth = $wechat->oauth();
+        $oUrl = input('get.state');
+        $url = explode('/', $oUrl);
+        $decryptData = $oauth->user()->getOriginal();
+        if ($decryptData) {
+            header('Location:' . $oUrl . '&openid=' . $decryptData['openid']);
+        } else {
+            $this->error('未获取到OPENID');
+        }
+    }
+
+    /**
+     * 第三方登录或自动注册或绑定
+     *
+     * @param string  $event        事件:login=登录, refresh=更新账号授权信息, bind=绑定第三方授权
+     * @param array   $decryptData  解密参数
+     * @param string  $platform     平台名称
+     * @param string  $provider     厂商名称
+     * @param int     $keeptime     有效时长
+     * @return string $token        返回用户token
+     */
+    private function oauthLoginOrRegisterOrBindOrRefresh($event, $decryptData, $platform, $provider, $keeptime = 0)
+    {
+        $oauthData = $decryptData;
+        $oauthData = array_merge($oauthData, [
+            'provider' => $provider,
+            'platform' => $platform,
+
+        ]);
+        if ($platform === 'wxMiniProgram' || $platform === 'App') {
+            $oauthData['expire_in'] = 7200;
+            $oauthData['expiretime'] = time() + 7200;
+        }
+        $userOauth = UserOauth::where(['openid' => $decryptData['openid'], 'user_id' => ['neq', 0]])->where('platform', $platform)->where('provider', $provider)->lock(true)->find();
+        switch ($event) {
+            case 'login':               // 登录(自动注册)
+                if (!$userOauth) {      // 没有找到第三方登录信息 创建新用户
+                    //默认创建新用户
+                    $user_id = 0;
+                    $createNewUser = true;
+                    $oauthData['logintime'] = time();
+                    $oauthData['logincount'] = 1;
+                    // 判断是否有unionid 并且已存在oauth数据中
+                    if (isset($oauthData['unionid'])) {
+                        //存在同厂商信息,添加oauthData数据,合并用户
+                        $userUnionOauth = UserOauth::get(['unionid' => $oauthData['unionid'], 'provider' => $provider, 'user_id' => ['neq', 0]]);
+                        if ($userUnionOauth) {
+                            $existUser = $this->auth->direct($userUnionOauth->user_id);
+                            if ($existUser) {
+                                $createNewUser = false;
+                            }
+                        }
+                    }
+
+                    // 创建空用户
+                    if ($createNewUser) {
+                        $username = Random::alnum(20);
+                        $password = '';
+                        $domain = request()->host();
+                        $extend = $this->getUserDefaultFields();
+                        $extend['nickname'] = $oauthData['nickname'] ? $oauthData['nickname'] : $extend['nickname'];
+                        $extend['avatar'] = $oauthData['headimgurl'] ? $oauthData['headimgurl'] : $extend['avatar'];
+                        $this->auth->register($username, $password, $username . '@' . $domain, '', $extend, $keeptime);
+                        if (empty($oauthData['nickname'])) {
+                            $this->auth->getUser()->save(['nickname' => $extend['nickname'] . $this->auth->getUser()->id]);
+                        }
+                    }
+                    $oauthData['user_id'] = $this->auth->getUser()->id;
+                    $oauthData['createtime'] = time();
+                    UserOauth::strict(false)->insert($oauthData);
+                } else {
+                    // 找到第三方登录信息,直接登录
+                    $user_id = $userOauth->user_id;
+                    if ($user_id && $this->auth->direct($user_id) && $this->auth->getUser()) {       // 获取到用户
+                        $oauthData['logincount'] = $userOauth->logincount + 1;
+                        $oauthData['logintime'] = time();
+                        $userOauth->allowField(true)->save($oauthData);
+                    } else {         // 用户已被删除 重新执行登录
+                        // throw \Exception('此用户已删除');
+                        $userOauth->delete();
+                        $this->oauthLoginOrRegisterOrBindOrRefresh($event, $decryptData, $platform, $provider);                    }
+                }
+                break;
+            case 'refresh':
+                if (!$userOauth) {
+                    throw \Exception('未找到第三方授权账户');
+                }
+                if (!empty($oauthData['nickname'])) {
+                    $refreshFields['nickname'] = $oauthData['nickname'];
+                }
+                if (!empty($oauthData['headimgurl'])) {
+                    $refreshFields['avatar'] = $oauthData['headimgurl'];
+                }
+                $this->auth->getUser()->save($refreshFields);
+                $userOauth->allowField(true)->save($oauthData);
+                break;
+            case 'bind':
+                if (!$this->auth->getUser()) {
+                    throw \Exception('请先登录');
+                }
+
+                $oauthData['user_id'] = $this->auth->getUser()->id;
+
+                if ($userOauth) {
+                    if ($userOauth['user_id'] != 0 && $userOauth['user_id'] != $this->auth->getUser()->id && UserModel::get($userOauth['user_id'])) {
+                        throw \Exception('该账号已被其他用户绑定');
+                    }
+                    $oauthData['id'] = $userOauth->id;
+                    $userOauth->strict(false)->update($oauthData);
+                } else {
+                    $oauthData['logincount'] = 1;
+                    $oauthData['logintime'] = time();
+                    $oauthData['createtime'] = time();
+                    UserOauth::strict(false)->insert($oauthData);
+                }
+                break;
+        }
+        if ($this->auth->getUser()) {
+            $this->setUserVerification($this->auth->getUser(), $provider, $platform);
+            return $this->auth->getToken();
+        }
+        return false;
+    }
+
+    /**
+     * 第三方用户授权信息
+     */
+    public function thirdOauthInfo()
+    {
+        $user = $this->auth->getUser();
+        $platform = request()->header('platform');
+        $userOauth = UserOauth::where([
+            'platform' => $platform,
+            'user_id'  => $user->id
+        ])->field('headimgurl, nickname')->find();
+        $this->success('获取成功', $userOauth);
+    }
+
+
+    /**
+     * 解除绑定
+     */
+    public function unbindThirdOauth()
+    {
+        $user = $this->auth->getUser();
+        $platform = $this->request->post('platform');
+        $provider = $this->request->post('provider');
+
+        $verification = $user->verification;
+        if (!$verification->mobile) {
+            $this->error('请先绑定手机号再进行解绑操作');
+        }
+
+        $verifyField = $platform;
+        if ($platform === 'App' && $provider === 'Wechat') {
+            $verifyField = 'wxOpenPlatform';
+        }
+
+        $verification->$verifyField = 0;
+        $user->verification = $verification;
+        $user->save();
+        $userOauth = UserOauth::where([
+            'platform' => $platform,
+            'provider'  => $provider,
+            'user_id' => $user->id
+        ])->delete();
+        if ($userOauth) {
+            $this->success('解绑成功');
+        }
+        $this->error('解绑失败');
+    }
+
+    /**
+     * 注销登录
+     */
+    public function logout()
+    {
+        if ($this->auth->isLogin()) {
+            $this->auth->logout();
+        }
+        $this->success(__('Logout successful'));
+    }
+
+
+    /**
+     * 修改会员个人信息
+     *
+     * @param string $avatar 头像地址
+     * @param string $username 用户名
+     * @param string $nickname 昵称
+     * @param string $birthday 生日
+     * @param string $bio 个人简介
+     */
+    public function profile()
+    {
+        $user = $this->auth->getUser();
+        $username = $this->request->post('username');
+        $nickname = $this->request->post('nickname');
+        $bio = $this->request->post('bio', '');
+        $birthday = $this->request->post('birthday');
+        $avatar = $this->request->post('avatar', '', 'trim,strip_tags,htmlspecialchars');
+        if ($username) {
+            $exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find();
+            if ($exists) {
+                $this->error(__('Username already exists'));
+            }
+            $user->username = $username;
+        }
+        $user->nickname = $nickname;
+        $user->bio = $bio;
+        $user->birthday = $birthday;
+        if (!empty($avatar)) {
+            $user->avatar = $avatar;
+        }
+        $user->save();
+        $this->success();
+    }
+
+    private function getUserDefaultFields()
+    {
+        $userConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'user'])->value, true);
+        return $userConfig;
+    }
+
+    private function setUserVerification($user, $provider, $platform)
+    {
+        $verification = $user->verification;
+        if ($platform === 'App') {
+            $platform = '';
+            if ($provider === 'Wechat') {
+                $platform = 'wxOpenPlatform';
+            } elseif ($provider === 'Alipay') {
+                $platform = 'aliOpenPlatform';
+            }
+        }
+        if ($platform !== '') {
+            $verification->$platform = 1;
+            $user->verification = $verification;
+            $user->save();
+        }
+    }
+}

+ 38 - 0
addons/shopro/controller/UserBank.php

@@ -0,0 +1,38 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class UserBank extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    // 获取提现账户信息
+    public function info()
+    {
+        $type = $this->request->get('type');
+        try {
+            $bankInfo = \addons\shopro\model\UserBank::info($type);
+        } catch (\Exception $e) {
+            $this->error($e->getMessage());
+        }
+        $this->success('提现账户', $bankInfo);
+    }
+
+
+    public function edit()
+    {
+        $params = $this->request->post();
+        if ($params['type'] === 'alipay') {
+            $params['bank_name'] = '支付宝账户';
+        }
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'edit');
+
+        $this->success('编辑成功', \addons\shopro\model\UserBank::edit($params));
+    }
+}

+ 28 - 0
addons/shopro/controller/UserSign.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class UserSign extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    // 按月份获取签到记录
+    public function index()
+    {
+        $params = $this->request->get();
+        
+        $this->success('获取成功', \addons\shopro\model\UserSign::getList($params));
+    }
+
+
+    public function sign () {
+        $params = $this->request->post();
+
+        $this->success('签到成功', \addons\shopro\model\UserSign::sign($params));
+    }
+
+}

+ 60 - 0
addons/shopro/controller/UserWalletApply.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace addons\shopro\controller;
+
+
+class UserWalletApply extends Base
+{
+
+    protected $noNeedLogin = ['rule'];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $this->success('提现记录', \addons\shopro\model\UserWalletApply::getList());
+    }
+
+
+    // 申请提现
+    public function apply()
+    {
+        $type = $this->request->post('type');
+        $money = $this->request->post('money');
+        $apply = \think\Db::transaction(function () use ($type, $money) {
+            try {
+                return \addons\shopro\model\UserWalletApply::apply($type, $money);
+            } catch (\Exception $e) {
+                $this->error($e->getMessage());
+            }
+        });
+        if($apply) {
+            $this->success('申请成功');            
+        }
+        $this->error('申请失败');
+    }
+
+
+    public function rule()
+    {
+        // 提现规则
+        $config = \addons\shopro\model\UserWalletApply::getWithdrawConfig();
+        $min = round(floatval($config['min']), 2);
+        $max = round(floatval($config['max']), 2);
+        $service_fee = floatval($config['service_fee']) * 100;
+        $service_fee = round($service_fee, 1);      // 1 位小数
+        $perday_amount = isset($config['perday_amount']) ? round(floatval($config['perday_amount']), 2) : 0;
+        $perday_num = isset($config['perday_num']) ? round(floatval($config['perday_num']), 2) : 0;
+
+        $rule = [
+            'min' => $min,
+            'max' => $max,
+            'service_fee' => $service_fee,
+            'perday_amount' => $perday_amount,
+            'perday_num' => $perday_num,
+            'methods' => $config['methods'] ?? []
+        ];
+
+        $this->success('提现规则', $rule);
+    }
+}

+ 26 - 0
addons/shopro/controller/UserWalletLog.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\exception\Exception;
+
+class UserWalletLog extends Base
+{
+
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $params = $this->request->get();
+        $wallet_type = $params['wallet_type'] ?? 'money';
+
+        if (!in_array($wallet_type, ['money', 'score'])) {
+            $this->error('参数错误');
+        }
+
+        $this->success(($wallet_type == 'money' ? '钱包记录' : '积分记录'), \addons\shopro\model\UserWalletLog::getList($params));
+    }
+
+}

+ 199 - 0
addons/shopro/controller/Wechat.php

@@ -0,0 +1,199 @@
+<?php
+
+namespace addons\shopro\controller;
+
+use addons\shopro\library\Wechat as WechatLibrary;
+use addons\shopro\model\Wechat as WechatModel;
+use addons\shopro\model\Config;
+
+/**
+ * 微信接口
+ */
+class Wechat extends Base
+{
+    protected $noNeedLogin = ['*'];
+    protected $noNeedRight = ['*'];
+    protected $app = null;
+    protected $userOpenId = '';
+    /**
+     * 微信公众号服务端API对接、处理消息回复
+     */
+    public function index()
+    {
+        $wechat = new WechatLibrary('wxOfficialAccount');
+        $this->app = $wechat->getApp();
+        $this->app->server->push(function ($message) {
+            //初始化信息
+            $this->userOpenId = $message['FromUserName'];
+            // return json_encode($message, JSON_UNESCAPED_UNICODE); //调试使用
+
+            switch ($message['MsgType']) {
+                case 'event': //收到事件消息
+                    switch ($message['Event']) {
+                        case 'subscribe': //订阅(关注)事件
+                            //获取粉丝信息并保存
+                            $subscribe = WechatModel::get(['type' => 'subscribe']);
+                            if ($subscribe) {
+                                return $this->response($subscribe);
+                            }
+                            break;
+                        case 'unsubscribe': //取消订阅(关注)事件
+                            //获取粉丝信息并保存
+                            break;
+                        case 'CLICK':  //自定义菜单事件
+                            return $this->response($message, 'CLICK');
+                            break;
+                        case 'SCAN': //扫码事件
+                            return '';
+                            break;
+                    }
+                    break;
+                case 'text': //收到文本消息
+                    //检测关键字回复
+                    $content = $message['Content'];
+                    $auto_reply = WechatModel::where('type', 'auto_reply')->where('find_in_set(:keywords,rules)', ['keywords' => $content])->find();
+                    if ($auto_reply) {
+                        return $this->response($auto_reply);
+                    }
+                case 'image': //收到图片消息
+                case 'voice': //收到语音消息
+                case 'video': //收到视频消息
+                case 'location': //收到坐标消息
+                case 'link': //收到链接消息
+                case 'file': //收到文件消息
+                default: // ... 默认回复消息
+                    $default_reply = WechatModel::where('type', 'default_reply')->find();
+                    if ($default_reply) {
+                        return $this->response($default_reply);
+                    }
+            }
+        });
+        $response = $this->app->server->serve();
+        // 将响应输出
+        $response->send();
+    }
+
+    public function jssdk()
+    {
+        $params = $this->request->post();
+        $apis = [
+            'checkJsApi',
+            'updateTimelineShareData',
+            'updateAppMessageShareData',
+            "onMenuShareAppMessage",
+            "onMenuShareTimeline",
+            'getLocation', //获取位置
+            'openLocation', //打开位置
+            'scanQRCode', //扫一扫接口
+            'chooseWXPay', //微信支付
+            'chooseImage', //拍照或从手机相册中选图接口
+            'previewImage', //预览图片接口       'uploadImage', //上传图片
+            'openAddress',   // 获取微信地址
+        ];
+        // $openTagList = [
+        //     'wx-open-subscribe'
+        // ];
+
+        $uri = urldecode($params['uri']);
+        
+        $wechat = new WechatLibrary('wxOfficialAccount');
+
+        $jssdk = $wechat->getApp()->jssdk->setUrl($uri);
+        // easywechat 版本 < 4.2.33 的 buildConfig 方法 没有 openTagList 参数,手动覆盖底层 buildConfig 方法
+        $res = $wechat->buildConfig($jssdk, $apis, $debug = false, $beta = false, $json = false);
+
+        $this->success('sdk', $res);
+    }
+
+
+
+    /**
+     * 微信公众号服务端API对接
+     */
+    public function wxacode()
+    {
+        $scene = $this->request->get('scene', '');
+        $path = $this->request->get('path', '');
+
+        if (empty($path)) {
+            $path = 'pages/index/index';
+        }
+
+        $wechat = new WechatLibrary('wxMiniProgram');
+        $content = $wechat->getApp()->app_code->getUnlimit($scene, [
+            'page' => $path,
+            'is_hyaline' => true,
+        ]);
+
+        if ($content instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
+            return response($content->getBody(), 200, ['Content-Length' => strlen($content)])->contentType('image/png');
+        } else {
+            // 小程序码获取失败
+            $msg = isset($content['errcode']) ? $content['errcode'] : '-';
+            $msg .= isset($content['errmsg']) ? $content['errmsg'] : '';
+            \think\Log::write('wxacode-error' . $msg);
+
+            $this->error('获取失败', $msg);
+        }
+    }
+
+    /**
+     * 回复消息
+     */
+    private function response($replyInfo, $event = 'text')
+    {
+        switch ($event) {
+            case 'SCAN': //解析扫码事件EventKey
+                break;
+            case 'CLICK': //解析菜单点击事件EventKey
+                $key = explode('|', $replyInfo['EventKey']);
+                if ($key) {
+                    $message['type'] = $key[0];
+                    if ($key[0] === 'text') {
+                        $message['content'] =  json_decode(WechatModel::get($key[1])->content, true);
+                    } elseif($key[0] === 'link') {
+                        $link = WechatModel::get($key[1]);
+                        $message = array_merge($message, json_decode($link->content, true));
+                        $message['title'] = $link->name;
+                        // return json_encode($message);
+                    }else {
+                        $message['media_id'] = $key[1];
+                    }
+                }
+                break;
+            default:
+                $message = json_decode($replyInfo['content'], true);
+                break;
+        }
+
+        switch ($message['type']) {
+            case 'text':  //回复文本
+                $content = new \EasyWeChat\Kernel\Messages\Text($message['content']);
+                break;
+            case 'image': //回复图片
+                $content = new \EasyWeChat\Kernel\Messages\Image($message['media_id']);
+                break;
+            case 'news': //回复图文
+                $message = new \EasyWeChat\Kernel\Messages\Media($message['media_id'], 'mpnews');
+                $this->app->customer_service->message($message)->to($this->userOpenId)->send();  //素材消息使用客服接口回复
+                break;
+            case 'voice': //回复语音
+                $content = new \EasyWeChat\Kernel\Messages\Voice($message['media_id']);
+                break;
+            case 'video': //回复视频
+                $content = new \EasyWeChat\Kernel\Messages\Video($message['media_id']);
+                break;
+            case 'link': //回复链接
+                $items = new  \EasyWeChat\Kernel\Messages\NewsItem([
+                    'title'       => $message['title'],
+                    'description' => $message['description'],
+                    'url'         => $message['url'],
+                    'image'       => cdnurl($message['image'], true),
+                    // ...
+                ]);
+                $content = new \EasyWeChat\Kernel\Messages\News([$items]);
+                break;
+        }
+        return $content;
+    }
+}

+ 39 - 0
addons/shopro/controller/chat/Index.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace addons\shopro\controller\chat;
+
+use addons\shopro\controller\Base as AddonsBase;
+use addons\shopro\model\chat\Question;
+
+/**
+ * Index 
+ */
+class Index extends AddonsBase
+{
+    protected $noNeedLogin = ['init'];
+    protected $noNeedRight = ['*'];
+
+
+    /**
+     * 客服初始化
+     *
+     * @return void
+     */
+    public function init() {
+        $config = json_decode(\addons\shopro\model\Config::where(['name' => 'chat'])->value('value'), true);
+        // 初始化 ssl 类型, 默认 cert
+        $config['system'] = $config['system'] ?? [];
+        $config['system']['ssl_type'] = $config['system']['ssl_type'] ?? 'cert';
+
+        // 常见问题
+        $question = Question::show()->order('weigh', 'desc')->select();
+
+        $result = [
+            'config' => $config,
+            'question' => $question,
+            'emoji' => json_decode(file_get_contents(ROOT_PATH . 'public/assets/addons/shopro/libs/emoji.json'), true)
+        ];
+
+        $this->success('初始化成功', $result);
+    }
+}

+ 34 - 0
addons/shopro/controller/store/Apply.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace addons\shopro\controller\store;
+
+use addons\shopro\exception\Exception;
+use addons\shopro\controller\Base as ShoproBase;
+
+/**
+ * 不继承门店的 base
+ */
+class Apply extends ShoproBase
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    public function info() {
+        $this->success('门店申请', \addons\shopro\model\store\Apply::info());
+    }
+
+
+    public function apply() {
+        $params = $this->request->post();
+
+        // 表单验证
+        $this->shoproValidate($params, get_class(), 'apply');
+
+        $order = \addons\shopro\model\store\Apply::apply($params);
+
+        $this->success('门店申请提交成功', $order);
+    }
+
+}

+ 48 - 0
addons/shopro/controller/store/Base.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace addons\shopro\controller\store;
+
+use addons\shopro\exception\Exception;
+use addons\shopro\controller\Base as AddonsBase;
+use addons\shopro\model\Store;
+use addons\shopro\model\User;
+use addons\shopro\model\UserStore;
+
+class Base extends AddonsBase
+{
+    public function _initialize()
+    {
+        parent::_initialize();
+
+        // 验证登录用户是否可以访问门店接口
+        $this->checkUserStore();
+    }
+
+
+    /**
+     * 检测用户管理的是否有门店
+     */
+    private function checkUserStore() {
+        // 获取当前用户的门店
+        $user = User::info();
+        $store_id = $this->request->param('store_id');
+
+        if (!$store_id) {
+            $this->error('请选择门店');
+        }
+
+        $userStore = UserStore::with('store')->where('user_id', $user->id)->where('store_id', $store_id)->find();
+        if (!$userStore || !$userStore->store) {
+            $this->error('权限不足');
+        }
+
+        $store = $userStore->store->toArray();
+
+        if (!$store['status']) {
+            $this->error('门店已被禁用');
+        }
+
+        // 存 session 本次请求有效
+        session('current_oper_store', $store);
+    }
+}

+ 39 - 0
addons/shopro/controller/store/Order.php

@@ -0,0 +1,39 @@
+<?php
+
+namespace addons\shopro\controller\store;
+
+class Order extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $params = $this->request->get();
+
+        $this->success('订单列表', \addons\shopro\model\store\Order::getList($params));
+    }
+
+
+
+    public function detail()
+    {
+        $params = $this->request->get();
+        $this->success('订单详情', \addons\shopro\model\store\Order::detail($params));
+    }
+
+
+    public function send() {
+        $params = $this->request->post();
+        $this->success('发货成功', \addons\shopro\model\store\Order::operSend($params));
+    }
+
+
+    public function confirm()
+    {
+        $params = $this->request->post();
+        $this->success('核销成功', \addons\shopro\model\store\Order::operConfirm($params));
+    }
+}

+ 26 - 0
addons/shopro/controller/store/Store.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace addons\shopro\controller\store;
+
+use addons\shopro\exception\Exception;
+use addons\shopro\model\Store as ModelStore;
+
+class Store extends Base
+{
+
+    protected $noNeedLogin = [];
+    protected $noNeedRight = ['*'];
+
+
+    public function index()
+    {
+        $params = $this->request->get();
+        $store = ModelStore::info();
+        if (!$store) {
+            $this->error('门店不存在');
+        }
+
+        $this->success('获取成功', $store);
+    }
+    
+}

+ 30 - 0
addons/shopro/exception/Exception.php

@@ -0,0 +1,30 @@
+<?php
+namespace addons\shopro\exception;
+
+use think\Response;
+
+class Exception
+{
+    protected $msg = '错误消息';
+    protected $code = 0;  //TOAST自动弹出消息
+    const NOT_LOGIN = 401; //未登录自动弹框提醒
+    const NOT_AUTHORIZE = 403;//
+    const IGNORE = -1;
+    public function __construct($msg, $code = 0, $status_code = 200)
+    {
+        $this->msg = $msg;
+        $this->code = $code;
+        $this->send($status_code);
+    }
+    protected function send($code = 200)
+    {
+        $data = [
+            'code' => $this->code,
+            'msg' => $this->msg,
+            'data' => null,
+            'time' => time()
+        ];
+        $response = Response::create($data, 'json', $code);
+        throw new \think\exception\HttpResponseException($response);
+    }
+}

+ 142 - 0
addons/shopro/helper.php

@@ -0,0 +1,142 @@
+<?php
+
+if (!function_exists('matchLatLng')) {
+    function matchLatLng($latlng) {
+        $match = "/^\d{1,3}\.\d{1,30}$/";
+        return preg_match($match, $latlng) ? $latlng : 0;
+    }
+}
+
+
+if (!function_exists('getDistanceBuilder')) {
+    function getDistanceBuilder($lat, $lng) {
+        return "ROUND(6378.138 * 2 * ASIN(SQRT(POW(SIN((". matchLatLng($lat) . " * PI() / 180 - latitude * PI() / 180) / 2), 2) + COS(". matchLatLng($lat). " * PI() / 180) * COS(latitude * PI() / 180) * POW(SIN((". matchLatLng($lng). " * PI() / 180 - longitude * PI() / 180) / 2), 2))) * 1000) AS distance";
+    }
+}
+
+
+/**
+ * 下划线转驼峰
+ * step1.原字符串转小写,原字符串中的分隔符用空格替换,在字符串开头加上分隔符
+ * step2.将字符串中每个单词的首字母转换为大写,再去空格,去字符串首部附加的分隔符.
+ */
+if (!function_exists('camelize')) {
+    function camelize($uncamelized_words, $separator = '_') {
+        $uncamelized_words = $separator . str_replace($separator, " ", strtolower($uncamelized_words));
+        return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $separator);
+    }
+}
+    
+/**
+ * 驼峰命名转下划线命名
+ * 思路:
+ * 小写和大写紧挨一起的地方,加上分隔符,然后全部转小写
+ */
+if (!function_exists('uncamelize')) {
+    function uncamelize($camelCaps, $separator='_')
+    {
+        return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
+    }
+}
+
+
+/**
+ * 检测系统必要环境
+ */
+if (!function_exists('checkEnv')) {
+    function checkEnv($need = [], $is_throw = true)
+    {
+        $need = is_string($need) ? [$need] : $need;
+
+        // 检测是否安装浮点数运算扩展
+        if (in_array('bcmath', $need)) {
+            if (!extension_loaded('bcmath')) {
+                if ($is_throw) {
+                    new \addons\shopro\exception\Exception('请安装浮点数扩展 【bcmath】');
+                } else {
+                    return false;
+                }
+            }
+        }
+
+        // 检测是否安装了队列
+        if (in_array('queue', $need)) {
+            if (!class_exists(\think\Queue::class)) {
+                if ($is_throw) {
+                    new \addons\shopro\exception\Exception('请安装 【topthink/think-queue:v1.1.6 队列扩展】');
+                } else {
+                    return false;
+                }
+            }
+        }
+
+        if (in_array('commission', $need)) {
+            if (!class_exists(\addons\shopro\listener\commission\CommissionHook::class)) {
+                if ($is_throw) {
+                    new \addons\shopro\exception\Exception('请先升级 【shopro】');
+                } else {
+                    return false;
+                }
+            }
+        }
+
+        if (in_array('yansongda', $need)) {
+            if (!class_exists(\Yansongda\Pay\Pay::class)) {
+                if ($is_throw) {
+                    new \addons\shopro\exception\Exception('请在后台安装 【微信支付宝整合插件】');
+                } else {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+}
+
+
+/**
+ * 删除 sql mode 指定模式,或者直接关闭 sql mode
+ */
+if (!function_exists('closeStrict')) {
+    function closeStrict($modes = [])
+    {
+        $modes = array_filter(is_array($modes) ? $modes : [$modes]);
+
+        $result = \think\Db::query("SELECT @@session.sql_mode");
+        $newModes = $oldModes = explode(',', ($result[0]['@@session.sql_mode'] ?? ''));
+
+        if ($modes) {
+            foreach ($modes as $mode) {
+                $delkey = array_search($mode, $newModes);
+                if ($delkey !== false) {
+                    unset($newModes[$delkey]);
+                }
+            }
+            $newModes = join(',', array_values(array_filter($newModes)));
+        } else {
+            $newModes = '';
+        }
+
+        \think\Db::execute("set session sql_mode='" . $newModes . "'");
+
+        return $oldModes;
+    }
+}
+
+
+/**
+ * 重新打开被关闭的 sql mode
+ */
+if (!function_exists('recoverStrict')) {
+    function recoverStrict($modes = [], $append = false)
+    {
+        if ($append) {
+            $result = \think\Db::query("SELECT @@session.sql_mode");
+            $oldModes = explode(',', ($result[0]['@@session.sql_mode'] ?? ''));
+
+            $modes = array_values(array_filter(array_unique(array_merge($oldModes, $modes))));
+        }
+
+        \think\Db::execute("set session sql_mode='" . join(',', $modes) . "'");
+    }
+}

+ 122 - 0
addons/shopro/hooks.php

@@ -0,0 +1,122 @@
+<?php
+
+$defaultHooks = [
+  // 订单创建
+  'order_create_before' => [       // 订单创建前
+    'addons\\shopro\\listener\\order\\Create'
+  ],
+  'order_create_after' => [        // 订单创建后
+    'addons\\shopro\\listener\\order\\Create'
+  ],
+  'order_payed_after' => [        // 订单支付成功
+    'addons\\shopro\\listener\\order\\Payed'
+  ],
+
+  // 订单关闭
+  'order_close_before' => [       // 订单关闭前
+  ],
+  'order_close_after' => [        // 订单关闭后
+    'addons\\shopro\\listener\\order\\Invalid'
+  ],
+
+  // 订单取消
+  'order_cancel_before' => [        // 订单取消前
+  ],
+  'order_cancel_after' => [         // 订单取消后
+    'addons\\shopro\\listener\\order\\Invalid'
+  ],
+
+  // 订单发货
+  'order_send_before' => [       // 订单发货前
+  ],
+  'order_send_after' => [        // 订单发货后
+    'addons\\shopro\\listener\\order\\Send'
+  ],
+
+  // 订单确认收货
+  'order_confirm_before' => [       // 订单确认收货前
+  ],
+  'order_confirm_after' => [        // 订单确认收货后
+    'addons\\shopro\\listener\\order\\Confirm'
+  ],
+  'order_confirm_finish' => [       // 订单确认收货完成
+  ],
+
+  // 订单完成事件
+  'order_finish' => [],
+
+  // 订单评价
+  'order_comment_before' => [       // 订单评价前
+  ],
+  'order_comment_after' => [        // 订单评价后
+    'addons\\shopro\\listener\\order\\Comment'
+  ],
+
+  // 订单退款
+  'order_refund_before' => [       // 订单退款前
+    'addons\\shopro\\listener\\order\\Refund'
+  ],
+  'order_refund_after' => [        // 订单退款后
+    'addons\\shopro\\listener\\order\\Refund'
+  ],
+
+  // 售后完成
+  'aftersale_finish_before' => [        // 售后完成前
+  ],
+  'aftersale_finish_after' => [        // 售后完成后
+  ],
+
+  // 售后拒绝
+  'aftersale_refuse_before' => [        // 售后拒绝前
+  ],
+  'aftersale_refuse_after' => [        // 售后拒绝后
+  ],
+
+  // 售后变动,(包含完成,拒绝)
+  'aftersale_change' => [               // 售后变动
+    'addons\\shopro\\listener\\order\\Aftersale'
+  ],
+
+  // 活动更新
+  'activity_update_after' => [        // 活动更新后
+    'addons\\shopro\\listener\\activity\\Update'
+  ],
+  'activity_delete_after' => [        // 活动删除之后
+    'addons\\shopro\\listener\\activity\\Update'
+  ],
+
+  // 拼团
+  'activity_groupon_finish' => [        // 拼团成功
+    'addons\\shopro\\listener\\activity\\Groupon'
+  ],
+  'activity_groupon_fail' => [        // 拼团失败,超时,后台手动解散等
+    'addons\\shopro\\listener\\activity\\Groupon'
+  ]
+];
+
+// 分销相关钩子
+$commissionHooks = [
+  'order_payed_after' => [        // 订单支付成功
+    'addons\\shopro\\listener\\commission\\CommissionHook'
+  ],
+  'share_after' => [            //分享后
+    'addons\\shopro\\listener\\commission\\CommissionHook'
+  ],
+  'order_confirm_after' => [        // 订单确认收货后
+    'addons\\shopro\\listener\\commission\\CommissionHook'
+  ],
+  'order_refund_after' => [        // 订单退款后
+    'addons\\shopro\\listener\\commission\\CommissionHook'
+  ],
+  'order_finish' => [   // 订单完成事件
+    'addons\\shopro\\listener\\commission\\CommissionHook'
+  ],
+  
+
+];
+
+if (file_exists(ROOT_PATH . 'addons/shopro/listener/commission')) {
+  $defaultHooks = array_merge_recursive($defaultHooks, $commissionHooks);
+}
+
+return $defaultHooks;

+ 11 - 0
addons/shopro/info.ini

@@ -0,0 +1,11 @@
+name = shopro
+title = Shopro商城
+intro = 客服系统、分销商城、多发货方式、到店核销、antV数据中心、店铺装修、小程序直播、跨端通用分享、自定义营销活动、Canvas分享海报、消息通知、微信管理、积分商城、拼团、秒杀等多种功能
+author = 星品科技
+website = https://shopro.top
+version = 1.3.8
+state = 1
+url = /addons/shopro
+first_menu = shopro
+license = regular
+licenseto = 46647

+ 5319 - 0
addons/shopro/install.sql

@@ -0,0 +1,5319 @@
+CREATE TABLE IF NOT EXISTS `__PREFIX__jobs` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `queue` varchar(255) CHARACTER SET utf8 NOT NULL,
+  `payload` longtext CHARACTER SET utf8 NOT NULL,
+  `attempts` tinyint(3) UNSIGNED NOT NULL,
+  `reserved` tinyint(3) UNSIGNED NOT NULL,
+  `reserved_at` int(10) UNSIGNED DEFAULT NULL,
+  `available_at` int(10) UNSIGNED NOT NULL,
+  `created_at` int(10) UNSIGNED NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_activity` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `title` varchar(50) DEFAULT NULL COMMENT '活动名称',
+  `goods_ids` varchar(1200) DEFAULT NULL COMMENT '商品组',
+  `type` varchar(20) DEFAULT NULL COMMENT '类型',
+  `richtext_id` int(11) DEFAULT 0 COMMENT '活动说明',
+  `richtext_title` varchar(255) DEFAULT NULL COMMENT '说明标题',
+  `starttime` int(11) DEFAULT NULL COMMENT '开始时间',
+  `endtime` int(11) DEFAULT NULL COMMENT '结束时间',
+  `rules` text COMMENT '活动规则',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='营销活动';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_activity_goods_sku_price` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `activity_id` int(11) NOT NULL DEFAULT '0' COMMENT '活动 id',
+  `sku_price_id` int(11) NOT NULL DEFAULT '0' COMMENT '规格 id',
+  `goods_id` int(11) NOT NULL COMMENT '所属产品',
+  `stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存',
+  `sales` int(11) NOT NULL DEFAULT '0' COMMENT '已售',
+  `price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '价格',
+  `status` varchar(20) DEFAULT NULL COMMENT '状态',
+  `createtime` int(11) DEFAULT NULL,
+  `updatetime` int(11) DEFAULT NULL,
+  `deletetime` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品规格';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_activity_groupon` (
+  `id` int(10) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '团长',
+  `goods_id` int(11) NOT NULL COMMENT '商品',
+  `activity_id` int(11) NOT NULL COMMENT '活动',
+  `num` int(11) NOT NULL COMMENT '成团人数',
+  `current_num` int(11) NOT NULL COMMENT '当前人数',
+  `status` enum('invalid','ing','finish','finish-fictitious') NOT NULL COMMENT '状态:invalid=已过期,ing=进行中,finish=已成团,finish-fictitious=虚拟成团',
+  `expiretime` int(10) DEFAULT NULL COMMENT '过期时间',
+  `finishtime` int(10) DEFAULT NULL COMMENT '成团时间',
+  `createtime` int(10) DEFAULT NULL COMMENT '添加时间',
+  `updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_activity_groupon_log` (
+  `id` int(10) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户',
+  `user_nickname` varchar(50) DEFAULT NULL COMMENT '用户昵称',
+  `user_avatar` varchar(1500) DEFAULT NULL COMMENT '头像',
+  `groupon_id` int(11) NOT NULL DEFAULT '0' COMMENT '团',
+  `goods_id` int(11) NOT NULL DEFAULT '0' COMMENT '商品',
+  `goods_sku_price_id` int(11) NOT NULL DEFAULT '0' COMMENT '商品规格',
+  `activity_id` int(11) NOT NULL DEFAULT '0' COMMENT '活动',
+  `is_leader` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否团长',
+  `is_fictitious` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否虚拟用户',
+  `order_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单',
+  `is_refund` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否退款',
+  `createtime` int(10) DEFAULT NULL COMMENT '添加时间',
+  `updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_area` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(50) DEFAULT NULL COMMENT '名称',
+  `pid` int(11) DEFAULT '0' COMMENT '上级',
+  `level` int(11) DEFAULT '1',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='省市区数据';
+
+INSERT INTO `__PREFIX__shopro_area` (`id`, `name`, `pid`, `level`) VALUES
+(110000, '北京市', 0, 1),
+(110100, '北京市', 110000, 2),
+(110101, '东城区', 110100, 3),
+(110102, '西城区', 110100, 3),
+(110105, '朝阳区', 110100, 3),
+(110106, '丰台区', 110100, 3),
+(110107, '石景山区', 110100, 3),
+(110108, '海淀区', 110100, 3),
+(110109, '门头沟区', 110100, 3),
+(110111, '房山区', 110100, 3),
+(110112, '通州区', 110100, 3),
+(110113, '顺义区', 110100, 3),
+(110114, '昌平区', 110100, 3),
+(110115, '大兴区', 110100, 3),
+(110116, '怀柔区', 110100, 3),
+(110117, '平谷区', 110100, 3),
+(110118, '密云区', 110100, 3),
+(110119, '延庆区', 110100, 3),
+(120000, '天津市', 0, 1),
+(120100, '天津市', 120000, 2),
+(120101, '和平区', 120100, 3),
+(120102, '河东区', 120100, 3),
+(120103, '河西区', 120100, 3),
+(120104, '南开区', 120100, 3),
+(120105, '河北区', 120100, 3),
+(120106, '红桥区', 120100, 3),
+(120110, '东丽区', 120100, 3),
+(120111, '西青区', 120100, 3),
+(120112, '津南区', 120100, 3),
+(120113, '北辰区', 120100, 3),
+(120114, '武清区', 120100, 3),
+(120115, '宝坻区', 120100, 3),
+(120116, '滨海新区', 120100, 3),
+(120117, '宁河区', 120100, 3),
+(120118, '静海区', 120100, 3),
+(120119, '蓟州区', 120100, 3),
+(130000, '河北省', 0, 1),
+(130100, '石家庄市', 130000, 2),
+(130102, '长安区', 130100, 3),
+(130104, '桥西区', 130100, 3),
+(130105, '新华区', 130100, 3),
+(130107, '井陉矿区', 130100, 3),
+(130108, '裕华区', 130100, 3),
+(130109, '藁城区', 130100, 3),
+(130110, '鹿泉区', 130100, 3),
+(130111, '栾城区', 130100, 3),
+(130121, '井陉县', 130100, 3),
+(130123, '正定县', 130100, 3),
+(130125, '行唐县', 130100, 3),
+(130126, '灵寿县', 130100, 3),
+(130127, '高邑县', 130100, 3),
+(130128, '深泽县', 130100, 3),
+(130129, '赞皇县', 130100, 3),
+(130130, '无极县', 130100, 3),
+(130131, '平山县', 130100, 3),
+(130132, '元氏县', 130100, 3),
+(130133, '赵县', 130100, 3),
+(130181, '辛集市', 130100, 3),
+(130183, '晋州市', 130100, 3),
+(130184, '新乐市', 130100, 3),
+(130200, '唐山市', 130000, 2),
+(130202, '路南区', 130200, 3),
+(130203, '路北区', 130200, 3),
+(130204, '古冶区', 130200, 3),
+(130205, '开平区', 130200, 3),
+(130207, '丰南区', 130200, 3),
+(130208, '丰润区', 130200, 3),
+(130209, '曹妃甸区', 130200, 3),
+(130223, '滦县', 130200, 3),
+(130224, '滦南县', 130200, 3),
+(130225, '乐亭县', 130200, 3),
+(130227, '迁西县', 130200, 3),
+(130229, '玉田县', 130200, 3),
+(130281, '遵化市', 130200, 3),
+(130283, '迁安市', 130200, 3),
+(130300, '秦皇岛市', 130000, 2),
+(130302, '海港区', 130300, 3),
+(130303, '山海关区', 130300, 3),
+(130304, '北戴河区', 130300, 3),
+(130306, '抚宁区', 130300, 3),
+(130321, '青龙满族自治县', 130300, 3),
+(130322, '昌黎县', 130300, 3),
+(130324, '卢龙县', 130300, 3),
+(130400, '邯郸市', 130000, 2),
+(130402, '邯山区', 130400, 3),
+(130403, '丛台区', 130400, 3),
+(130404, '复兴区', 130400, 3),
+(130406, '峰峰矿区', 130400, 3),
+(130407, '肥乡区', 130400, 3),
+(130408, '永年区', 130400, 3),
+(130423, '临漳县', 130400, 3),
+(130424, '成安县', 130400, 3),
+(130425, '大名县', 130400, 3),
+(130426, '涉县', 130400, 3),
+(130427, '磁县', 130400, 3),
+(130430, '邱县', 130400, 3),
+(130431, '鸡泽县', 130400, 3),
+(130432, '广平县', 130400, 3),
+(130433, '馆陶县', 130400, 3),
+(130434, '魏县', 130400, 3),
+(130435, '曲周县', 130400, 3),
+(130481, '武安市', 130400, 3),
+(130500, '邢台市', 130000, 2),
+(130502, '桥东区', 130500, 3),
+(130503, '桥西区', 130500, 3),
+(130521, '邢台县', 130500, 3),
+(130522, '临城县', 130500, 3),
+(130523, '内丘县', 130500, 3),
+(130524, '柏乡县', 130500, 3),
+(130525, '隆尧县', 130500, 3),
+(130526, '任县', 130500, 3),
+(130527, '南和县', 130500, 3),
+(130528, '宁晋县', 130500, 3),
+(130529, '巨鹿县', 130500, 3),
+(130530, '新河县', 130500, 3),
+(130531, '广宗县', 130500, 3),
+(130532, '平乡县', 130500, 3),
+(130533, '威县', 130500, 3),
+(130534, '清河县', 130500, 3),
+(130535, '临西县', 130500, 3),
+(130581, '南宫市', 130500, 3),
+(130582, '沙河市', 130500, 3),
+(130600, '保定市', 130000, 2),
+(130602, '竞秀区', 130600, 3),
+(130606, '莲池区', 130600, 3),
+(130607, '满城区', 130600, 3),
+(130608, '清苑区', 130600, 3),
+(130609, '徐水区', 130600, 3),
+(130623, '涞水县', 130600, 3),
+(130624, '阜平县', 130600, 3),
+(130626, '定兴县', 130600, 3),
+(130627, '唐县', 130600, 3),
+(130628, '高阳县', 130600, 3),
+(130629, '容城县', 130600, 3),
+(130630, '涞源县', 130600, 3),
+(130631, '望都县', 130600, 3),
+(130632, '安新县', 130600, 3),
+(130633, '易县', 130600, 3),
+(130634, '曲阳县', 130600, 3),
+(130635, '蠡县', 130600, 3),
+(130636, '顺平县', 130600, 3),
+(130637, '博野县', 130600, 3),
+(130638, '雄县', 130600, 3),
+(130681, '涿州市', 130600, 3),
+(130682, '定州市', 130600, 3),
+(130683, '安国市', 130600, 3),
+(130684, '高碑店市', 130600, 3),
+(130700, '张家口市', 130000, 2),
+(130702, '桥东区', 130700, 3),
+(130703, '桥西区', 130700, 3),
+(130705, '宣化区', 130700, 3),
+(130706, '下花园区', 130700, 3),
+(130708, '万全区', 130700, 3),
+(130709, '崇礼区', 130700, 3),
+(130722, '张北县', 130700, 3),
+(130723, '康保县', 130700, 3),
+(130724, '沽源县', 130700, 3),
+(130725, '尚义县', 130700, 3),
+(130726, '蔚县', 130700, 3),
+(130727, '阳原县', 130700, 3),
+(130728, '怀安县', 130700, 3),
+(130730, '怀来县', 130700, 3),
+(130731, '涿鹿县', 130700, 3),
+(130732, '赤城县', 130700, 3),
+(130800, '承德市', 130000, 2),
+(130802, '双桥区', 130800, 3),
+(130803, '双滦区', 130800, 3),
+(130804, '鹰手营子矿区', 130800, 3),
+(130821, '承德县', 130800, 3),
+(130822, '兴隆县', 130800, 3),
+(130824, '滦平县', 130800, 3),
+(130825, '隆化县', 130800, 3),
+(130826, '丰宁满族自治县', 130800, 3),
+(130827, '宽城满族自治县', 130800, 3),
+(130828, '围场满族蒙古族自治县', 130800, 3),
+(130881, '平泉市', 130800, 3),
+(130900, '沧州市', 130000, 2),
+(130902, '新华区', 130900, 3),
+(130903, '运河区', 130900, 3),
+(130921, '沧县', 130900, 3),
+(130922, '青县', 130900, 3),
+(130923, '东光县', 130900, 3),
+(130924, '海兴县', 130900, 3),
+(130925, '盐山县', 130900, 3),
+(130926, '肃宁县', 130900, 3),
+(130927, '南皮县', 130900, 3),
+(130928, '吴桥县', 130900, 3),
+(130929, '献县', 130900, 3),
+(130930, '孟村回族自治县', 130900, 3),
+(130981, '泊头市', 130900, 3),
+(130982, '任丘市', 130900, 3),
+(130983, '黄骅市', 130900, 3),
+(130984, '河间市', 130900, 3),
+(131000, '廊坊市', 130000, 2),
+(131002, '安次区', 131000, 3),
+(131003, '广阳区', 131000, 3),
+(131022, '固安县', 131000, 3),
+(131023, '永清县', 131000, 3),
+(131024, '香河县', 131000, 3),
+(131025, '大城县', 131000, 3),
+(131026, '文安县', 131000, 3),
+(131028, '大厂回族自治县', 131000, 3),
+(131081, '霸州市', 131000, 3),
+(131082, '三河市', 131000, 3),
+(131100, '衡水市', 130000, 2),
+(131102, '桃城区', 131100, 3),
+(131103, '冀州区', 131100, 3),
+(131121, '枣强县', 131100, 3),
+(131122, '武邑县', 131100, 3),
+(131123, '武强县', 131100, 3),
+(131124, '饶阳县', 131100, 3),
+(131125, '安平县', 131100, 3),
+(131126, '故城县', 131100, 3),
+(131127, '景县', 131100, 3),
+(131128, '阜城县', 131100, 3),
+(131182, '深州市', 131100, 3),
+(140000, '山西省', 0, 1),
+(140100, '太原市', 140000, 2),
+(140105, '小店区', 140100, 3),
+(140106, '迎泽区', 140100, 3),
+(140107, '杏花岭区', 140100, 3),
+(140108, '尖草坪区', 140100, 3),
+(140109, '万柏林区', 140100, 3),
+(140110, '晋源区', 140100, 3),
+(140121, '清徐县', 140100, 3),
+(140122, '阳曲县', 140100, 3),
+(140123, '娄烦县', 140100, 3),
+(140181, '古交市', 140100, 3),
+(140200, '大同市', 140000, 2),
+(140202, '城区', 140200, 3),
+(140203, '矿区', 140200, 3),
+(140211, '南郊区', 140200, 3),
+(140212, '新荣区', 140200, 3),
+(140221, '阳高县', 140200, 3),
+(140222, '天镇县', 140200, 3),
+(140223, '广灵县', 140200, 3),
+(140224, '灵丘县', 140200, 3),
+(140225, '浑源县', 140200, 3),
+(140226, '左云县', 140200, 3),
+(140227, '大同县', 140200, 3),
+(140300, '阳泉市', 140000, 2),
+(140302, '城区', 140300, 3),
+(140303, '矿区', 140300, 3),
+(140311, '郊区', 140300, 3),
+(140321, '平定县', 140300, 3),
+(140322, '盂县', 140300, 3),
+(140400, '长治市', 140000, 2),
+(140402, '城区', 140400, 3),
+(140411, '郊区', 140400, 3),
+(140421, '长治县', 140400, 3),
+(140423, '襄垣县', 140400, 3),
+(140424, '屯留县', 140400, 3),
+(140425, '平顺县', 140400, 3),
+(140426, '黎城县', 140400, 3),
+(140427, '壶关县', 140400, 3),
+(140428, '长子县', 140400, 3),
+(140429, '武乡县', 140400, 3),
+(140430, '沁县', 140400, 3),
+(140431, '沁源县', 140400, 3),
+(140481, '潞城市', 140400, 3),
+(140500, '晋城市', 140000, 2),
+(140502, '城区', 140500, 3),
+(140521, '沁水县', 140500, 3),
+(140522, '阳城县', 140500, 3),
+(140524, '陵川县', 140500, 3),
+(140525, '泽州县', 140500, 3),
+(140581, '高平市', 140500, 3),
+(140600, '朔州市', 140000, 2),
+(140602, '朔城区', 140600, 3),
+(140603, '平鲁区', 140600, 3),
+(140621, '山阴县', 140600, 3),
+(140622, '应县', 140600, 3),
+(140623, '右玉县', 140600, 3),
+(140624, '怀仁县', 140600, 3),
+(140700, '晋中市', 140000, 2),
+(140702, '榆次区', 140700, 3),
+(140721, '榆社县', 140700, 3),
+(140722, '左权县', 140700, 3),
+(140723, '和顺县', 140700, 3),
+(140724, '昔阳县', 140700, 3),
+(140725, '寿阳县', 140700, 3),
+(140726, '太谷县', 140700, 3),
+(140727, '祁县', 140700, 3),
+(140728, '平遥县', 140700, 3),
+(140729, '灵石县', 140700, 3),
+(140781, '介休市', 140700, 3),
+(140800, '运城市', 140000, 2),
+(140802, '盐湖区', 140800, 3),
+(140821, '临猗县', 140800, 3),
+(140822, '万荣县', 140800, 3),
+(140823, '闻喜县', 140800, 3),
+(140824, '稷山县', 140800, 3),
+(140825, '新绛县', 140800, 3),
+(140826, '绛县', 140800, 3),
+(140827, '垣曲县', 140800, 3),
+(140828, '夏县', 140800, 3),
+(140829, '平陆县', 140800, 3),
+(140830, '芮城县', 140800, 3),
+(140881, '永济市', 140800, 3),
+(140882, '河津市', 140800, 3),
+(140900, '忻州市', 140000, 2),
+(140902, '忻府区', 140900, 3),
+(140921, '定襄县', 140900, 3),
+(140922, '五台县', 140900, 3),
+(140923, '代县', 140900, 3),
+(140924, '繁峙县', 140900, 3),
+(140925, '宁武县', 140900, 3),
+(140926, '静乐县', 140900, 3),
+(140927, '神池县', 140900, 3),
+(140928, '五寨县', 140900, 3),
+(140929, '岢岚县', 140900, 3),
+(140930, '河曲县', 140900, 3),
+(140931, '保德县', 140900, 3),
+(140932, '偏关县', 140900, 3),
+(140981, '原平市', 140900, 3),
+(141000, '临汾市', 140000, 2),
+(141002, '尧都区', 141000, 3),
+(141021, '曲沃县', 141000, 3),
+(141022, '翼城县', 141000, 3),
+(141023, '襄汾县', 141000, 3),
+(141024, '洪洞县', 141000, 3),
+(141025, '古县', 141000, 3),
+(141026, '安泽县', 141000, 3),
+(141027, '浮山县', 141000, 3),
+(141028, '吉县', 141000, 3),
+(141029, '乡宁县', 141000, 3),
+(141030, '大宁县', 141000, 3),
+(141031, '隰县', 141000, 3),
+(141032, '永和县', 141000, 3),
+(141033, '蒲县', 141000, 3),
+(141034, '汾西县', 141000, 3),
+(141081, '侯马市', 141000, 3),
+(141082, '霍州市', 141000, 3),
+(141100, '吕梁市', 140000, 2),
+(141102, '离石区', 141100, 3),
+(141121, '文水县', 141100, 3),
+(141122, '交城县', 141100, 3),
+(141123, '兴县', 141100, 3),
+(141124, '临县', 141100, 3),
+(141125, '柳林县', 141100, 3),
+(141126, '石楼县', 141100, 3),
+(141127, '岚县', 141100, 3),
+(141128, '方山县', 141100, 3),
+(141129, '中阳县', 141100, 3),
+(141130, '交口县', 141100, 3),
+(141181, '孝义市', 141100, 3),
+(141182, '汾阳市', 141100, 3),
+(150000, '内蒙古自治区', 0, 1),
+(150100, '呼和浩特市', 150000, 2),
+(150102, '新城区', 150100, 3),
+(150103, '回民区', 150100, 3),
+(150104, '玉泉区', 150100, 3),
+(150105, '赛罕区', 150100, 3),
+(150121, '土默特左旗', 150100, 3),
+(150122, '托克托县', 150100, 3),
+(150123, '和林格尔县', 150100, 3),
+(150124, '清水河县', 150100, 3),
+(150125, '武川县', 150100, 3),
+(150200, '包头市', 150000, 2),
+(150202, '东河区', 150200, 3),
+(150203, '昆都仑区', 150200, 3),
+(150204, '青山区', 150200, 3),
+(150205, '石拐区', 150200, 3),
+(150206, '白云鄂博矿区', 150200, 3),
+(150207, '九原区', 150200, 3),
+(150221, '土默特右旗', 150200, 3),
+(150222, '固阳县', 150200, 3),
+(150223, '达尔罕茂明安联合旗', 150200, 3),
+(150300, '乌海市', 150000, 2),
+(150302, '海勃湾区', 150300, 3),
+(150303, '海南区', 150300, 3),
+(150304, '乌达区', 150300, 3),
+(150400, '赤峰市', 150000, 2),
+(150402, '红山区', 150400, 3),
+(150403, '元宝山区', 150400, 3),
+(150404, '松山区', 150400, 3),
+(150421, '阿鲁科尔沁旗', 150400, 3),
+(150422, '巴林左旗', 150400, 3),
+(150423, '巴林右旗', 150400, 3),
+(150424, '林西县', 150400, 3),
+(150425, '克什克腾旗', 150400, 3),
+(150426, '翁牛特旗', 150400, 3),
+(150428, '喀喇沁旗', 150400, 3),
+(150429, '宁城县', 150400, 3),
+(150430, '敖汉旗', 150400, 3),
+(150500, '通辽市', 150000, 2),
+(150502, '科尔沁区', 150500, 3),
+(150521, '科尔沁左翼中旗', 150500, 3),
+(150522, '科尔沁左翼后旗', 150500, 3),
+(150523, '开鲁县', 150500, 3),
+(150524, '库伦旗', 150500, 3),
+(150525, '奈曼旗', 150500, 3),
+(150526, '扎鲁特旗', 150500, 3),
+(150581, '霍林郭勒市', 150500, 3),
+(150600, '鄂尔多斯市', 150000, 2),
+(150602, '东胜区', 150600, 3),
+(150603, '康巴什区', 150600, 3),
+(150621, '达拉特旗', 150600, 3),
+(150622, '准格尔旗', 150600, 3),
+(150623, '鄂托克前旗', 150600, 3),
+(150624, '鄂托克旗', 150600, 3),
+(150625, '杭锦旗', 150600, 3),
+(150626, '乌审旗', 150600, 3),
+(150627, '伊金霍洛旗', 150600, 3),
+(150700, '呼伦贝尔市', 150000, 2),
+(150702, '海拉尔区', 150700, 3),
+(150703, '扎赉诺尔区', 150700, 3),
+(150721, '阿荣旗', 150700, 3),
+(150722, '莫力达瓦达斡尔族自治旗', 150700, 3),
+(150723, '鄂伦春自治旗', 150700, 3),
+(150724, '鄂温克族自治旗', 150700, 3),
+(150725, '陈巴尔虎旗', 150700, 3),
+(150726, '新巴尔虎左旗', 150700, 3),
+(150727, '新巴尔虎右旗', 150700, 3),
+(150781, '满洲里市', 150700, 3),
+(150782, '牙克石市', 150700, 3),
+(150783, '扎兰屯市', 150700, 3),
+(150784, '额尔古纳市', 150700, 3),
+(150785, '根河市', 150700, 3),
+(150800, '巴彦淖尔市', 150000, 2),
+(150802, '临河区', 150800, 3),
+(150821, '五原县', 150800, 3),
+(150822, '磴口县', 150800, 3),
+(150823, '乌拉特前旗', 150800, 3),
+(150824, '乌拉特中旗', 150800, 3),
+(150825, '乌拉特后旗', 150800, 3),
+(150826, '杭锦后旗', 150800, 3),
+(150900, '乌兰察布市', 150000, 2),
+(150902, '集宁区', 150900, 3),
+(150921, '卓资县', 150900, 3),
+(150922, '化德县', 150900, 3),
+(150923, '商都县', 150900, 3),
+(150924, '兴和县', 150900, 3),
+(150925, '凉城县', 150900, 3),
+(150926, '察哈尔右翼前旗', 150900, 3),
+(150927, '察哈尔右翼中旗', 150900, 3),
+(150928, '察哈尔右翼后旗', 150900, 3),
+(150929, '四子王旗', 150900, 3),
+(150981, '丰镇市', 150900, 3),
+(152200, '兴安盟', 150000, 2),
+(152201, '乌兰浩特市', 152200, 3),
+(152202, '阿尔山市', 152200, 3),
+(152221, '科尔沁右翼前旗', 152200, 3),
+(152222, '科尔沁右翼中旗', 152200, 3),
+(152223, '扎赉特旗', 152200, 3),
+(152224, '突泉县', 152200, 3),
+(152500, '锡林郭勒盟', 150000, 2),
+(152501, '二连浩特市', 152500, 3),
+(152502, '锡林浩特市', 152500, 3),
+(152522, '阿巴嘎旗', 152500, 3),
+(152523, '苏尼特左旗', 152500, 3),
+(152524, '苏尼特右旗', 152500, 3),
+(152525, '东乌珠穆沁旗', 152500, 3),
+(152526, '西乌珠穆沁旗', 152500, 3),
+(152527, '太仆寺旗', 152500, 3),
+(152528, '镶黄旗', 152500, 3),
+(152529, '正镶白旗', 152500, 3),
+(152530, '正蓝旗', 152500, 3),
+(152531, '多伦县', 152500, 3),
+(152900, '阿拉善盟', 150000, 2),
+(152921, '阿拉善左旗', 152900, 3),
+(152922, '阿拉善右旗', 152900, 3),
+(152923, '额济纳旗', 152900, 3),
+(210000, '辽宁省', 0, 1),
+(210100, '沈阳市', 210000, 2),
+(210102, '和平区', 210100, 3),
+(210103, '沈河区', 210100, 3),
+(210104, '大东区', 210100, 3),
+(210105, '皇姑区', 210100, 3),
+(210106, '铁西区', 210100, 3),
+(210111, '苏家屯区', 210100, 3),
+(210112, '浑南区', 210100, 3),
+(210113, '沈北新区', 210100, 3),
+(210114, '于洪区', 210100, 3),
+(210115, '辽中区', 210100, 3),
+(210123, '康平县', 210100, 3),
+(210124, '法库县', 210100, 3),
+(210181, '新民市', 210100, 3),
+(210200, '大连市', 210000, 2),
+(210202, '中山区', 210200, 3),
+(210203, '西岗区', 210200, 3),
+(210204, '沙河口区', 210200, 3),
+(210211, '甘井子区', 210200, 3),
+(210212, '旅顺口区', 210200, 3),
+(210213, '金州区', 210200, 3),
+(210214, '普兰店区', 210200, 3),
+(210224, '长海县', 210200, 3),
+(210281, '瓦房店市', 210200, 3),
+(210283, '庄河市', 210200, 3),
+(210300, '鞍山市', 210000, 2),
+(210302, '铁东区', 210300, 3),
+(210303, '铁西区', 210300, 3),
+(210304, '立山区', 210300, 3),
+(210311, '千山区', 210300, 3),
+(210321, '台安县', 210300, 3),
+(210323, '岫岩满族自治县', 210300, 3),
+(210381, '海城市', 210300, 3),
+(210400, '抚顺市', 210000, 2),
+(210402, '新抚区', 210400, 3),
+(210403, '东洲区', 210400, 3),
+(210404, '望花区', 210400, 3),
+(210411, '顺城区', 210400, 3),
+(210421, '抚顺县', 210400, 3),
+(210422, '新宾满族自治县', 210400, 3),
+(210423, '清原满族自治县', 210400, 3),
+(210500, '本溪市', 210000, 2),
+(210502, '平山区', 210500, 3),
+(210503, '溪湖区', 210500, 3),
+(210504, '明山区', 210500, 3),
+(210505, '南芬区', 210500, 3),
+(210521, '本溪满族自治县', 210500, 3),
+(210522, '桓仁满族自治县', 210500, 3),
+(210600, '丹东市', 210000, 2),
+(210602, '元宝区', 210600, 3),
+(210603, '振兴区', 210600, 3),
+(210604, '振安区', 210600, 3),
+(210624, '宽甸满族自治县', 210600, 3),
+(210681, '东港市', 210600, 3),
+(210682, '凤城市', 210600, 3),
+(210700, '锦州市', 210000, 2),
+(210702, '古塔区', 210700, 3),
+(210703, '凌河区', 210700, 3),
+(210711, '太和区', 210700, 3),
+(210726, '黑山县', 210700, 3),
+(210727, '义县', 210700, 3),
+(210781, '凌海市', 210700, 3),
+(210782, '北镇市', 210700, 3),
+(210800, '营口市', 210000, 2),
+(210802, '站前区', 210800, 3),
+(210803, '西市区', 210800, 3),
+(210804, '鲅鱼圈区', 210800, 3),
+(210811, '老边区', 210800, 3),
+(210881, '盖州市', 210800, 3),
+(210882, '大石桥市', 210800, 3),
+(210900, '阜新市', 210000, 2),
+(210902, '海州区', 210900, 3),
+(210903, '新邱区', 210900, 3),
+(210904, '太平区', 210900, 3),
+(210905, '清河门区', 210900, 3),
+(210911, '细河区', 210900, 3),
+(210921, '阜新蒙古族自治县', 210900, 3),
+(210922, '彰武县', 210900, 3),
+(211000, '辽阳市', 210000, 2),
+(211002, '白塔区', 211000, 3),
+(211003, '文圣区', 211000, 3),
+(211004, '宏伟区', 211000, 3),
+(211005, '弓长岭区', 211000, 3),
+(211011, '太子河区', 211000, 3),
+(211021, '辽阳县', 211000, 3),
+(211081, '灯塔市', 211000, 3),
+(211100, '盘锦市', 210000, 2),
+(211102, '双台子区', 211100, 3),
+(211103, '兴隆台区', 211100, 3),
+(211104, '大洼区', 211100, 3),
+(211122, '盘山县', 211100, 3),
+(211200, '铁岭市', 210000, 2),
+(211202, '银州区', 211200, 3),
+(211204, '清河区', 211200, 3),
+(211221, '铁岭县', 211200, 3),
+(211223, '西丰县', 211200, 3),
+(211224, '昌图县', 211200, 3),
+(211281, '调兵山市', 211200, 3),
+(211282, '开原市', 211200, 3),
+(211300, '朝阳市', 210000, 2),
+(211302, '双塔区', 211300, 3),
+(211303, '龙城区', 211300, 3),
+(211321, '朝阳县', 211300, 3),
+(211322, '建平县', 211300, 3),
+(211324, '喀喇沁左翼蒙古族自治县', 211300, 3),
+(211381, '北票市', 211300, 3),
+(211382, '凌源市', 211300, 3),
+(211400, '葫芦岛市', 210000, 2),
+(211402, '连山区', 211400, 3),
+(211403, '龙港区', 211400, 3),
+(211404, '南票区', 211400, 3),
+(211421, '绥中县', 211400, 3),
+(211422, '建昌县', 211400, 3),
+(211481, '兴城市', 211400, 3),
+(220000, '吉林省', 0, 1),
+(220100, '长春市', 220000, 2),
+(220102, '南关区', 220100, 3),
+(220103, '宽城区', 220100, 3),
+(220104, '朝阳区', 220100, 3),
+(220105, '二道区', 220100, 3),
+(220106, '绿园区', 220100, 3),
+(220112, '双阳区', 220100, 3),
+(220113, '九台区', 220100, 3),
+(220122, '农安县', 220100, 3),
+(220182, '榆树市', 220100, 3),
+(220183, '德惠市', 220100, 3),
+(220200, '吉林市', 220000, 2),
+(220202, '昌邑区', 220200, 3),
+(220203, '龙潭区', 220200, 3),
+(220204, '船营区', 220200, 3),
+(220211, '丰满区', 220200, 3),
+(220221, '永吉县', 220200, 3),
+(220281, '蛟河市', 220200, 3),
+(220282, '桦甸市', 220200, 3),
+(220283, '舒兰市', 220200, 3),
+(220284, '磐石市', 220200, 3),
+(220300, '四平市', 220000, 2),
+(220302, '铁西区', 220300, 3),
+(220303, '铁东区', 220300, 3),
+(220322, '梨树县', 220300, 3),
+(220323, '伊通满族自治县', 220300, 3),
+(220381, '公主岭市', 220300, 3),
+(220382, '双辽市', 220300, 3),
+(220400, '辽源市', 220000, 2),
+(220402, '龙山区', 220400, 3),
+(220403, '西安区', 220400, 3),
+(220421, '东丰县', 220400, 3),
+(220422, '东辽县', 220400, 3),
+(220500, '通化市', 220000, 2),
+(220502, '东昌区', 220500, 3),
+(220503, '二道江区', 220500, 3),
+(220521, '通化县', 220500, 3),
+(220523, '辉南县', 220500, 3),
+(220524, '柳河县', 220500, 3),
+(220581, '梅河口市', 220500, 3),
+(220582, '集安市', 220500, 3),
+(220600, '白山市', 220000, 2),
+(220602, '浑江区', 220600, 3),
+(220605, '江源区', 220600, 3),
+(220621, '抚松县', 220600, 3),
+(220622, '靖宇县', 220600, 3),
+(220623, '长白朝鲜族自治县', 220600, 3),
+(220681, '临江市', 220600, 3),
+(220700, '松原市', 220000, 2),
+(220702, '宁江区', 220700, 3),
+(220721, '前郭尔罗斯蒙古族自治县', 220700, 3),
+(220722, '长岭县', 220700, 3),
+(220723, '乾安县', 220700, 3),
+(220781, '扶余市', 220700, 3),
+(220800, '白城市', 220000, 2),
+(220802, '洮北区', 220800, 3),
+(220821, '镇赉县', 220800, 3),
+(220822, '通榆县', 220800, 3),
+(220881, '洮南市', 220800, 3),
+(220882, '大安市', 220800, 3),
+(222400, '延边朝鲜族自治州', 220000, 2),
+(222401, '延吉市', 222400, 3),
+(222402, '图们市', 222400, 3),
+(222403, '敦化市', 222400, 3),
+(222404, '珲春市', 222400, 3),
+(222405, '龙井市', 222400, 3),
+(222406, '和龙市', 222400, 3),
+(222424, '汪清县', 222400, 3),
+(222426, '安图县', 222400, 3),
+(230000, '黑龙江省', 0, 1),
+(230100, '哈尔滨市', 230000, 2),
+(230102, '道里区', 230100, 3),
+(230103, '南岗区', 230100, 3),
+(230104, '道外区', 230100, 3),
+(230108, '平房区', 230100, 3),
+(230109, '松北区', 230100, 3),
+(230110, '香坊区', 230100, 3),
+(230111, '呼兰区', 230100, 3),
+(230112, '阿城区', 230100, 3),
+(230113, '双城区', 230100, 3),
+(230123, '依兰县', 230100, 3),
+(230124, '方正县', 230100, 3),
+(230125, '宾县', 230100, 3),
+(230126, '巴彦县', 230100, 3),
+(230127, '木兰县', 230100, 3),
+(230128, '通河县', 230100, 3),
+(230129, '延寿县', 230100, 3),
+(230183, '尚志市', 230100, 3),
+(230184, '五常市', 230100, 3),
+(230200, '齐齐哈尔市', 230000, 2),
+(230202, '龙沙区', 230200, 3),
+(230203, '建华区', 230200, 3),
+(230204, '铁锋区', 230200, 3),
+(230205, '昂昂溪区', 230200, 3),
+(230206, '富拉尔基区', 230200, 3),
+(230207, '碾子山区', 230200, 3),
+(230208, '梅里斯达斡尔族区', 230200, 3),
+(230221, '龙江县', 230200, 3),
+(230223, '依安县', 230200, 3),
+(230224, '泰来县', 230200, 3),
+(230225, '甘南县', 230200, 3),
+(230227, '富裕县', 230200, 3),
+(230229, '克山县', 230200, 3),
+(230230, '克东县', 230200, 3),
+(230231, '拜泉县', 230200, 3),
+(230281, '讷河市', 230200, 3),
+(230300, '鸡西市', 230000, 2),
+(230302, '鸡冠区', 230300, 3),
+(230303, '恒山区', 230300, 3),
+(230304, '滴道区', 230300, 3),
+(230305, '梨树区', 230300, 3),
+(230306, '城子河区', 230300, 3),
+(230307, '麻山区', 230300, 3),
+(230321, '鸡东县', 230300, 3),
+(230381, '虎林市', 230300, 3),
+(230382, '密山市', 230300, 3),
+(230400, '鹤岗市', 230000, 2),
+(230402, '向阳区', 230400, 3),
+(230403, '工农区', 230400, 3),
+(230404, '南山区', 230400, 3),
+(230405, '兴安区', 230400, 3),
+(230406, '东山区', 230400, 3),
+(230407, '兴山区', 230400, 3),
+(230421, '萝北县', 230400, 3),
+(230422, '绥滨县', 230400, 3),
+(230500, '双鸭山市', 230000, 2),
+(230502, '尖山区', 230500, 3),
+(230503, '岭东区', 230500, 3),
+(230505, '四方台区', 230500, 3),
+(230506, '宝山区', 230500, 3),
+(230521, '集贤县', 230500, 3),
+(230522, '友谊县', 230500, 3),
+(230523, '宝清县', 230500, 3),
+(230524, '饶河县', 230500, 3),
+(230600, '大庆市', 230000, 2),
+(230602, '萨尔图区', 230600, 3),
+(230603, '龙凤区', 230600, 3),
+(230604, '让胡路区', 230600, 3),
+(230605, '红岗区', 230600, 3),
+(230606, '大同区', 230600, 3),
+(230621, '肇州县', 230600, 3),
+(230622, '肇源县', 230600, 3),
+(230623, '林甸县', 230600, 3),
+(230624, '杜尔伯特蒙古族自治县', 230600, 3),
+(230700, '伊春市', 230000, 2),
+(230702, '伊春区', 230700, 3),
+(230703, '南岔区', 230700, 3),
+(230704, '友好区', 230700, 3),
+(230705, '西林区', 230700, 3),
+(230706, '翠峦区', 230700, 3),
+(230707, '新青区', 230700, 3),
+(230708, '美溪区', 230700, 3),
+(230709, '金山屯区', 230700, 3),
+(230710, '五营区', 230700, 3),
+(230711, '乌马河区', 230700, 3),
+(230712, '汤旺河区', 230700, 3),
+(230713, '带岭区', 230700, 3),
+(230714, '乌伊岭区', 230700, 3),
+(230715, '红星区', 230700, 3),
+(230716, '上甘岭区', 230700, 3),
+(230722, '嘉荫县', 230700, 3),
+(230781, '铁力市', 230700, 3),
+(230800, '佳木斯市', 230000, 2),
+(230803, '向阳区', 230800, 3),
+(230804, '前进区', 230800, 3),
+(230805, '东风区', 230800, 3),
+(230811, '郊区', 230800, 3),
+(230822, '桦南县', 230800, 3),
+(230826, '桦川县', 230800, 3),
+(230828, '汤原县', 230800, 3),
+(230881, '同江市', 230800, 3),
+(230882, '富锦市', 230800, 3),
+(230883, '抚远市', 230800, 3),
+(230900, '七台河市', 230000, 2),
+(230902, '新兴区', 230900, 3),
+(230903, '桃山区', 230900, 3),
+(230904, '茄子河区', 230900, 3),
+(230921, '勃利县', 230900, 3),
+(231000, '牡丹江市', 230000, 2),
+(231002, '东安区', 231000, 3),
+(231003, '阳明区', 231000, 3),
+(231004, '爱民区', 231000, 3),
+(231005, '西安区', 231000, 3),
+(231025, '林口县', 231000, 3),
+(231081, '绥芬河市', 231000, 3),
+(231083, '海林市', 231000, 3),
+(231084, '宁安市', 231000, 3),
+(231085, '穆棱市', 231000, 3),
+(231086, '东宁市', 231000, 3),
+(231100, '黑河市', 230000, 2),
+(231102, '爱辉区', 231100, 3),
+(231121, '嫩江县', 231100, 3),
+(231123, '逊克县', 231100, 3),
+(231124, '孙吴县', 231100, 3),
+(231181, '北安市', 231100, 3),
+(231182, '五大连池市', 231100, 3),
+(231200, '绥化市', 230000, 2),
+(231202, '北林区', 231200, 3),
+(231221, '望奎县', 231200, 3),
+(231222, '兰西县', 231200, 3),
+(231223, '青冈县', 231200, 3),
+(231224, '庆安县', 231200, 3),
+(231225, '明水县', 231200, 3),
+(231226, '绥棱县', 231200, 3),
+(231281, '安达市', 231200, 3),
+(231282, '肇东市', 231200, 3),
+(231283, '海伦市', 231200, 3),
+(232700, '大兴安岭地区', 230000, 2),
+(232701, '加格达奇区', 232700, 3),
+(232702, '松岭区', 232700, 3),
+(232703, '新林区', 232700, 3),
+(232704, '呼中区', 232700, 3),
+(232721, '呼玛县', 232700, 3),
+(232722, '塔河县', 232700, 3),
+(232723, '漠河县', 232700, 3),
+(310000, '上海市', 0, 1),
+(310100, '上海市', 310000, 2),
+(310101, '黄浦区', 310100, 3),
+(310104, '徐汇区', 310100, 3),
+(310105, '长宁区', 310100, 3),
+(310106, '静安区', 310100, 3),
+(310107, '普陀区', 310100, 3),
+(310109, '虹口区', 310100, 3),
+(310110, '杨浦区', 310100, 3),
+(310112, '闵行区', 310100, 3),
+(310113, '宝山区', 310100, 3),
+(310114, '嘉定区', 310100, 3),
+(310115, '浦东新区', 310100, 3),
+(310116, '金山区', 310100, 3),
+(310117, '松江区', 310100, 3),
+(310118, '青浦区', 310100, 3),
+(310120, '奉贤区', 310100, 3),
+(310151, '崇明区', 310100, 3),
+(320000, '江苏省', 0, 1),
+(320100, '南京市', 320000, 2),
+(320102, '玄武区', 320100, 3),
+(320104, '秦淮区', 320100, 3),
+(320105, '建邺区', 320100, 3),
+(320106, '鼓楼区', 320100, 3),
+(320111, '浦口区', 320100, 3),
+(320113, '栖霞区', 320100, 3),
+(320114, '雨花台区', 320100, 3),
+(320115, '江宁区', 320100, 3),
+(320116, '六合区', 320100, 3),
+(320117, '溧水区', 320100, 3),
+(320118, '高淳区', 320100, 3),
+(320200, '无锡市', 320000, 2),
+(320205, '锡山区', 320200, 3),
+(320206, '惠山区', 320200, 3),
+(320211, '滨湖区', 320200, 3),
+(320213, '梁溪区', 320200, 3),
+(320214, '新吴区', 320200, 3),
+(320281, '江阴市', 320200, 3),
+(320282, '宜兴市', 320200, 3),
+(320300, '徐州市', 320000, 2),
+(320302, '鼓楼区', 320300, 3),
+(320303, '云龙区', 320300, 3),
+(320305, '贾汪区', 320300, 3),
+(320311, '泉山区', 320300, 3),
+(320312, '铜山区', 320300, 3),
+(320321, '丰县', 320300, 3),
+(320322, '沛县', 320300, 3),
+(320324, '睢宁县', 320300, 3),
+(320381, '新沂市', 320300, 3),
+(320382, '邳州市', 320300, 3),
+(320400, '常州市', 320000, 2),
+(320402, '天宁区', 320400, 3),
+(320404, '钟楼区', 320400, 3),
+(320411, '新北区', 320400, 3),
+(320412, '武进区', 320400, 3),
+(320413, '金坛区', 320400, 3),
+(320481, '溧阳市', 320400, 3),
+(320500, '苏州市', 320000, 2),
+(320505, '虎丘区', 320500, 3),
+(320506, '吴中区', 320500, 3),
+(320507, '相城区', 320500, 3),
+(320508, '姑苏区', 320500, 3),
+(320509, '吴江区', 320500, 3),
+(320581, '常熟市', 320500, 3),
+(320582, '张家港市', 320500, 3),
+(320583, '昆山市', 320500, 3),
+(320585, '太仓市', 320500, 3),
+(320600, '南通市', 320000, 2),
+(320602, '崇川区', 320600, 3),
+(320611, '港闸区', 320600, 3),
+(320612, '通州区', 320600, 3),
+(320621, '海安县', 320600, 3),
+(320623, '如东县', 320600, 3),
+(320681, '启东市', 320600, 3),
+(320682, '如皋市', 320600, 3),
+(320684, '海门市', 320600, 3),
+(320700, '连云港市', 320000, 2),
+(320703, '连云区', 320700, 3),
+(320706, '海州区', 320700, 3),
+(320707, '赣榆区', 320700, 3),
+(320722, '东海县', 320700, 3),
+(320723, '灌云县', 320700, 3),
+(320724, '灌南县', 320700, 3),
+(320800, '淮安市', 320000, 2),
+(320803, '淮安区', 320800, 3),
+(320804, '淮阴区', 320800, 3),
+(320812, '清江浦区', 320800, 3),
+(320813, '洪泽区', 320800, 3),
+(320826, '涟水县', 320800, 3),
+(320830, '盱眙县', 320800, 3),
+(320831, '金湖县', 320800, 3),
+(320900, '盐城市', 320000, 2),
+(320902, '亭湖区', 320900, 3),
+(320903, '盐都区', 320900, 3),
+(320904, '大丰区', 320900, 3),
+(320921, '响水县', 320900, 3),
+(320922, '滨海县', 320900, 3),
+(320923, '阜宁县', 320900, 3),
+(320924, '射阳县', 320900, 3),
+(320925, '建湖县', 320900, 3),
+(320981, '东台市', 320900, 3),
+(321000, '扬州市', 320000, 2),
+(321002, '广陵区', 321000, 3),
+(321003, '邗江区', 321000, 3),
+(321012, '江都区', 321000, 3),
+(321023, '宝应县', 321000, 3),
+(321081, '仪征市', 321000, 3),
+(321084, '高邮市', 321000, 3),
+(321100, '镇江市', 320000, 2),
+(321102, '京口区', 321100, 3),
+(321111, '润州区', 321100, 3),
+(321112, '丹徒区', 321100, 3),
+(321181, '丹阳市', 321100, 3),
+(321182, '扬中市', 321100, 3),
+(321183, '句容市', 321100, 3),
+(321200, '泰州市', 320000, 2),
+(321202, '海陵区', 321200, 3),
+(321203, '高港区', 321200, 3),
+(321204, '姜堰区', 321200, 3),
+(321281, '兴化市', 321200, 3),
+(321282, '靖江市', 321200, 3),
+(321283, '泰兴市', 321200, 3),
+(321300, '宿迁市', 320000, 2),
+(321302, '宿城区', 321300, 3),
+(321311, '宿豫区', 321300, 3),
+(321322, '沭阳县', 321300, 3),
+(321323, '泗阳县', 321300, 3),
+(321324, '泗洪县', 321300, 3),
+(330000, '浙江省', 0, 1),
+(330100, '杭州市', 330000, 2),
+(330102, '上城区', 330100, 3),
+(330103, '下城区', 330100, 3),
+(330104, '江干区', 330100, 3),
+(330105, '拱墅区', 330100, 3),
+(330106, '西湖区', 330100, 3),
+(330108, '滨江区', 330100, 3),
+(330109, '萧山区', 330100, 3),
+(330110, '余杭区', 330100, 3),
+(330111, '富阳区', 330100, 3),
+(330112, '临安区', 330100, 3),
+(330122, '桐庐县', 330100, 3),
+(330127, '淳安县', 330100, 3),
+(330182, '建德市', 330100, 3),
+(330200, '宁波市', 330000, 2),
+(330203, '海曙区', 330200, 3),
+(330205, '江北区', 330200, 3),
+(330206, '北仑区', 330200, 3),
+(330211, '镇海区', 330200, 3),
+(330212, '鄞州区', 330200, 3),
+(330213, '奉化区', 330200, 3),
+(330225, '象山县', 330200, 3),
+(330226, '宁海县', 330200, 3),
+(330281, '余姚市', 330200, 3),
+(330282, '慈溪市', 330200, 3),
+(330300, '温州市', 330000, 2),
+(330302, '鹿城区', 330300, 3),
+(330303, '龙湾区', 330300, 3),
+(330304, '瓯海区', 330300, 3),
+(330305, '洞头区', 330300, 3),
+(330324, '永嘉县', 330300, 3),
+(330326, '平阳县', 330300, 3),
+(330327, '苍南县', 330300, 3),
+(330328, '文成县', 330300, 3),
+(330329, '泰顺县', 330300, 3),
+(330381, '瑞安市', 330300, 3),
+(330382, '乐清市', 330300, 3),
+(330400, '嘉兴市', 330000, 2),
+(330402, '南湖区', 330400, 3),
+(330411, '秀洲区', 330400, 3),
+(330421, '嘉善县', 330400, 3),
+(330424, '海盐县', 330400, 3),
+(330481, '海宁市', 330400, 3),
+(330482, '平湖市', 330400, 3),
+(330483, '桐乡市', 330400, 3),
+(330500, '湖州市', 330000, 2),
+(330502, '吴兴区', 330500, 3),
+(330503, '南浔区', 330500, 3),
+(330521, '德清县', 330500, 3),
+(330522, '长兴县', 330500, 3),
+(330523, '安吉县', 330500, 3),
+(330600, '绍兴市', 330000, 2),
+(330602, '越城区', 330600, 3),
+(330603, '柯桥区', 330600, 3),
+(330604, '上虞区', 330600, 3),
+(330624, '新昌县', 330600, 3),
+(330681, '诸暨市', 330600, 3),
+(330683, '嵊州市', 330600, 3),
+(330700, '金华市', 330000, 2),
+(330702, '婺城区', 330700, 3),
+(330703, '金东区', 330700, 3),
+(330723, '武义县', 330700, 3),
+(330726, '浦江县', 330700, 3),
+(330727, '磐安县', 330700, 3),
+(330781, '兰溪市', 330700, 3),
+(330782, '义乌市', 330700, 3),
+(330783, '东阳市', 330700, 3),
+(330784, '永康市', 330700, 3),
+(330800, '衢州市', 330000, 2),
+(330802, '柯城区', 330800, 3),
+(330803, '衢江区', 330800, 3),
+(330822, '常山县', 330800, 3),
+(330824, '开化县', 330800, 3),
+(330825, '龙游县', 330800, 3),
+(330881, '江山市', 330800, 3),
+(330900, '舟山市', 330000, 2),
+(330902, '定海区', 330900, 3),
+(330903, '普陀区', 330900, 3),
+(330921, '岱山县', 330900, 3),
+(330922, '嵊泗县', 330900, 3),
+(331000, '台州市', 330000, 2),
+(331002, '椒江区', 331000, 3),
+(331003, '黄岩区', 331000, 3),
+(331004, '路桥区', 331000, 3),
+(331022, '三门县', 331000, 3),
+(331023, '天台县', 331000, 3),
+(331024, '仙居县', 331000, 3),
+(331081, '温岭市', 331000, 3),
+(331082, '临海市', 331000, 3),
+(331083, '玉环市', 331000, 3),
+(331100, '丽水市', 330000, 2),
+(331102, '莲都区', 331100, 3),
+(331121, '青田县', 331100, 3),
+(331122, '缙云县', 331100, 3),
+(331123, '遂昌县', 331100, 3),
+(331124, '松阳县', 331100, 3),
+(331125, '云和县', 331100, 3),
+(331126, '庆元县', 331100, 3),
+(331127, '景宁畲族自治县', 331100, 3),
+(331181, '龙泉市', 331100, 3),
+(340000, '安徽省', 0, 1),
+(340100, '合肥市', 340000, 2),
+(340102, '瑶海区', 340100, 3),
+(340103, '庐阳区', 340100, 3),
+(340104, '蜀山区', 340100, 3),
+(340111, '包河区', 340100, 3),
+(340121, '长丰县', 340100, 3),
+(340122, '肥东县', 340100, 3),
+(340123, '肥西县', 340100, 3),
+(340124, '庐江县', 340100, 3),
+(340181, '巢湖市', 340100, 3),
+(340200, '芜湖市', 340000, 2),
+(340202, '镜湖区', 340200, 3),
+(340203, '弋江区', 340200, 3),
+(340207, '鸠江区', 340200, 3),
+(340208, '三山区', 340200, 3),
+(340221, '芜湖县', 340200, 3),
+(340222, '繁昌县', 340200, 3),
+(340223, '南陵县', 340200, 3),
+(340225, '无为县', 340200, 3),
+(340300, '蚌埠市', 340000, 2),
+(340302, '龙子湖区', 340300, 3),
+(340303, '蚌山区', 340300, 3),
+(340304, '禹会区', 340300, 3),
+(340311, '淮上区', 340300, 3),
+(340321, '怀远县', 340300, 3),
+(340322, '五河县', 340300, 3),
+(340323, '固镇县', 340300, 3),
+(340400, '淮南市', 340000, 2),
+(340402, '大通区', 340400, 3),
+(340403, '田家庵区', 340400, 3),
+(340404, '谢家集区', 340400, 3),
+(340405, '八公山区', 340400, 3),
+(340406, '潘集区', 340400, 3),
+(340421, '凤台县', 340400, 3),
+(340422, '寿县', 340400, 3),
+(340500, '马鞍山市', 340000, 2),
+(340503, '花山区', 340500, 3),
+(340504, '雨山区', 340500, 3),
+(340506, '博望区', 340500, 3),
+(340521, '当涂县', 340500, 3),
+(340522, '含山县', 340500, 3),
+(340523, '和县', 340500, 3),
+(340600, '淮北市', 340000, 2),
+(340602, '杜集区', 340600, 3),
+(340603, '相山区', 340600, 3),
+(340604, '烈山区', 340600, 3),
+(340621, '濉溪县', 340600, 3),
+(340700, '铜陵市', 340000, 2),
+(340705, '铜官区', 340700, 3),
+(340706, '义安区', 340700, 3),
+(340711, '郊区', 340700, 3),
+(340722, '枞阳县', 340700, 3),
+(340800, '安庆市', 340000, 2),
+(340802, '迎江区', 340800, 3),
+(340803, '大观区', 340800, 3),
+(340811, '宜秀区', 340800, 3),
+(340822, '怀宁县', 340800, 3),
+(340824, '潜山县', 340800, 3),
+(340825, '太湖县', 340800, 3),
+(340826, '宿松县', 340800, 3),
+(340827, '望江县', 340800, 3),
+(340828, '岳西县', 340800, 3),
+(340881, '桐城市', 340800, 3),
+(341000, '黄山市', 340000, 2),
+(341002, '屯溪区', 341000, 3),
+(341003, '黄山区', 341000, 3),
+(341004, '徽州区', 341000, 3),
+(341021, '歙县', 341000, 3),
+(341022, '休宁县', 341000, 3),
+(341023, '黟县', 341000, 3),
+(341024, '祁门县', 341000, 3),
+(341100, '滁州市', 340000, 2),
+(341102, '琅琊区', 341100, 3),
+(341103, '南谯区', 341100, 3),
+(341122, '来安县', 341100, 3),
+(341124, '全椒县', 341100, 3),
+(341125, '定远县', 341100, 3),
+(341126, '凤阳县', 341100, 3),
+(341181, '天长市', 341100, 3),
+(341182, '明光市', 341100, 3),
+(341200, '阜阳市', 340000, 2),
+(341202, '颍州区', 341200, 3),
+(341203, '颍东区', 341200, 3),
+(341204, '颍泉区', 341200, 3),
+(341221, '临泉县', 341200, 3),
+(341222, '太和县', 341200, 3),
+(341225, '阜南县', 341200, 3),
+(341226, '颍上县', 341200, 3),
+(341282, '界首市', 341200, 3),
+(341300, '宿州市', 340000, 2),
+(341302, '埇桥区', 341300, 3),
+(341321, '砀山县', 341300, 3),
+(341322, '萧县', 341300, 3),
+(341323, '灵璧县', 341300, 3),
+(341324, '泗县', 341300, 3),
+(341500, '六安市', 340000, 2),
+(341502, '金安区', 341500, 3),
+(341503, '裕安区', 341500, 3),
+(341504, '叶集区', 341500, 3),
+(341522, '霍邱县', 341500, 3),
+(341523, '舒城县', 341500, 3),
+(341524, '金寨县', 341500, 3),
+(341525, '霍山县', 341500, 3),
+(341600, '亳州市', 340000, 2),
+(341602, '谯城区', 341600, 3),
+(341621, '涡阳县', 341600, 3),
+(341622, '蒙城县', 341600, 3),
+(341623, '利辛县', 341600, 3),
+(341700, '池州市', 340000, 2),
+(341702, '贵池区', 341700, 3),
+(341721, '东至县', 341700, 3),
+(341722, '石台县', 341700, 3),
+(341723, '青阳县', 341700, 3),
+(341800, '宣城市', 340000, 2),
+(341802, '宣州区', 341800, 3),
+(341821, '郎溪县', 341800, 3),
+(341822, '广德县', 341800, 3),
+(341823, '泾县', 341800, 3),
+(341824, '绩溪县', 341800, 3),
+(341825, '旌德县', 341800, 3),
+(341881, '宁国市', 341800, 3),
+(350000, '福建省', 0, 1),
+(350100, '福州市', 350000, 2),
+(350102, '鼓楼区', 350100, 3),
+(350103, '台江区', 350100, 3),
+(350104, '仓山区', 350100, 3),
+(350105, '马尾区', 350100, 3),
+(350111, '晋安区', 350100, 3),
+(350112, '长乐区', 350100, 3),
+(350121, '闽侯县', 350100, 3),
+(350122, '连江县', 350100, 3),
+(350123, '罗源县', 350100, 3),
+(350124, '闽清县', 350100, 3),
+(350125, '永泰县', 350100, 3),
+(350128, '平潭县', 350100, 3),
+(350181, '福清市', 350100, 3),
+(350200, '厦门市', 350000, 2),
+(350203, '思明区', 350200, 3),
+(350205, '海沧区', 350200, 3),
+(350206, '湖里区', 350200, 3),
+(350211, '集美区', 350200, 3),
+(350212, '同安区', 350200, 3),
+(350213, '翔安区', 350200, 3),
+(350300, '莆田市', 350000, 2),
+(350302, '城厢区', 350300, 3),
+(350303, '涵江区', 350300, 3),
+(350304, '荔城区', 350300, 3),
+(350305, '秀屿区', 350300, 3),
+(350322, '仙游县', 350300, 3),
+(350400, '三明市', 350000, 2),
+(350402, '梅列区', 350400, 3),
+(350403, '三元区', 350400, 3),
+(350421, '明溪县', 350400, 3),
+(350423, '清流县', 350400, 3),
+(350424, '宁化县', 350400, 3),
+(350425, '大田县', 350400, 3),
+(350426, '尤溪县', 350400, 3),
+(350427, '沙县', 350400, 3),
+(350428, '将乐县', 350400, 3),
+(350429, '泰宁县', 350400, 3),
+(350430, '建宁县', 350400, 3),
+(350481, '永安市', 350400, 3),
+(350500, '泉州市', 350000, 2),
+(350502, '鲤城区', 350500, 3),
+(350503, '丰泽区', 350500, 3),
+(350504, '洛江区', 350500, 3),
+(350505, '泉港区', 350500, 3),
+(350521, '惠安县', 350500, 3),
+(350524, '安溪县', 350500, 3),
+(350525, '永春县', 350500, 3),
+(350526, '德化县', 350500, 3),
+(350527, '金门县', 350500, 3),
+(350581, '石狮市', 350500, 3),
+(350582, '晋江市', 350500, 3),
+(350583, '南安市', 350500, 3),
+(350600, '漳州市', 350000, 2),
+(350602, '芗城区', 350600, 3),
+(350603, '龙文区', 350600, 3),
+(350622, '云霄县', 350600, 3),
+(350623, '漳浦县', 350600, 3),
+(350624, '诏安县', 350600, 3),
+(350625, '长泰县', 350600, 3),
+(350626, '东山县', 350600, 3),
+(350627, '南靖县', 350600, 3),
+(350628, '平和县', 350600, 3),
+(350629, '华安县', 350600, 3),
+(350681, '龙海市', 350600, 3),
+(350700, '南平市', 350000, 2),
+(350702, '延平区', 350700, 3),
+(350703, '建阳区', 350700, 3),
+(350721, '顺昌县', 350700, 3),
+(350722, '浦城县', 350700, 3),
+(350723, '光泽县', 350700, 3),
+(350724, '松溪县', 350700, 3),
+(350725, '政和县', 350700, 3),
+(350781, '邵武市', 350700, 3),
+(350782, '武夷山市', 350700, 3),
+(350783, '建瓯市', 350700, 3),
+(350800, '龙岩市', 350000, 2),
+(350802, '新罗区', 350800, 3),
+(350803, '永定区', 350800, 3),
+(350821, '长汀县', 350800, 3),
+(350823, '上杭县', 350800, 3),
+(350824, '武平县', 350800, 3),
+(350825, '连城县', 350800, 3),
+(350881, '漳平市', 350800, 3),
+(350900, '宁德市', 350000, 2),
+(350902, '蕉城区', 350900, 3),
+(350921, '霞浦县', 350900, 3),
+(350922, '古田县', 350900, 3),
+(350923, '屏南县', 350900, 3),
+(350924, '寿宁县', 350900, 3),
+(350925, '周宁县', 350900, 3),
+(350926, '柘荣县', 350900, 3),
+(350981, '福安市', 350900, 3),
+(350982, '福鼎市', 350900, 3),
+(360000, '江西省', 0, 1),
+(360100, '南昌市', 360000, 2),
+(360102, '东湖区', 360100, 3),
+(360103, '西湖区', 360100, 3),
+(360104, '青云谱区', 360100, 3),
+(360105, '湾里区', 360100, 3),
+(360111, '青山湖区', 360100, 3),
+(360112, '新建区', 360100, 3),
+(360121, '南昌县', 360100, 3),
+(360123, '安义县', 360100, 3),
+(360124, '进贤县', 360100, 3),
+(360200, '景德镇市', 360000, 2),
+(360202, '昌江区', 360200, 3),
+(360203, '珠山区', 360200, 3),
+(360222, '浮梁县', 360200, 3),
+(360281, '乐平市', 360200, 3),
+(360300, '萍乡市', 360000, 2),
+(360302, '安源区', 360300, 3),
+(360313, '湘东区', 360300, 3),
+(360321, '莲花县', 360300, 3),
+(360322, '上栗县', 360300, 3),
+(360323, '芦溪县', 360300, 3),
+(360400, '九江市', 360000, 2),
+(360402, '濂溪区', 360400, 3),
+(360403, '浔阳区', 360400, 3),
+(360404, '柴桑区', 360400, 3),
+(360423, '武宁县', 360400, 3),
+(360424, '修水县', 360400, 3),
+(360425, '永修县', 360400, 3),
+(360426, '德安县', 360400, 3),
+(360428, '都昌县', 360400, 3),
+(360429, '湖口县', 360400, 3),
+(360430, '彭泽县', 360400, 3),
+(360481, '瑞昌市', 360400, 3),
+(360482, '共青城市', 360400, 3),
+(360483, '庐山市', 360400, 3),
+(360500, '新余市', 360000, 2),
+(360502, '渝水区', 360500, 3),
+(360521, '分宜县', 360500, 3),
+(360600, '鹰潭市', 360000, 2),
+(360602, '月湖区', 360600, 3),
+(360622, '余江区', 360600, 3),
+(360681, '贵溪市', 360600, 3),
+(360700, '赣州市', 360000, 2),
+(360702, '章贡区', 360700, 3),
+(360703, '南康区', 360700, 3),
+(360704, '赣县区', 360700, 3),
+(360722, '信丰县', 360700, 3),
+(360723, '大余县', 360700, 3),
+(360724, '上犹县', 360700, 3),
+(360725, '崇义县', 360700, 3),
+(360726, '安远县', 360700, 3),
+(360727, '龙南县', 360700, 3),
+(360728, '定南县', 360700, 3),
+(360729, '全南县', 360700, 3),
+(360730, '宁都县', 360700, 3),
+(360731, '于都县', 360700, 3),
+(360732, '兴国县', 360700, 3),
+(360733, '会昌县', 360700, 3),
+(360734, '寻乌县', 360700, 3),
+(360735, '石城县', 360700, 3),
+(360781, '瑞金市', 360700, 3),
+(360800, '吉安市', 360000, 2),
+(360802, '吉州区', 360800, 3),
+(360803, '青原区', 360800, 3),
+(360821, '吉安县', 360800, 3),
+(360822, '吉水县', 360800, 3),
+(360823, '峡江县', 360800, 3),
+(360824, '新干县', 360800, 3),
+(360825, '永丰县', 360800, 3),
+(360826, '泰和县', 360800, 3),
+(360827, '遂川县', 360800, 3),
+(360828, '万安县', 360800, 3),
+(360829, '安福县', 360800, 3),
+(360830, '永新县', 360800, 3),
+(360881, '井冈山市', 360800, 3),
+(360900, '宜春市', 360000, 2),
+(360902, '袁州区', 360900, 3),
+(360921, '奉新县', 360900, 3),
+(360922, '万载县', 360900, 3),
+(360923, '上高县', 360900, 3),
+(360924, '宜丰县', 360900, 3),
+(360925, '靖安县', 360900, 3),
+(360926, '铜鼓县', 360900, 3),
+(360981, '丰城市', 360900, 3),
+(360982, '樟树市', 360900, 3),
+(360983, '高安市', 360900, 3),
+(361000, '抚州市', 360000, 2),
+(361002, '临川区', 361000, 3),
+(361003, '东乡区', 361000, 3),
+(361021, '南城县', 361000, 3),
+(361022, '黎川县', 361000, 3),
+(361023, '南丰县', 361000, 3),
+(361024, '崇仁县', 361000, 3),
+(361025, '乐安县', 361000, 3),
+(361026, '宜黄县', 361000, 3),
+(361027, '金溪县', 361000, 3),
+(361028, '资溪县', 361000, 3),
+(361030, '广昌县', 361000, 3),
+(361100, '上饶市', 360000, 2),
+(361102, '信州区', 361100, 3),
+(361103, '广丰区', 361100, 3),
+(361121, '上饶县', 361100, 3),
+(361123, '玉山县', 361100, 3),
+(361124, '铅山县', 361100, 3),
+(361125, '横峰县', 361100, 3),
+(361126, '弋阳县', 361100, 3),
+(361127, '余干县', 361100, 3),
+(361128, '鄱阳县', 361100, 3),
+(361129, '万年县', 361100, 3),
+(361130, '婺源县', 361100, 3),
+(361181, '德兴市', 361100, 3),
+(370000, '山东省', 0, 1),
+(370100, '济南市', 370000, 2),
+(370102, '历下区', 370100, 3),
+(370103, '市中区', 370100, 3),
+(370104, '槐荫区', 370100, 3),
+(370105, '天桥区', 370100, 3),
+(370112, '历城区', 370100, 3),
+(370113, '长清区', 370100, 3),
+(370114, '章丘区', 370100, 3),
+(370124, '平阴县', 370100, 3),
+(370125, '济阳县', 370100, 3),
+(370126, '商河县', 370100, 3),
+(370200, '青岛市', 370000, 2),
+(370202, '市南区', 370200, 3),
+(370203, '市北区', 370200, 3),
+(370211, '黄岛区', 370200, 3),
+(370212, '崂山区', 370200, 3),
+(370213, '李沧区', 370200, 3),
+(370214, '城阳区', 370200, 3),
+(370215, '即墨区', 370200, 3),
+(370281, '胶州市', 370200, 3),
+(370283, '平度市', 370200, 3),
+(370285, '莱西市', 370200, 3),
+(370300, '淄博市', 370000, 2),
+(370302, '淄川区', 370300, 3),
+(370303, '张店区', 370300, 3),
+(370304, '博山区', 370300, 3),
+(370305, '临淄区', 370300, 3),
+(370306, '周村区', 370300, 3),
+(370321, '桓台县', 370300, 3),
+(370322, '高青县', 370300, 3),
+(370323, '沂源县', 370300, 3),
+(370400, '枣庄市', 370000, 2),
+(370402, '市中区', 370400, 3),
+(370403, '薛城区', 370400, 3),
+(370404, '峄城区', 370400, 3),
+(370405, '台儿庄区', 370400, 3),
+(370406, '山亭区', 370400, 3),
+(370481, '滕州市', 370400, 3),
+(370500, '东营市', 370000, 2),
+(370502, '东营区', 370500, 3),
+(370503, '河口区', 370500, 3),
+(370505, '垦利区', 370500, 3),
+(370522, '利津县', 370500, 3),
+(370523, '广饶县', 370500, 3),
+(370600, '烟台市', 370000, 2),
+(370602, '芝罘区', 370600, 3),
+(370611, '福山区', 370600, 3),
+(370612, '牟平区', 370600, 3),
+(370613, '莱山区', 370600, 3),
+(370634, '长岛县', 370600, 3),
+(370681, '龙口市', 370600, 3),
+(370682, '莱阳市', 370600, 3),
+(370683, '莱州市', 370600, 3),
+(370684, '蓬莱市', 370600, 3),
+(370685, '招远市', 370600, 3),
+(370686, '栖霞市', 370600, 3),
+(370687, '海阳市', 370600, 3),
+(370700, '潍坊市', 370000, 2),
+(370702, '潍城区', 370700, 3),
+(370703, '寒亭区', 370700, 3),
+(370704, '坊子区', 370700, 3),
+(370705, '奎文区', 370700, 3),
+(370724, '临朐县', 370700, 3),
+(370725, '昌乐县', 370700, 3),
+(370781, '青州市', 370700, 3),
+(370782, '诸城市', 370700, 3),
+(370783, '寿光市', 370700, 3),
+(370784, '安丘市', 370700, 3),
+(370785, '高密市', 370700, 3),
+(370786, '昌邑市', 370700, 3),
+(370800, '济宁市', 370000, 2),
+(370811, '任城区', 370800, 3),
+(370812, '兖州区', 370800, 3),
+(370826, '微山县', 370800, 3),
+(370827, '鱼台县', 370800, 3),
+(370828, '金乡县', 370800, 3),
+(370829, '嘉祥县', 370800, 3),
+(370830, '汶上县', 370800, 3),
+(370831, '泗水县', 370800, 3),
+(370832, '梁山县', 370800, 3),
+(370881, '曲阜市', 370800, 3),
+(370883, '邹城市', 370800, 3),
+(370900, '泰安市', 370000, 2),
+(370902, '泰山区', 370900, 3),
+(370911, '岱岳区', 370900, 3),
+(370921, '宁阳县', 370900, 3),
+(370923, '东平县', 370900, 3),
+(370982, '新泰市', 370900, 3),
+(370983, '肥城市', 370900, 3),
+(371000, '威海市', 370000, 2),
+(371002, '环翠区', 371000, 3),
+(371003, '文登区', 371000, 3),
+(371082, '荣成市', 371000, 3),
+(371083, '乳山市', 371000, 3),
+(371100, '日照市', 370000, 2),
+(371102, '东港区', 371100, 3),
+(371103, '岚山区', 371100, 3),
+(371121, '五莲县', 371100, 3),
+(371122, '莒县', 371100, 3),
+(371200, '莱芜市', 370000, 2),
+(371202, '莱城区', 371200, 3),
+(371203, '钢城区', 371200, 3),
+(371300, '临沂市', 370000, 2),
+(371302, '兰山区', 371300, 3),
+(371311, '罗庄区', 371300, 3),
+(371312, '河东区', 371300, 3),
+(371321, '沂南县', 371300, 3),
+(371322, '郯城县', 371300, 3),
+(371323, '沂水县', 371300, 3),
+(371324, '兰陵县', 371300, 3),
+(371325, '费县', 371300, 3),
+(371326, '平邑县', 371300, 3),
+(371327, '莒南县', 371300, 3),
+(371328, '蒙阴县', 371300, 3),
+(371329, '临沭县', 371300, 3),
+(371400, '德州市', 370000, 2),
+(371402, '德城区', 371400, 3),
+(371403, '陵城区', 371400, 3),
+(371422, '宁津县', 371400, 3),
+(371423, '庆云县', 371400, 3),
+(371424, '临邑县', 371400, 3),
+(371425, '齐河县', 371400, 3),
+(371426, '平原县', 371400, 3),
+(371427, '夏津县', 371400, 3),
+(371428, '武城县', 371400, 3),
+(371481, '乐陵市', 371400, 3),
+(371482, '禹城市', 371400, 3),
+(371500, '聊城市', 370000, 2),
+(371502, '东昌府区', 371500, 3),
+(371521, '阳谷县', 371500, 3),
+(371522, '莘县', 371500, 3),
+(371523, '茌平县', 371500, 3),
+(371524, '东阿县', 371500, 3),
+(371525, '冠县', 371500, 3),
+(371526, '高唐县', 371500, 3),
+(371581, '临清市', 371500, 3),
+(371600, '滨州市', 370000, 2),
+(371602, '滨城区', 371600, 3),
+(371603, '沾化区', 371600, 3),
+(371621, '惠民县', 371600, 3),
+(371622, '阳信县', 371600, 3),
+(371623, '无棣县', 371600, 3),
+(371625, '博兴县', 371600, 3),
+(371626, '邹平县', 371600, 3),
+(371700, '菏泽市', 370000, 2),
+(371702, '牡丹区', 371700, 3),
+(371703, '定陶区', 371700, 3),
+(371721, '曹县', 371700, 3),
+(371722, '单县', 371700, 3),
+(371723, '成武县', 371700, 3),
+(371724, '巨野县', 371700, 3),
+(371725, '郓城县', 371700, 3),
+(371726, '鄄城县', 371700, 3),
+(371728, '东明县', 371700, 3),
+(410000, '河南省', 0, 1),
+(410100, '郑州市', 410000, 2),
+(410102, '中原区', 410100, 3),
+(410103, '二七区', 410100, 3),
+(410104, '管城回族区', 410100, 3),
+(410105, '金水区', 410100, 3),
+(410106, '上街区', 410100, 3),
+(410108, '惠济区', 410100, 3),
+(410122, '中牟县', 410100, 3),
+(410181, '巩义市', 410100, 3),
+(410182, '荥阳市', 410100, 3),
+(410183, '新密市', 410100, 3),
+(410184, '新郑市', 410100, 3),
+(410185, '登封市', 410100, 3),
+(410200, '开封市', 410000, 2),
+(410202, '龙亭区', 410200, 3),
+(410203, '顺河回族区', 410200, 3),
+(410204, '鼓楼区', 410200, 3),
+(410205, '禹王台区', 410200, 3),
+(410212, '祥符区', 410200, 3),
+(410221, '杞县', 410200, 3),
+(410222, '通许县', 410200, 3),
+(410223, '尉氏县', 410200, 3),
+(410225, '兰考县', 410200, 3),
+(410300, '洛阳市', 410000, 2),
+(410302, '老城区', 410300, 3),
+(410303, '西工区', 410300, 3),
+(410304, '瀍河回族区', 410300, 3),
+(410305, '涧西区', 410300, 3),
+(410306, '吉利区', 410300, 3),
+(410311, '洛龙区', 410300, 3),
+(410322, '孟津县', 410300, 3),
+(410323, '新安县', 410300, 3),
+(410324, '栾川县', 410300, 3),
+(410325, '嵩县', 410300, 3),
+(410326, '汝阳县', 410300, 3),
+(410327, '宜阳县', 410300, 3),
+(410328, '洛宁县', 410300, 3),
+(410329, '伊川县', 410300, 3),
+(410381, '偃师市', 410300, 3),
+(410400, '平顶山市', 410000, 2),
+(410402, '新华区', 410400, 3),
+(410403, '卫东区', 410400, 3),
+(410404, '石龙区', 410400, 3),
+(410411, '湛河区', 410400, 3),
+(410421, '宝丰县', 410400, 3),
+(410422, '叶县', 410400, 3),
+(410423, '鲁山县', 410400, 3),
+(410425, '郏县', 410400, 3),
+(410481, '舞钢市', 410400, 3),
+(410482, '汝州市', 410400, 3),
+(410500, '安阳市', 410000, 2),
+(410502, '文峰区', 410500, 3),
+(410503, '北关区', 410500, 3),
+(410505, '殷都区', 410500, 3),
+(410506, '龙安区', 410500, 3),
+(410522, '安阳县', 410500, 3),
+(410523, '汤阴县', 410500, 3),
+(410526, '滑县', 410500, 3),
+(410527, '内黄县', 410500, 3),
+(410581, '林州市', 410500, 3),
+(410600, '鹤壁市', 410000, 2),
+(410602, '鹤山区', 410600, 3),
+(410603, '山城区', 410600, 3),
+(410611, '淇滨区', 410600, 3),
+(410621, '浚县', 410600, 3),
+(410622, '淇县', 410600, 3),
+(410700, '新乡市', 410000, 2),
+(410702, '红旗区', 410700, 3),
+(410703, '卫滨区', 410700, 3),
+(410704, '凤泉区', 410700, 3),
+(410711, '牧野区', 410700, 3),
+(410721, '新乡县', 410700, 3),
+(410724, '获嘉县', 410700, 3),
+(410725, '原阳县', 410700, 3),
+(410726, '延津县', 410700, 3),
+(410727, '封丘县', 410700, 3),
+(410728, '长垣县', 410700, 3),
+(410781, '卫辉市', 410700, 3),
+(410782, '辉县市', 410700, 3),
+(410800, '焦作市', 410000, 2),
+(410802, '解放区', 410800, 3),
+(410803, '中站区', 410800, 3),
+(410804, '马村区', 410800, 3),
+(410811, '山阳区', 410800, 3),
+(410821, '修武县', 410800, 3),
+(410822, '博爱县', 410800, 3),
+(410823, '武陟县', 410800, 3),
+(410825, '温县', 410800, 3),
+(410882, '沁阳市', 410800, 3),
+(410883, '孟州市', 410800, 3),
+(410900, '濮阳市', 410000, 2),
+(410902, '华龙区', 410900, 3),
+(410922, '清丰县', 410900, 3),
+(410923, '南乐县', 410900, 3),
+(410926, '范县', 410900, 3),
+(410927, '台前县', 410900, 3),
+(410928, '濮阳县', 410900, 3),
+(411000, '许昌市', 410000, 2),
+(411002, '魏都区', 411000, 3),
+(411003, '建安区', 411000, 3),
+(411024, '鄢陵县', 411000, 3),
+(411025, '襄城县', 411000, 3),
+(411081, '禹州市', 411000, 3),
+(411082, '长葛市', 411000, 3),
+(411100, '漯河市', 410000, 2),
+(411102, '源汇区', 411100, 3),
+(411103, '郾城区', 411100, 3),
+(411104, '召陵区', 411100, 3),
+(411121, '舞阳县', 411100, 3),
+(411122, '临颍县', 411100, 3),
+(411200, '三门峡市', 410000, 2),
+(411202, '湖滨区', 411200, 3),
+(411203, '陕州区', 411200, 3),
+(411221, '渑池县', 411200, 3),
+(411224, '卢氏县', 411200, 3),
+(411281, '义马市', 411200, 3),
+(411282, '灵宝市', 411200, 3),
+(411300, '南阳市', 410000, 2),
+(411302, '宛城区', 411300, 3),
+(411303, '卧龙区', 411300, 3),
+(411321, '南召县', 411300, 3),
+(411322, '方城县', 411300, 3),
+(411323, '西峡县', 411300, 3),
+(411324, '镇平县', 411300, 3),
+(411325, '内乡县', 411300, 3),
+(411326, '淅川县', 411300, 3),
+(411327, '社旗县', 411300, 3),
+(411328, '唐河县', 411300, 3),
+(411329, '新野县', 411300, 3),
+(411330, '桐柏县', 411300, 3),
+(411381, '邓州市', 411300, 3),
+(411400, '商丘市', 410000, 2),
+(411402, '梁园区', 411400, 3),
+(411403, '睢阳区', 411400, 3),
+(411421, '民权县', 411400, 3),
+(411422, '睢县', 411400, 3),
+(411423, '宁陵县', 411400, 3),
+(411424, '柘城县', 411400, 3),
+(411425, '虞城县', 411400, 3),
+(411426, '夏邑县', 411400, 3),
+(411481, '永城市', 411400, 3),
+(411500, '信阳市', 410000, 2),
+(411502, '浉河区', 411500, 3),
+(411503, '平桥区', 411500, 3),
+(411521, '罗山县', 411500, 3),
+(411522, '光山县', 411500, 3),
+(411523, '新县', 411500, 3),
+(411524, '商城县', 411500, 3),
+(411525, '固始县', 411500, 3),
+(411526, '潢川县', 411500, 3),
+(411527, '淮滨县', 411500, 3),
+(411528, '息县', 411500, 3),
+(411600, '周口市', 410000, 2),
+(411602, '川汇区', 411600, 3),
+(411621, '扶沟县', 411600, 3),
+(411622, '西华县', 411600, 3),
+(411623, '商水县', 411600, 3),
+(411624, '沈丘县', 411600, 3),
+(411625, '郸城县', 411600, 3),
+(411626, '淮阳县', 411600, 3),
+(411627, '太康县', 411600, 3),
+(411628, '鹿邑县', 411600, 3),
+(411681, '项城市', 411600, 3),
+(411700, '驻马店市', 410000, 2),
+(411702, '驿城区', 411700, 3),
+(411721, '西平县', 411700, 3),
+(411722, '上蔡县', 411700, 3),
+(411723, '平舆县', 411700, 3),
+(411724, '正阳县', 411700, 3),
+(411725, '确山县', 411700, 3),
+(411726, '泌阳县', 411700, 3),
+(411727, '汝南县', 411700, 3),
+(411728, '遂平县', 411700, 3),
+(411729, '新蔡县', 411700, 3),
+(419000, '省直辖县级行政区划', 410000, 2),
+(419001, '济源市', 419000, 3),
+(420000, '湖北省', 0, 1),
+(420100, '武汉市', 420000, 2),
+(420102, '江岸区', 420100, 3),
+(420103, '江汉区', 420100, 3),
+(420104, '硚口区', 420100, 3),
+(420105, '汉阳区', 420100, 3),
+(420106, '武昌区', 420100, 3),
+(420107, '青山区', 420100, 3),
+(420111, '洪山区', 420100, 3),
+(420112, '东西湖区', 420100, 3),
+(420113, '汉南区', 420100, 3),
+(420114, '蔡甸区', 420100, 3),
+(420115, '江夏区', 420100, 3),
+(420116, '黄陂区', 420100, 3),
+(420117, '新洲区', 420100, 3),
+(420200, '黄石市', 420000, 2),
+(420202, '黄石港区', 420200, 3),
+(420203, '西塞山区', 420200, 3),
+(420204, '下陆区', 420200, 3),
+(420205, '铁山区', 420200, 3),
+(420222, '阳新县', 420200, 3),
+(420281, '大冶市', 420200, 3),
+(420300, '十堰市', 420000, 2),
+(420302, '茅箭区', 420300, 3),
+(420303, '张湾区', 420300, 3),
+(420304, '郧阳区', 420300, 3),
+(420322, '郧西县', 420300, 3),
+(420323, '竹山县', 420300, 3),
+(420324, '竹溪县', 420300, 3),
+(420325, '房县', 420300, 3),
+(420381, '丹江口市', 420300, 3),
+(420500, '宜昌市', 420000, 2),
+(420502, '西陵区', 420500, 3),
+(420503, '伍家岗区', 420500, 3),
+(420504, '点军区', 420500, 3),
+(420505, '猇亭区', 420500, 3),
+(420506, '夷陵区', 420500, 3),
+(420525, '远安县', 420500, 3),
+(420526, '兴山县', 420500, 3),
+(420527, '秭归县', 420500, 3),
+(420528, '长阳土家族自治县', 420500, 3),
+(420529, '五峰土家族自治县', 420500, 3),
+(420581, '宜都市', 420500, 3),
+(420582, '当阳市', 420500, 3),
+(420583, '枝江市', 420500, 3),
+(420600, '襄阳市', 420000, 2),
+(420602, '襄城区', 420600, 3),
+(420606, '樊城区', 420600, 3),
+(420607, '襄州区', 420600, 3),
+(420624, '南漳县', 420600, 3),
+(420625, '谷城县', 420600, 3),
+(420626, '保康县', 420600, 3),
+(420682, '老河口市', 420600, 3),
+(420683, '枣阳市', 420600, 3),
+(420684, '宜城市', 420600, 3),
+(420700, '鄂州市', 420000, 2),
+(420702, '梁子湖区', 420700, 3),
+(420703, '华容区', 420700, 3),
+(420704, '鄂城区', 420700, 3),
+(420800, '荆门市', 420000, 2),
+(420802, '东宝区', 420800, 3),
+(420804, '掇刀区', 420800, 3),
+(420821, '京山县', 420800, 3),
+(420822, '沙洋县', 420800, 3),
+(420881, '钟祥市', 420800, 3),
+(420900, '孝感市', 420000, 2),
+(420902, '孝南区', 420900, 3),
+(420921, '孝昌县', 420900, 3),
+(420922, '大悟县', 420900, 3),
+(420923, '云梦县', 420900, 3),
+(420981, '应城市', 420900, 3),
+(420982, '安陆市', 420900, 3),
+(420984, '汉川市', 420900, 3),
+(421000, '荆州市', 420000, 2),
+(421002, '沙市区', 421000, 3),
+(421003, '荆州区', 421000, 3),
+(421022, '公安县', 421000, 3),
+(421023, '监利县', 421000, 3),
+(421024, '江陵县', 421000, 3),
+(421081, '石首市', 421000, 3),
+(421083, '洪湖市', 421000, 3),
+(421087, '松滋市', 421000, 3),
+(421100, '黄冈市', 420000, 2),
+(421102, '黄州区', 421100, 3),
+(421121, '团风县', 421100, 3),
+(421122, '红安县', 421100, 3),
+(421123, '罗田县', 421100, 3),
+(421124, '英山县', 421100, 3),
+(421125, '浠水县', 421100, 3),
+(421126, '蕲春县', 421100, 3),
+(421127, '黄梅县', 421100, 3),
+(421181, '麻城市', 421100, 3),
+(421182, '武穴市', 421100, 3),
+(421200, '咸宁市', 420000, 2),
+(421202, '咸安区', 421200, 3),
+(421221, '嘉鱼县', 421200, 3),
+(421222, '通城县', 421200, 3),
+(421223, '崇阳县', 421200, 3),
+(421224, '通山县', 421200, 3),
+(421281, '赤壁市', 421200, 3),
+(421300, '随州市', 420000, 2),
+(421303, '曾都区', 421300, 3),
+(421321, '随县', 421300, 3),
+(421381, '广水市', 421300, 3),
+(422800, '恩施土家族苗族自治州', 420000, 2),
+(422801, '恩施市', 422800, 3),
+(422802, '利川市', 422800, 3),
+(422822, '建始县', 422800, 3),
+(422823, '巴东县', 422800, 3),
+(422825, '宣恩县', 422800, 3),
+(422826, '咸丰县', 422800, 3),
+(422827, '来凤县', 422800, 3),
+(422828, '鹤峰县', 422800, 3),
+(429000, '省直辖县级行政区划', 420000, 2),
+(429004, '仙桃市', 429000, 3),
+(429005, '潜江市', 429000, 3),
+(429006, '天门市', 429000, 3),
+(429021, '神农架林区', 429000, 3),
+(430000, '湖南省', 0, 1),
+(430100, '长沙市', 430000, 2),
+(430102, '芙蓉区', 430100, 3),
+(430103, '天心区', 430100, 3),
+(430104, '岳麓区', 430100, 3),
+(430105, '开福区', 430100, 3),
+(430111, '雨花区', 430100, 3),
+(430112, '望城区', 430100, 3),
+(430121, '长沙县', 430100, 3),
+(430181, '浏阳市', 430100, 3),
+(430182, '宁乡市', 430100, 3),
+(430200, '株洲市', 430000, 2),
+(430202, '荷塘区', 430200, 3),
+(430203, '芦淞区', 430200, 3),
+(430204, '石峰区', 430200, 3),
+(430211, '天元区', 430200, 3),
+(430221, '株洲县', 430200, 3),
+(430223, '攸县', 430200, 3),
+(430224, '茶陵县', 430200, 3),
+(430225, '炎陵县', 430200, 3),
+(430281, '醴陵市', 430200, 3),
+(430300, '湘潭市', 430000, 2),
+(430302, '雨湖区', 430300, 3),
+(430304, '岳塘区', 430300, 3),
+(430321, '湘潭县', 430300, 3),
+(430381, '湘乡市', 430300, 3),
+(430382, '韶山市', 430300, 3),
+(430400, '衡阳市', 430000, 2),
+(430405, '珠晖区', 430400, 3),
+(430406, '雁峰区', 430400, 3),
+(430407, '石鼓区', 430400, 3),
+(430408, '蒸湘区', 430400, 3),
+(430412, '南岳区', 430400, 3),
+(430421, '衡阳县', 430400, 3),
+(430422, '衡南县', 430400, 3),
+(430423, '衡山县', 430400, 3),
+(430424, '衡东县', 430400, 3),
+(430426, '祁东县', 430400, 3),
+(430481, '耒阳市', 430400, 3),
+(430482, '常宁市', 430400, 3),
+(430500, '邵阳市', 430000, 2),
+(430502, '双清区', 430500, 3),
+(430503, '大祥区', 430500, 3),
+(430511, '北塔区', 430500, 3),
+(430521, '邵东县', 430500, 3),
+(430522, '新邵县', 430500, 3),
+(430523, '邵阳县', 430500, 3),
+(430524, '隆回县', 430500, 3),
+(430525, '洞口县', 430500, 3),
+(430527, '绥宁县', 430500, 3),
+(430528, '新宁县', 430500, 3),
+(430529, '城步苗族自治县', 430500, 3),
+(430581, '武冈市', 430500, 3),
+(430600, '岳阳市', 430000, 2),
+(430602, '岳阳楼区', 430600, 3),
+(430603, '云溪区', 430600, 3),
+(430611, '君山区', 430600, 3),
+(430621, '岳阳县', 430600, 3),
+(430623, '华容县', 430600, 3),
+(430624, '湘阴县', 430600, 3),
+(430626, '平江县', 430600, 3),
+(430681, '汨罗市', 430600, 3),
+(430682, '临湘市', 430600, 3),
+(430700, '常德市', 430000, 2),
+(430702, '武陵区', 430700, 3),
+(430703, '鼎城区', 430700, 3),
+(430721, '安乡县', 430700, 3),
+(430722, '汉寿县', 430700, 3),
+(430723, '澧县', 430700, 3),
+(430724, '临澧县', 430700, 3),
+(430725, '桃源县', 430700, 3),
+(430726, '石门县', 430700, 3),
+(430781, '津市市', 430700, 3),
+(430800, '张家界市', 430000, 2),
+(430802, '永定区', 430800, 3),
+(430811, '武陵源区', 430800, 3),
+(430821, '慈利县', 430800, 3),
+(430822, '桑植县', 430800, 3),
+(430900, '益阳市', 430000, 2),
+(430902, '资阳区', 430900, 3),
+(430903, '赫山区', 430900, 3),
+(430921, '南县', 430900, 3),
+(430922, '桃江县', 430900, 3),
+(430923, '安化县', 430900, 3),
+(430981, '沅江市', 430900, 3),
+(431000, '郴州市', 430000, 2),
+(431002, '北湖区', 431000, 3),
+(431003, '苏仙区', 431000, 3),
+(431021, '桂阳县', 431000, 3),
+(431022, '宜章县', 431000, 3),
+(431023, '永兴县', 431000, 3),
+(431024, '嘉禾县', 431000, 3),
+(431025, '临武县', 431000, 3),
+(431026, '汝城县', 431000, 3),
+(431027, '桂东县', 431000, 3),
+(431028, '安仁县', 431000, 3),
+(431081, '资兴市', 431000, 3),
+(431100, '永州市', 430000, 2),
+(431102, '零陵区', 431100, 3),
+(431103, '冷水滩区', 431100, 3),
+(431121, '祁阳县', 431100, 3),
+(431122, '东安县', 431100, 3),
+(431123, '双牌县', 431100, 3),
+(431124, '道县', 431100, 3),
+(431125, '江永县', 431100, 3),
+(431126, '宁远县', 431100, 3),
+(431127, '蓝山县', 431100, 3),
+(431128, '新田县', 431100, 3),
+(431129, '江华瑶族自治县', 431100, 3);
+INSERT INTO `__PREFIX__shopro_area` (`id`, `name`, `pid`, `level`) VALUES
+(431200, '怀化市', 430000, 2),
+(431202, '鹤城区', 431200, 3),
+(431221, '中方县', 431200, 3),
+(431222, '沅陵县', 431200, 3),
+(431223, '辰溪县', 431200, 3),
+(431224, '溆浦县', 431200, 3),
+(431225, '会同县', 431200, 3),
+(431226, '麻阳苗族自治县', 431200, 3),
+(431227, '新晃侗族自治县', 431200, 3),
+(431228, '芷江侗族自治县', 431200, 3),
+(431229, '靖州苗族侗族自治县', 431200, 3),
+(431230, '通道侗族自治县', 431200, 3),
+(431281, '洪江市', 431200, 3),
+(431300, '娄底市', 430000, 2),
+(431302, '娄星区', 431300, 3),
+(431321, '双峰县', 431300, 3),
+(431322, '新化县', 431300, 3),
+(431381, '冷水江市', 431300, 3),
+(431382, '涟源市', 431300, 3),
+(433100, '湘西土家族苗族自治州', 430000, 2),
+(433101, '吉首市', 433100, 3),
+(433122, '泸溪县', 433100, 3),
+(433123, '凤凰县', 433100, 3),
+(433124, '花垣县', 433100, 3),
+(433125, '保靖县', 433100, 3),
+(433126, '古丈县', 433100, 3),
+(433127, '永顺县', 433100, 3),
+(433130, '龙山县', 433100, 3),
+(440000, '广东省', 0, 1),
+(440100, '广州市', 440000, 2),
+(440103, '荔湾区', 440100, 3),
+(440104, '越秀区', 440100, 3),
+(440105, '海珠区', 440100, 3),
+(440106, '天河区', 440100, 3),
+(440111, '白云区', 440100, 3),
+(440112, '黄埔区', 440100, 3),
+(440113, '番禺区', 440100, 3),
+(440114, '花都区', 440100, 3),
+(440115, '南沙区', 440100, 3),
+(440117, '从化区', 440100, 3),
+(440118, '增城区', 440100, 3),
+(440200, '韶关市', 440000, 2),
+(440203, '武江区', 440200, 3),
+(440204, '浈江区', 440200, 3),
+(440205, '曲江区', 440200, 3),
+(440222, '始兴县', 440200, 3),
+(440224, '仁化县', 440200, 3),
+(440229, '翁源县', 440200, 3),
+(440232, '乳源瑶族自治县', 440200, 3),
+(440233, '新丰县', 440200, 3),
+(440281, '乐昌市', 440200, 3),
+(440282, '南雄市', 440200, 3),
+(440300, '深圳市', 440000, 2),
+(440303, '罗湖区', 440300, 3),
+(440304, '福田区', 440300, 3),
+(440305, '南山区', 440300, 3),
+(440306, '宝安区', 440300, 3),
+(440307, '龙岗区', 440300, 3),
+(440308, '盐田区', 440300, 3),
+(440309, '龙华区', 440300, 3),
+(440310, '坪山区', 440300, 3),
+(440400, '珠海市', 440000, 2),
+(440402, '香洲区', 440400, 3),
+(440403, '斗门区', 440400, 3),
+(440404, '金湾区', 440400, 3),
+(440500, '汕头市', 440000, 2),
+(440507, '龙湖区', 440500, 3),
+(440511, '金平区', 440500, 3),
+(440512, '濠江区', 440500, 3),
+(440513, '潮阳区', 440500, 3),
+(440514, '潮南区', 440500, 3),
+(440515, '澄海区', 440500, 3),
+(440523, '南澳县', 440500, 3),
+(440600, '佛山市', 440000, 2),
+(440604, '禅城区', 440600, 3),
+(440605, '南海区', 440600, 3),
+(440606, '顺德区', 440600, 3),
+(440607, '三水区', 440600, 3),
+(440608, '高明区', 440600, 3),
+(440700, '江门市', 440000, 2),
+(440703, '蓬江区', 440700, 3),
+(440704, '江海区', 440700, 3),
+(440705, '新会区', 440700, 3),
+(440781, '台山市', 440700, 3),
+(440783, '开平市', 440700, 3),
+(440784, '鹤山市', 440700, 3),
+(440785, '恩平市', 440700, 3),
+(440800, '湛江市', 440000, 2),
+(440802, '赤坎区', 440800, 3),
+(440803, '霞山区', 440800, 3),
+(440804, '坡头区', 440800, 3),
+(440811, '麻章区', 440800, 3),
+(440823, '遂溪县', 440800, 3),
+(440825, '徐闻县', 440800, 3),
+(440881, '廉江市', 440800, 3),
+(440882, '雷州市', 440800, 3),
+(440883, '吴川市', 440800, 3),
+(440900, '茂名市', 440000, 2),
+(440902, '茂南区', 440900, 3),
+(440904, '电白区', 440900, 3),
+(440981, '高州市', 440900, 3),
+(440982, '化州市', 440900, 3),
+(440983, '信宜市', 440900, 3),
+(441200, '肇庆市', 440000, 2),
+(441202, '端州区', 441200, 3),
+(441203, '鼎湖区', 441200, 3),
+(441204, '高要区', 441200, 3),
+(441223, '广宁县', 441200, 3),
+(441224, '怀集县', 441200, 3),
+(441225, '封开县', 441200, 3),
+(441226, '德庆县', 441200, 3),
+(441284, '四会市', 441200, 3),
+(441300, '惠州市', 440000, 2),
+(441302, '惠城区', 441300, 3),
+(441303, '惠阳区', 441300, 3),
+(441322, '博罗县', 441300, 3),
+(441323, '惠东县', 441300, 3),
+(441324, '龙门县', 441300, 3),
+(441400, '梅州市', 440000, 2),
+(441402, '梅江区', 441400, 3),
+(441403, '梅县区', 441400, 3),
+(441422, '大埔县', 441400, 3),
+(441423, '丰顺县', 441400, 3),
+(441424, '五华县', 441400, 3),
+(441426, '平远县', 441400, 3),
+(441427, '蕉岭县', 441400, 3),
+(441481, '兴宁市', 441400, 3),
+(441500, '汕尾市', 440000, 2),
+(441502, '城区', 441500, 3),
+(441521, '海丰县', 441500, 3),
+(441523, '陆河县', 441500, 3),
+(441581, '陆丰市', 441500, 3),
+(441600, '河源市', 440000, 2),
+(441602, '源城区', 441600, 3),
+(441621, '紫金县', 441600, 3),
+(441622, '龙川县', 441600, 3),
+(441623, '连平县', 441600, 3),
+(441624, '和平县', 441600, 3),
+(441625, '东源县', 441600, 3),
+(441700, '阳江市', 440000, 2),
+(441702, '江城区', 441700, 3),
+(441704, '阳东区', 441700, 3),
+(441721, '阳西县', 441700, 3),
+(441781, '阳春市', 441700, 3),
+(441800, '清远市', 440000, 2),
+(441802, '清城区', 441800, 3),
+(441803, '清新区', 441800, 3),
+(441821, '佛冈县', 441800, 3),
+(441823, '阳山县', 441800, 3),
+(441825, '连山壮族瑶族自治县', 441800, 3),
+(441826, '连南瑶族自治县', 441800, 3),
+(441881, '英德市', 441800, 3),
+(441882, '连州市', 441800, 3),
+(441900, '东莞市', 440000, 2),
+(441901, '东城街道', 441900, 3),
+(441902, '南城街道', 441900, 3),
+(441903, '万江街道', 441900, 3),
+(441904, '莞城街道', 441900, 3),
+(441905, '石碣镇', 441900, 3),
+(441906, '石龙镇', 441900, 3),
+(441907, '茶山镇', 441900, 3),
+(441908, '石排镇', 441900, 3),
+(441909, '企石镇', 441900, 3),
+(441910, '横沥镇', 441900, 3),
+(441911, '桥头镇', 441900, 3),
+(441912, '谢岗镇', 441900, 3),
+(441913, '东坑镇', 441900, 3),
+(441914, '常平镇', 441900, 3),
+(441915, '寮步镇', 441900, 3),
+(441916, '樟木头镇', 441900, 3),
+(441917, '大朗镇', 441900, 3),
+(441918, '黄江镇', 441900, 3),
+(441919, '清溪镇', 441900, 3),
+(441920, '塘厦镇', 441900, 3),
+(441921, '凤岗镇', 441900, 3),
+(441922, '大岭山镇', 441900, 3),
+(441923, '长安镇', 441900, 3),
+(441924, '虎门镇', 441900, 3),
+(441925, '厚街镇', 441900, 3),
+(441926, '沙田镇', 441900, 3),
+(441927, '道滘镇', 441900, 3),
+(441928, '洪梅镇', 441900, 3),
+(441929, '麻涌镇', 441900, 3),
+(441930, '望牛墩镇', 441900, 3),
+(441931, '中堂镇', 441900, 3),
+(441932, '高埗镇', 441900, 3),
+(441933, '松山湖管委会', 441900, 3),
+(441934, '虎门港管委会', 441900, 3),
+(441935, '东莞生态园', 441900, 3),
+(442000, '中山市', 440000, 2),
+(442001, '石岐区街道', 442000, 3),
+(442002, '东区街道', 442000, 3),
+(442003, '火炬开发区', 442000, 3),
+(442004, '西区街道', 442000, 3),
+(442005, '南区街道', 442000, 3),
+(442006, '五桂山街道', 442000, 3),
+(442007, '小榄镇', 442000, 3),
+(442008, '黄圃镇', 442000, 3),
+(442009, '民众镇', 442000, 3),
+(442010, '东凤镇', 442000, 3),
+(442011, '东升镇', 442000, 3),
+(442012, '古镇镇', 442000, 3),
+(442013, '沙溪镇', 442000, 3),
+(442014, '坦洲镇', 442000, 3),
+(442015, '港口镇', 442000, 3),
+(442016, '三角镇', 442000, 3),
+(442017, '横栏镇', 442000, 3),
+(442018, '南头镇', 442000, 3),
+(442019, '阜沙镇', 442000, 3),
+(442020, '南朗镇', 442000, 3),
+(442021, '三乡镇', 442000, 3),
+(442022, '板芙镇', 442000, 3),
+(442023, '大涌镇', 442000, 3),
+(442024, '神湾镇', 442000, 3),
+(445100, '潮州市', 440000, 2),
+(445102, '湘桥区', 445100, 3),
+(445103, '潮安区', 445100, 3),
+(445122, '饶平县', 445100, 3),
+(445200, '揭阳市', 440000, 2),
+(445202, '榕城区', 445200, 3),
+(445203, '揭东区', 445200, 3),
+(445222, '揭西县', 445200, 3),
+(445224, '惠来县', 445200, 3),
+(445281, '普宁市', 445200, 3),
+(445300, '云浮市', 440000, 2),
+(445302, '云城区', 445300, 3),
+(445303, '云安区', 445300, 3),
+(445321, '新兴县', 445300, 3),
+(445322, '郁南县', 445300, 3),
+(445381, '罗定市', 445300, 3),
+(450000, '广西壮族自治区', 0, 1),
+(450100, '南宁市', 450000, 2),
+(450102, '兴宁区', 450100, 3),
+(450103, '青秀区', 450100, 3),
+(450105, '江南区', 450100, 3),
+(450107, '西乡塘区', 450100, 3),
+(450108, '良庆区', 450100, 3),
+(450109, '邕宁区', 450100, 3),
+(450110, '武鸣区', 450100, 3),
+(450123, '隆安县', 450100, 3),
+(450124, '马山县', 450100, 3),
+(450125, '上林县', 450100, 3),
+(450126, '宾阳县', 450100, 3),
+(450127, '横县', 450100, 3),
+(450200, '柳州市', 450000, 2),
+(450202, '城中区', 450200, 3),
+(450203, '鱼峰区', 450200, 3),
+(450204, '柳南区', 450200, 3),
+(450205, '柳北区', 450200, 3),
+(450206, '柳江区', 450200, 3),
+(450222, '柳城县', 450200, 3),
+(450223, '鹿寨县', 450200, 3),
+(450224, '融安县', 450200, 3),
+(450225, '融水苗族自治县', 450200, 3),
+(450226, '三江侗族自治县', 450200, 3),
+(450300, '桂林市', 450000, 2),
+(450302, '秀峰区', 450300, 3),
+(450303, '叠彩区', 450300, 3),
+(450304, '象山区', 450300, 3),
+(450305, '七星区', 450300, 3),
+(450311, '雁山区', 450300, 3),
+(450312, '临桂区', 450300, 3),
+(450321, '阳朔县', 450300, 3),
+(450323, '灵川县', 450300, 3),
+(450324, '全州县', 450300, 3),
+(450325, '兴安县', 450300, 3),
+(450326, '永福县', 450300, 3),
+(450327, '灌阳县', 450300, 3),
+(450328, '龙胜各族自治县', 450300, 3),
+(450329, '资源县', 450300, 3),
+(450330, '平乐县', 450300, 3),
+(450331, '荔浦县', 450300, 3),
+(450332, '恭城瑶族自治县', 450300, 3),
+(450400, '梧州市', 450000, 2),
+(450403, '万秀区', 450400, 3),
+(450405, '长洲区', 450400, 3),
+(450406, '龙圩区', 450400, 3),
+(450421, '苍梧县', 450400, 3),
+(450422, '藤县', 450400, 3),
+(450423, '蒙山县', 450400, 3),
+(450481, '岑溪市', 450400, 3),
+(450500, '北海市', 450000, 2),
+(450502, '海城区', 450500, 3),
+(450503, '银海区', 450500, 3),
+(450512, '铁山港区', 450500, 3),
+(450521, '合浦县', 450500, 3),
+(450600, '防城港市', 450000, 2),
+(450602, '港口区', 450600, 3),
+(450603, '防城区', 450600, 3),
+(450621, '上思县', 450600, 3),
+(450681, '东兴市', 450600, 3),
+(450700, '钦州市', 450000, 2),
+(450702, '钦南区', 450700, 3),
+(450703, '钦北区', 450700, 3),
+(450721, '灵山县', 450700, 3),
+(450722, '浦北县', 450700, 3),
+(450800, '贵港市', 450000, 2),
+(450802, '港北区', 450800, 3),
+(450803, '港南区', 450800, 3),
+(450804, '覃塘区', 450800, 3),
+(450821, '平南县', 450800, 3),
+(450881, '桂平市', 450800, 3),
+(450900, '玉林市', 450000, 2),
+(450902, '玉州区', 450900, 3),
+(450903, '福绵区', 450900, 3),
+(450921, '容县', 450900, 3),
+(450922, '陆川县', 450900, 3),
+(450923, '博白县', 450900, 3),
+(450924, '兴业县', 450900, 3),
+(450981, '北流市', 450900, 3),
+(451000, '百色市', 450000, 2),
+(451002, '右江区', 451000, 3),
+(451021, '田阳县', 451000, 3),
+(451022, '田东县', 451000, 3),
+(451023, '平果县', 451000, 3),
+(451024, '德保县', 451000, 3),
+(451026, '那坡县', 451000, 3),
+(451027, '凌云县', 451000, 3),
+(451028, '乐业县', 451000, 3),
+(451029, '田林县', 451000, 3),
+(451030, '西林县', 451000, 3),
+(451031, '隆林各族自治县', 451000, 3),
+(451081, '靖西市', 451000, 3),
+(451100, '贺州市', 450000, 2),
+(451102, '八步区', 451100, 3),
+(451103, '平桂区', 451100, 3),
+(451121, '昭平县', 451100, 3),
+(451122, '钟山县', 451100, 3),
+(451123, '富川瑶族自治县', 451100, 3),
+(451200, '河池市', 450000, 2),
+(451202, '金城江区', 451200, 3),
+(451203, '宜州区', 451200, 3),
+(451221, '南丹县', 451200, 3),
+(451222, '天峨县', 451200, 3),
+(451223, '凤山县', 451200, 3),
+(451224, '东兰县', 451200, 3),
+(451225, '罗城仫佬族自治县', 451200, 3),
+(451226, '环江毛南族自治县', 451200, 3),
+(451227, '巴马瑶族自治县', 451200, 3),
+(451228, '都安瑶族自治县', 451200, 3),
+(451229, '大化瑶族自治县', 451200, 3),
+(451300, '来宾市', 450000, 2),
+(451302, '兴宾区', 451300, 3),
+(451321, '忻城县', 451300, 3),
+(451322, '象州县', 451300, 3),
+(451323, '武宣县', 451300, 3),
+(451324, '金秀瑶族自治县', 451300, 3),
+(451381, '合山市', 451300, 3),
+(451400, '崇左市', 450000, 2),
+(451402, '江州区', 451400, 3),
+(451421, '扶绥县', 451400, 3),
+(451422, '宁明县', 451400, 3),
+(451423, '龙州县', 451400, 3),
+(451424, '大新县', 451400, 3),
+(451425, '天等县', 451400, 3),
+(451481, '凭祥市', 451400, 3),
+(460000, '海南省', 0, 1),
+(460100, '海口市', 460000, 2),
+(460105, '秀英区', 460100, 3),
+(460106, '龙华区', 460100, 3),
+(460107, '琼山区', 460100, 3),
+(460108, '美兰区', 460100, 3),
+(460200, '三亚市', 460000, 2),
+(460202, '海棠区', 460200, 3),
+(460203, '吉阳区', 460200, 3),
+(460204, '天涯区', 460200, 3),
+(460205, '崖州区', 460200, 3),
+(460300, '三沙市', 460000, 2),
+(460321, '西沙群岛', 460300, 3),
+(460322, '南沙群岛', 460300, 3),
+(460323, '中沙群岛的岛礁及其海域', 460300, 3),
+(460400, '儋州市', 460000, 2),
+(460401, '那大镇', 460400, 3),
+(460402, '和庆镇', 460400, 3),
+(460403, '南丰镇', 460400, 3),
+(460404, '大成镇', 460400, 3),
+(460405, '雅星镇', 460400, 3),
+(460406, '兰洋镇', 460400, 3),
+(460407, '光村镇', 460400, 3),
+(460408, '木棠镇', 460400, 3),
+(460409, '海头镇', 460400, 3),
+(460410, '峨蔓镇', 460400, 3),
+(460411, '三都镇', 460400, 3),
+(460412, '王五镇', 460400, 3),
+(460413, '白马井镇', 460400, 3),
+(460414, '中和镇', 460400, 3),
+(460415, '排浦镇', 460400, 3),
+(460416, '东成镇', 460400, 3),
+(460417, '新州镇', 460400, 3),
+(460418, '国营西培农场', 460400, 3),
+(460419, '国营西联农场', 460400, 3),
+(460420, '国营蓝洋农场', 460400, 3),
+(460421, '国营八一农场', 460400, 3),
+(460422, '洋浦经济开发区', 460400, 3),
+(460423, '华南热作学院', 460400, 3),
+(460424, '红岭农场', 460400, 3),
+(469000, '省直辖县级行政区划', 460000, 2),
+(469001, '五指山市', 469000, 3),
+(469002, '琼海市', 469000, 3),
+(469005, '文昌市', 469000, 3),
+(469006, '万宁市', 469000, 3),
+(469007, '东方市', 469000, 3),
+(469021, '定安县', 469000, 3),
+(469022, '屯昌县', 469000, 3),
+(469023, '澄迈县', 469000, 3),
+(469024, '临高县', 469000, 3),
+(469025, '白沙黎族自治县', 469000, 3),
+(469026, '昌江黎族自治县', 469000, 3),
+(469027, '乐东黎族自治县', 469000, 3),
+(469028, '陵水黎族自治县', 469000, 3),
+(469029, '保亭黎族苗族自治县', 469000, 3),
+(469030, '琼中黎族苗族自治县', 469000, 3),
+(500000, '重庆市', 0, 1),
+(500100, '重庆市', 500000, 2),
+(500101, '万州区', 500100, 3),
+(500102, '涪陵区', 500100, 3),
+(500103, '渝中区', 500100, 3),
+(500104, '大渡口区', 500100, 3),
+(500105, '江北区', 500100, 3),
+(500106, '沙坪坝区', 500100, 3),
+(500107, '九龙坡区', 500100, 3),
+(500108, '南岸区', 500100, 3),
+(500109, '北碚区', 500100, 3),
+(500110, '綦江区', 500100, 3),
+(500111, '大足区', 500100, 3),
+(500112, '渝北区', 500100, 3),
+(500113, '巴南区', 500100, 3),
+(500114, '黔江区', 500100, 3),
+(500115, '长寿区', 500100, 3),
+(500116, '江津区', 500100, 3),
+(500117, '合川区', 500100, 3),
+(500118, '永川区', 500100, 3),
+(500119, '南川区', 500100, 3),
+(500120, '璧山区', 500100, 3),
+(500151, '铜梁区', 500100, 3),
+(500152, '潼南区', 500100, 3),
+(500153, '荣昌区', 500100, 3),
+(500154, '开州区', 500100, 3),
+(500155, '梁平区', 500100, 3),
+(500156, '武隆区', 500100, 3),
+(500200, '县', 500000, 2),
+(500229, '城口县', 500200, 3),
+(500230, '丰都县', 500200, 3),
+(500231, '垫江县', 500200, 3),
+(500233, '忠县', 500200, 3),
+(500235, '云阳县', 500200, 3),
+(500236, '奉节县', 500200, 3),
+(500237, '巫山县', 500200, 3),
+(500238, '巫溪县', 500200, 3),
+(500240, '石柱土家族自治县', 500200, 3),
+(500241, '秀山土家族苗族自治县', 500200, 3),
+(500242, '酉阳土家族苗族自治县', 500200, 3),
+(500243, '彭水苗族土家族自治县', 500200, 3),
+(510000, '四川省', 0, 1),
+(510100, '成都市', 510000, 2),
+(510104, '锦江区', 510100, 3),
+(510105, '青羊区', 510100, 3),
+(510106, '金牛区', 510100, 3),
+(510107, '武侯区', 510100, 3),
+(510108, '成华区', 510100, 3),
+(510112, '龙泉驿区', 510100, 3),
+(510113, '青白江区', 510100, 3),
+(510114, '新都区', 510100, 3),
+(510115, '温江区', 510100, 3),
+(510116, '双流区', 510100, 3),
+(510117, '郫都区', 510100, 3),
+(510121, '金堂县', 510100, 3),
+(510129, '大邑县', 510100, 3),
+(510131, '蒲江县', 510100, 3),
+(510132, '新津县', 510100, 3),
+(510181, '都江堰市', 510100, 3),
+(510182, '彭州市', 510100, 3),
+(510183, '邛崃市', 510100, 3),
+(510184, '崇州市', 510100, 3),
+(510185, '简阳市', 510100, 3),
+(510300, '自贡市', 510000, 2),
+(510302, '自流井区', 510300, 3),
+(510303, '贡井区', 510300, 3),
+(510304, '大安区', 510300, 3),
+(510311, '沿滩区', 510300, 3),
+(510321, '荣县', 510300, 3),
+(510322, '富顺县', 510300, 3),
+(510400, '攀枝花市', 510000, 2),
+(510402, '东区', 510400, 3),
+(510403, '西区', 510400, 3),
+(510411, '仁和区', 510400, 3),
+(510421, '米易县', 510400, 3),
+(510422, '盐边县', 510400, 3),
+(510500, '泸州市', 510000, 2),
+(510502, '江阳区', 510500, 3),
+(510503, '纳溪区', 510500, 3),
+(510504, '龙马潭区', 510500, 3),
+(510521, '泸县', 510500, 3),
+(510522, '合江县', 510500, 3),
+(510524, '叙永县', 510500, 3),
+(510525, '古蔺县', 510500, 3),
+(510600, '德阳市', 510000, 2),
+(510603, '旌阳区', 510600, 3),
+(510604, '罗江区', 510600, 3),
+(510623, '中江县', 510600, 3),
+(510681, '广汉市', 510600, 3),
+(510682, '什邡市', 510600, 3),
+(510683, '绵竹市', 510600, 3),
+(510700, '绵阳市', 510000, 2),
+(510703, '涪城区', 510700, 3),
+(510704, '游仙区', 510700, 3),
+(510705, '安州区', 510700, 3),
+(510722, '三台县', 510700, 3),
+(510723, '盐亭县', 510700, 3),
+(510725, '梓潼县', 510700, 3),
+(510726, '北川羌族自治县', 510700, 3),
+(510727, '平武县', 510700, 3),
+(510781, '江油市', 510700, 3),
+(510800, '广元市', 510000, 2),
+(510802, '利州区', 510800, 3),
+(510811, '昭化区', 510800, 3),
+(510812, '朝天区', 510800, 3),
+(510821, '旺苍县', 510800, 3),
+(510822, '青川县', 510800, 3),
+(510823, '剑阁县', 510800, 3),
+(510824, '苍溪县', 510800, 3),
+(510900, '遂宁市', 510000, 2),
+(510903, '船山区', 510900, 3),
+(510904, '安居区', 510900, 3),
+(510921, '蓬溪县', 510900, 3),
+(510922, '射洪县', 510900, 3),
+(510923, '大英县', 510900, 3),
+(511000, '内江市', 510000, 2),
+(511002, '市中区', 511000, 3),
+(511011, '东兴区', 511000, 3),
+(511024, '威远县', 511000, 3),
+(511025, '资中县', 511000, 3),
+(511083, '隆昌市', 511000, 3),
+(511100, '乐山市', 510000, 2),
+(511102, '市中区', 511100, 3),
+(511111, '沙湾区', 511100, 3),
+(511112, '五通桥区', 511100, 3),
+(511113, '金口河区', 511100, 3),
+(511123, '犍为县', 511100, 3),
+(511124, '井研县', 511100, 3),
+(511126, '夹江县', 511100, 3),
+(511129, '沐川县', 511100, 3),
+(511132, '峨边彝族自治县', 511100, 3),
+(511133, '马边彝族自治县', 511100, 3),
+(511181, '峨眉山市', 511100, 3),
+(511300, '南充市', 510000, 2),
+(511302, '顺庆区', 511300, 3),
+(511303, '高坪区', 511300, 3),
+(511304, '嘉陵区', 511300, 3),
+(511321, '南部县', 511300, 3),
+(511322, '营山县', 511300, 3),
+(511323, '蓬安县', 511300, 3),
+(511324, '仪陇县', 511300, 3),
+(511325, '西充县', 511300, 3),
+(511381, '阆中市', 511300, 3),
+(511400, '眉山市', 510000, 2),
+(511402, '东坡区', 511400, 3),
+(511403, '彭山区', 511400, 3),
+(511421, '仁寿县', 511400, 3),
+(511423, '洪雅县', 511400, 3),
+(511424, '丹棱县', 511400, 3),
+(511425, '青神县', 511400, 3),
+(511500, '宜宾市', 510000, 2),
+(511502, '翠屏区', 511500, 3),
+(511503, '南溪区', 511500, 3),
+(511521, '宜宾县', 511500, 3),
+(511523, '江安县', 511500, 3),
+(511524, '长宁县', 511500, 3),
+(511525, '高县', 511500, 3),
+(511526, '珙县', 511500, 3),
+(511527, '筠连县', 511500, 3),
+(511528, '兴文县', 511500, 3),
+(511529, '屏山县', 511500, 3),
+(511600, '广安市', 510000, 2),
+(511602, '广安区', 511600, 3),
+(511603, '前锋区', 511600, 3),
+(511621, '岳池县', 511600, 3),
+(511622, '武胜县', 511600, 3),
+(511623, '邻水县', 511600, 3),
+(511681, '华蓥市', 511600, 3),
+(511700, '达州市', 510000, 2),
+(511702, '通川区', 511700, 3),
+(511703, '达川区', 511700, 3),
+(511722, '宣汉县', 511700, 3),
+(511723, '开江县', 511700, 3),
+(511724, '大竹县', 511700, 3),
+(511725, '渠县', 511700, 3),
+(511781, '万源市', 511700, 3),
+(511800, '雅安市', 510000, 2),
+(511802, '雨城区', 511800, 3),
+(511803, '名山区', 511800, 3),
+(511822, '荥经县', 511800, 3),
+(511823, '汉源县', 511800, 3),
+(511824, '石棉县', 511800, 3),
+(511825, '天全县', 511800, 3),
+(511826, '芦山县', 511800, 3),
+(511827, '宝兴县', 511800, 3),
+(511900, '巴中市', 510000, 2),
+(511902, '巴州区', 511900, 3),
+(511903, '恩阳区', 511900, 3),
+(511921, '通江县', 511900, 3),
+(511922, '南江县', 511900, 3),
+(511923, '平昌县', 511900, 3),
+(512000, '资阳市', 510000, 2),
+(512002, '雁江区', 512000, 3),
+(512021, '安岳县', 512000, 3),
+(512022, '乐至县', 512000, 3),
+(513200, '阿坝藏族羌族自治州', 510000, 2),
+(513201, '马尔康市', 513200, 3),
+(513221, '汶川县', 513200, 3),
+(513222, '理县', 513200, 3),
+(513223, '茂县', 513200, 3),
+(513224, '松潘县', 513200, 3),
+(513225, '九寨沟县', 513200, 3),
+(513226, '金川县', 513200, 3),
+(513227, '小金县', 513200, 3),
+(513228, '黑水县', 513200, 3),
+(513230, '壤塘县', 513200, 3),
+(513231, '阿坝县', 513200, 3),
+(513232, '若尔盖县', 513200, 3),
+(513233, '红原县', 513200, 3),
+(513300, '甘孜藏族自治州', 510000, 2),
+(513301, '康定市', 513300, 3),
+(513322, '泸定县', 513300, 3),
+(513323, '丹巴县', 513300, 3),
+(513324, '九龙县', 513300, 3),
+(513325, '雅江县', 513300, 3),
+(513326, '道孚县', 513300, 3),
+(513327, '炉霍县', 513300, 3),
+(513328, '甘孜县', 513300, 3),
+(513329, '新龙县', 513300, 3),
+(513330, '德格县', 513300, 3),
+(513331, '白玉县', 513300, 3),
+(513332, '石渠县', 513300, 3),
+(513333, '色达县', 513300, 3),
+(513334, '理塘县', 513300, 3),
+(513335, '巴塘县', 513300, 3),
+(513336, '乡城县', 513300, 3),
+(513337, '稻城县', 513300, 3),
+(513338, '得荣县', 513300, 3),
+(513400, '凉山彝族自治州', 510000, 2),
+(513401, '西昌市', 513400, 3),
+(513422, '木里藏族自治县', 513400, 3),
+(513423, '盐源县', 513400, 3),
+(513424, '德昌县', 513400, 3),
+(513425, '会理县', 513400, 3),
+(513426, '会东县', 513400, 3),
+(513427, '宁南县', 513400, 3),
+(513428, '普格县', 513400, 3),
+(513429, '布拖县', 513400, 3),
+(513430, '金阳县', 513400, 3),
+(513431, '昭觉县', 513400, 3),
+(513432, '喜德县', 513400, 3),
+(513433, '冕宁县', 513400, 3),
+(513434, '越西县', 513400, 3),
+(513435, '甘洛县', 513400, 3),
+(513436, '美姑县', 513400, 3),
+(513437, '雷波县', 513400, 3),
+(520000, '贵州省', 0, 1),
+(520100, '贵阳市', 520000, 2),
+(520102, '南明区', 520100, 3),
+(520103, '云岩区', 520100, 3),
+(520111, '花溪区', 520100, 3),
+(520112, '乌当区', 520100, 3),
+(520113, '白云区', 520100, 3),
+(520115, '观山湖区', 520100, 3),
+(520121, '开阳县', 520100, 3),
+(520122, '息烽县', 520100, 3),
+(520123, '修文县', 520100, 3),
+(520181, '清镇市', 520100, 3),
+(520200, '六盘水市', 520000, 2),
+(520201, '钟山区', 520200, 3),
+(520203, '六枝特区', 520200, 3),
+(520221, '水城县', 520200, 3),
+(520281, '盘州市', 520200, 3),
+(520300, '遵义市', 520000, 2),
+(520302, '红花岗区', 520300, 3),
+(520303, '汇川区', 520300, 3),
+(520304, '播州区', 520300, 3),
+(520322, '桐梓县', 520300, 3),
+(520323, '绥阳县', 520300, 3),
+(520324, '正安县', 520300, 3),
+(520325, '道真仡佬族苗族自治县', 520300, 3),
+(520326, '务川仡佬族苗族自治县', 520300, 3),
+(520327, '凤冈县', 520300, 3),
+(520328, '湄潭县', 520300, 3),
+(520329, '余庆县', 520300, 3),
+(520330, '习水县', 520300, 3),
+(520381, '赤水市', 520300, 3),
+(520382, '仁怀市', 520300, 3),
+(520400, '安顺市', 520000, 2),
+(520402, '西秀区', 520400, 3),
+(520403, '平坝区', 520400, 3),
+(520422, '普定县', 520400, 3),
+(520423, '镇宁布依族苗族自治县', 520400, 3),
+(520424, '关岭布依族苗族自治县', 520400, 3),
+(520425, '紫云苗族布依族自治县', 520400, 3),
+(520500, '毕节市', 520000, 2),
+(520502, '七星关区', 520500, 3),
+(520521, '大方县', 520500, 3),
+(520522, '黔西县', 520500, 3),
+(520523, '金沙县', 520500, 3),
+(520524, '织金县', 520500, 3),
+(520525, '纳雍县', 520500, 3),
+(520526, '威宁彝族回族苗族自治县', 520500, 3),
+(520527, '赫章县', 520500, 3),
+(520600, '铜仁市', 520000, 2),
+(520602, '碧江区', 520600, 3),
+(520603, '万山区', 520600, 3),
+(520621, '江口县', 520600, 3),
+(520622, '玉屏侗族自治县', 520600, 3),
+(520623, '石阡县', 520600, 3),
+(520624, '思南县', 520600, 3),
+(520625, '印江土家族苗族自治县', 520600, 3),
+(520626, '德江县', 520600, 3),
+(520627, '沿河土家族自治县', 520600, 3),
+(520628, '松桃苗族自治县', 520600, 3),
+(522300, '黔西南布依族苗族自治州', 520000, 2),
+(522301, '兴义市', 522300, 3),
+(522322, '兴仁县', 522300, 3),
+(522323, '普安县', 522300, 3),
+(522324, '晴隆县', 522300, 3),
+(522325, '贞丰县', 522300, 3),
+(522326, '望谟县', 522300, 3),
+(522327, '册亨县', 522300, 3),
+(522328, '安龙县', 522300, 3),
+(522600, '黔东南苗族侗族自治州', 520000, 2),
+(522601, '凯里市', 522600, 3),
+(522622, '黄平县', 522600, 3),
+(522623, '施秉县', 522600, 3),
+(522624, '三穗县', 522600, 3),
+(522625, '镇远县', 522600, 3),
+(522626, '岑巩县', 522600, 3),
+(522627, '天柱县', 522600, 3),
+(522628, '锦屏县', 522600, 3),
+(522629, '剑河县', 522600, 3),
+(522630, '台江县', 522600, 3),
+(522631, '黎平县', 522600, 3),
+(522632, '榕江县', 522600, 3),
+(522633, '从江县', 522600, 3),
+(522634, '雷山县', 522600, 3),
+(522635, '麻江县', 522600, 3),
+(522636, '丹寨县', 522600, 3),
+(522700, '黔南布依族苗族自治州', 520000, 2),
+(522701, '都匀市', 522700, 3),
+(522702, '福泉市', 522700, 3),
+(522722, '荔波县', 522700, 3),
+(522723, '贵定县', 522700, 3),
+(522725, '瓮安县', 522700, 3),
+(522726, '独山县', 522700, 3),
+(522727, '平塘县', 522700, 3),
+(522728, '罗甸县', 522700, 3),
+(522729, '长顺县', 522700, 3),
+(522730, '龙里县', 522700, 3),
+(522731, '惠水县', 522700, 3),
+(522732, '三都水族自治县', 522700, 3),
+(530000, '云南省', 0, 1),
+(530100, '昆明市', 530000, 2),
+(530102, '五华区', 530100, 3),
+(530103, '盘龙区', 530100, 3),
+(530111, '官渡区', 530100, 3),
+(530112, '西山区', 530100, 3),
+(530113, '东川区', 530100, 3),
+(530114, '呈贡区', 530100, 3),
+(530115, '晋宁区', 530100, 3),
+(530124, '富民县', 530100, 3),
+(530125, '宜良县', 530100, 3),
+(530126, '石林彝族自治县', 530100, 3),
+(530127, '嵩明县', 530100, 3),
+(530128, '禄劝彝族苗族自治县', 530100, 3),
+(530129, '寻甸回族彝族自治县', 530100, 3),
+(530181, '安宁市', 530100, 3),
+(530300, '曲靖市', 530000, 2),
+(530302, '麒麟区', 530300, 3),
+(530303, '沾益区', 530300, 3),
+(530321, '马龙县', 530300, 3),
+(530322, '陆良县', 530300, 3),
+(530323, '师宗县', 530300, 3),
+(530324, '罗平县', 530300, 3),
+(530325, '富源县', 530300, 3),
+(530326, '会泽县', 530300, 3),
+(530381, '宣威市', 530300, 3),
+(530400, '玉溪市', 530000, 2),
+(530402, '红塔区', 530400, 3),
+(530403, '江川区', 530400, 3),
+(530422, '澄江县', 530400, 3),
+(530423, '通海县', 530400, 3),
+(530424, '华宁县', 530400, 3),
+(530425, '易门县', 530400, 3),
+(530426, '峨山彝族自治县', 530400, 3),
+(530427, '新平彝族傣族自治县', 530400, 3),
+(530428, '元江哈尼族彝族傣族自治县', 530400, 3),
+(530500, '保山市', 530000, 2),
+(530502, '隆阳区', 530500, 3),
+(530521, '施甸县', 530500, 3),
+(530523, '龙陵县', 530500, 3),
+(530524, '昌宁县', 530500, 3),
+(530581, '腾冲市', 530500, 3),
+(530600, '昭通市', 530000, 2),
+(530602, '昭阳区', 530600, 3),
+(530621, '鲁甸县', 530600, 3),
+(530622, '巧家县', 530600, 3),
+(530623, '盐津县', 530600, 3),
+(530624, '大关县', 530600, 3),
+(530625, '永善县', 530600, 3),
+(530626, '绥江县', 530600, 3),
+(530627, '镇雄县', 530600, 3),
+(530628, '彝良县', 530600, 3),
+(530629, '威信县', 530600, 3),
+(530630, '水富县', 530600, 3),
+(530700, '丽江市', 530000, 2),
+(530702, '古城区', 530700, 3),
+(530721, '玉龙纳西族自治县', 530700, 3),
+(530722, '永胜县', 530700, 3),
+(530723, '华坪县', 530700, 3),
+(530724, '宁蒗彝族自治县', 530700, 3),
+(530800, '普洱市', 530000, 2),
+(530802, '思茅区', 530800, 3),
+(530821, '宁洱哈尼族彝族自治县', 530800, 3),
+(530822, '墨江哈尼族自治县', 530800, 3),
+(530823, '景东彝族自治县', 530800, 3),
+(530824, '景谷傣族彝族自治县', 530800, 3),
+(530825, '镇沅彝族哈尼族拉祜族自治县', 530800, 3),
+(530826, '江城哈尼族彝族自治县', 530800, 3),
+(530827, '孟连傣族拉祜族佤族自治县', 530800, 3),
+(530828, '澜沧拉祜族自治县', 530800, 3),
+(530829, '西盟佤族自治县', 530800, 3),
+(530900, '临沧市', 530000, 2),
+(530902, '临翔区', 530900, 3),
+(530921, '凤庆县', 530900, 3),
+(530922, '云县', 530900, 3),
+(530923, '永德县', 530900, 3),
+(530924, '镇康县', 530900, 3),
+(530925, '双江拉祜族佤族布朗族傣族自治县', 530900, 3),
+(530926, '耿马傣族佤族自治县', 530900, 3),
+(530927, '沧源佤族自治县', 530900, 3),
+(532300, '楚雄彝族自治州', 530000, 2),
+(532301, '楚雄市', 532300, 3),
+(532322, '双柏县', 532300, 3),
+(532323, '牟定县', 532300, 3),
+(532324, '南华县', 532300, 3),
+(532325, '姚安县', 532300, 3),
+(532326, '大姚县', 532300, 3),
+(532327, '永仁县', 532300, 3),
+(532328, '元谋县', 532300, 3),
+(532329, '武定县', 532300, 3),
+(532331, '禄丰县', 532300, 3),
+(532500, '红河哈尼族彝族自治州', 530000, 2),
+(532501, '个旧市', 532500, 3),
+(532502, '开远市', 532500, 3),
+(532503, '蒙自市', 532500, 3),
+(532504, '弥勒市', 532500, 3),
+(532523, '屏边苗族自治县', 532500, 3),
+(532524, '建水县', 532500, 3),
+(532525, '石屏县', 532500, 3),
+(532527, '泸西县', 532500, 3),
+(532528, '元阳县', 532500, 3),
+(532529, '红河县', 532500, 3),
+(532530, '金平苗族瑶族傣族自治县', 532500, 3),
+(532531, '绿春县', 532500, 3),
+(532532, '河口瑶族自治县', 532500, 3),
+(532600, '文山壮族苗族自治州', 530000, 2),
+(532601, '文山市', 532600, 3),
+(532622, '砚山县', 532600, 3),
+(532623, '西畴县', 532600, 3),
+(532624, '麻栗坡县', 532600, 3),
+(532625, '马关县', 532600, 3),
+(532626, '丘北县', 532600, 3),
+(532627, '广南县', 532600, 3),
+(532628, '富宁县', 532600, 3),
+(532800, '西双版纳傣族自治州', 530000, 2),
+(532801, '景洪市', 532800, 3),
+(532822, '勐海县', 532800, 3),
+(532823, '勐腊县', 532800, 3),
+(532900, '大理白族自治州', 530000, 2),
+(532901, '大理市', 532900, 3),
+(532922, '漾濞彝族自治县', 532900, 3),
+(532923, '祥云县', 532900, 3),
+(532924, '宾川县', 532900, 3),
+(532925, '弥渡县', 532900, 3),
+(532926, '南涧彝族自治县', 532900, 3),
+(532927, '巍山彝族回族自治县', 532900, 3),
+(532928, '永平县', 532900, 3),
+(532929, '云龙县', 532900, 3),
+(532930, '洱源县', 532900, 3),
+(532931, '剑川县', 532900, 3),
+(532932, '鹤庆县', 532900, 3),
+(533100, '德宏傣族景颇族自治州', 530000, 2),
+(533102, '瑞丽市', 533100, 3),
+(533103, '芒市', 533100, 3),
+(533122, '梁河县', 533100, 3),
+(533123, '盈江县', 533100, 3),
+(533124, '陇川县', 533100, 3),
+(533300, '怒江傈僳族自治州', 530000, 2),
+(533301, '泸水市', 533300, 3),
+(533323, '福贡县', 533300, 3),
+(533324, '贡山独龙族怒族自治县', 533300, 3),
+(533325, '兰坪白族普米族自治县', 533300, 3),
+(533400, '迪庆藏族自治州', 530000, 2),
+(533401, '香格里拉市', 533400, 3),
+(533422, '德钦县', 533400, 3),
+(533423, '维西傈僳族自治县', 533400, 3),
+(540000, '西藏自治区', 0, 1),
+(540100, '拉萨市', 540000, 2),
+(540102, '城关区', 540100, 3),
+(540103, '堆龙德庆区', 540100, 3),
+(540104, '达孜区', 540100, 3),
+(540121, '林周县', 540100, 3),
+(540122, '当雄县', 540100, 3),
+(540123, '尼木县', 540100, 3),
+(540124, '曲水县', 540100, 3),
+(540127, '墨竹工卡县', 540100, 3),
+(540200, '日喀则市', 540000, 2),
+(540202, '桑珠孜区', 540200, 3),
+(540221, '南木林县', 540200, 3),
+(540222, '江孜县', 540200, 3),
+(540223, '定日县', 540200, 3),
+(540224, '萨迦县', 540200, 3),
+(540225, '拉孜县', 540200, 3),
+(540226, '昂仁县', 540200, 3),
+(540227, '谢通门县', 540200, 3),
+(540228, '白朗县', 540200, 3),
+(540229, '仁布县', 540200, 3),
+(540230, '康马县', 540200, 3),
+(540231, '定结县', 540200, 3),
+(540232, '仲巴县', 540200, 3),
+(540233, '亚东县', 540200, 3),
+(540234, '吉隆县', 540200, 3),
+(540235, '聂拉木县', 540200, 3),
+(540236, '萨嘎县', 540200, 3),
+(540237, '岗巴县', 540200, 3),
+(540300, '昌都市', 540000, 2),
+(540302, '卡若区', 540300, 3),
+(540321, '江达县', 540300, 3),
+(540322, '贡觉县', 540300, 3),
+(540323, '类乌齐县', 540300, 3),
+(540324, '丁青县', 540300, 3),
+(540325, '察雅县', 540300, 3),
+(540326, '八宿县', 540300, 3),
+(540327, '左贡县', 540300, 3),
+(540328, '芒康县', 540300, 3),
+(540329, '洛隆县', 540300, 3),
+(540330, '边坝县', 540300, 3),
+(540400, '林芝市', 540000, 2),
+(540402, '巴宜区', 540400, 3),
+(540421, '工布江达县', 540400, 3),
+(540422, '米林县', 540400, 3),
+(540423, '墨脱县', 540400, 3),
+(540424, '波密县', 540400, 3),
+(540425, '察隅县', 540400, 3),
+(540426, '朗县', 540400, 3),
+(540500, '山南市', 540000, 2),
+(540502, '乃东区', 540500, 3),
+(540521, '扎囊县', 540500, 3),
+(540522, '贡嘎县', 540500, 3),
+(540523, '桑日县', 540500, 3),
+(540524, '琼结县', 540500, 3),
+(540525, '曲松县', 540500, 3),
+(540526, '措美县', 540500, 3),
+(540527, '洛扎县', 540500, 3),
+(540528, '加查县', 540500, 3),
+(540529, '隆子县', 540500, 3),
+(540530, '错那县', 540500, 3),
+(540531, '浪卡子县', 540500, 3),
+(542400, '那曲地区', 540000, 2),
+(542421, '那曲县', 542400, 3),
+(542422, '嘉黎县', 542400, 3),
+(542423, '比如县', 542400, 3),
+(542424, '聂荣县', 542400, 3),
+(542425, '安多县', 542400, 3),
+(542426, '申扎县', 542400, 3),
+(542427, '索县', 542400, 3),
+(542428, '班戈县', 542400, 3),
+(542429, '巴青县', 542400, 3),
+(542430, '尼玛县', 542400, 3),
+(542431, '双湖县', 542400, 3),
+(542500, '阿里地区', 540000, 2),
+(542521, '普兰县', 542500, 3),
+(542522, '札达县', 542500, 3),
+(542523, '噶尔县', 542500, 3),
+(542524, '日土县', 542500, 3),
+(542525, '革吉县', 542500, 3),
+(542526, '改则县', 542500, 3),
+(542527, '措勤县', 542500, 3),
+(610000, '陕西省', 0, 1),
+(610100, '西安市', 610000, 2),
+(610102, '新城区', 610100, 3),
+(610103, '碑林区', 610100, 3),
+(610104, '莲湖区', 610100, 3),
+(610111, '灞桥区', 610100, 3),
+(610112, '未央区', 610100, 3),
+(610113, '雁塔区', 610100, 3),
+(610114, '阎良区', 610100, 3),
+(610115, '临潼区', 610100, 3),
+(610116, '长安区', 610100, 3),
+(610117, '高陵区', 610100, 3),
+(610118, '鄠邑区', 610100, 3),
+(610122, '蓝田县', 610100, 3),
+(610124, '周至县', 610100, 3),
+(610200, '铜川市', 610000, 2),
+(610202, '王益区', 610200, 3),
+(610203, '印台区', 610200, 3),
+(610204, '耀州区', 610200, 3),
+(610222, '宜君县', 610200, 3),
+(610300, '宝鸡市', 610000, 2),
+(610302, '渭滨区', 610300, 3),
+(610303, '金台区', 610300, 3),
+(610304, '陈仓区', 610300, 3),
+(610322, '凤翔县', 610300, 3),
+(610323, '岐山县', 610300, 3),
+(610324, '扶风县', 610300, 3),
+(610326, '眉县', 610300, 3),
+(610327, '陇县', 610300, 3),
+(610328, '千阳县', 610300, 3),
+(610329, '麟游县', 610300, 3),
+(610330, '凤县', 610300, 3),
+(610331, '太白县', 610300, 3),
+(610400, '咸阳市', 610000, 2),
+(610402, '秦都区', 610400, 3),
+(610403, '杨陵区', 610400, 3),
+(610404, '渭城区', 610400, 3),
+(610422, '三原县', 610400, 3),
+(610423, '泾阳县', 610400, 3),
+(610424, '乾县', 610400, 3),
+(610425, '礼泉县', 610400, 3),
+(610426, '永寿县', 610400, 3),
+(610427, '彬州市', 610400, 3),
+(610428, '长武县', 610400, 3),
+(610429, '旬邑县', 610400, 3),
+(610430, '淳化县', 610400, 3),
+(610431, '武功县', 610400, 3),
+(610481, '兴平市', 610400, 3),
+(610500, '渭南市', 610000, 2),
+(610502, '临渭区', 610500, 3),
+(610503, '华州区', 610500, 3),
+(610522, '潼关县', 610500, 3),
+(610523, '大荔县', 610500, 3),
+(610524, '合阳县', 610500, 3),
+(610525, '澄城县', 610500, 3),
+(610526, '蒲城县', 610500, 3),
+(610527, '白水县', 610500, 3),
+(610528, '富平县', 610500, 3),
+(610581, '韩城市', 610500, 3),
+(610582, '华阴市', 610500, 3),
+(610600, '延安市', 610000, 2),
+(610602, '宝塔区', 610600, 3),
+(610603, '安塞区', 610600, 3),
+(610621, '延长县', 610600, 3),
+(610622, '延川县', 610600, 3),
+(610623, '子长县', 610600, 3),
+(610625, '志丹县', 610600, 3),
+(610626, '吴起县', 610600, 3),
+(610627, '甘泉县', 610600, 3),
+(610628, '富县', 610600, 3),
+(610629, '洛川县', 610600, 3),
+(610630, '宜川县', 610600, 3),
+(610631, '黄龙县', 610600, 3),
+(610632, '黄陵县', 610600, 3),
+(610700, '汉中市', 610000, 2),
+(610702, '汉台区', 610700, 3),
+(610703, '南郑区', 610700, 3),
+(610722, '城固县', 610700, 3),
+(610723, '洋县', 610700, 3),
+(610724, '西乡县', 610700, 3),
+(610725, '勉县', 610700, 3),
+(610726, '宁强县', 610700, 3),
+(610727, '略阳县', 610700, 3),
+(610728, '镇巴县', 610700, 3),
+(610729, '留坝县', 610700, 3),
+(610730, '佛坪县', 610700, 3),
+(610800, '榆林市', 610000, 2),
+(610802, '榆阳区', 610800, 3),
+(610803, '横山区', 610800, 3),
+(610822, '府谷县', 610800, 3),
+(610824, '靖边县', 610800, 3),
+(610825, '定边县', 610800, 3),
+(610826, '绥德县', 610800, 3),
+(610827, '米脂县', 610800, 3),
+(610828, '佳县', 610800, 3),
+(610829, '吴堡县', 610800, 3),
+(610830, '清涧县', 610800, 3),
+(610831, '子洲县', 610800, 3),
+(610881, '神木市', 610800, 3),
+(610900, '安康市', 610000, 2),
+(610902, '汉滨区', 610900, 3),
+(610921, '汉阴县', 610900, 3),
+(610922, '石泉县', 610900, 3),
+(610923, '宁陕县', 610900, 3),
+(610924, '紫阳县', 610900, 3),
+(610925, '岚皋县', 610900, 3),
+(610926, '平利县', 610900, 3),
+(610927, '镇坪县', 610900, 3),
+(610928, '旬阳县', 610900, 3),
+(610929, '白河县', 610900, 3),
+(611000, '商洛市', 610000, 2),
+(611002, '商州区', 611000, 3),
+(611021, '洛南县', 611000, 3),
+(611022, '丹凤县', 611000, 3),
+(611023, '商南县', 611000, 3),
+(611024, '山阳县', 611000, 3),
+(611025, '镇安县', 611000, 3),
+(611026, '柞水县', 611000, 3),
+(620000, '甘肃省', 0, 1),
+(620100, '兰州市', 620000, 2),
+(620102, '城关区', 620100, 3),
+(620103, '七里河区', 620100, 3),
+(620104, '西固区', 620100, 3),
+(620105, '安宁区', 620100, 3),
+(620111, '红古区', 620100, 3),
+(620121, '永登县', 620100, 3),
+(620122, '皋兰县', 620100, 3),
+(620123, '榆中县', 620100, 3),
+(620200, '嘉峪关市', 620000, 2),
+(620201, '雄关区', 620200, 3),
+(620202, '镜铁区', 620200, 3),
+(620203, '长城区', 620200, 3),
+(620300, '金昌市', 620000, 2),
+(620302, '金川区', 620300, 3),
+(620321, '永昌县', 620300, 3),
+(620400, '白银市', 620000, 2),
+(620402, '白银区', 620400, 3),
+(620403, '平川区', 620400, 3),
+(620421, '靖远县', 620400, 3),
+(620422, '会宁县', 620400, 3),
+(620423, '景泰县', 620400, 3),
+(620500, '天水市', 620000, 2),
+(620502, '秦州区', 620500, 3),
+(620503, '麦积区', 620500, 3),
+(620521, '清水县', 620500, 3),
+(620522, '秦安县', 620500, 3),
+(620523, '甘谷县', 620500, 3),
+(620524, '武山县', 620500, 3),
+(620525, '张家川回族自治县', 620500, 3),
+(620600, '武威市', 620000, 2),
+(620602, '凉州区', 620600, 3),
+(620621, '民勤县', 620600, 3),
+(620622, '古浪县', 620600, 3),
+(620623, '天祝藏族自治县', 620600, 3),
+(620700, '张掖市', 620000, 2),
+(620702, '甘州区', 620700, 3),
+(620721, '肃南裕固族自治县', 620700, 3),
+(620722, '民乐县', 620700, 3),
+(620723, '临泽县', 620700, 3),
+(620724, '高台县', 620700, 3),
+(620725, '山丹县', 620700, 3),
+(620800, '平凉市', 620000, 2),
+(620802, '崆峒区', 620800, 3),
+(620821, '泾川县', 620800, 3),
+(620822, '灵台县', 620800, 3),
+(620823, '崇信县', 620800, 3),
+(620824, '华亭县', 620800, 3),
+(620825, '庄浪县', 620800, 3),
+(620826, '静宁县', 620800, 3),
+(620900, '酒泉市', 620000, 2),
+(620902, '肃州区', 620900, 3),
+(620921, '金塔县', 620900, 3),
+(620922, '瓜州县', 620900, 3),
+(620923, '肃北蒙古族自治县', 620900, 3),
+(620924, '阿克塞哈萨克族自治县', 620900, 3),
+(620981, '玉门市', 620900, 3),
+(620982, '敦煌市', 620900, 3),
+(621000, '庆阳市', 620000, 2),
+(621002, '西峰区', 621000, 3),
+(621021, '庆城县', 621000, 3),
+(621022, '环县', 621000, 3),
+(621023, '华池县', 621000, 3),
+(621024, '合水县', 621000, 3),
+(621025, '正宁县', 621000, 3),
+(621026, '宁县', 621000, 3),
+(621027, '镇原县', 621000, 3),
+(621100, '定西市', 620000, 2),
+(621102, '安定区', 621100, 3),
+(621121, '通渭县', 621100, 3),
+(621122, '陇西县', 621100, 3),
+(621123, '渭源县', 621100, 3),
+(621124, '临洮县', 621100, 3),
+(621125, '漳县', 621100, 3),
+(621126, '岷县', 621100, 3),
+(621200, '陇南市', 620000, 2),
+(621202, '武都区', 621200, 3),
+(621221, '成县', 621200, 3),
+(621222, '文县', 621200, 3),
+(621223, '宕昌县', 621200, 3),
+(621224, '康县', 621200, 3),
+(621225, '西和县', 621200, 3),
+(621226, '礼县', 621200, 3),
+(621227, '徽县', 621200, 3),
+(621228, '两当县', 621200, 3),
+(622900, '临夏回族自治州', 620000, 2),
+(622901, '临夏市', 622900, 3),
+(622921, '临夏县', 622900, 3),
+(622922, '康乐县', 622900, 3),
+(622923, '永靖县', 622900, 3),
+(622924, '广河县', 622900, 3),
+(622925, '和政县', 622900, 3),
+(622926, '东乡族自治县', 622900, 3),
+(622927, '积石山保安族东乡族撒拉族自治县', 622900, 3),
+(623000, '甘南藏族自治州', 620000, 2),
+(623001, '合作市', 623000, 3),
+(623021, '临潭县', 623000, 3),
+(623022, '卓尼县', 623000, 3),
+(623023, '舟曲县', 623000, 3),
+(623024, '迭部县', 623000, 3),
+(623025, '玛曲县', 623000, 3),
+(623026, '碌曲县', 623000, 3),
+(623027, '夏河县', 623000, 3),
+(630000, '青海省', 0, 1),
+(630100, '西宁市', 630000, 2),
+(630102, '城东区', 630100, 3),
+(630103, '城中区', 630100, 3),
+(630104, '城西区', 630100, 3),
+(630105, '城北区', 630100, 3),
+(630121, '大通回族土族自治县', 630100, 3),
+(630122, '湟中县', 630100, 3),
+(630123, '湟源县', 630100, 3),
+(630200, '海东市', 630000, 2),
+(630202, '乐都区', 630200, 3),
+(630203, '平安区', 630200, 3),
+(630222, '民和回族土族自治县', 630200, 3),
+(630223, '互助土族自治县', 630200, 3),
+(630224, '化隆回族自治县', 630200, 3),
+(630225, '循化撒拉族自治县', 630200, 3),
+(632200, '海北藏族自治州', 630000, 2),
+(632221, '门源回族自治县', 632200, 3),
+(632222, '祁连县', 632200, 3),
+(632223, '海晏县', 632200, 3),
+(632224, '刚察县', 632200, 3),
+(632300, '黄南藏族自治州', 630000, 2),
+(632321, '同仁县', 632300, 3),
+(632322, '尖扎县', 632300, 3),
+(632323, '泽库县', 632300, 3),
+(632324, '河南蒙古族自治县', 632300, 3),
+(632500, '海南藏族自治州', 630000, 2),
+(632521, '共和县', 632500, 3),
+(632522, '同德县', 632500, 3),
+(632523, '贵德县', 632500, 3),
+(632524, '兴海县', 632500, 3),
+(632525, '贵南县', 632500, 3),
+(632600, '果洛藏族自治州', 630000, 2),
+(632621, '玛沁县', 632600, 3),
+(632622, '班玛县', 632600, 3),
+(632623, '甘德县', 632600, 3),
+(632624, '达日县', 632600, 3),
+(632625, '久治县', 632600, 3),
+(632626, '玛多县', 632600, 3),
+(632700, '玉树藏族自治州', 630000, 2),
+(632701, '玉树市', 632700, 3),
+(632722, '杂多县', 632700, 3),
+(632723, '称多县', 632700, 3),
+(632724, '治多县', 632700, 3),
+(632725, '囊谦县', 632700, 3),
+(632726, '曲麻莱县', 632700, 3),
+(632800, '海西蒙古族藏族自治州', 630000, 2),
+(632801, '格尔木市', 632800, 3),
+(632802, '德令哈市', 632800, 3),
+(632821, '乌兰县', 632800, 3),
+(632822, '都兰县', 632800, 3),
+(632823, '天峻县', 632800, 3),
+(632824, '冷湖行政委员会', 632800, 3),
+(632825, '大柴旦行政委员会', 632800, 3),
+(632826, '茫崖行政委员会', 632800, 3),
+(640000, '宁夏回族自治区', 0, 1),
+(640100, '银川市', 640000, 2),
+(640104, '兴庆区', 640100, 3),
+(640105, '西夏区', 640100, 3),
+(640106, '金凤区', 640100, 3),
+(640121, '永宁县', 640100, 3),
+(640122, '贺兰县', 640100, 3),
+(640181, '灵武市', 640100, 3),
+(640200, '石嘴山市', 640000, 2),
+(640202, '大武口区', 640200, 3),
+(640205, '惠农区', 640200, 3),
+(640221, '平罗县', 640200, 3),
+(640300, '吴忠市', 640000, 2),
+(640302, '利通区', 640300, 3),
+(640303, '红寺堡区', 640300, 3),
+(640323, '盐池县', 640300, 3),
+(640324, '同心县', 640300, 3),
+(640381, '青铜峡市', 640300, 3),
+(640400, '固原市', 640000, 2),
+(640402, '原州区', 640400, 3),
+(640422, '西吉县', 640400, 3),
+(640423, '隆德县', 640400, 3),
+(640424, '泾源县', 640400, 3),
+(640425, '彭阳县', 640400, 3),
+(640500, '中卫市', 640000, 2),
+(640502, '沙坡头区', 640500, 3),
+(640521, '中宁县', 640500, 3),
+(640522, '海原县', 640500, 3),
+(650000, '新疆维吾尔自治区', 0, 1),
+(650100, '乌鲁木齐市', 650000, 2),
+(650102, '天山区', 650100, 3),
+(650103, '沙依巴克区', 650100, 3),
+(650104, '新市区', 650100, 3),
+(650105, '水磨沟区', 650100, 3),
+(650106, '头屯河区', 650100, 3),
+(650107, '达坂城区', 650100, 3),
+(650109, '米东区', 650100, 3),
+(650121, '乌鲁木齐县', 650100, 3),
+(650200, '克拉玛依市', 650000, 2),
+(650202, '独山子区', 650200, 3),
+(650203, '克拉玛依区', 650200, 3),
+(650204, '白碱滩区', 650200, 3),
+(650205, '乌尔禾区', 650200, 3),
+(650400, '吐鲁番市', 650000, 2),
+(650402, '高昌区', 650400, 3),
+(650421, '鄯善县', 650400, 3),
+(650422, '托克逊县', 650400, 3),
+(650500, '哈密市', 650000, 2),
+(650502, '伊州区', 650500, 3),
+(650521, '巴里坤哈萨克自治县', 650500, 3),
+(650522, '伊吾县', 650500, 3),
+(652300, '昌吉回族自治州', 650000, 2),
+(652301, '昌吉市', 652300, 3),
+(652302, '阜康市', 652300, 3),
+(652323, '呼图壁县', 652300, 3),
+(652324, '玛纳斯县', 652300, 3),
+(652325, '奇台县', 652300, 3),
+(652327, '吉木萨尔县', 652300, 3),
+(652328, '木垒哈萨克自治县', 652300, 3),
+(652700, '博尔塔拉蒙古自治州', 650000, 2),
+(652701, '博乐市', 652700, 3),
+(652702, '阿拉山口市', 652700, 3),
+(652722, '精河县', 652700, 3),
+(652723, '温泉县', 652700, 3),
+(652800, '巴音郭楞蒙古自治州', 650000, 2),
+(652801, '库尔勒市', 652800, 3),
+(652822, '轮台县', 652800, 3),
+(652823, '尉犁县', 652800, 3),
+(652824, '若羌县', 652800, 3),
+(652825, '且末县', 652800, 3),
+(652826, '焉耆回族自治县', 652800, 3),
+(652827, '和静县', 652800, 3),
+(652828, '和硕县', 652800, 3),
+(652829, '博湖县', 652800, 3),
+(652900, '阿克苏地区', 650000, 2),
+(652901, '阿克苏市', 652900, 3),
+(652922, '温宿县', 652900, 3),
+(652923, '库车县', 652900, 3),
+(652924, '沙雅县', 652900, 3),
+(652925, '新和县', 652900, 3),
+(652926, '拜城县', 652900, 3),
+(652927, '乌什县', 652900, 3),
+(652928, '阿瓦提县', 652900, 3),
+(652929, '柯坪县', 652900, 3),
+(653000, '克孜勒苏柯尔克孜自治州', 650000, 2),
+(653001, '阿图什市', 653000, 3),
+(653022, '阿克陶县', 653000, 3),
+(653023, '阿合奇县', 653000, 3),
+(653024, '乌恰县', 653000, 3),
+(653100, '喀什地区', 650000, 2),
+(653101, '喀什市', 653100, 3),
+(653121, '疏附县', 653100, 3),
+(653122, '疏勒县', 653100, 3),
+(653123, '英吉沙县', 653100, 3),
+(653124, '泽普县', 653100, 3),
+(653125, '莎车县', 653100, 3),
+(653126, '叶城县', 653100, 3),
+(653127, '麦盖提县', 653100, 3),
+(653128, '岳普湖县', 653100, 3),
+(653129, '伽师县', 653100, 3),
+(653130, '巴楚县', 653100, 3),
+(653131, '塔什库尔干塔吉克自治县', 653100, 3),
+(653200, '和田地区', 650000, 2),
+(653201, '和田市', 653200, 3),
+(653221, '和田县', 653200, 3),
+(653222, '墨玉县', 653200, 3),
+(653223, '皮山县', 653200, 3),
+(653224, '洛浦县', 653200, 3),
+(653225, '策勒县', 653200, 3),
+(653226, '于田县', 653200, 3),
+(653227, '民丰县', 653200, 3),
+(654000, '伊犁哈萨克自治州', 650000, 2),
+(654002, '伊宁市', 654000, 3),
+(654003, '奎屯市', 654000, 3),
+(654004, '霍尔果斯市', 654000, 3),
+(654021, '伊宁县', 654000, 3),
+(654022, '察布查尔锡伯自治县', 654000, 3),
+(654023, '霍城县', 654000, 3),
+(654024, '巩留县', 654000, 3),
+(654025, '新源县', 654000, 3),
+(654026, '昭苏县', 654000, 3),
+(654027, '特克斯县', 654000, 3),
+(654028, '尼勒克县', 654000, 3),
+(654200, '塔城地区', 650000, 2),
+(654201, '塔城市', 654200, 3),
+(654202, '乌苏市', 654200, 3),
+(654221, '额敏县', 654200, 3),
+(654223, '沙湾县', 654200, 3),
+(654224, '托里县', 654200, 3),
+(654225, '裕民县', 654200, 3),
+(654226, '和布克赛尔蒙古自治县', 654200, 3),
+(654300, '阿勒泰地区', 650000, 2),
+(654301, '阿勒泰市', 654300, 3),
+(654321, '布尔津县', 654300, 3),
+(654322, '富蕴县', 654300, 3),
+(654323, '福海县', 654300, 3),
+(654324, '哈巴河县', 654300, 3),
+(654325, '青河县', 654300, 3),
+(654326, '吉木乃县', 654300, 3),
+(659000, '自治区直辖县级行政区划', 650000, 2),
+(659001, '石河子市', 659000, 3),
+(659002, '阿拉尔市', 659000, 3),
+(659003, '图木舒克市', 659000, 3),
+(659004, '五家渠市', 659000, 3),
+(659005, '北屯市', 659000, 3),
+(659006, '铁门关市', 659000, 3),
+(659007, '双河市', 659000, 3),
+(659008, '可克达拉市', 659000, 3),
+(659009, '昆玉市', 659000, 3),
+(710000, '台湾省', 0, 1),
+(710100, '台北市', 710000, 2),
+(710101, '中正区', 710100, 3),
+(710102, '大同区', 710100, 3),
+(710103, '中山区', 710100, 3),
+(710104, '松山区', 710100, 3),
+(710105, '大安区', 710100, 3),
+(710106, '万华区', 710100, 3),
+(710107, '信义区', 710100, 3),
+(710108, '士林区', 710100, 3),
+(710109, '北投区', 710100, 3),
+(710110, '内湖区', 710100, 3),
+(710111, '南港区', 710100, 3),
+(710112, '文山区', 710100, 3),
+(710200, '高雄市', 710000, 2),
+(710201, '新兴区', 710200, 3),
+(710202, '前金区', 710200, 3),
+(710203, '苓雅区', 710200, 3),
+(710204, '盐埕区', 710200, 3),
+(710205, '鼓山区', 710200, 3),
+(710206, '旗津区', 710200, 3),
+(710207, '前镇区', 710200, 3),
+(710208, '三民区', 710200, 3),
+(710209, '左营区', 710200, 3),
+(710210, '楠梓区', 710200, 3),
+(710211, '小港区', 710200, 3),
+(710242, '仁武区', 710200, 3),
+(710243, '大社区', 710200, 3),
+(710244, '冈山区', 710200, 3),
+(710245, '路竹区', 710200, 3),
+(710246, '阿莲区', 710200, 3),
+(710247, '田寮区', 710200, 3),
+(710248, '燕巢区', 710200, 3),
+(710249, '桥头区', 710200, 3),
+(710250, '梓官区', 710200, 3),
+(710251, '弥陀区', 710200, 3),
+(710252, '永安区', 710200, 3),
+(710253, '湖内区', 710200, 3),
+(710254, '凤山区', 710200, 3),
+(710255, '大寮区', 710200, 3),
+(710256, '林园区', 710200, 3),
+(710257, '鸟松区', 710200, 3),
+(710258, '大树区', 710200, 3),
+(710259, '旗山区', 710200, 3),
+(710260, '美浓区', 710200, 3),
+(710261, '六龟区', 710200, 3),
+(710262, '内门区', 710200, 3),
+(710263, '杉林区', 710200, 3),
+(710264, '甲仙区', 710200, 3),
+(710265, '桃源区', 710200, 3),
+(710266, '那玛夏区', 710200, 3),
+(710267, '茂林区', 710200, 3),
+(710268, '茄萣区', 710200, 3),
+(710300, '台南市', 710000, 2),
+(710301, '中西区', 710300, 3),
+(710302, '东区', 710300, 3),
+(710303, '南区', 710300, 3),
+(710304, '北区', 710300, 3),
+(710305, '安平区', 710300, 3),
+(710306, '安南区', 710300, 3),
+(710339, '永康区', 710300, 3),
+(710340, '归仁区', 710300, 3),
+(710341, '新化区', 710300, 3),
+(710342, '左镇区', 710300, 3),
+(710343, '玉井区', 710300, 3),
+(710344, '楠西区', 710300, 3),
+(710345, '南化区', 710300, 3),
+(710346, '仁德区', 710300, 3),
+(710347, '关庙区', 710300, 3),
+(710348, '龙崎区', 710300, 3),
+(710349, '官田区', 710300, 3),
+(710350, '麻豆区', 710300, 3),
+(710351, '佳里区', 710300, 3),
+(710352, '西港区', 710300, 3),
+(710353, '七股区', 710300, 3),
+(710354, '将军区', 710300, 3),
+(710355, '学甲区', 710300, 3),
+(710356, '北门区', 710300, 3),
+(710357, '新营区', 710300, 3),
+(710358, '后壁区', 710300, 3),
+(710359, '白河区', 710300, 3),
+(710360, '东山区', 710300, 3),
+(710361, '六甲区', 710300, 3),
+(710362, '下营区', 710300, 3),
+(710363, '柳营区', 710300, 3),
+(710364, '盐水区', 710300, 3),
+(710365, '善化区', 710300, 3),
+(710366, '大内区', 710300, 3),
+(710367, '山上区', 710300, 3),
+(710368, '新市区', 710300, 3),
+(710369, '安定区', 710300, 3),
+(710400, '台中市', 710000, 2),
+(710401, '中区', 710400, 3),
+(710402, '东区', 710400, 3),
+(710403, '南区', 710400, 3),
+(710404, '西区', 710400, 3),
+(710405, '北区', 710400, 3),
+(710406, '北屯区', 710400, 3),
+(710407, '西屯区', 710400, 3),
+(710408, '南屯区', 710400, 3),
+(710431, '太平区', 710400, 3),
+(710432, '大里区', 710400, 3),
+(710433, '雾峰区', 710400, 3),
+(710434, '乌日区', 710400, 3),
+(710435, '丰原区', 710400, 3),
+(710436, '后里区', 710400, 3),
+(710437, '石冈区', 710400, 3),
+(710438, '东势区', 710400, 3),
+(710439, '和平区', 710400, 3),
+(710440, '新社区', 710400, 3),
+(710441, '潭子区', 710400, 3),
+(710442, '大雅区', 710400, 3),
+(710443, '神冈区', 710400, 3),
+(710444, '大肚区', 710400, 3),
+(710445, '沙鹿区', 710400, 3),
+(710446, '龙井区', 710400, 3),
+(710447, '梧栖区', 710400, 3),
+(710448, '清水区', 710400, 3),
+(710449, '大甲区', 710400, 3),
+(710450, '外埔区', 710400, 3),
+(710451, '大安区', 710400, 3),
+(710600, '南投县', 710000, 2),
+(710614, '南投市', 710600, 3),
+(710615, '中寮乡', 710600, 3),
+(710616, '草屯镇', 710600, 3),
+(710617, '国姓乡', 710600, 3),
+(710618, '埔里镇', 710600, 3),
+(710619, '仁爱乡', 710600, 3),
+(710620, '名间乡', 710600, 3),
+(710621, '集集镇', 710600, 3),
+(710622, '水里乡', 710600, 3),
+(710623, '鱼池乡', 710600, 3),
+(710624, '信义乡', 710600, 3),
+(710625, '竹山镇', 710600, 3),
+(710626, '鹿谷乡', 710600, 3),
+(710700, '基隆市', 710000, 2),
+(710701, '仁爱区', 710700, 3),
+(710702, '信义区', 710700, 3),
+(710703, '中正区', 710700, 3),
+(710704, '中山区', 710700, 3),
+(710705, '安乐区', 710700, 3),
+(710706, '暖暖区', 710700, 3),
+(710707, '七堵区', 710700, 3),
+(710800, '新竹市', 710000, 2),
+(710801, '东区', 710800, 3),
+(710802, '北区', 710800, 3),
+(710803, '香山区', 710800, 3),
+(710900, '嘉义市', 710000, 2),
+(710901, '东区', 710900, 3),
+(710902, '西区', 710900, 3),
+(711100, '新北市', 710000, 2),
+(711130, '万里区', 711100, 3),
+(711131, '金山区', 711100, 3),
+(711132, '板桥区', 711100, 3),
+(711133, '汐止区', 711100, 3),
+(711134, '深坑区', 711100, 3),
+(711135, '石碇区', 711100, 3),
+(711136, '瑞芳区', 711100, 3),
+(711137, '平溪区', 711100, 3),
+(711138, '双溪区', 711100, 3),
+(711139, '贡寮区', 711100, 3),
+(711140, '新店区', 711100, 3),
+(711141, '坪林区', 711100, 3),
+(711142, '乌来区', 711100, 3),
+(711143, '永和区', 711100, 3),
+(711144, '中和区', 711100, 3),
+(711145, '土城区', 711100, 3),
+(711146, '三峡区', 711100, 3),
+(711147, '树林区', 711100, 3),
+(711148, '莺歌区', 711100, 3),
+(711149, '三重区', 711100, 3),
+(711150, '新庄区', 711100, 3),
+(711151, '泰山区', 711100, 3),
+(711152, '林口区', 711100, 3),
+(711153, '芦洲区', 711100, 3),
+(711154, '五股区', 711100, 3),
+(711155, '八里区', 711100, 3),
+(711156, '淡水区', 711100, 3),
+(711157, '三芝区', 711100, 3),
+(711158, '石门区', 711100, 3),
+(711200, '宜兰县', 710000, 2),
+(711214, '宜兰市', 711200, 3),
+(711215, '头城镇', 711200, 3),
+(711216, '礁溪乡', 711200, 3),
+(711217, '壮围乡', 711200, 3),
+(711218, '员山乡', 711200, 3),
+(711219, '罗东镇', 711200, 3),
+(711220, '三星乡', 711200, 3),
+(711221, '大同乡', 711200, 3),
+(711222, '五结乡', 711200, 3),
+(711223, '冬山乡', 711200, 3),
+(711224, '苏澳镇', 711200, 3),
+(711225, '南澳乡', 711200, 3),
+(711300, '新竹县', 710000, 2),
+(711314, '竹北市', 711300, 3),
+(711315, '湖口乡', 711300, 3),
+(711316, '新丰乡', 711300, 3),
+(711317, '新埔镇', 711300, 3),
+(711318, '关西镇', 711300, 3),
+(711319, '芎林乡', 711300, 3),
+(711320, '宝山乡', 711300, 3),
+(711321, '竹东镇', 711300, 3),
+(711322, '五峰乡', 711300, 3),
+(711323, '横山乡', 711300, 3),
+(711324, '尖石乡', 711300, 3),
+(711325, '北埔乡', 711300, 3),
+(711326, '峨眉乡', 711300, 3),
+(711400, '桃园市', 710000, 2),
+(711414, '中坜区', 711400, 3),
+(711415, '平镇区', 711400, 3),
+(711416, '龙潭区', 711400, 3),
+(711417, '杨梅区', 711400, 3),
+(711418, '新屋区', 711400, 3),
+(711419, '观音区', 711400, 3),
+(711420, '桃园区', 711400, 3),
+(711421, '龟山区', 711400, 3),
+(711422, '八德区', 711400, 3),
+(711423, '大溪区', 711400, 3),
+(711424, '复兴区', 711400, 3),
+(711425, '大园区', 711400, 3),
+(711426, '芦竹区', 711400, 3),
+(711500, '苗栗县', 710000, 2),
+(711519, '竹南镇', 711500, 3),
+(711520, '头份市', 711500, 3),
+(711521, '三湾乡', 711500, 3),
+(711522, '南庄乡', 711500, 3),
+(711523, '狮潭乡', 711500, 3),
+(711524, '后龙镇', 711500, 3),
+(711525, '通霄镇', 711500, 3),
+(711526, '苑里镇', 711500, 3),
+(711527, '苗栗市', 711500, 3),
+(711528, '造桥乡', 711500, 3),
+(711529, '头屋乡', 711500, 3),
+(711530, '公馆乡', 711500, 3),
+(711531, '大湖乡', 711500, 3),
+(711532, '泰安乡', 711500, 3),
+(711533, '铜锣乡', 711500, 3),
+(711534, '三义乡', 711500, 3),
+(711535, '西湖乡', 711500, 3),
+(711536, '卓兰镇', 711500, 3),
+(711700, '彰化县', 710000, 2),
+(711727, '彰化市', 711700, 3),
+(711728, '芬园乡', 711700, 3),
+(711729, '花坛乡', 711700, 3),
+(711730, '秀水乡', 711700, 3),
+(711731, '鹿港镇', 711700, 3),
+(711732, '福兴乡', 711700, 3),
+(711733, '线西乡', 711700, 3),
+(711734, '和美镇', 711700, 3),
+(711735, '伸港乡', 711700, 3),
+(711736, '员林市', 711700, 3),
+(711737, '社头乡', 711700, 3),
+(711738, '永靖乡', 711700, 3),
+(711739, '埔心乡', 711700, 3),
+(711740, '溪湖镇', 711700, 3),
+(711741, '大村乡', 711700, 3),
+(711742, '埔盐乡', 711700, 3),
+(711743, '田中镇', 711700, 3),
+(711744, '北斗镇', 711700, 3),
+(711745, '田尾乡', 711700, 3),
+(711746, '埤头乡', 711700, 3),
+(711747, '溪州乡', 711700, 3),
+(711748, '竹塘乡', 711700, 3),
+(711749, '二林镇', 711700, 3),
+(711750, '大城乡', 711700, 3),
+(711751, '芳苑乡', 711700, 3),
+(711752, '二水乡', 711700, 3),
+(711900, '嘉义县', 710000, 2),
+(711919, '番路乡', 711900, 3),
+(711920, '梅山乡', 711900, 3),
+(711921, '竹崎乡', 711900, 3),
+(711922, '阿里山乡', 711900, 3),
+(711923, '中埔乡', 711900, 3),
+(711924, '大埔乡', 711900, 3),
+(711925, '水上乡', 711900, 3),
+(711926, '鹿草乡', 711900, 3),
+(711927, '太保市', 711900, 3),
+(711928, '朴子市', 711900, 3),
+(711929, '东石乡', 711900, 3),
+(711930, '六脚乡', 711900, 3),
+(711931, '新港乡', 711900, 3),
+(711932, '民雄乡', 711900, 3),
+(711933, '大林镇', 711900, 3),
+(711934, '溪口乡', 711900, 3),
+(711935, '义竹乡', 711900, 3),
+(711936, '布袋镇', 711900, 3),
+(712100, '云林县', 710000, 2),
+(712121, '斗南镇', 712100, 3),
+(712122, '大埤乡', 712100, 3),
+(712123, '虎尾镇', 712100, 3),
+(712124, '土库镇', 712100, 3),
+(712125, '褒忠乡', 712100, 3),
+(712126, '东势乡', 712100, 3),
+(712127, '台西乡', 712100, 3),
+(712128, '仑背乡', 712100, 3),
+(712129, '麦寮乡', 712100, 3),
+(712130, '斗六市', 712100, 3),
+(712131, '林内乡', 712100, 3),
+(712132, '古坑乡', 712100, 3),
+(712133, '莿桐乡', 712100, 3),
+(712134, '西螺镇', 712100, 3),
+(712135, '二仑乡', 712100, 3),
+(712136, '北港镇', 712100, 3),
+(712137, '水林乡', 712100, 3),
+(712138, '口湖乡', 712100, 3),
+(712139, '四湖乡', 712100, 3),
+(712140, '元长乡', 712100, 3),
+(712400, '屏东县', 710000, 2),
+(712434, '屏东市', 712400, 3),
+(712435, '三地门乡', 712400, 3),
+(712436, '雾台乡', 712400, 3),
+(712437, '玛家乡', 712400, 3),
+(712438, '九如乡', 712400, 3),
+(712439, '里港乡', 712400, 3),
+(712440, '高树乡', 712400, 3),
+(712441, '盐埔乡', 712400, 3),
+(712442, '长治乡', 712400, 3),
+(712443, '麟洛乡', 712400, 3),
+(712444, '竹田乡', 712400, 3),
+(712445, '内埔乡', 712400, 3),
+(712446, '万丹乡', 712400, 3),
+(712447, '潮州镇', 712400, 3),
+(712448, '泰武乡', 712400, 3),
+(712449, '来义乡', 712400, 3),
+(712450, '万峦乡', 712400, 3),
+(712451, '崁顶乡', 712400, 3),
+(712452, '新埤乡', 712400, 3),
+(712453, '南州乡', 712400, 3),
+(712454, '林边乡', 712400, 3),
+(712455, '东港镇', 712400, 3),
+(712456, '琉球乡', 712400, 3),
+(712457, '佳冬乡', 712400, 3),
+(712458, '新园乡', 712400, 3),
+(712459, '枋寮乡', 712400, 3),
+(712460, '枋山乡', 712400, 3),
+(712461, '春日乡', 712400, 3),
+(712462, '狮子乡', 712400, 3),
+(712463, '车城乡', 712400, 3),
+(712464, '牡丹乡', 712400, 3),
+(712465, '恒春镇', 712400, 3),
+(712466, '满州乡', 712400, 3),
+(712500, '台东县', 710000, 2),
+(712517, '台东市', 712500, 3),
+(712518, '绿岛乡', 712500, 3),
+(712519, '兰屿乡', 712500, 3),
+(712520, '延平乡', 712500, 3),
+(712521, '卑南乡', 712500, 3),
+(712522, '鹿野乡', 712500, 3),
+(712523, '关山镇', 712500, 3),
+(712524, '海端乡', 712500, 3),
+(712525, '池上乡', 712500, 3),
+(712526, '东河乡', 712500, 3),
+(712527, '成功镇', 712500, 3),
+(712528, '长滨乡', 712500, 3),
+(712529, '金峰乡', 712500, 3),
+(712530, '大武乡', 712500, 3),
+(712531, '达仁乡', 712500, 3),
+(712532, '太麻里乡', 712500, 3),
+(712600, '花莲县', 710000, 2),
+(712615, '花莲市', 712600, 3),
+(712616, '新城乡', 712600, 3),
+(712618, '秀林乡', 712600, 3),
+(712619, '吉安乡', 712600, 3),
+(712620, '寿丰乡', 712600, 3),
+(712621, '凤林镇', 712600, 3),
+(712622, '光复乡', 712600, 3),
+(712623, '丰滨乡', 712600, 3),
+(712624, '瑞穗乡', 712600, 3),
+(712625, '万荣乡', 712600, 3),
+(712626, '玉里镇', 712600, 3),
+(712627, '卓溪乡', 712600, 3),
+(712628, '富里乡', 712600, 3),
+(712700, '澎湖县', 710000, 2),
+(712707, '马公市', 712700, 3),
+(712708, '西屿乡', 712700, 3),
+(712709, '望安乡', 712700, 3),
+(712710, '七美乡', 712700, 3),
+(712711, '白沙乡', 712700, 3),
+(712712, '湖西乡', 712700, 3),
+(810000, '香港特别行政区', 0, 1),
+(810100, '香港特别行政区', 810000, 2),
+(810101, '中西区', 810100, 3),
+(810102, '东区', 810100, 3),
+(810103, '九龙城区', 810100, 3),
+(810104, '观塘区', 810100, 3),
+(810105, '南区', 810100, 3),
+(810106, '深水埗区', 810100, 3),
+(810107, '湾仔区', 810100, 3),
+(810108, '黄大仙区', 810100, 3),
+(810109, '油尖旺区', 810100, 3),
+(810110, '离岛区', 810100, 3),
+(810111, '葵青区', 810100, 3),
+(810112, '北区', 810100, 3),
+(810113, '西贡区', 810100, 3),
+(810114, '沙田区', 810100, 3),
+(810115, '屯门区', 810100, 3),
+(810116, '大埔区', 810100, 3),
+(810117, '荃湾区', 810100, 3),
+(810118, '元朗区', 810100, 3),
+(820000, '澳门特别行政区', 0, 1),
+(820100, '澳门特别行政区', 820000, 2),
+(820101, '澳门半岛', 820100, 3),
+(820102, '凼仔', 820100, 3),
+(820103, '路凼城', 820100, 3),
+(820104, '路环', 820100, 3);
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_cart` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) DEFAULT NULL COMMENT '用户',
+  `goods_id` int(11) DEFAULT NULL,
+  `goods_num` int(11) DEFAULT NULL,
+  `sku_price_id` int(11) DEFAULT NULL COMMENT '规格',
+  `createtime` int(11) DEFAULT NULL,
+  `updatetime` int(11) DEFAULT NULL,
+  `deletetime` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='购物车';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_category` (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `name` varchar(30) NOT NULL DEFAULT '',
+  `type` varchar(30) NOT NULL DEFAULT '' COMMENT '栏目类型',
+  `image` varchar(100) NOT NULL DEFAULT '' COMMENT '图片',
+  `pid` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '父ID',
+  `weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
+  `description` varchar(255) NOT NULL DEFAULT '' COMMENT '描述',
+  `status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
+  `createtime` int(10) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `pid` (`pid`) USING BTREE,
+  KEY `weigh_id` (`weigh`,`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城分类表';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_config` (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `name` varchar(30) NOT NULL DEFAULT '' COMMENT '变量名',
+  `group` varchar(30) NOT NULL DEFAULT '' COMMENT '分组',
+  `title` varchar(100) NOT NULL DEFAULT '' COMMENT '变量标题',
+  `tip` varchar(100) NOT NULL DEFAULT '' COMMENT '变量描述',
+  `type` varchar(30) NOT NULL DEFAULT '' COMMENT '类型:string,text,int,bool,array,datetime,date,file',
+  `value` longtext NOT NULL COMMENT '变量值',
+  `content` longtext DEFAULT NULL COMMENT '变量字典数据',
+  `rule` varchar(100) NOT NULL DEFAULT '' COMMENT '验证规则',
+  `extend` varchar(255) NOT NULL DEFAULT '' COMMENT '扩展属性',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `name` (`name`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商城配置';
+
+INSERT INTO `__PREFIX__shopro_config` (`id`, `name`, `group`, `title`, `tip`, `type`, `value`, `content`, `rule`, `extend`) VALUES 
+(1, 'shopro', 'basic', '商城信息', '', 'array', '{\"name\":\"Shopro\",\"domain\":\"https://m.shopro.top/\",\"version\":\"1.3.0\",\"logo\":\"http://file.shopro.top/uploads/20200410/d5b2c163e9a23d78c7205d9ab5d7e47c.png\",\"copyright\":[\"星品科技Shopro版权所有\",\"Copyright 2020-2021\"],\"user_protocol\":1,\"privacy_protocol\":2,\"about_us\":3}', NULL, '', ''),
+(2, 'user', 'basic', '会员配置', '', 'array', '{\"nickname\":\"Shopro-\",\"avatar\":\"http://file.shopro.top/uploads/20200410/default-avatar.png\",\"group_id\":\"1\"}', NULL, '', ''),
+(3, 'share', 'basic', '分享配置', '', 'array', '{\"title\":\"邀请有好礼\",\"image\":\"http://file.shopro.top/uploads/20200410/4be7c944935a0fd6fc890f0214e6c3e0.jpeg\",\"goods_poster_bg\":\"http://file.shopro.top/uploads/20200410/ab863760d809b0d0bfdf5eed24fecb61.png\",\"user_poster_bg\":\"http://file.shopro.top/uploads/20200410/000fada6ece566b12ccfc348861fedf6.png\",\"groupon_poster_bg\":\"http://file.shopro.top/uploads/20200410/c65b86f0ffb7f334fe7ca7528d2bb44a.png\"}', NULL, '', ''),
+(4, 'score', 'basic', '积分配置', '', 'array', '{\"everyday\":\"1\",\"until_day\":\"1\",\"inc_value\":\"7\"}', NULL, '', ''),
+(5, 'withdraw', 'basic', '提现配置', '', 'array', '{\"methods\":[\"wechat\",\"alipay\",\"bank\"],\"wechat_alipay_auto\":\"0\",\"service_fee\":\"0.03\",\"min\":\"100\",\"max\":\"1000\"}', NULL, '', ''),
+(6, 'order', 'basic', '商城配置', '', 'array', '{\"order_auto_close\":\"15\",\"order_auto_confirm\":\"6\",\"order_auto_comment\":\"3\",\"order_comment_content\":\"客户默认好评~\",\"goods\":{\"stock_warning\":\"20\"}}', NULL, '', ''),
+(7, 'services', 'basic', '第三方服务', '', 'array', '{\"amap\":{\"appkey\":\"654b72d9fd8a1*********6156be7f\"},\"express\":{\"ebusiness_id\":\"1655***\",\"type\":\"free\",\"appkey\":\"af70d0-******-3eda4ae78fb2\",\"jd_code\":\"001K1***50\",\"Sender\":{\"Name\":\"\",\"Mobile\":\"\",\"ProvinceName\":\"\",\"CityName\":\"\",\"ExpAreaName\":\"\",\"Address\":\"\"},\"PayType\":1,\"ExpType\":1,\"CustomerName\":\"\",\"CustomerPwd\":\"\",\"ShipperCode\":\"\"}}', NULL, '', ''),
+(8, 'chat', 'basic', '客服配置', '', 'array', '{\"type\":\"shopro\",\"basic\":{\"last_customer_service\":1,\"allocate\":\"busy\",\"notice\":\"显示在用户端头部\"},\"system\":{\"is_ssl\":1,\"ssl_cert\":\"/www/server/panel/vhost/cert/****/fullchain.pem\",\"ssl_key\":\"/www/server/panel/vhost/cert/****/privkey.pem\",\"gateway_port\":1819,\"gateway_num\":2,\"gateway_start_port\":2010,\"business_worker_port\":2238,\"business_worker_num\":4}}', NULL, '', ''),
+(9, 'store', 'basic', '门店配置', '', 'array', '{\"protocol\":\"\",\"selfetch_protocol\":\"\"}', NULL, '', ''),
+(10, 'wxOfficialAccount', 'platform', '微信公众号', '', 'array', '{\"name\":\"\",\"wx_type\":\"4\",\"avatar\":\"\",\"qrcode\":\"\",\"app_id\":\"\",\"secret\":\"\",\"url\":\"http://demo.shopro.top/addons/shopro/wechat\",\"token\":\"\",\"aes_key\":\"\",\"auto_login\":\"1\",\"status\":\"0\"}', NULL, '', ''),
+(11, 'wxMiniProgram', 'platform', '小程序', '', 'array', '{\"name\":\"\",\"avatar\":\"\",\"qrcode\":\"\",\"app_id\":\"\",\"secret\":\"\",\"auto_login\":\"1\"}', NULL, '', ''),
+(12, 'H5', 'platform', 'H5', '', 'array', '{\"app_id\":\"\",\"secret\":\"\"}', NULL, '', ''),
+(13, 'App', 'platform', 'App', '', 'array', '{\"app_id\":\"\",\"secret\":\"\"}', NULL, '', '');
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_coupons` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(50) DEFAULT NULL COMMENT '名称',
+  `type` enum('cash','discount') NOT NULL DEFAULT 'cash' COMMENT '类型:cash=代金券,discount=折扣券',
+  `goods_ids` varchar(1200) DEFAULT NULL COMMENT '适用商品',
+  `amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '券面额',
+  `enough` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '消费门槛',
+  `stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存',
+  `limit` int(11) NOT NULL DEFAULT '1' COMMENT '每人限制',
+  `gettime` varchar(50) DEFAULT NULL COMMENT '领取周期',
+  `usetime` varchar(50) DEFAULT NULL COMMENT '有效期',
+  `description` varchar(255) DEFAULT NULL COMMENT '描述',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  `usetimestart` int(11) DEFAULT NULL,
+  `usetimeend` int(11) DEFAULT NULL,
+  `gettimestart` int(11) DEFAULT NULL,
+  `gettimeend` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='优惠券';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_decorate` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(50) DEFAULT NULL COMMENT '模板名称',
+  `type` enum('shop','custom','preview') NOT NULL DEFAULT 'shop' COMMENT '页面分类:shop=商城,custom=自定义,preview=临时预览',
+  `image` varchar(255) DEFAULT NULL COMMENT '图片',
+  `memo` varchar(255) DEFAULT NULL COMMENT '备注',
+  `status` enum('normal','hidden') DEFAULT 'normal' COMMENT '状态',
+  `platform` set('H5','wxOfficialAccount','wxMiniProgram','App','preview') DEFAULT NULL COMMENT '适用平台:H5=H5,wxOfficialAccount=微信公众号网页,wxMiniProgram=微信小程序,App=App,preview=预览',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店铺装修';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_decorate_content` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `type` varchar(20) DEFAULT NULL COMMENT '类型',
+  `category` enum('home','user','tabbar','popup','custom','float-button') NOT NULL COMMENT '页面类型:home=首页,user=个人中心,tabbar=底部导航,popup=弹出提醒,float-button=悬浮按钮,custom=自定义',
+  `name` varchar(50) DEFAULT NULL COMMENT '名称',
+  `content` text COMMENT '规则',
+  `decorate_id` int(11) DEFAULT NULL COMMENT '归属模板ID',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='模板内容';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_dispatch` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(50) DEFAULT NULL COMMENT '名称',
+  `type` enum('express','selfetch','store','autosend') NOT NULL COMMENT '发货方式:express=物流快递,selfetch=用户自提,store=商户配送,autosend=自动发货',
+  `type_ids` varchar(255) DEFAULT NULL COMMENT '包含模板',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='发货设置';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_dispatch_autosend` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `type` enum('card','text','params') NOT NULL COMMENT '自动发货类型:card=卡密,text=固定内容,params=自定义内容',
+  `content` varchar(1200) NOT NULL COMMENT '发货内容',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='自动发货';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_dispatch_express` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `type` enum('number','weight') DEFAULT NULL COMMENT '计费方式:number=件数,weight=重量',
+  `weigh` int(11) DEFAULT NULL COMMENT '权重',
+  `first_num` int(11) NOT NULL DEFAULT '1' COMMENT '首(重/件)数',
+  `first_price` decimal(10,2) DEFAULT '0.00' COMMENT '首(重/件)',
+  `additional_num` int(11) NOT NULL DEFAULT '0' COMMENT '续(重/件)数',
+  `additional_price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '续(重/件)',
+  `province_ids` varchar(255) DEFAULT NULL COMMENT '省份',
+  `city_ids` varchar(2500) DEFAULT NULL COMMENT '市级',
+  `area_ids` text COMMENT '区域',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='运费模板';
+
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_dispatch_selfetch` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `store_ids` varchar(255) NOT NULL COMMENT '包含门店',
+  `expire_type` enum('day','time') NOT NULL DEFAULT 'day' COMMENT '过期类型:day=天数,time=截至日期',
+  `expire_day` int(11) NOT NULL DEFAULT '0' COMMENT 'X天过期',
+  `expire_time` int(11) NOT NULL DEFAULT '0' COMMENT '截至日期',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='自提点';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_dispatch_store` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `store_ids` varchar(255) NOT NULL COMMENT '包含门店',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商家配送';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_failed_job` (
+  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '失败队列',
+  `data` varchar(2048) DEFAULT NULL COMMENT '数据',
+  `createtime` int(10) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_faq` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) DEFAULT NULL COMMENT '标题',
+  `content` longtext COMMENT '内容',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='常见问题';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_feedback` (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL COMMENT '反馈用户',
+  `type` varchar(30) DEFAULT NULL COMMENT '反馈类型',
+  `content` varchar(255) DEFAULT NULL COMMENT '反馈内容',
+  `images` varchar(512) DEFAULT NULL COMMENT '图片',
+  `phone` varchar(30) DEFAULT NULL COMMENT '联系电话',
+  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否处理:0=未处理,1=已处理',
+  `remark` varchar(191) DEFAULT NULL COMMENT '处理备注',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='意见反馈';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_goods` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `type` enum('normal','virtual') NOT NULL DEFAULT 'normal' COMMENT '商品类型:normal=实体商品,virtual=虚拟商品',
+  `title` varchar(100) NOT NULL COMMENT '标题',
+  `subtitle` varchar(255) DEFAULT NULL COMMENT '副标题',
+  `status` enum('up','hidden','down') DEFAULT NULL COMMENT '商品状态:up=上架,hidden=隐藏商品,down=下架',
+  `weigh` int(11) NOT NULL DEFAULT '0' COMMENT '排序(从大到小)',
+  `category_ids` varchar(120) DEFAULT NULL COMMENT '所属分类',
+  `image` varchar(255) DEFAULT NULL COMMENT '商品主图',
+  `images` varchar(2500) DEFAULT NULL COMMENT '轮播图',
+  `params` varchar(2500) DEFAULT NULL COMMENT '参数详情',
+  `content` text COMMENT '图文详情',
+  `price` varchar(20) NOT NULL COMMENT '价格',
+  `original_price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '原价',
+  `is_sku` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否多规格',
+  `likes` int(11) NOT NULL DEFAULT '0' COMMENT '收藏人数',
+  `views` int(11) NOT NULL DEFAULT '0' COMMENT '浏览人数',
+  `sales` int(11) NOT NULL DEFAULT '0' COMMENT '销量',
+  `show_sales` int(11) NOT NULL COMMENT '显示销量',
+  `service_ids` varchar(255) DEFAULT NULL COMMENT '服务标签',
+  `dispatch_type` set('express','selfetch','store','autosend') DEFAULT NULL COMMENT '发货方式:express=物流快递,selfetch=用户自提,store=商家配送,autosend=自动发货',
+  `dispatch_ids` varchar(255) DEFAULT NULL COMMENT '发货模板',
+  `createtime` int(11) DEFAULT NULL COMMENT '添加时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_goods_comment` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '评论 id',
+  `goods_id` int(11) NOT NULL DEFAULT '0' COMMENT '商品',
+  `order_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单',
+  `order_item_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单商品',
+  `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户',
+  `level` tinyint(4) NOT NULL DEFAULT '0' COMMENT '评价星级',
+  `content` varchar(255) DEFAULT NULL COMMENT '评价内容',
+  `images` varchar(2500) DEFAULT NULL COMMENT '评价图片',
+  `status` enum('show','hidden') NOT NULL DEFAULT 'show' COMMENT '显示状态',
+  `admin_id` int(11) NOT NULL DEFAULT '0' COMMENT '管理员 id',
+  `reply_content` varchar(255) DEFAULT NULL COMMENT '回复内容',
+  `replytime` int(11) DEFAULT NULL COMMENT '回复时间',
+  `createtime` int(11) DEFAULT NULL COMMENT '评论时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品评价';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_goods_service` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(10) DEFAULT NULL COMMENT '名称',
+  `image` varchar(255) DEFAULT NULL COMMENT '服务标志',
+  `description` varchar(127) DEFAULT NULL COMMENT '描述',
+  `createtime` int(11) DEFAULT NULL,
+  `updatetime` int(11) DEFAULT NULL,
+  `deletetime` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='服务标签';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_goods_sku` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(50) DEFAULT NULL COMMENT '名称',
+  `pid` int(11) NOT NULL DEFAULT '0' COMMENT '所属规格',
+  `goods_id` int(11) NOT NULL COMMENT '产品',
+  `weigh` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品规格';
+
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_goods_sku_price` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `goods_sku_ids` varchar(255) DEFAULT NULL,
+  `goods_id` int(11) NOT NULL COMMENT '所属产品',
+  `weigh` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
+  `image` varchar(255) DEFAULT NULL COMMENT '缩略图',
+  `stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存',
+  `sales` int(11) NOT NULL DEFAULT '0' COMMENT '已售',
+  `sn` varchar(50) DEFAULT NULL COMMENT '货号',
+  `weight` int(11) DEFAULT NULL COMMENT '重量(kg)',
+  `price` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '价格',
+  `goods_sku_text` varchar(255) DEFAULT NULL COMMENT '中文规格',
+  `status` varchar(10) DEFAULT 'up' COMMENT '状态',
+  `createtime` int(11) DEFAULT NULL,
+  `updatetime` int(11) DEFAULT NULL,
+  `deletetime` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品规格';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_link` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(50) DEFAULT NULL COMMENT '名称',
+  `path` varchar(255) DEFAULT NULL COMMENT '路径',
+  `group` varchar(20) DEFAULT NULL COMMENT '所属分组',
+  `createtime` int(11) DEFAULT NULL,
+  `updatetime` int(11) DEFAULT NULL,
+  `deletetime` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='页面链接';
+
+INSERT INTO `__PREFIX__shopro_link` (`id`, `name`, `path`, `group`, `createtime`, `updatetime`, `deletetime`) VALUES 
+(1, '首页', '/pages/index/index', '商城', 1622197045, 1622197045, NULL),
+(2, '分类', '/pages/index/category', '商城', 1622197045, 1622197045, NULL),
+(3, '购物车', '/pages/index/cart', '商城', 1622197045, 1622197045, NULL),
+(4, '我的', '/pages/index/user', '商城', 1622197045, 1622197045, NULL),
+(5, '签到中心', '/pages/activity/sign/index', '应用', 1622197045, 1622197045, NULL),
+(6, '限时秒杀', '/pages/activity/seckill/list', '秒杀', 1622197045, 1622197045, NULL),
+(7, '今日必拼', '/pages/activity/groupon/list', '拼团', 1622197045, 1622197045, NULL),
+(8, '我的拼团', '/pages/activity/groupon/my-groupon', '拼团', 1622197045, 1622197045, NULL),
+(9, '积分商品', '/pages/app/score/list', '积分', 1622197045, 1622197045, NULL),
+(10, '优惠券中心', '/pages/app/coupon/list', '优惠券', 1622197045, 1622197045, NULL),
+(11, '优惠券详情', '/pages/app/coupon/detail', '优惠券', 1622197045, 1622197045, NULL),
+(12, '门店入驻', '/pages/app/merchant/apply', '门店', 1622197045, 1622197045, NULL),
+(13, '我的门店', '/pages/app/merchant/list', '门店', 1622197045, 1622197045, NULL),
+(14, '分销中心', '/pages/app/commission/index', '分销', 1622197045, 1622197045, NULL),
+(15, '我的团队', '/pages/app/commission/team', '分销', 1622197045, 1622197045, NULL),
+(16, '佣金明细', '/pages/app/commission/commission-log', '分销', 1622197045, 1622197045, NULL),
+(17, '分销订单', '/pages/app/commission/order', '分销', 1622197045, 1622197045, NULL),
+(18, '推广商品', '/pages/app/commission/goods', '分销', 1622197045, 1622197045, NULL),
+(19, '申请分销商', '/pages/app/commission/apply', '分销', 1622197045, 1622197045, NULL),
+(20, '分销排行', '/pages/app/commission/rankings', '分销', 1622197045, 1622197045, NULL),
+(21, '商品列表', '/pages/goods/list', '商品', 1622197045, 1622197045, NULL),
+(22, '商品详情', '/pages/goods/detail', '商品', 1622197045, 1622197045, NULL),
+(23, '订单列表', '/pages/order/list', '订单', 1622197045, 1622197045, NULL),
+(24, '售后列表', '/pages/order/after-sale/list', '订单', 1622197045, 1622197045, NULL),
+(25, '常见问题', '/pages/public/faq', '通用', 1622197045, 1622197045, NULL),
+(26, '问题反馈', '/pages/public/feedback', '通用', 1622197045, 1622197045, NULL),
+(27, '客服', '/pages/public/chat/index', '通用', 1622197045, 1622197045, NULL),
+(28, '搜索', '/pages/public/search', '通用', 1622197045, 1622197045, NULL),
+(29, '富文本', '/pages/public/richtext', '通用', 1622197045, 1622197045, NULL),
+(30, '外链', '/pages/public/webview', '通用', 1622197045, 1622197045, NULL),
+(31, '个人信息', '/pages/user/info', '用户', 1622197045, 1622197045, NULL),
+(32, '系统设置', '/pages/user/set', '通用', 1622197045, 1622197045, NULL),
+(33, '浏览足迹', '/pages/user/view-log', '用户', 1622197045, 1622197045, NULL),
+(34, '钱包', '/pages/user/wallet/index', '用户', 1622197045, 1622197045, NULL),
+(35, '提现', '/pages/user/wallet/withdraw', '用户', 1622197045, 1622197045, NULL),
+(36, '提现记录', '/pages/user/wallet/withdraw-log', '用户', 1622197045, 1622197045, NULL),
+(37, '积分余额', '/pages/user/wallet/score-balance', '积分', 1622197045, 1622197045, NULL),
+(38, '收货地址', '/pages/user/address/list', '用户', 1622197045, 1622197045, NULL),
+(39, '我的收藏', '/pages/user/favorite', '用户', 1622197045, 1622197045, NULL);
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_live` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(255) NOT NULL COMMENT '房间名',
+  `room_id` int(11) NOT NULL DEFAULT '0' COMMENT '房间 ID',
+  `cover_img` varchar(255) DEFAULT NULL COMMENT '房间背景',
+  `live_status` enum('101','102','103','104','105','106','107') NOT NULL COMMENT '直播状态:101=直播中,102=未开始,103=已结束,104=禁播,105=暂停中,106=异常,107=已过期',
+  `starttime` int(10) NOT NULL DEFAULT '0' COMMENT '开始时间',
+  `endtime` int(10) NOT NULL DEFAULT '0' COMMENT '结束时间',
+  `anchor_name` varchar(255) NOT NULL COMMENT '主播',
+  `anchor_img` varchar(255) DEFAULT NULL COMMENT '主播头像',
+  `share_img` varchar(255) DEFAULT NULL COMMENT '分享封面',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_live_goods` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `live_id` int(11) NOT NULL COMMENT '直播ID',
+  `name` varchar(255) NOT NULL COMMENT '商品名称',
+  `origin_price` decimal(10,2) NOT NULL COMMENT '原价',
+  `price` decimal(10,2) NOT NULL COMMENT '价格',
+  `max_price` decimal(10,2) NOT NULL COMMENT '最大价格',
+  `url` varchar(255) DEFAULT NULL COMMENT '商品链接',
+  `cover_img` varchar(255) DEFAULT NULL COMMENT '商品图片',
+  `createtime` int(10) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_live_link` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `live_id` int(11) NOT NULL COMMENT '直播ID',
+  `media_url` varchar(255) NOT NULL COMMENT '回放链接',
+  `create_time` datetime DEFAULT NULL COMMENT '回放创建时间',
+  `expire_time` datetime DEFAULT NULL COMMENT '回放过期时间',
+  `createtime` int(10) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_order` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `type` enum('goods','score') NOT NULL DEFAULT 'goods' COMMENT '订单类型:goods=商城订单,score=积分商城订单',
+  `order_sn` varchar(60) NOT NULL COMMENT '订单号',
+  `user_id` int(11) DEFAULT '0' COMMENT '用户',
+  `activity_type` varchar(255) DEFAULT NULL COMMENT '活动类型',
+  `goods_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '商品总价',
+  `dispatch_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '总运费',
+  `phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
+  `consignee` varchar(20) DEFAULT NULL COMMENT '收货人',
+  `province_name` varchar(20) DEFAULT NULL COMMENT '省',
+  `city_name` varchar(20) DEFAULT NULL COMMENT '市',
+  `area_name` varchar(20) DEFAULT NULL COMMENT '区',
+  `address` varchar(255) DEFAULT NULL COMMENT '详细地址',
+  `province_id` int(11) NOT NULL DEFAULT '0',
+  `city_id` int(11) NOT NULL DEFAULT '0',
+  `area_id` int(11) NOT NULL DEFAULT '0',
+  `status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '订单状态:-2=交易关闭,-1=已取消,0=未支付,1=已支付,2=已完成',
+  `memo` varchar(255) DEFAULT NULL COMMENT '商户备注',
+  `remark` varchar(255) DEFAULT NULL COMMENT '用户备注',
+  `total_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '订单总金额',
+  `score_amount` int(11) NOT NULL DEFAULT '0' COMMENT '积分总数',
+  `total_fee` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '支付金额',
+  `discount_fee` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '折扣总金额',
+  `coupon_fee` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '优惠券抵用金额',
+  `pay_fee` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '实际支付金额',
+  `score_fee` int(11) NOT NULL DEFAULT '0' COMMENT '积分支付数',
+  `goods_original_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '商品原价',
+  `coupons_id` int(11) NOT NULL DEFAULT '0' COMMENT '优惠券 id',
+  `transaction_id` varchar(60) DEFAULT NULL COMMENT '交易单号',
+  `payment_json` varchar(2500) DEFAULT NULL COMMENT '交易原始数据',
+  `pay_type` enum('wechat','alipay','wallet','score') DEFAULT NULL COMMENT '支付方式:wechat=微信支付,alipay=支付宝,wallet=钱包支付,score=积分支付',
+  `paytime` int(11) DEFAULT NULL COMMENT '支付时间',
+  `ext` varchar(255) DEFAULT NULL COMMENT '附加字段',
+  `platform` enum('H5','App','wxOfficialAccount','wxMiniProgram') DEFAULT NULL COMMENT '平台:H5=H5,wxOfficialAccount=微信公众号,wxMiniProgram=微信小程序,App=App',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `order_sn` (`order_sn`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单管理';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_order_action` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '操作记录 id',
+  `order_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单 id',
+  `order_item_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单商品id',
+  `oper_type` enum('user','store','admin','system') NOT NULL COMMENT '操作人类型',
+  `oper_id` int(11) NOT NULL DEFAULT '0' COMMENT '操作人 id',
+  `order_status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '订单状态',
+  `dispatch_status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '发货状态',
+  `comment_status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '评论状态',
+  `aftersale_status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '售后状态',
+  `refund_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '退款状态',
+  `remark` varchar(255) DEFAULT NULL COMMENT '操作备注',
+  `createtime` int(11) DEFAULT NULL COMMENT '操作时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单操作记录';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_order_item` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) DEFAULT NULL COMMENT '用户',
+  `order_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单',
+  `goods_id` int(11) NOT NULL DEFAULT '0' COMMENT '商品',
+  `goods_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'normal' COMMENT '商品类型:normal=实体商品,virtual=虚拟商品',
+  `goods_sku_price_id` int(11) NOT NULL DEFAULT '0' COMMENT '规格 id',
+  `activity_id` int(11) NOT NULL DEFAULT '0' COMMENT '活动 id',
+  `activity_type` varchar(255) DEFAULT NULL COMMENT '活动类型',
+  `item_goods_sku_price_id` int(11) NOT NULL DEFAULT '0' COMMENT '活动规格|积分商城规格 id',
+  `goods_sku_text` varchar(30) DEFAULT NULL COMMENT '规格名',
+  `goods_title` varchar(255) DEFAULT NULL COMMENT '商品名称',
+  `goods_image` varchar(255) DEFAULT NULL COMMENT '商品图片',
+  `goods_original_price` decimal(10,2) NOT NULL COMMENT '商品原价',
+  `discount_fee` decimal(10,2) DEFAULT NULL COMMENT '优惠费用',
+  `goods_price` decimal(10,2) NOT NULL COMMENT '商品价格',
+  `goods_num` int(11) NOT NULL DEFAULT '0' COMMENT '购买数量',
+  `pay_price` decimal(10, 2) NOT NULL COMMENT '支付金额(不含运费)',
+  `dispatch_status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '发货状态:0=未发货,1=已发货,2=已收货',
+  `dispatch_fee` decimal(10,2) DEFAULT NULL COMMENT '发货费用',
+  `dispatch_type` varchar(20) DEFAULT NULL COMMENT '发货方式',
+  `dispatch_id` int(11) DEFAULT NULL COMMENT '发货模板',
+  `store_id` int(11) NOT NULL DEFAULT 0 COMMENT '门店',
+  `aftersale_status` tinyint(2) NOT NULL COMMENT '售后状态:-1=拒绝,0=未申请,1=申请售后,2=售后完成',
+  `comment_status` tinyint(2) NOT NULL COMMENT '评价状态:0=未评价,1=已评价',
+  `refund_status` tinyint(1) DEFAULT NULL COMMENT '退款状态:-1=拒绝退款,0=无,1=申请中,2=同意',
+  `refund_fee` decimal(10,2) DEFAULT NULL COMMENT '退款金额',
+  `refund_msg` varchar(255) DEFAULT NULL COMMENT '退款原因',
+  `express_name` varchar(60) DEFAULT NULL COMMENT '快递公司',
+  `express_code` varchar(60) DEFAULT NULL COMMENT '快递公司编号',
+  `express_no` varchar(60) DEFAULT NULL COMMENT '快递单号',
+  `ext` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '附加字段',
+  `createtime` int(11) DEFAULT NULL COMMENT '添加时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单商品明细';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_refund_log` (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `order_sn` varchar(45) DEFAULT NULL COMMENT '商户订单号',
+  `refund_sn` varchar(45) DEFAULT NULL COMMENT '商户退款单号',
+  `order_item_id` varchar(45) DEFAULT NULL COMMENT '订单商品',
+  `pay_fee` decimal(10,2) DEFAULT NULL COMMENT '支付金额',
+  `refund_fee` decimal(10,2) DEFAULT NULL COMMENT '退款金额',
+  `pay_type` varchar(20) NOT NULL DEFAULT '' COMMENT '付款方式',
+  `status` tinyint(1) DEFAULT '0' COMMENT '退款状态:0=退款中,1=退款完成,-1=退款失败',
+  `payment_json` varchar(1024) DEFAULT NULL COMMENT '退款原始数据',
+  `createtime` int(10) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='退款日志';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_richtext` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `title` varchar(255) DEFAULT NULL COMMENT '标题',
+  `content` longtext COMMENT '内容',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='富文本';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_score_goods_sku_price` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `sku_price_id` int(11) NOT NULL DEFAULT '0' COMMENT '规格 id',
+  `goods_id` int(11) NOT NULL COMMENT '所属产品',
+  `status` enum('up','hidden','down') NOT NULL COMMENT '上架状态:up=上架,hidden=隐藏,down=下架',
+  `stock` int(11) NOT NULL DEFAULT '0' COMMENT '库存',
+  `sales` int(11) NOT NULL DEFAULT '0' COMMENT '已售',
+  `price` decimal(10,2) DEFAULT NULL COMMENT '价格',
+  `score` int(11) NOT NULL DEFAULT '0' COMMENT '积分',
+  `createtime` int(11) DEFAULT NULL,
+  `updatetime` int(11) DEFAULT NULL,
+  `deletetime` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='积分商城商品规格';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_share` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL COMMENT '用户',
+  `share_id` int(11) NOT NULL COMMENT '分享人',
+  `type` varchar(20) DEFAULT NULL COMMENT '识别类型',
+  `type_id` varchar(255) DEFAULT NULL COMMENT '识别标识',
+  `platform` varchar(20) DEFAULT NULL COMMENT '平台',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户分享';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_startup` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) DEFAULT '0' COMMENT '用户',
+  `platform` varchar(20) DEFAULT NULL COMMENT '终端',
+  `content` varchar(1200) DEFAULT NULL COMMENT '访问详情',
+  `ip` varchar(20) DEFAULT NULL COMMENT '客户端IP',
+  `createtime` int(11) DEFAULT NULL COMMENT '访问时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='客户端启动信息';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_address` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `is_default` enum('0','1') DEFAULT '0' COMMENT '默认',
+  `user_id` int(11) DEFAULT NULL COMMENT '用户',
+  `consignee` varchar(20) DEFAULT NULL COMMENT '收货人',
+  `phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
+  `province_name` varchar(20) DEFAULT NULL COMMENT '省',
+  `city_name` varchar(20) DEFAULT NULL COMMENT '市',
+  `area_name` varchar(20) DEFAULT NULL COMMENT '区',
+  `address` varchar(255) DEFAULT NULL COMMENT '详细地址',
+  `province_id` int(11) DEFAULT NULL,
+  `city_id` int(11) DEFAULT NULL,
+  `area_id` int(11) DEFAULT NULL,
+  `latitude` decimal(10, 6) NULL DEFAULT NULL COMMENT '纬度',
+  `longitude` decimal(10, 6) NULL DEFAULT NULL COMMENT '经度',
+  `createtime` int(11) DEFAULT NULL,
+  `updatetime` int(11) DEFAULT NULL,
+  `deletetime` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户地址';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_bank` (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL COMMENT '用户id',
+  `real_name` varchar(191) DEFAULT NULL COMMENT '真实姓名',
+  `bank_name` varchar(191) DEFAULT NULL COMMENT '银行名',
+  `card_no` varchar(191) DEFAULT NULL COMMENT '卡号',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='提现银行卡';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_coupons` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) DEFAULT NULL COMMENT '用户',
+  `coupons_id` int(11) DEFAULT NULL COMMENT '优惠券',
+  `use_order_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单 id',
+  `usetime` int(11) DEFAULT NULL COMMENT '使用时间',
+  `createtime` int(11) DEFAULT NULL COMMENT '领取时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户优惠券';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_fake` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `nickname` varchar(20) NOT NULL COMMENT '昵称',
+  `avatar` varchar(255) NOT NULL COMMENT '头像',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='虚拟用户';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_favorite` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) DEFAULT NULL COMMENT '用户',
+  `goods_id` int(11) DEFAULT NULL COMMENT '商品',
+  `createtime` int(11) DEFAULT NULL,
+  `updatetime` int(11) DEFAULT NULL,
+  `deletetime` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户收藏';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_oauth` (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `user_id` int(10) UNSIGNED DEFAULT '0' COMMENT '用户',
+  `provider` varchar(50) NOT NULL COMMENT '厂商',
+  `platform` varchar(50) NOT NULL COMMENT '平台',
+  `unionid` varchar(50) DEFAULT NULL COMMENT '厂商ID',
+  `openid` varchar(50) NOT NULL COMMENT '平台ID',
+  `nickname` varchar(255) DEFAULT '' COMMENT '昵称',
+  `sex` tinyint(1) DEFAULT '0' COMMENT '性别',
+  `country` varchar(50) DEFAULT NULL COMMENT '国家',
+  `province` varchar(50) DEFAULT '' COMMENT '省',
+  `city` varchar(50) DEFAULT '' COMMENT '市',
+  `headimgurl` varchar(500) DEFAULT '' COMMENT '头像',
+  `logintime` int(11) DEFAULT NULL COMMENT '登录时间',
+  `logincount` int(11) DEFAULT '0' COMMENT '累计登陆',
+  `expire_in` int(11) DEFAULT NULL COMMENT '过期周期(s)',
+  `expiretime` int(11) DEFAULT NULL COMMENT '过期时间',
+  `session_key` varchar(45) DEFAULT '' COMMENT 'session_key',
+  `refresh_token` varchar(110) DEFAULT NULL COMMENT 'refresh_token',
+  `access_token` varchar(110) DEFAULT NULL COMMENT 'access_token',
+  `createtime` int(10) DEFAULT '0' COMMENT '创建时间',
+  `updatetime` int(10) DEFAULT '0' COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='第三方授权';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_sign` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户',
+  `date` varchar(30) DEFAULT NULL COMMENT '签到日期',
+  `score` int(11) NOT NULL DEFAULT '0' COMMENT '所得积分',
+  `is_replenish` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否补签:0=正常,1=补签',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `date` (`date`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户签到';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_view` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户',
+  `goods_id` int(11) NOT NULL DEFAULT '0' COMMENT '商品',
+  `createtime` int(11) DEFAULT NULL COMMENT '添加时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户浏览记录';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_wallet_apply` (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL COMMENT '提现用户',
+  `money` decimal(10,2) NOT NULL COMMENT '提现金额',
+  `charge_money` decimal(10,2) NOT NULL COMMENT '手续费',
+  `service_fee` decimal(10,3) DEFAULT NULL COMMENT '手续费率',
+  `get_type` enum('bank') DEFAULT NULL COMMENT '收款类型:bank=银行卡',
+  `bank_id` int(11) NOT NULL DEFAULT '0' COMMENT '银行卡',
+  `real_name` varchar(30) DEFAULT NULL COMMENT '真实姓名',
+  `bank_info` varchar(255) DEFAULT NULL COMMENT '打款信息',
+  `status` tinyint(1) DEFAULT '0' COMMENT '提现状态:0=申请中,1=已打款,-1=已拒绝',
+  `status_msg` varchar(255) DEFAULT NULL COMMENT '驳回理由',
+  `createtime` int(11) DEFAULT NULL COMMENT '申请时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '操作时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户提现';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_wallet_log` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '日志 id',
+  `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户',
+  `wallet` decimal(10,2) NOT NULL COMMENT '变动金额',
+  `type` varchar(30) NOT NULL COMMENT '变动类型',
+  `wallet_type` enum('money','score') NOT NULL COMMENT '日志类型:money=余额,score=积分',
+  `item_id` varchar(60) DEFAULT NULL COMMENT '项目 id',
+  `ext` varchar(512) DEFAULT NULL COMMENT '附加字段',
+  `oper_type` enum('user','store','admin','system') CHARACTER SET utf8mb4 NOT NULL DEFAULT 'user' COMMENT '操作人类型',
+  `oper_id` int(11) NOT NULL DEFAULT 0 COMMENT '操作人',
+  `createtime` int(11) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='钱包日志';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_wechat` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `type` varchar(50) NOT NULL COMMENT '配置类型',
+  `name` varchar(50) NOT NULL COMMENT '名称',
+  `rules` varchar(255) CHARACTER SET utf8mb4  NULL DEFAULT NULL COMMENT '规则',
+  `content` text NOT NULL COMMENT '内容',
+  `createtime` int(11) NOT NULL COMMENT '创建时间',
+  `updatetime` int(11) NOT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='微信管理';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_wechat_fans` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `nickname` varchar(50) DEFAULT NULL COMMENT '粉丝昵称',
+  `headimgurl` varchar(255) NOT NULL COMMENT '粉丝头像',
+  `openid` varchar(30) NOT NULL COMMENT 'openid',
+  `sex` int(11) NOT NULL DEFAULT '0' COMMENT '性别',
+  `country` varchar(20) NOT NULL COMMENT '国家',
+  `province` varchar(20) NOT NULL COMMENT '省',
+  `city` varchar(20) NOT NULL COMMENT '市',
+  `subscribe` enum('0','1') NOT NULL COMMENT '关注状态:0=取消关注,1=已关注',
+  `subscribe_time` int(11) NOT NULL COMMENT '关注时间',
+  `createtime` int(11) NOT NULL COMMENT '创建时间',
+  `updatetime` int(11) NOT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='粉丝管理';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_notification` (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '消息表',
+  `type` varchar(60) NOT NULL COMMENT '消息类型',
+  `notifiable_id` int(10) UNSIGNED NOT NULL COMMENT '接收人',
+  `notifiable_type` varchar(255) NOT NULL COMMENT '接收人类型',
+  `data` text NOT NULL COMMENT '数据',
+  `readtime` int(10) DEFAULT NULL COMMENT '是否已读',
+  `createtime` int(10) DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(10) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  KEY `notifiable_id_notifiable_type` (`notifiable_id`,`notifiable_type`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='消息管理';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_notification_config` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `platform` varchar(50) NOT NULL COMMENT '发送平台',
+  `name` varchar(50) NOT NULL COMMENT '消息名称',
+  `event` varchar(50) NOT NULL COMMENT '消息事件',
+  `content` text COMMENT '消息内容',
+  `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:0=关闭,1=启用',
+  `sendnum` int(11) NOT NULL DEFAULT '0' COMMENT '发送次数',
+  `createtime` int(11) DEFAULT NULL,
+  `updatetime` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通知配置';
+
+ALTER TABLE `__PREFIX__shopro_goods` ADD COLUMN `show_sales` INT(10) NOT NULL DEFAULT 0 COMMENT '虚增销量' AFTER `sales`;
+ALTER TABLE `__PREFIX__shopro_goods` ADD COLUMN `is_sku` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否多规格' AFTER `original_price`;
+ALTER TABLE `__PREFIX__shopro_order` ADD COLUMN `activity_type` VARCHAR(255) DEFAULT NULL COMMENT '活动类型' AFTER `type`;
+ALTER TABLE `__PREFIX__shopro_order_item` ADD COLUMN `refund_msg` VARCHAR(255) DEFAULT NULL COMMENT '退款原因' AFTER `refund_fee`;
+ALTER TABLE `__PREFIX__shopro_activity` ADD COLUMN `richtext_id` INT(11) DEFAULT 0 COMMENT '活动说明' AFTER `type`;
+ALTER TABLE `__PREFIX__shopro_activity` ADD COLUMN `richtext_title` VARCHAR(255) DEFAULT '' COMMENT '说明标题' AFTER `type`;
+ALTER TABLE `__PREFIX__shopro_decorate` ADD COLUMN `type` enum('shop','custom','preview') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'shop' COMMENT '页面分类:shop=商城,custom=自定义,preview=临时预览' AFTER `name`;
+ALTER TABLE `__PREFIX__shopro_decorate` ADD COLUMN `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '图片' AFTER `type`;
+ALTER TABLE `__PREFIX__shopro_decorate_content` ADD COLUMN `category` enum('home','user','tabbar','popup','custom','float-button') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '页面类型:home=首页,user=个人中心,tabbar=底部导航,popup=弹出提醒,float-button=悬浮按钮,custom=自定义' AFTER `type`;
+
+-- 1.0.7更新 ↓
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_express` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `name` varchar(60) DEFAULT NULL COMMENT '快递公司',
+  `code` varchar(60) DEFAULT NULL COMMENT '编码',
+  `weigh` int(11) NOT NULL DEFAULT '0' COMMENT '权重',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='快递公司';
+INSERT INTO `__PREFIX__shopro_express` (`id`, `name`, `code`, `weigh`) VALUES
+(1, '顺丰速运', 'SF', 0),
+(2, '百世快递', 'HTKY', 0),
+(3, '中通快递', 'ZTO', 0),
+(4, '申通快递', 'STO', 0),
+(5, '圆通速递', 'YTO', 0),
+(6, '韵达速递', 'YD', 0),
+(7, '邮政快递包裹', 'YZPY', 0),
+(8, 'EMS', 'EMS', 0),
+(9, '天天快递', 'HHTT', 0),
+(10, '京东快递', 'JD', 0),
+(11, '优速快递', 'UC', 0),
+(12, '德邦快递', 'DBL', 0),
+(13, '宅急送', 'ZJS', 0),
+(14, '安捷快递', 'AJ', 0),
+(15, '阿里跨境电商物流', 'ALKJWL', 0),
+(16, '安迅物流', 'AX', 0),
+(17, '安邮美国', 'AYUS', 0),
+(18, '亚马逊物流', 'AMAZON', 0),
+(19, '澳门邮政', 'AOMENYZ', 0),
+(20, '安能物流', 'ANE', 0),
+(21, '澳多多', 'ADD', 0),
+(22, '澳邮专线', 'AYCA', 0),
+(23, '安鲜达', 'AXD', 0),
+(24, '安能快运', 'ANEKY', 0),
+(25, '澳邦国际', 'ABGJ', 0),
+(26, '安得物流', 'ANNTO', 0),
+(27, '八达通  ', 'BDT', 0),
+(28, '百腾物流', 'BETWL', 0),
+(29, '北极星快运', 'BJXKY', 0),
+(30, '奔腾物流', 'BNTWL', 0),
+(31, '百福东方', 'BFDF', 0),
+(32, '贝海国际 ', 'BHGJ', 0),
+(33, '八方安运', 'BFAY', 0),
+(34, '百世快运', 'BTWL', 0),
+(35, '帮帮发转运', 'BBFZY', 0),
+(36, '百城通物流', 'BCTWL', 0),
+(37, '春风物流', 'CFWL', 0),
+(38, '诚通物流', 'CHTWL', 0),
+(39, '传喜物流', 'CXHY', 0),
+(40, '城市100', 'CITY100', 0),
+(41, '城际快递', 'CJKD', 0),
+(42, 'CNPEX中邮快递', 'CNPEX', 0),
+(43, 'COE东方快递', 'COE', 0),
+(44, '长沙创一', 'CSCY', 0),
+(45, '成都善途速运', 'CDSTKY', 0),
+(46, '联合运通', 'CTG', 0),
+(47, '疯狂快递', 'CRAZY', 0),
+(48, 'CBO钏博物流', 'CBO', 0),
+(49, '佳吉快运', 'CNEX', 0),
+(50, '承诺达', 'CND', 0),
+(51, '畅顺通达', 'CSTD', 0),
+(52, 'D速物流', 'DSWL', 0),
+(53, '到了港', 'DLG ', 0),
+(54, '大田物流', 'DTWL', 0),
+(55, '东骏快捷物流', 'DJKJWL', 0),
+(56, '德坤', 'DEKUN', 0),
+(57, '德邦快运', 'DBLKY', 0),
+(58, '大马鹿', 'DML', 0),
+(59, '丹鸟物流', 'DNWL', 0),
+(60, '东方汇', 'EST365', 0),
+(61, 'E特快', 'ETK', 0),
+(62, 'EMS国内', 'EMS2', 0),
+(63, 'EWE', 'EWE', 0),
+(64, '飞康达', 'FKD', 0),
+(65, '富腾达  ', 'FTD', 0),
+(66, '凡宇货的', 'FYKD', 0),
+(67, '速派快递', 'FASTGO', 0),
+(68, '飞豹快递', 'FBKD', 0),
+(69, '丰巢', 'FBOX', 0),
+(70, '飞狐快递', 'FHKD', 0),
+(71, '复融供应链', 'FRGYL', 0),
+(72, '飞远配送', 'FYPS', 0),
+(73, '凡宇速递', 'FYSD', 0),
+(74, '丰通快运', 'FT', 0),
+(75, '冠达   ', 'GD', 0),
+(76, '广东邮政', 'GDEMS', 0),
+(77, '共速达', 'GSD', 0),
+(78, '广通       ', 'GTONG', 0),
+(79, '冠达快递', 'GDKD', 0),
+(80, '挂号信', 'GHX', 0),
+(81, '广通速递', 'GTKD', 0),
+(82, '高铁快运', 'GTKY', 0),
+(83, '迦递快递', 'GAI', 0),
+(84, '港快速递', 'GKSD', 0),
+(85, '高铁速递', 'GTSD', 0),
+(86, '黑狗冷链', 'HGLL', 0),
+(87, '恒路物流', 'HLWL', 0),
+(88, '天地华宇', 'HOAU', 0),
+(89, '鸿桥供应链', 'HOTSCM', 0),
+(90, '海派通物流公司', 'HPTEX', 0),
+(91, '华强物流', 'hq568', 0),
+(92, '环球速运  ', 'HQSY', 0),
+(93, '华夏龙物流', 'HXLWL', 0),
+(94, '河北建华', 'HBJH', 0),
+(95, '汇丰物流', 'HF', 0),
+(96, '华航快递', 'HHKD', 0),
+(97, '华翰物流', 'HHWL', 0),
+(98, '黄马甲快递', 'HMJKD', 0),
+(99, '海盟速递', 'HMSD', 0),
+(100, '华企快运', 'HQKY', 0),
+(101, '昊盛物流', 'HSWL', 0),
+(102, '鸿泰物流', 'HTWL', 0),
+(103, '豪翔物流 ', 'HXWL', 0),
+(104, '合肥汇文', 'HFHW', 0),
+(105, '辉隆物流', 'HLONGWL', 0),
+(106, '华企快递', 'HQKD', 0),
+(107, '韩润物流', 'HRWL', 0),
+(108, '青岛恒通快递', 'HTKD', 0),
+(109, '货运皇物流', 'HYH', 0),
+(110, '好来运快递', 'HLYSD', 0),
+(111, '皇家物流', 'HJWL', 0),
+(112, '海信物流', 'HISENSE', 0),
+(113, '捷安达  ', 'JAD', 0),
+(114, '京广速递', 'JGSD', 0),
+(115, '九曳供应链', 'JIUYE', 0),
+(116, '急先达', 'JXD', 0),
+(117, '晋越快递', 'JYKD', 0),
+(118, '佳成国际', 'JCEX', 0),
+(119, '捷特快递', 'JTKD', 0),
+(120, '精英速运', 'JYSY', 0),
+(121, '加运美', 'JYM', 0),
+(122, '景光物流', 'JGWL', 0),
+(123, '佳怡物流', 'JYWL', 0),
+(124, '京东快运', 'JDKY', 0),
+(125, '金大物流', 'JDWL', 0),
+(126, '极兔速递', 'JTSD', 0),
+(127, '跨越速运', 'KYSY', 0),
+(128, '快服务', 'KFW', 0),
+(129, '快速递物流', 'KSDWL', 0),
+(130, '康力物流', 'KLWL', 0),
+(131, '快淘快递', 'KTKD', 0),
+(132, '快优达速递', 'KYDSD', 0),
+(133, '跨越物流', 'KYWL', 0),
+(134, '快8速运', 'KBSY', 0),
+(135, '龙邦快递', 'LB', 0),
+(136, '蓝弧快递', 'LHKD', 0),
+(137, '乐捷递', 'LJD', 0),
+(138, '立即送', 'LJS', 0),
+(139, '联昊通速递', 'LHT', 0),
+(140, '民邦快递', 'MB', 0),
+(141, '民航快递', 'MHKD', 0),
+(142, '美快    ', 'MK', 0),
+(143, '门对门快递', 'MDM', 0),
+(144, '迈达', 'MD', 0),
+(145, '闽盛快递', 'MSKD', 0),
+(146, '迈隆递运', 'MRDY', 0),
+(147, '明亮物流', 'MLWL', 0),
+(148, '南方传媒物流', 'NFCM', 0),
+(149, '南京晟邦物流', 'NJSBWL', 0),
+(150, '能达速递', 'NEDA', 0),
+(151, '平安达腾飞快递', 'PADTF', 0),
+(152, '泛捷快递', 'PANEX', 0),
+(153, '品骏快递', 'PJ', 0),
+(154, '陪行物流', 'PXWL', 0),
+(155, 'PCA Express', 'PCA', 0),
+(156, '全晨快递', 'QCKD', 0),
+(157, '全日通快递', 'QRT', 0),
+(158, '快客快递', 'QUICK', 0),
+(159, '全信通', 'QXT', 0),
+(160, '七曜中邮', 'QYZY', 0),
+(161, '如风达', 'RFD', 0),
+(162, '荣庆物流', 'RQ', 0),
+(163, '日日顺物流', 'RRS', 0),
+(164, '日昱物流', 'RLWL', 0),
+(165, '瑞丰速递', 'RFEX', 0),
+(166, '赛澳递', 'SAD', 0),
+(167, '苏宁物流', 'SNWL', 0),
+(168, '圣安物流', 'SAWL', 0),
+(169, '晟邦物流', 'SBWL', 0),
+(170, '上大物流', 'SDWL', 0),
+(171, '盛丰物流', 'SFWL', 0),
+(172, '速通物流', 'ST', 0),
+(173, '速腾快递', 'STWL', 0),
+(174, '速必达物流', 'SUBIDA', 0),
+(175, '速递e站', 'SDEZ', 0),
+(176, '速呈宅配', 'SCZPDS', 0),
+(177, '速尔快递', 'SURE', 0),
+(178, '山东海红', 'SDHH', 0),
+(179, '顺丰国际', 'SFGJ', 0),
+(180, '盛辉物流', 'SHWL', 0),
+(181, '穗佳物流', 'SJWL', 0),
+(182, '三态速递', 'STSD', 0),
+(183, '山西红马甲', 'SXHMJ', 0),
+(184, '世运快递', 'SYKD', 0),
+(185, '闪送', 'SS', 0),
+(186, '盛通快递', 'STKD', 0),
+(187, '郑州速捷', 'SJ', 0),
+(188, '顺心捷达', 'SX', 0),
+(189, '商桥物流', 'SQWL', 0),
+(190, '佳旺达物流', 'SYJWDX', 0),
+(191, '台湾邮政', 'TAIWANYZ', 0),
+(192, '唐山申通', 'TSSTO', 0),
+(193, '特急送', 'TJS', 0),
+(194, '通用物流', 'TYWL', 0),
+(195, '华宇物流', 'TDHY', 0),
+(196, '通和天下', 'THTX', 0),
+(197, '腾林物流', 'TLWL', 0),
+(198, '全一快递', 'UAPEX', 0),
+(199, 'UBI', 'UBI', 0),
+(200, 'UEQ Express', 'UEQ', 0),
+(201, '万家康  ', 'WJK', 0),
+(202, '万家物流', 'WJWL', 0),
+(203, '武汉同舟行', 'WHTZX', 0),
+(204, '维普恩', 'WPE', 0),
+(205, '中粮我买网', 'WM', 0),
+(206, '万象物流', 'WXWL', 0),
+(207, '微特派', 'WTP', 0),
+(208, '温通物流', 'WTWL', 0),
+(209, '迅驰物流  ', 'XCWL', 0),
+(210, '信丰物流', 'XFEX', 0),
+(211, '希优特', 'XYT', 0),
+(212, '新邦物流', 'XBWL', 0),
+(213, '祥龙运通', 'XLYT', 0),
+(214, '新杰物流', 'XJ', 0),
+(215, '源安达快递', 'YADEX', 0),
+(216, '远成物流', 'YCWL', 0),
+(217, '远成快运', 'YCSY', 0),
+(218, '义达国际物流', 'YDH', 0),
+(219, '易达通  ', 'YDT', 0),
+(220, '原飞航物流', 'YFHEX', 0),
+(221, '亚风快递', 'YFSD', 0),
+(222, '运通快递', 'YTKD', 0),
+(223, '亿翔快递', 'YXKD', 0),
+(224, '运东西网', 'YUNDX', 0),
+(225, '壹米滴答', 'YMDD', 0),
+(226, '邮政国内标快', 'YZBK', 0),
+(227, '一站通速运', 'YZTSY', 0),
+(228, '驭丰速运', 'YFSUYUN', 0),
+(229, '余氏东风', 'YSDF', 0),
+(230, '耀飞快递', 'YF', 0),
+(231, '韵达快运', 'YDKY', 0),
+(232, '云路', 'YL', 0),
+(233, '邮必佳', 'YBJ', 0),
+(234, '越丰物流', 'YFEX', 0),
+(235, '银捷速递', 'YJSD', 0),
+(236, '优联吉运', 'YLJY', 0),
+(237, '亿领速运', 'YLSY', 0),
+(238, '英脉物流', 'YMWL', 0),
+(239, '亿顺航', 'YSH', 0),
+(240, '音素快运', 'YSKY', 0),
+(241, '易通达', 'YTD', 0),
+(242, '一统飞鸿', 'YTFH', 0),
+(243, '圆通国际', 'YTOGJ', 0),
+(244, '宇鑫物流', 'YXWL', 0),
+(245, '包裹/平邮/挂号信', 'YZGN', 0),
+(246, '一智通', 'YZT', 0),
+(247, '优拜物流', 'YBWL', 0),
+(248, '增益快递', 'ZENY', 0),
+(249, '中睿速递', 'ZRSD', 0),
+(250, '中铁快运', 'ZTKY', 0),
+(251, '中天万运', 'ZTWY', 0),
+(252, '中外运速递', 'ZWYSD', 0),
+(253, '澳转运', 'ZY_AZY', 0),
+(254, '八达网', 'ZY_BDA', 0),
+(255, '贝易购', 'ZY_BYECO', 0),
+(256, '赤兔马转运', 'ZY_CTM', 0),
+(257, 'CUL中美速递', 'ZY_CUL', 0),
+(258, 'ETD', 'ZY_ETD', 0),
+(259, '风驰快递', 'ZY_FCKD', 0),
+(260, '风雷速递', 'ZY_FLSD', 0),
+(261, '皓晨优递', 'ZY_HCYD', 0),
+(262, '海带宝', 'ZY_HDB', 0),
+(263, '汇丰美中速递', 'ZY_HFMZ', 0),
+(264, '豪杰速递', 'ZY_HJSD', 0),
+(265, '华美快递', 'ZY_HMKD', 0),
+(266, '360hitao转运', 'ZY_HTAO', 0),
+(267, '海淘村', 'ZY_HTCUN', 0),
+(268, '365海淘客', 'ZY_HTKE', 0),
+(269, '华通快运', 'ZY_HTONG', 0),
+(270, '海星桥快递', 'ZY_HXKD', 0),
+(271, '华兴速运', 'ZY_HXSY', 0),
+(272, 'LogisticsY', 'ZY_IHERB', 0),
+(273, '领跑者快递', 'ZY_LPZ', 0),
+(274, '量子物流', 'ZY_LZWL', 0),
+(275, '明邦转运', 'ZY_MBZY', 0),
+(276, '美嘉快递', 'ZY_MJ', 0),
+(277, '168 美中快递', 'ZY_MZ', 0),
+(278, '欧e捷', 'ZY_OEJ', 0),
+(279, '欧洲疯', 'ZY_OZF', 0),
+(280, '欧洲GO', 'ZY_OZGO', 0),
+(281, '全美通', 'ZY_QMT', 0),
+(282, 'SCS国际物流', 'ZY_SCS', 0),
+(283, 'SOHO苏豪国际', 'ZY_SOHO', 0),
+(284, 'Sonic-Ex速递', 'ZY_SONIC', 0),
+(285, '通诚美中快递', 'ZY_TCM', 0),
+(286, 'TrakPak', 'ZY_TPAK', 0),
+(287, '天天海淘', 'ZY_TTHT', 0),
+(288, '天泽快递', 'ZY_TZKD', 0),
+(289, '迅达快递', 'ZY_XDKD', 0),
+(290, '信达速运', 'ZY_XDSY', 0),
+(291, '新干线快递', 'ZY_XGX', 0),
+(292, '信捷转运', 'ZY_XJ', 0),
+(293, '优购快递', 'ZY_YGKD', 0),
+(294, '友家速递(UCS)', 'ZY_YJSD', 0),
+(295, '云畔网', 'ZY_YPW', 0),
+(296, '易送网', 'ZY_YSW', 0),
+(297, '中运全速', 'ZYQS', 0),
+(298, '中邮物流', 'ZYWL', 0),
+(299, '汇强快递', 'ZHQKD', 0),
+(300, '众通快递', 'ZTE', 0),
+(301, '中通快运', 'ZTOKY', 0),
+(302, '中邮快递', 'ZYKD', 0),
+(303, '芝麻开门', 'ZMKM', 0),
+(304, '中骅物流', 'ZHWL', 0),
+(305, '中铁物流', 'ZTWL', 0),
+(306, '智汇鸟', 'ZHN', 99),
+(307, '众邮快递', 'ZYE', 0);
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_order_aftersale` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `aftersale_sn` varchar(40) NOT NULL COMMENT '售后单号',
+  `user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户',
+  `type` varchar(20) NOT NULL COMMENT '类型:refund=退款,return=退货,other=其他',
+  `phone` varchar(20) DEFAULT NULL COMMENT '联系方式',
+  `activity_id` int(11) DEFAULT NULL COMMENT '活动',
+  `activity_type` varchar(255) DEFAULT NULL COMMENT '活动类型',
+  `order_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单',
+  `order_item_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单商品',
+  `goods_id` int(11) NOT NULL DEFAULT '0' COMMENT '商品',
+  `goods_sku_price_id` int(11) NOT NULL DEFAULT '0' COMMENT '规格 id',
+  `goods_sku_text` varchar(30) DEFAULT NULL COMMENT '规格名',
+  `goods_title` varchar(255) DEFAULT NULL COMMENT '商品名称',
+  `goods_image` varchar(255) DEFAULT NULL COMMENT '商品图片',
+  `goods_original_price` decimal(10,2) NOT NULL COMMENT '商品原价',
+  `discount_fee` decimal(10,2) DEFAULT NULL COMMENT '优惠费用',
+  `goods_price` decimal(10,2) NOT NULL COMMENT '商品价格',
+  `goods_num` int(11) NOT NULL DEFAULT '0' COMMENT '购买数量',
+  `dispatch_status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '发货状态:0=未发货,1=已发货,2=已收货',
+  `dispatch_fee` decimal(10,2) DEFAULT NULL COMMENT '发货费用',
+  `aftersale_status` tinyint(2) NOT NULL COMMENT '售后状态:-1=拒绝,0=未处理,1=处理中,2=售后完成',
+  `refund_status` tinyint(1) DEFAULT NULL COMMENT '退款状态:-1=拒绝退款,0=未退款,1=同意',
+  `refund_fee` decimal(10,2) DEFAULT NULL COMMENT '退款金额',
+  `createtime` int(11) DEFAULT NULL COMMENT '添加时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `aftersale_sn` (`aftersale_sn`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='售后单';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_order_aftersale_log` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '操作记录 id',
+  `order_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单',
+  `order_aftersale_id` int(11) NOT NULL DEFAULT '0' COMMENT '售后单',
+  `oper_type` enum('user','store','admin','system') NOT NULL COMMENT '操作人类型',
+  `oper_id` int(11) NOT NULL DEFAULT '0' COMMENT '操作人 id',
+  `dispatch_status` tinyint(2) NOT NULL COMMENT '发货状态',
+  `aftersale_status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '售后状态',
+  `refund_status` tinyint(2) NOT NULL DEFAULT '0' COMMENT '退款状态',
+  `reason` varchar(255) DEFAULT NULL COMMENT '售后原因',
+  `content` varchar(255) DEFAULT NULL COMMENT '内容',
+  `images` varchar(2500) DEFAULT NULL COMMENT '图片',
+  `createtime` int(11) DEFAULT NULL COMMENT '操作时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='售后单记录';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_order_express` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL COMMENT '用户',
+  `order_id` int(11) NOT NULL COMMENT '订单',
+  `express_name` varchar(60) DEFAULT NULL COMMENT '快递公司',
+  `express_code` varchar(60) DEFAULT NULL COMMENT '公司编号',
+  `express_no` varchar(60) DEFAULT NULL COMMENT '快递单号',
+  `createtime` int(11) DEFAULT NULL COMMENT '添加时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='快递包裹';
+
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_order_express_log` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL COMMENT '用户',
+  `order_id` int(11) NOT NULL COMMENT '订单',
+  `order_express_id` int(11) NOT NULL COMMENT '包裹',
+  `status` tinyint(4) DEFAULT '0' COMMENT '物流状态',
+  `location` varchar(255) DEFAULT NULL COMMENT '城市',
+  `content` varchar(512) DEFAULT NULL COMMENT '物流信息',
+  `changedate` datetime DEFAULT NULL COMMENT '变动时间',
+  `createtime` int(11) DEFAULT NULL COMMENT '添加时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流信息';
+
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_store` (
+  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `name` varchar(50) NOT NULL COMMENT '门店名称',
+  `images` varchar(2500) NOT NULL COMMENT '门店图片',
+  `realname` varchar(50) NOT NULL COMMENT '联系人',
+  `phone` varchar(20) NOT NULL COMMENT '联系电话',
+  `province_name` varchar(50) NOT NULL COMMENT '省',
+  `city_name` varchar(50) NOT NULL COMMENT '市',
+  `area_name` varchar(50) NOT NULL COMMENT '区',
+  `province_id` int(11) NOT NULL COMMENT '省ID',
+  `city_id` int(11) NOT NULL COMMENT '市ID',
+  `area_id` int(11) NOT NULL COMMENT '区ID',
+  `address` varchar(255) NOT NULL COMMENT '详细地址',
+  `latitude` decimal(10,6) NULL DEFAULT NULL COMMENT '纬度',
+  `longitude` decimal(10,6) NULL DEFAULT NULL COMMENT '经度',
+  `store` enum('0','1') NOT NULL DEFAULT '0' COMMENT '支持配送:0=否,1=是',
+  `selfetch` enum('0','1') NOT NULL DEFAULT '0' COMMENT '支持自提:0=否,1=是',
+  `service_type` varchar(20) NOT NULL COMMENT '服务范围',
+  `service_radius` int(11) NOT NULL DEFAULT '0' COMMENT '服务半径',
+  `service_province_ids` varchar(1200) DEFAULT NULL COMMENT '服务行政省',
+  `service_city_ids` varchar(1200) DEFAULT NULL COMMENT '服务行政市',
+  `service_area_ids` varchar(1200) DEFAULT NULL COMMENT '服务行政区',
+  `openhours` varchar(20) NOT NULL COMMENT '营业时间',
+  `openweeks` set('1','2','3','4','5','6','7') NOT NULL DEFAULT '1,2,3,4,5,6,7' COMMENT '营业天数',
+  `status` enum('0','1') NOT NULL DEFAULT '1' COMMENT '门店状态:0=禁用,1=启用',
+  `createtime` int(11) NOT NULL COMMENT '创建时间',
+  `updatetime` int(11) NOT NULL COMMENT '更新时间',
+  `deletetime` int(11) DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='门店';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_user_store` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL COMMENT '用户',
+  `store_id` int(11) NOT NULL COMMENT '门店',
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='门店管理员';
+
+CREATE TABLE IF NOT EXISTS `__PREFIX__shopro_verify` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL COMMENT '用户',
+  `type` varchar(30) DEFAULT 'verify' COMMENT '类型:verify=核销券',
+  `code` varchar(20) NOT NULL COMMENT '核销码',
+  `order_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单',
+  `order_item_id` int(11) NOT NULL DEFAULT '0' COMMENT '订单商品',
+  `usetime` int(11) DEFAULT NULL COMMENT '使用时间',
+  `expiretime` int(11) DEFAULT NULL COMMENT '过期时间',
+  `oper_type` enum('user','store','admin','system') DEFAULT NULL COMMENT '操作人类型',
+  `oper_id` int(11) NOT NULL DEFAULT '0' COMMENT '操作人',
+  `createtime` int(11) DEFAULT NULL COMMENT '添加时间',
+  `updatetime` int(11) DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE KEY `code` (`code`) USING BTREE COMMENT '核销码'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='二维码';
+
+-- 用户地理位置加入经纬度
+ALTER TABLE `__PREFIX__shopro_user_address` ADD COLUMN `latitude` decimal(10, 6) NULL DEFAULT NULL COMMENT '纬度' AFTER `area_id`;
+ALTER TABLE `__PREFIX__shopro_user_address` ADD COLUMN `longitude` decimal(10, 6) NULL DEFAULT NULL COMMENT '经度' AFTER `latitude`;
+
+-- 订单副表加入扩展字段
+ALTER TABLE `__PREFIX__shopro_order_item` ADD COLUMN `goods_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'normal' COMMENT '商品类型:normal=实体商品,virtual=虚拟商品' AFTER `goods_id`;
+ALTER TABLE `__PREFIX__shopro_order_item` ADD COLUMN `store_id` int(11) NOT NULL DEFAULT 0 COMMENT '门店' AFTER `dispatch_id`;
+ALTER TABLE `__PREFIX__shopro_order_item` MODIFY COLUMN `aftersale_status` tinyint(2) NOT NULL COMMENT '售后状态:-1=拒绝,0=未申请,1=申请售后,2=售后完成' AFTER `store_id`;
+ALTER TABLE `__PREFIX__shopro_order_item` ADD COLUMN `express_code` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '公司编号' AFTER `express_name`;
+ALTER TABLE `__PREFIX__shopro_order_item` ADD COLUMN `ext` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '附加字段' AFTER `express_no`;
+
+-- 订单操作日志加入操作人类型
+ALTER TABLE `__PREFIX__shopro_order_action` MODIFY COLUMN `oper_type` enum('user','store','admin','system') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '操作人类型' AFTER `order_item_id`;
+
+-- 配送方式 商家配送
+ALTER TABLE `__PREFIX__shopro_dispatch_store` COMMENT = '商家配送';
+ALTER TABLE `__PREFIX__shopro_dispatch_store` ADD COLUMN `store_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '包含门店' AFTER `id`;
+ALTER TABLE `__PREFIX__shopro_dispatch_store` ADD COLUMN `createtime` int(11) DEFAULT NULL COMMENT '创建时间' AFTER `store_ids`;
+ALTER TABLE `__PREFIX__shopro_dispatch_store` ADD COLUMN `updatetime` int(11) DEFAULT NULL COMMENT '更新时间' AFTER `createtime`;
+ALTER TABLE `__PREFIX__shopro_dispatch_store` ADD COLUMN `deletetime` int(11) NULL DEFAULT NULL COMMENT '删除时间' AFTER `updatetime`;
+
+-- 配送方式 自提点
+ALTER TABLE `__PREFIX__shopro_dispatch_selfetch` drop COLUMN `name`;
+ALTER TABLE `__PREFIX__shopro_dispatch_selfetch` drop COLUMN `weigh`;
+ALTER TABLE `__PREFIX__shopro_dispatch_selfetch` drop COLUMN `longitude`;
+ALTER TABLE `__PREFIX__shopro_dispatch_selfetch` drop COLUMN `latitude`;
+ALTER TABLE `__PREFIX__shopro_dispatch_selfetch` drop COLUMN `address`;
+ALTER TABLE `__PREFIX__shopro_dispatch_selfetch` ADD COLUMN `store_ids` varchar(255) CHARACTER SET utf8mb4 NOT NULL COMMENT '包含门店' AFTER `id`;
+ALTER TABLE `__PREFIX__shopro_dispatch_selfetch` ADD COLUMN `expire_type` enum('day','time') CHARACTER SET utf8mb4  NOT NULL DEFAULT 'day' COMMENT '过期类型:day=天数,time=截至日期' AFTER `store_ids`;
+ALTER TABLE `__PREFIX__shopro_dispatch_selfetch` ADD COLUMN `expire_day` int(11) NOT NULL DEFAULT 0 COMMENT 'X天过期' AFTER `expire_type`;
+ALTER TABLE `__PREFIX__shopro_dispatch_selfetch` ADD COLUMN `expire_time` int(11) NOT NULL DEFAULT 0 COMMENT '截至日期' AFTER `expire_day`;
+
+-- 配送方式 快递物流
+ALTER TABLE `__PREFIX__shopro_dispatch_express` DROP COLUMN `name`;
+
+-- 配送方式 自动发货
+ALTER TABLE `__PREFIX__shopro_dispatch_autosend` ADD COLUMN `type` enum('card','text','params') CHARACTER SET utf8mb4 NOT NULL COMMENT '自动发货类型:card=卡密,text=固定内容,params=自定义内容' AFTER `id`;
+ALTER TABLE `__PREFIX__shopro_dispatch_autosend` ADD COLUMN `content` varchar(1200) CHARACTER SET utf8mb4 NOT NULL COMMENT '发货内容' AFTER `type`;
+ALTER TABLE `__PREFIX__shopro_dispatch_autosend` ADD COLUMN `createtime` int(11) DEFAULT NULL COMMENT '创建时间' AFTER `content`;
+ALTER TABLE `__PREFIX__shopro_dispatch_autosend` ADD COLUMN `updatetime` int(11) DEFAULT NULL COMMENT '更新时间' AFTER `createtime`;
+ALTER TABLE `__PREFIX__shopro_dispatch_autosend` ADD COLUMN `deletetime` int(11) NULL DEFAULT NULL COMMENT '删除时间' AFTER `updatetime`;
+
+-- 优惠券 添加多类型
+ALTER TABLE `__PREFIX__shopro_coupons` ADD COLUMN `type` enum('cash','discount') NOT NULL DEFAULT 'cash' COMMENT '类型:cash=代金券,discount=折扣券' AFTER `name`;
+
+-- 用户钱包记录 添加操作人
+ALTER TABLE `__PREFIX__shopro_user_wallet_log` ADD COLUMN `oper_type` enum('user','store','admin','system') CHARACTER SET utf8mb4 NOT NULL DEFAULT 'user' COMMENT '操作人类型' AFTER `ext`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_log` ADD COLUMN `oper_id` int(11) NOT NULL DEFAULT 0 COMMENT '操作人 id' AFTER `oper_type`;
+
+-- 微信管理 添加自定义规则
+ALTER TABLE `__PREFIX__shopro_wechat` ADD COLUMN `rules` varchar(255) CHARACTER SET utf8mb4  NULL DEFAULT NULL COMMENT '规则' AFTER `name`;
+
+-- 会员组 添加等级徽章
+ALTER TABLE `__PREFIX__user_group` ADD COLUMN `image` varchar(255) CHARACTER SET utf8mb4 NULL DEFAULT NULL COMMENT '等级徽章' AFTER `rules`;
+
+-- 配置 更改字段为空
+ALTER TABLE `__PREFIX__shopro_config` MODIFY COLUMN `content` longtext CHARACTER SET utf8mb4 NULL DEFAULT NULL COMMENT '变量字典数据';
+-- 1.0.7更新 ↑
+
+
+-- 1.2.0 标准版更新 ↓
+
+ALTER TABLE `__PREFIX__shopro_order_item` ADD COLUMN `pay_price` decimal(10, 2) NOT NULL COMMENT '支付金额(不含运费)' AFTER `goods_num`;
+
+CREATE TABLE `__PREFIX__shopro_store_apply`  (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `user_id` int(11) NOT NULL COMMENT '用户',
+  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '门店名称',
+  `images` varchar(2500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '门店图片',
+  `realname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '联系人',
+  `phone` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '联系电话',
+  `province_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '省',
+  `city_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '市',
+  `area_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '区',
+  `province_id` int(11) NOT NULL COMMENT '省ID',
+  `city_id` int(11) NOT NULL COMMENT '市ID',
+  `area_id` int(11) NOT NULL COMMENT '区ID',
+  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '详细地址',
+  `latitude` decimal(10, 6) NOT NULL DEFAULT 0.000000 COMMENT '纬度',
+  `longitude` decimal(10, 6) NOT NULL DEFAULT 0.000000 COMMENT '经度',
+  `openhours` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '营业时间',
+  `openweeks` set('1','2','3','4','5','6','7') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '1,2,3,4,5,6,7' COMMENT '营业天数',
+  `apply_num` int(10) NOT NULL DEFAULT 0 COMMENT '申请次数',
+  `status` enum('-1','0','1') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '0' COMMENT '审核状态:-1驳回,0=未审核,1=已通过',
+  `status_msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '驳回原因',
+  `createtime` int(11) NOT NULL COMMENT '创建时间',
+  `updatetime` int(11) NOT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '门店入驻';
+
+CREATE TABLE `__PREFIX__shopro_chat`  (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `admin_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '绑定管理员',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '客服昵称',
+  `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '客服头像',
+  `max_num` tinyint(3) UNSIGNED NOT NULL DEFAULT 1 COMMENT '接待上限',
+  `lasttime` int(10) NOT NULL DEFAULT 0 COMMENT '上次服务时间',
+  `status` enum('offline','online','busy') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'offline' COMMENT '状态:offline=离线,online=在线',
+  `createtime` int(10) NULL DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '客服表';
+
+CREATE TABLE `__PREFIX__shopro_chat_connection`  (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `session_id` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户标识',
+  `user_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '用户',
+  `nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '昵称',
+  `customer_service_id` int(10) NOT NULL DEFAULT 0 COMMENT '客服',
+  `starttime` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '开始时间',
+  `endtime` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '结束时间',
+  `status` enum('waiting','ing','end') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'waiting' COMMENT '状态:watting=等待中,ing=服务中,end=已结束',
+  `createtime` int(10) NULL DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `session_id`(`session_id`) USING BTREE,
+  INDEX `user_id`(`user_id`) USING BTREE,
+  INDEX `customer_service_id`(`customer_service_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '连接表';
+
+CREATE TABLE `__PREFIX__shopro_chat_fast_reply`  (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '名称',
+  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '内容',
+  `status` enum('normal','hidden') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'normal' COMMENT '状态:normal=启用,hidden=隐藏',
+  `weigh` int(10) NOT NULL DEFAULT 0 COMMENT '权重',
+  `createtime` int(10) NULL DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '快捷回复';
+
+INSERT INTO `__PREFIX__shopro_chat_fast_reply` (`id`, `name`, `content`, `status`, `weigh`, `createtime`, `updatetime`) VALUES 
+(1, '退款退回问题', '亲,钱款都是按照原支付路径进行退回的,一般会在1~3三个工作日内完成退款,请注意查收', 'normal', 1, 1608629981, 1608629981),
+(2, '红包退回问题', '亲,如果是双11的红包,因为只能当天使用,所以退款的时候,红包将不会退回', 'normal', 2, 1608630134, 1608630134),
+(3, '发货问题', '<span style=\"white-space:normal;\">亲,一般会在下完单两天之内进行发货,如遇双十一等节日最晚会在一周内发货的,请耐心等待</span>', 'normal', 3, 1608630165, 1608630165);
+
+CREATE TABLE `__PREFIX__shopro_chat_log`  (
+  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `session_id` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '会话ID',
+  `user_id` int(11) NOT NULL DEFAULT 0 COMMENT '用户',
+  `sender_identify` enum('customer_service','user') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'user' COMMENT '发送人身份:customer_service=客服,user=用户',
+  `sender_id` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '发送人ID',
+  `message_type` enum('text','image','file','system','goods','order') CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT 'text' COMMENT '消息类型:text=文本,image=图片,file=文件,system=系统消息,goods=商品卡片,order=订单卡片',
+  `message` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '消息',
+  `readtime` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '读取时间',
+  `createtime` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `session_id`(`session_id`) USING BTREE,
+  INDEX `user_id`(`user_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '聊天记录表';
+
+CREATE TABLE `__PREFIX__shopro_chat_question`  (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '标题',
+  `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '内容',
+  `status` enum('normal','hidden') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'normal' COMMENT '状态:normal=启用,hidden=隐藏',
+  `weigh` int(10) NOT NULL DEFAULT 0 COMMENT '权重',
+  `createtime` int(10) NULL DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '常见问题';
+
+CREATE TABLE `__PREFIX__shopro_chat_user`  (
+  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
+  `session_id` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '标识',
+  `user_id` int(10) NOT NULL DEFAULT 0 COMMENT '用户',
+  `nickname` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '昵称',
+  `avatar` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '头像',
+  `customer_service_id` int(10) NOT NULL DEFAULT 0 COMMENT '最后接待客服',
+  `lasttime` int(10) UNSIGNED NULL DEFAULT NULL COMMENT '上次上线时间',
+  `createtime` int(10) NULL DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(10) NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `session_id`(`session_id`) USING BTREE COMMENT 'session 标识',
+  INDEX `user_id`(`user_id`) USING BTREE COMMENT 'user_id'
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '客服用户表';
+-- 1.2.0 标准版更新 ↑
+
+
+-- 1.3.0 标准版更新 ↓
+
+CREATE TABLE `__PREFIX__shopro_stock_warning`  (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `goods_id` int(10) NOT NULL DEFAULT 0 COMMENT '商品',
+  `goods_sku_price_id` int(10) NOT NULL DEFAULT 0 COMMENT '规格',
+  `goods_sku_text` varchar(255) NULL DEFAULT NULL COMMENT '中文规格',
+  `stock_warning` int(11) NULL DEFAULT 0 COMMENT '预警值',
+  `createtime` int(11) NULL DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) NULL DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) NULL DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '库存预警';
+
+ALTER TABLE `__PREFIX__shopro_goods_sku_price` ADD COLUMN `stock_warning` int(11) NULL DEFAULT NULL COMMENT '库存预警' AFTER `stock`;
+
+ALTER TABLE `__PREFIX__shopro_order` ADD COLUMN `activity_discount_money` decimal(10, 2) NOT NULL DEFAULT '0.00' COMMENT '活动优惠' AFTER `coupon_fee`;
+ALTER TABLE `__PREFIX__shopro_order` MODIFY COLUMN `ext` varchar(2048) NULL DEFAULT NULL COMMENT '附加字段' AFTER `paytime`;
+ALTER TABLE `__PREFIX__shopro_order` ADD INDEX `user_id`(`user_id`) USING BTREE;
+ALTER TABLE `__PREFIX__shopro_order` ADD INDEX `status`(`status`) USING BTREE;
+ALTER TABLE `__PREFIX__shopro_order` ADD INDEX `createtime`(`createtime`) USING BTREE;
+
+ALTER TABLE `__PREFIX__shopro_order_aftersale` ADD INDEX `user_id`(`user_id`) USING BTREE;
+ALTER TABLE `__PREFIX__shopro_order_aftersale` ADD INDEX `order_id`(`order_id`) USING BTREE;
+
+ALTER TABLE `__PREFIX__shopro_order_item` MODIFY COLUMN `goods_sku_text` varchar(60) NULL DEFAULT NULL COMMENT '规格名' AFTER `item_goods_sku_price_id`;
+ALTER TABLE `__PREFIX__shopro_order_item` ADD COLUMN `goods_weight` int(11) NOT NULL DEFAULT 0 COMMENT '商品重量' AFTER `goods_num`;
+ALTER TABLE `__PREFIX__shopro_order_item` ADD INDEX `order_id`(`order_id`) USING BTREE;
+ALTER TABLE `__PREFIX__shopro_order_item` ADD INDEX `store_id`(`store_id`) USING BTREE;
+ALTER TABLE `__PREFIX__shopro_order_item` ADD INDEX `activity_id`(`activity_id`) USING BTREE;
+ALTER TABLE `__PREFIX__shopro_order_item` ADD INDEX `goods_id`(`goods_id`) USING BTREE;
+
+ALTER TABLE `__PREFIX__shopro_share` MODIFY COLUMN `platform` varchar(20) NULL DEFAULT NULL COMMENT '识别平台' AFTER `type_id`;
+ALTER TABLE `__PREFIX__shopro_share` ADD COLUMN `share_platform` varchar(20) NULL DEFAULT NULL COMMENT '分享来源' AFTER `platform`;
+ALTER TABLE `__PREFIX__shopro_share` ADD COLUMN `from` varchar(20) NULL DEFAULT NULL COMMENT '分享方式' AFTER `share_platform`;
+
+ALTER TABLE `__PREFIX__shopro_user_bank` ADD COLUMN `type` enum('bank','alipay') NULL DEFAULT NULL COMMENT '账户类型:bank=银行卡,alipay=支付宝账户' AFTER `user_id`;
+
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` ADD COLUMN `apply_sn` varchar(60) NULL DEFAULT NULL COMMENT '提现单号' AFTER `user_id`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` CHANGE `get_type` `apply_type` enum('bank','wechat','alipay') NULL DEFAULT NULL COMMENT '收款类型:bank=银行卡,wechat=微信零钱,alipay=支付宝' AFTER `apply_sn`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` ADD COLUMN `actual_money` decimal(10, 2) NOT NULL DEFAULT '0.00' COMMENT '实际到账' AFTER `money`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` MODIFY COLUMN `service_fee` decimal(10, 3) NULL DEFAULT NULL COMMENT '手续费率' AFTER `charge_money`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` CHANGE `bank_info` `apply_info` varchar(255) NULL DEFAULT NULL COMMENT '打款信息' AFTER `service_fee`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` MODIFY COLUMN `status` tinyint(1) NULL DEFAULT 0 COMMENT '提现状态:-1=已拒绝,0=待审核,1=处理中,2=已处理' AFTER `apply_info`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` ADD COLUMN `platform` varchar(20) NULL DEFAULT NULL COMMENT '平台' AFTER `status`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` ADD COLUMN `payment_json` varchar(2500) NULL DEFAULT NULL COMMENT '交易原始数据' AFTER `platform`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` ADD COLUMN `log` text NULL COMMENT '操作日志' AFTER `updatetime`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` ADD UNIQUE INDEX `apply_sn`(`apply_sn`) USING BTREE COMMENT '提现单号';
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` DROP COLUMN `bank_id`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` DROP COLUMN `real_name`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` DROP COLUMN `status_msg`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_apply` DROP COLUMN `deletetime`;
+
+ALTER TABLE `__PREFIX__shopro_user_wallet_log` MODIFY COLUMN `type` varchar(30) NOT NULL COMMENT '变动类型' AFTER `wallet_type`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_log` ADD COLUMN `before` decimal(10, 2) NOT NULL COMMENT '变动前' AFTER `type`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_log` ADD COLUMN `after` decimal(10, 2) NOT NULL COMMENT '变动后' AFTER `before`;
+ALTER TABLE `__PREFIX__shopro_user_wallet_log` ADD COLUMN `memo` varchar(255) NULL DEFAULT '' COMMENT '备注' AFTER `item_id`;
+
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `headimgurl` varchar(255) NULL DEFAULT NULL COMMENT '粉丝头像' AFTER `nickname`;
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `openid` varchar(30) NULL DEFAULT NULL COMMENT 'openid' AFTER `headimgurl`;
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `sex` int(11) NULL DEFAULT 0 COMMENT '性别' AFTER `openid`;
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `country` varchar(50) NULL DEFAULT NULL COMMENT '国家' AFTER `sex`;
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `province` varchar(50) NULL DEFAULT NULL COMMENT '省' AFTER `country`;
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `city` varchar(50) NULL DEFAULT NULL COMMENT '市' AFTER `province`;
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `subscribe` enum('0','1') NULL DEFAULT NULL COMMENT '关注状态:0=取消关注,1=已关注' AFTER `city`;
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `subscribe_time` int(11) NULL DEFAULT NULL COMMENT '关注时间' AFTER `subscribe`;
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `createtime` int(11) NULL DEFAULT NULL COMMENT '创建时间' AFTER `subscribe_time`;
+ALTER TABLE `__PREFIX__shopro_wechat_fans` MODIFY COLUMN `updatetime` int(11) NULL DEFAULT NULL COMMENT '更新时间' AFTER `createtime`;
+
+ALTER TABLE `__PREFIX__shopro_user_oauth` MODIFY COLUMN `country` varchar(50) NULL DEFAULT NULL COMMENT '国家' AFTER `sex`;
+ALTER TABLE `__PREFIX__shopro_user_oauth` MODIFY COLUMN `province` varchar(50) NULL DEFAULT NULL COMMENT '省' AFTER `country`;
+ALTER TABLE `__PREFIX__shopro_user_oauth` MODIFY COLUMN `city` varchar(50) NULL DEFAULT NULL COMMENT '市' AFTER `province`;
+ALTER TABLE `__PREFIX__shopro_user_oauth` ADD INDEX `openid`(`openid`) USING BTREE;
+-- 1.3.0 标准版更新 ↑
+
+
+-- 1.3.2 标准版更新 ↓
+
+ALTER TABLE `__PREFIX__shopro_order` ADD COLUMN `dispatch_discount_money` decimal(10, 2) NOT NULL DEFAULT '0.00' COMMENT '运费优惠' AFTER `activity_discount_money`;
+
+-- 1.3.2 标准版更新 ↑
+
+
+-- 1.3.7 标准版更新 ↓
+
+CREATE TABLE `__PREFIX__shopro_order_invoice`  (
+  `id` int(10) NOT NULL AUTO_INCREMENT,
+  `type` enum('person','company') NOT NULL COMMENT '发票类型:person=个人,company=企事业单位',
+  `header_name` varchar(50) NOT NULL COMMENT '抬头名称',
+  `tax_no` varchar(50) NULL DEFAULT NULL COMMENT '税号',
+  `mobile` varchar(20) NOT NULL COMMENT '手机号',
+  `amount` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '金额',
+  `order_id` int(10) NOT NULL COMMENT '订单',
+  `user_id` int(10) NOT NULL COMMENT '用户',
+  `status` enum('0','1','-1') NOT NULL DEFAULT '-1' COMMENT '状态:0=审核中,1=已开具,-1=已取消',
+  `createtime` int(10) NOT NULL COMMENT '申请时间',
+  `confirmtime` int(10) NULL DEFAULT NULL COMMENT '确认时间',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '订单发票';
+
+ALTER TABLE `__PREFIX__shopro_order` ADD COLUMN `invoice_status` enum('-1','0','1') NOT NULL DEFAULT '-1' COMMENT '发票开具状态:-1=不可开具,0=未申请,1=已申请' AFTER `status`;
+-- 1.3.7 标准版更新 ↑
+
+
+-- 1.3.8 标准版更新 ↓
+
+CREATE TABLE `__PREFIX__shopro_trade_order`  (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `type` enum('recharge') NOT NULL COMMENT '订单类型:recharge=余额充值',
+  `order_sn` varchar(60) NOT NULL COMMENT '订单号',
+  `user_id` int(11) NULL DEFAULT 0 COMMENT '用户',
+  `status` tinyint(2) NOT NULL DEFAULT 0 COMMENT '订单状态:-2=交易关闭,-1=已取消,0=未支付,1=已支付,2=已完成',
+  `remark` varchar(255) NULL DEFAULT NULL COMMENT '用户备注',
+  `total_amount` decimal(10, 2) NOT NULL COMMENT '订单总金额',
+  `total_fee` decimal(10, 2) NOT NULL COMMENT '支付金额',
+  `pay_fee` decimal(10, 2) NOT NULL COMMENT '实际支付金额',
+  `transaction_id` varchar(60) NULL DEFAULT NULL COMMENT '交易单号',
+  `payment_json` varchar(2500) NULL DEFAULT NULL COMMENT '交易原始数据',
+  `pay_type` enum('wechat','alipay','wallet','score') NULL DEFAULT NULL COMMENT '支付方式:wechat=微信支付,alipay=支付宝,wallet=钱包支付,score=积分支付',
+  `paytime` int(11) NULL DEFAULT NULL COMMENT '支付时间',
+  `ext` varchar(2048) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '附加字段',
+  `platform` enum('H5','App','wxOfficialAccount','wxMiniProgram') NULL DEFAULT NULL COMMENT '平台:H5=H5,wxOfficialAccount=微信公众号,wxMiniProgram=微信小程序,App=App',
+  `createtime` int(11) NULL DEFAULT NULL COMMENT '创建时间',
+  `updatetime` int(11) NULL DEFAULT NULL COMMENT '更新时间',
+  `deletetime` int(11) NULL DEFAULT NULL COMMENT '删除时间',
+  PRIMARY KEY (`id`) USING BTREE,
+  UNIQUE INDEX `order_sn`(`order_sn`) USING BTREE,
+  INDEX `user_id`(`user_id`) USING BTREE,
+  INDEX `status`(`status`) USING BTREE,
+  INDEX `createtime`(`createtime`) USING BTREE
+) ENGINE = InnoDB COMMENT = '交易订单管理';
+
+ALTER TABLE `__PREFIX__shopro_order` ADD COLUMN `last_total_fee` decimal(10, 2) NOT NULL DEFAULT '0.00' COMMENT '改价前金额' AFTER `total_fee`;
+ALTER TABLE `__PREFIX__shopro_order_express_log` MODIFY COLUMN `status` smallint(8) NULL DEFAULT 0 COMMENT '物流状态' AFTER `order_express_id`;
+-- 1.3.8 标准版更新 ↑
+
+COMMIT;

+ 57 - 0
addons/shopro/job/ActivityAutoOper.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace addons\shopro\job;
+
+use addons\shopro\library\traits\ActivityCache;
+use addons\shopro\model\Activity;
+use think\queue\Job;
+
+
+/**
+ * 订单自动操作
+ */
+class ActivityAutoOper extends BaseJob
+{
+    use ActivityCache;
+
+    /**
+     * 活动自动删除
+     */
+    public function autoClose(Job $job, $data){
+        try {
+            $activity = $data['activity'];
+
+            $activity = Activity::get($activity['id']);
+
+            // 一个活动会存在多个队列,要排重
+            if ($activity) {
+                // 如果活动还没被删除
+
+                // 规则
+                $rules = $activity['rules'];
+
+                // 当前配置应该自动结束的时间
+                $laterTime = $activity['endtime'];
+                if (isset($rules['activity_auto_close']) && $rules['activity_auto_close'] > 0) {
+                    $laterTime += ($rules['activity_auto_close'] * 60);
+                }
+
+                // 如果当前时间大于 laterTime,可以执行删除
+                if (time() >= $laterTime) {
+                    // 删除活动 【软删】
+                    $activity->delete();
+
+                    // 删除活动缓存
+                    $this->delActivity($activity);
+                }
+            }
+
+            // 删除 job
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            \think\Log::write('queue-' . get_class() . '-autoClose' . ':执行失败,错误信息:' . $e->getMessage());
+        }
+    }
+    
+}

+ 57 - 0
addons/shopro/job/ActivityGrouponAutoOper.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace addons\shopro\job;
+
+use addons\shopro\library\traits\ActivityCache;
+use addons\shopro\library\traits\Groupon;
+use addons\shopro\model\Activity;
+use addons\shopro\model\ActivityGroupon;
+use think\queue\Job;
+
+
+/**
+ * 订单自动操作
+ */
+class ActivityGrouponAutoOper extends BaseJob
+{
+    use ActivityCache, Groupon;
+
+    /**
+     * 拼团判断,将团结束, 
+     */
+    public function expire(Job $job, $data){
+        try {
+            $activity = $data['activity'];
+            $activity_groupon_id = $data['activity_groupon_id'];
+            $activityGroupon = ActivityGroupon::where('id', $activity_groupon_id)->find();
+
+            // 活动正在进行中, 走这里的说明人数 都没满
+            if ($activityGroupon && $activityGroupon['status'] == 'ing') {
+                \think\Db::transaction(function () use ($activity, $activityGroupon) {
+                    $rules = $activity['rules'];
+                    // 是否虚拟成团
+                    $is_fictitious = $rules['is_fictitious'] ?? 0;
+                    // 最大虚拟人数 ,不填或者 "" 不限制人数,都允许虚拟成团, 0相当于不允许虚拟成团
+                    $fictitious_num = (!isset($rules['fictitious_num']) || $rules['fictitious_num'] == '') ? 'no-limit' : $rules['fictitious_num'];
+                    // 拼团剩余人数
+                    $surplus_num = $activityGroupon['num'] - $activityGroupon['current_num'];
+
+                    if ($is_fictitious && ($fictitious_num == 'no-limit' || $fictitious_num >= $surplus_num)) {
+                        // 虚拟成团,如果虚拟用户不够,则自动解散
+                        $this->finishFictitiousGroupon($activityGroupon);
+                    } else {
+                        // 解散退款
+                        $this->invalidRefundGroupon($activityGroupon);
+                    }
+                });
+            }
+
+            // 删除 job
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            \think\Log::write('queue-' . get_class() . '-expire' . ':执行失败,错误信息:' . $e->getMessage());
+        }
+    }
+    
+}

+ 25 - 0
addons/shopro/job/BaseJob.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace addons\shopro\job;
+
+use addons\shopro\model\Order;
+use addons\shopro\model\OrderAction;
+use think\queue\Job;
+
+
+/**
+ * BaseJob 基类
+ */
+class BaseJob
+{
+
+    public function failed($data){
+        // 记录日志
+        \think\Db::name('shopro_failed_job')->insert([
+            'data' => json_encode($data),
+            'createtime' => time(),
+            'updatetime' => time()
+        ]);
+    }
+
+}

+ 40 - 0
addons/shopro/job/Notification.php

@@ -0,0 +1,40 @@
+<?php
+
+namespace addons\shopro\job;
+
+use think\queue\Job;
+
+/**
+ * 队列消息通知
+ */
+class Notification extends BaseJob
+{
+    /**
+     * 发送通知
+     */
+    public function send(Job $job, $data){
+        try {
+            // 这里获取到的 $notifiables 和 notification 两个都是数组,不是类,尴尬, 更可恨的 notification 只是 {"delay":0,"event":"changemobile"}
+            $notifiables = $data['notifiables'];
+            $notification = $data['notification'];
+            // 因为 notification 只有参数,需要把对应的类传过来,在这里重新初始化
+            $notification_name = $data['notification_name'];
+
+            // 重新实例化 notification 实例
+            if (class_exists($notification_name)) {
+                $notification = new $notification_name($notification['data']);
+
+                // 发送消息
+                \addons\shopro\library\notify\Notify::sendNow($notifiables, $notification);
+            }
+            
+            // 删除 job
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            \think\Log::error('queue-' . get_class()
+                . (isset($notification->event) ? ('-' . $notification->event) : '') 
+                . ':执行失败,错误信息:' . $e->getMessage());
+        }
+    }
+}

+ 142 - 0
addons/shopro/job/OrderAutoOper.php

@@ -0,0 +1,142 @@
+<?php
+
+namespace addons\shopro\job;
+
+use addons\shopro\model\GoodsComment;
+use addons\shopro\model\Order;
+use addons\shopro\model\OrderAction;
+use addons\shopro\model\OrderItem;
+use addons\shopro\model\Config;
+use think\queue\Job;
+
+
+/**
+ * 订单自动操作
+ */
+class OrderAutoOper extends BaseJob
+{
+
+    /**
+     * 订单自动关闭
+     */
+    public function autoClose(Job $job, $data){
+        try {
+            $order = $data['order'];
+
+            // 重新查询订单
+            $order = Order::get($order['id']);
+
+            if ($order && $order['status'] == 0) {
+                \think\Db::transaction(function () use ($order, $data) {
+                    // 订单关闭前
+                    \think\Hook::listen('order_close_before', $data);
+                    // 执行关闭
+                    $order->status = Order::STATUS_INVALID;
+                    $order->ext = json_encode($order->setExt($order, ['invalid_time' => time()]));      // 取消时间
+                    $order->save();
+    
+                    OrderAction::operAdd($order, null, null, 'system', '系统自动失效订单');
+    
+                    // 订单自动关闭之后 行为 返还用户优惠券,积分
+                    $data = ['order' => $order];
+                    \think\Hook::listen('order_close_after', $data);
+                });
+            }
+
+            // 删除 job
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            \think\Log::write('queue-' . get_class() . '-autoClose' . ':执行失败,错误信息:' . $e->getMessage());
+        }
+    }
+
+
+    /**
+     * 订单自动确认
+     */
+    public function autoConfirm(Job $job, $data) {
+        try {
+            $order = $data['order'];
+            $item = $data['item'];
+
+            // 重新查询订单
+            $order = Order::get($order['id']);
+            
+            // 只要没有退款成功,所有队列正常执行
+            $item = OrderItem::where('id', $item['id'])
+                            ->where('dispatch_status', OrderItem::DISPATCH_STATUS_SENDED)
+                            ->where('refund_status', 'not in', [OrderItem::REFUND_STATUS_OK, OrderItem::REFUND_STATUS_FINISH])
+                            ->find();
+
+            if ($order && $item) {
+                \think\Db::transaction(function () use ($order, $item, $data) {
+                    (new Order())->getedItem($order, $item, ['oper_type' => 'system']);
+                });
+            }
+
+            // 删除 job
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            \think\Log::write('queue-' . get_class() . '-autoConfirm' . ':执行失败,错误信息:' . $e->getMessage());
+        }
+    }
+
+
+
+    public function autoComment(Job $job, $data) {
+        try {
+            $order = $data['order'];
+            $item = $data['item'];
+
+            // 重新查询订单
+            $order = Order::get($order['id']);
+
+            // 只要没有退款成功,所有队列正常执行
+            $item = OrderItem::where('id', $item['id'])
+                ->where('dispatch_status', OrderItem::DISPATCH_STATUS_GETED)
+                ->where('comment_status', OrderItem::COMMENT_STATUS_NO)
+                ->where('refund_status', 'not in', [OrderItem::REFUND_STATUS_OK, OrderItem::REFUND_STATUS_FINISH])
+                ->find();
+
+            if ($order && $item) {
+                \think\Db::transaction(function () use ($order, $item, $data) {
+                    // 订单评价前
+                    \think\Hook::listen('order_comment_before', $data);
+
+                    // 获取自动好评内容
+                    $config = Config::where('name', 'order')->cache(300)->find();        // 读取配置自动缓存 5 分钟
+                    $config = isset($config) ? json_decode($config['value'], true) : [];
+                    $comment_content = (isset($config['order_comment_content']) && $config['order_comment_content'])
+                                ? $config['order_comment_content'] : '用户默认好评';       // 单位天 
+
+                    GoodsComment::create([
+                        'goods_id' => $item['goods_id'],
+                        'order_id' => $order['id'],
+                        'user_id' => $order['user_id'],
+                        'level' => 5,           // 自动好评
+                        'content' => $comment_content,
+                        'images' => '',
+                        'status' => 'show'
+                    ]);
+
+                    $item->comment_status = OrderItem::COMMENT_STATUS_OK;        // 评价成功
+                    $item->save();
+
+                    OrderAction::operAdd($order, $item, null, 'system', '系统自动评价成功');
+
+                    // 订单评价后
+                    $data = ['order' => $order, 'item' => $item];
+                    \think\Hook::listen('order_comment_after', $data);
+                });
+            }
+
+            // 删除 job
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            \think\Log::write('queue-' . get_class() . '-autoComment' . $e->getMessage());
+        }
+    }
+}

+ 87 - 0
addons/shopro/job/OrderPayed.php

@@ -0,0 +1,87 @@
+<?php
+
+namespace addons\shopro\job;
+
+use addons\shopro\library\traits\ActivityCache;
+use addons\shopro\library\traits\Groupon;
+use addons\shopro\library\traits\StockSale;
+use addons\shopro\model\Config;
+use addons\shopro\model\GoodsComment;
+use addons\shopro\model\Order;
+use addons\shopro\model\OrderAction;
+use addons\shopro\model\OrderItem;
+use think\queue\Job;
+
+/**
+ * 订单支付完成
+ */
+class OrderPayed extends BaseJob
+{
+    use StockSale, ActivityCache, Groupon;
+
+    /**
+     * 订单支付完成
+     */
+    public function payed(Job $job, $data)
+    {
+        try {
+            $order = $data['order'];
+            $user = $data['user'];
+
+            $order = Order::with('item')->where('id', $order['id'])->find();
+
+            // 数据库删订单的问题常见,这里被删的订单直接把队列移除
+            if ($order) {
+                \think\Db::transaction(function () use ($order, $user, $data) {
+                    // 订单减库存
+                    $this->realForwardStockSale($order);
+
+                    // 判断,如果是拼团 真实加入团
+                    if (strpos($order['activity_type'], 'groupon') !== false) {
+                        $this->joinGroupon($order, $user);
+                    }
+
+                    // 处理发票审核
+                    if ($order->invoice_status == 1) {
+                        $invoice = \addons\shopro\model\OrderInvoice::get(['order_id' => $order->id]);
+                        if ($invoice) {
+                            $invoice->status = 0;
+                            $invoice->save();
+                        }
+                    }
+                    // 处理消费返积分 TODO: 待测试
+                    $scoreConfig = Config::where('name', 'score')->find();
+                    $scoreConfig = json_decode($scoreConfig['value'], true);
+                    if(!empty($scoreConfig['consume_get_score']) && !empty($scoreConfig['consume_get_score_ratio'])) {
+                        $scoreRatio = intval($scoreConfig['consume_get_score_ratio']);
+                        $score = intval($scoreRatio * 0.01 * $order->total_fee);
+                        if($score > 0) {
+                            \addons\shopro\model\User::score($score, $user['id'], 'consume_get_score', $order['id']);
+                        }
+                    }
+                    
+                    // 触发订单支付完成事件, 如果这个订单刚好完成拼团,并且是自动发货订单,则这个订单的自动发货事件会比订单支付之后事件早
+                    $data = ['order' => $order];
+                    \think\Hook::listen('order_payed_after', $data);
+
+                    // 检测有没有自动发货的商品,有就自动发货
+                    $order->checkDispatchAndSend($order, ['user' => $user]);
+                });
+            }
+
+            // 删除 job
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            $error = json_encode([
+                'a' => $e->getLine(),
+                'b' => $e->getFile(),
+                'c' => $e->getTrace(),
+                'd' => $e->getMessage()
+            ], JSON_UNESCAPED_UNICODE);
+
+
+            \think\Log::error('queue-' . get_class() . '-payed' . ':执行失败,错误信息:' . $error);
+        }
+    }
+}

+ 42 - 0
addons/shopro/job/TradeOrderAutoOper.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace addons\shopro\job;
+
+use addons\shopro\model\TradeOrder;
+use addons\shopro\model\Config;
+use think\queue\Job;
+
+
+/**
+ * 交易订单自动操作
+ */
+class TradeOrderAutoOper extends BaseJob
+{
+
+    /**
+     * 订单自动关闭
+     */
+    public function autoClose(Job $job, $data){
+        try {
+            $order = $data['order'];
+
+            // 重新查询订单
+            $order = TradeOrder::get($order['id']);
+
+            if ($order && $order['status'] == 0) {
+                \think\Db::transaction(function () use ($order, $data) {
+                    // 执行关闭
+                    $order->status = TradeOrder::STATUS_INVALID;
+                    $order->ext = json_encode($order->setExt($order, ['invalid_time' => time()]));      // 取消时间
+                    $order->save();
+                });
+            }
+
+            // 删除 job
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            \think\Log::write('queue-' . get_class() . '-autoClose' . ':执行失败,错误信息:' . $e->getMessage());
+        }
+    }
+}

+ 74 - 0
addons/shopro/job/Wechat.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace addons\shopro\job;
+
+use think\queue\Job;
+
+/**
+ * 微信任务
+ */
+class Wechat extends BaseJob
+{
+    /**
+     * 异步分批创建新的队列任务
+     */
+    public function createQueueByOpenIdsArray(Job $job, $openIdsArray)
+    {
+        try {
+            $count = count($openIdsArray);
+            if ($count > 0) {
+                $page = ceil($count / 100);
+                for ($i = 0; $i < $page; $i++) {
+                    \think\Queue::push('\addons\shopro\job\Wechat@saveSubscribeUserInfo', array_slice($openIdsArray, $i * 100, 100), 'shopro');
+                }
+            }
+            // 删除 job
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            \think\Log::error('queue-' . get_class() . '-createQueueByOpenIdsArray' . ':执行失败,错误信息:' . $e->getMessage());
+        }
+    }
+
+    /**
+     * 保存更新关注用户
+     */
+    public function saveSubscribeUserInfo(Job $job, $openIdsArray)
+    {
+        try {
+            $wechat = new \addons\shopro\library\Wechat('wxOfficialAccount');
+            $result = $wechat->getSubscribeUserInfoByOpenId($openIdsArray);
+
+            if (isset($result['user_info_list'])) {
+                $userInfoList = $result['user_info_list'];
+                $insertData = [];
+                foreach ($userInfoList as $u) {
+                    $wechatFans = \app\admin\model\shopro\wechat\Fans::get(['openid' => $u['openid']]);
+                    if ($wechatFans) {
+                        $wechatFans->save([
+                            'nickname' => $u['nickname'],
+                            'headimgurl' => $u['headimgurl'],
+                            'sex' => $u['sex'],
+                            'country' => $u['country'],
+                            'province' => $u['province'],
+                            'city' => $u['city'],
+                            'subscribe' => 1,
+                            'subscribe_time' => $u['subscribe_time']
+                        ]);
+                    }else{
+                        $insertData[] = $u;
+                    }
+                }
+                if (count($insertData) > 0) {
+                    $wechatFans = new \app\admin\model\shopro\wechat\Fans;
+                    $wechatFans->allowField(true)->saveAll($insertData);
+                }
+
+            }
+            $job->delete();
+        } catch (\Exception $e) {
+            // 队列执行失败
+            \think\Log::error('queue-' . get_class() . '-saveSubscribeUserInfo' . ':执行失败,错误信息2:' . $e->getMessage() . '|' . json_encode($insertData, JSON_UNESCAPED_UNICODE));
+        }
+    }
+}

+ 84 - 0
addons/shopro/lang/zh-cn.php

@@ -0,0 +1,84 @@
+<?php
+
+return [
+    'Keep login'                                  => '保持会话',
+    'Username'                                    => '用户名',
+    'User id'                                     => '会员ID',
+    'Nickname'                                    => '昵称',
+    'Password'                                    => '密码',
+    'Sign up'                                     => '注 册',
+    'Sign in'                                     => '登 录',
+    'Sign out'                                    => '注 销',
+    'Guest'                                       => '游客',
+    'Welcome'                                     => '%s,你好!',
+    'Add'                                         => '添加',
+    'Edit'                                        => '编辑',
+    'Delete'                                      => '删除',
+    'Move'                                        => '移动',
+    'Name'                                        => '名称',
+    'Status'                                      => '状态',
+    'Weigh'                                       => '权重',
+    'Operate'                                     => '操作',
+    'Warning'                                     => '温馨提示',
+    'Default'                                     => '默认',
+    'Article'                                     => '文章',
+    'Page'                                        => '单页',
+    'OK'                                          => '确定',
+    'Cancel'                                      => '取消',
+    'Loading'                                     => '加载中',
+    'More'                                        => '更多',
+    'Normal'                                      => '正常',
+    'Hidden'                                      => '隐藏',
+    'Submit'                                      => '提交',
+    'Reset'                                       => '重置',
+    'Execute'                                     => '执行',
+    'Close'                                       => '关闭',
+    'Search'                                      => '搜索',
+    'Refresh'                                     => '刷新',
+    'First'                                       => '首页',
+    'Previous'                                    => '上一页',
+    'Next'                                        => '下一页',
+    'Last'                                        => '末页',
+    'None'                                        => '无',
+    'Home'                                        => '主页',
+    'Online'                                      => '在线',
+    'Logout'                                      => '注销',
+    'Profile'                                     => '个人资料',
+    'Index'                                       => '首页',
+    'Hot'                                         => '热门',
+    'Recommend'                                   => '推荐',
+    'Dashboard'                                   => '控制台',
+    'Code'                                        => '编号',
+    'Message'                                     => '内容',
+    'Line'                                        => '行号',
+    'File'                                        => '文件',
+    'Menu'                                        => '菜单',
+    'Type'                                        => '类型',
+    'Title'                                       => '标题',
+    'Content'                                     => '内容',
+    'Append'                                      => '追加',
+    'Memo'                                        => '备注',
+    'Parent'                                      => '父级',
+    'Params'                                      => '参数',
+    'Permission'                                  => '权限',
+    'Advance search'                              => '高级搜索',
+    'Check all'                                   => '选中全部',
+    'Expand all'                                  => '展开全部',
+    'Begin time'                                  => '开始时间',
+    'End time'                                    => '结束时间',
+    'Create time'                                 => '创建时间',
+    'Flag'                                        => '标志',
+    'Please login first'                          => '请登录后操作',
+    'Redirect now'                                => '立即跳转',
+    'Operation completed'                         => '操作成功!',
+    'Operation failed'                            => '操作失败!',
+    'Unknown data format'                         => '未知的数据格式!',
+    'Network error'                               => '网络错误!',
+    'Advanced search'                             => '高级搜索',
+    'Invalid parameters'                          => '未知参数',
+    'No results were found'                       => '记录未找到',
+    'Parameter %s can not be empty'               => '参数%s不能为空',
+    'You have no permission'                      => '你没有权限访问',
+    'An unexpected error occurred'                => '发生了一个意外错误,程序猿正在紧急处理中',
+    'This page will be re-directed in %s seconds' => '页面将在 %s 秒后自动跳转',
+];

+ 8 - 0
addons/shopro/lang/zh-cn/common.php

@@ -0,0 +1,8 @@
+<?php
+
+return [
+    'No file upload or server upload limit exceeded' => '未上传文件或超出服务器上传限制',
+    'Uploaded file format is limited'                => '上传文件格式受限制',
+    'Uploaded file is not a valid image'             => '上传文件不是有效的图片文件',
+    'Upload successful'                              => '上传成功',
+];

+ 39 - 0
addons/shopro/lang/zh-cn/user.php

@@ -0,0 +1,39 @@
+<?php
+
+return [
+    'User center'                           => '会员中心',
+    'Register'                              => '注册',
+    'Login'                                 => '登录',
+    'Sign up successful'                    => '注册成功',
+    'Username can not be empty'             => '用户名不能为空',
+    'Username must be 6 to 30 characters'   => '用户名必须6-30个字符',
+    'Password can not be empty'             => '密码不能为空',
+    'Password must be 6 to 30 characters'   => '密码必须6-30个字符',
+    'Mobile is incorrect'                   => '手机格式不正确',
+    'Username already exist'                => '用户名已经存在',
+    'Email already exist'                   => '邮箱已经存在',
+    'Mobile already exists'                 => '手机号已经存在',
+    'Mobile is binded'                      => '绑定成功',
+    'Username is incorrect'                 => '用户名不正确',
+    'Email is incorrect'                    => '邮箱不正确',
+    'Account is locked'                     => '账户已经被锁定',
+    'Password is incorrect'                 => '密码不正确',
+    'Account is incorrect'                  => '账户不正确',
+    'Account not exist'                     => '账户不存在',
+    'User not found'                     =>    '账户不存在',
+    'Account can not be empty'              => '账户不能为空',
+    'Username or password is incorrect'     => '用户名或密码不正确',
+    'You are not logged in'                 => '你当前还未登录',
+    'You\'ve logged in, do not login again' => '你已经存在,请不要重复登录',
+    'Profile'                               => '个人资料',
+    'Verify email'                          => '邮箱验证',
+    'Change password'                       => '修改密码',
+    'Captcha is incorrect'                  => '验证码不正确',
+    'Logged in successful'                  => '登录成功',
+    'Logout successful'                     => '注销成功',
+    'Operation failed'                      => '操作失败',
+    'Invalid parameters'                    => '参数不正确',
+    'Change password failure'               => '修改密码失败',
+    'Change password successful'            => '修改密码成功',
+    'Reset password successful'             => '重置密码成功',
+];

+ 116 - 0
addons/shopro/library/Export.php

@@ -0,0 +1,116 @@
+<?php
+
+namespace addons\shopro\library;
+
+use EasyWeChat\Factory;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
+use League\Flysystem\Adapter\Local;
+use League\Flysystem\Filesystem;
+use Cache\Adapter\Filesystem\FilesystemCachePool;
+use addons\shopro\library\Redis;
+/**
+ *
+ */
+class Export
+{
+
+
+    public function __construct()
+    {
+    }
+
+    public function exportExcel($expTitle, $expCellName, $expTableData, &$spreadsheet = null, &$sheet = null, $pages = [])
+    {
+        $page = $pages['page'] ?? 1;
+        $page_size = $pages['page_size'] ?? 1000;
+        $is_last_page = $pages['is_last_page'] ?? 1;
+        $current_total = $pages['current_total'] ?? 0;
+
+        if ($current_total) {
+            // 每次传来的 expTableData 数据条数不等,比如订单导出
+            $base_cell = $current_total - count($expTableData) + 2;
+        }else {
+            $base_cell = ($page - 1) * $page_size + 2;
+        }
+
+        $fileName = $expTitle;
+        $cellNum = count($expCellName);
+        $dataNum = count($expTableData);
+        $cellName = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ');
+
+        if ($page == 1) {
+            // 不限时
+            set_time_limit(0);
+            // 根据需要调大内存限制
+            ini_set('memory_limit', '512M');
+            
+            $cache_type = 'redis';
+            // 设置缓存
+            if ($cache_type == 'redis' && class_exists(\Cache\Adapter\Redis\RedisCachePool::class)) {
+                // 将表格数据暂存 redis,可以降低 php 进程内存占用,需要安装扩展包  composer require cache/simple-cache-bridge cache/redis-adapter
+                $options = [
+                    // 'select' => 0        // 注释解开,并且换成一个空的 select 库,redis 库默认是 0-15 共 16 个库
+                ];
+
+                $redis = (new Redis($options))->getRedis();
+                $pool = new \Cache\Adapter\Redis\RedisCachePool($redis);
+                $simpleCache = new \Cache\Bridge\SimpleCache\SimpleCacheBridge($pool);
+
+                \PhpOffice\PhpSpreadsheet\Settings::setCache($simpleCache);
+            } else if ($cache_type == 'file' && class_exists(FilesystemCachePool::class)) {
+                // 将数据暂存磁盘,可以降低内存,但是导出速度会大幅下降 需要安装扩展包  composer require cache/filesystem-adapter
+                $path = ROOT_PATH . 'runtime' . DS . 'export/';
+                @mkdir($path);
+                $filesystemAdapter = new Local($path);
+                $filesystem        = new Filesystem($filesystemAdapter);
+                $pool = new FilesystemCachePool($filesystem);
+    
+                \PhpOffice\PhpSpreadsheet\Settings::setCache($pool);
+            }
+
+            // 实例化excel
+            $spreadsheet = new Spreadsheet();
+            // 初始化工作簿
+            $sheet = $spreadsheet->getActiveSheet(0);
+            // 给表头设置边框
+            $sheet->getStyle('A1:' . $cellName[$cellNum - 1] . '1')->getFont()->setBold(true);
+
+            // 表头
+            $i = 0;
+            foreach ($expCellName as $key => $cell) {
+                $sheet->setCellValue($cellName[$i] . '1', $cell);
+                $i++;
+            }
+        }
+
+        // for ($i = 0; $i < $cellNum; $i++) {
+        //     $sheet->getColumnDimension($cellName[$i])->setWidth(30);
+        // }
+
+        // 写入数据
+        for ($i = 0; $i < $dataNum; $i++) {
+            if ($is_last_page && $i == ($dataNum - 1)) {
+                $sheet->mergeCells('A' . ($i + $base_cell) . ':' . $cellName[$cellNum - 1] . ($i + $base_cell));
+                $sheet->setCellValue('A' . ($i + $base_cell), $expTableData[$i][key($expCellName)]);
+            } else {
+                $j = 0;
+                foreach ($expCellName as $key => $cell) {
+                    $sheet->setCellValue($cellName[$j] . ($i + $base_cell), $expTableData[$i][$key]);
+                    $j++;
+                }
+            }
+        }
+
+        if ($is_last_page) {
+            // ini_set('memory_limit', '256M');
+
+            ob_end_clean();
+            header('pragma:public');
+            header('Content-type:application/vnd.ms-excel;charset=utf-8;name="' . $fileName . '.xlsx"');
+            header("Content-Disposition:attachment;filename=$fileName.xlsx"); //attachment新窗口打印inline本窗口打印
+            $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
+            $writer->save('php://output');
+        }
+    }
+}

+ 230 - 0
addons/shopro/library/Express.php

@@ -0,0 +1,230 @@
+<?php
+
+namespace addons\shopro\library;
+
+use fast\Http;
+
+class Express
+{
+    // 查询接口
+    const REQURL = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";
+    // 订阅接口
+    const SUBURL = "https://api.kdniao.com/api/dist";
+    // 电子面单下单接口
+    const API_EORDER = "https://api.kdniao.com/api/EOrderService";
+    protected $config = [];
+
+    /**
+     * 构造函数
+     */
+    public function __construct()
+    {
+        $config = \addons\shopro\model\Config::get(['name' => 'services']);
+        $config = ($config && $config->value) ? json_decode($config->value, true) : [];
+
+        $expressConfig = $config['express'] ?? [];
+        if (!$expressConfig || !$expressConfig['ebusiness_id'] || !$expressConfig['appkey']) {
+            throw new \Exception('请配置快递接口');
+        }
+
+        $this->config = $expressConfig;
+    }
+
+
+    /**
+     * Json方式  物流信息订阅
+     */
+    public function subscribe($data = [], $orderExpress = null, $order = null)
+    {
+        $requestData = $this->getRequestData($data, $orderExpress, $order);
+
+        $datas = [
+            'EBusinessID' => $this->config['ebusiness_id'],
+            'RequestType' => $this->config['type'] == 'free' ? '1008' : '8008',
+            'RequestData' => urlencode($requestData),
+            'DataType' => '2',
+        ];
+        $datas['DataSign'] = $this->encrypt($requestData, $this->config['appkey']);
+
+        $result = Http::sendRequest(self::SUBURL, $datas, 'POST', []);
+
+        if ($result['ret'] == 1) {
+            $exResult = json_decode($result['msg'], true);
+
+            if (!$exResult['Success']) {
+                throw new \Exception($exResult['Reason']);
+            }
+
+            return $exResult;
+        } else {
+            throw new \Exception($result['msg']);
+        }
+    }
+
+
+    // 查询快递信息
+    public function search($data = [], $orderExpress = null, $order = null)
+    {
+        $requestData = $this->getRequestData($data, $orderExpress, $order);
+        
+        $datas = [
+            'EBusinessID' => $this->config['ebusiness_id'],
+            'RequestType' => $this->config['type'] == 'free' ? '1002' : '8001',
+            'RequestData' => urlencode($requestData),
+            'DataType' => '2',
+        ];
+        $datas['DataSign'] = $this->encrypt($requestData, $this->config['appkey']);
+        $result = Http::sendRequest(self::REQURL, $datas, 'POST', []);
+
+        if ($result['ret'] == 1) {
+            $exResult = json_decode($result['msg'], true);
+
+            if (!$exResult['Success']) {
+                throw new \Exception($exResult['Reason']);
+            }
+
+            return $exResult;
+        } else {
+            throw new \Exception($result['msg']);
+        }
+    }
+
+
+    // 组装请求数据
+    private function getRequestData($data = [], $orderExpress = null, $order = null) {
+        $requestData = [
+            'OrderCode' => $order ? $order->order_sn : '',
+            'ShipperCode' => $data['express_code'],
+            'LogisticCode' => $data['express_no'],
+        ];
+
+        if ($data['express_code'] == 'JD') {
+            // 京东青龙配送单号
+            $requestData['CustomerName'] = $this->config['jd_code'];
+        } else if ($data['express_code'] == 'SF') {
+            // 收件人手机号后四位
+            $requestData['CustomerName'] = substr($order->phone, 7);
+        }
+
+        $requestData = json_encode($requestData);
+
+        return $requestData;
+    }
+
+
+
+    // 差异更新物流信息
+    public function checkAndAddTraces ($orderExpress, $express) {
+        $traces = $express['Traces'];
+
+        // 查询现有轨迹记录
+        $orderExpressLog = \addons\shopro\model\OrderExpressLog::where('order_express_id', $orderExpress->id)->select();
+
+        $log_count = count($orderExpressLog);
+        if ($log_count > 0) {
+            // 移除已经存在的记录
+            array_splice($traces, 0, $log_count);
+        }
+
+        // 增加包裹记录
+        foreach ($traces as $k => $trace) {
+            $orderExpressLog = new \addons\shopro\model\OrderExpressLog();
+    
+            $orderExpressLog->user_id = $orderExpress['user_id'];
+            $orderExpressLog->order_id = $orderExpress['order_id'];
+            $orderExpressLog->order_express_id = $orderExpress['id'];
+            $orderExpressLog->status = $trace['Action'] ?? $express['State'];
+            $orderExpressLog->content = $trace['AcceptStation'];
+            $orderExpressLog->changedate = substr($trace['AcceptTime'], 0, 19);     // 快递鸟测试数据 返回的是个 2020-08-03 16:58:272 格式
+            $orderExpressLog->location = $trace['Location'] ?? ($express['Location'] ?? null);
+            $orderExpressLog->save();
+        }
+    }
+
+    public function eorder($order, $item_lists)
+    {
+        if($this->config['type'] !== 'vip') {
+            throw new \Exception('请使用快递鸟标准版开通此功能');
+        }
+        $orderData = [
+            "OrderCode" => $order->order_sn,
+            "CustomerName" => $this->config['CustomerName'],
+            "CustomerPwd" => $this->config['CustomerPwd'],
+            "ShipperCode" => $this->config['ShipperCode'],
+            "PayType" => $this->config['PayType'],
+            "ExpType" => $this->config['ExpType'],
+            "IsReturnPrintTemplate" => 0,   //返回打印面单模板
+            "TemplateSize" => '130',    // 一联单   
+            "Sender" => $this->config['Sender'],
+            "Volume" => 0,
+            "Remark" => $order->remark ? $order->remark : "小心轻放"
+          ];
+          $totalCount = 0;
+          $totalWeight = 0;
+          foreach($item_lists as $k => $item) {
+            if($item->goods_sku_text) {
+                $goodsName = $item->goods_title . '-' . $item->goods_sku_text;
+            }else {
+                $goodsName = $item->goods_title;
+            }
+            $orderData['Commodity'][] = [
+                "GoodsName" =>  $goodsName,
+                "Goodsquantity" => $item->goods_num,
+                "GoodsWeight" => $item->goods_num * $item->goods_weight
+            ];
+            $totalCount += $item->goods_num;
+            $totalWeight += $item->goods_num * $item->goods_weight;
+          }
+          $orderData['Quantity'] = $totalCount; // 商品数量
+          $orderData['Weight'] = $totalWeight;
+          $orderData['Receiver'] = [
+            "Name" => $order->consignee,
+            "Mobile" => $order->phone,
+            "ProvinceName" => $order->province_name,
+            "CityName" => $order->city_name,
+            "ExpAreaName" => $order->area_name,
+            "Address" => $order->address
+          ];
+          $data = json_encode($orderData, JSON_UNESCAPED_UNICODE);
+          $datas = [
+            'EBusinessID' => $this->config['ebusiness_id'],
+            'RequestType' => '1007',
+            'RequestData' => urlencode($data),
+        ];
+        $datas['DataSign'] = $this->encrypt($data, $this->config['appkey']);
+
+        $result = Http::sendRequest(self::API_EORDER, $datas, 'POST', []);
+     
+        if ($result['ret'] == 1) {
+            $exResult = json_decode($result['msg'], true);
+
+            if (!$exResult['Success']) {
+                throw new \Exception($exResult['Reason']);
+            }
+
+            return $exResult;
+        } else {
+            throw new \Exception($result['msg']);
+        }
+    }
+
+
+    // 组装返回结果
+    public function setPushResult($success = false, $reason = '') {
+        $result = [
+            "EBusinessID" => $this->config['ebusiness_id'],
+            "UpdateTime" => date('Y-m-d H:i:s'),
+            "Success" => $success,
+            "Reason" => $reason
+        ];
+
+        return json_encode($result);
+    }
+
+
+    // 加签
+    function encrypt($data, $appkey)
+    {
+        return urlencode(base64_encode(md5($data . $appkey)));
+    }
+}

+ 25 - 0
addons/shopro/library/Hook.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace addons\shopro\library;
+
+class Hook
+{
+
+    public function __construct()
+    {
+        
+    }
+
+    public static function register ($behaviors = []) {
+        $default = require ROOT_PATH . 'addons/shopro/hooks.php';
+
+        $behaviors = array_merge($default, $behaviors);
+        foreach ($behaviors as $tag => $behavior) {
+            // 数组反转 保证最上面的行为优先级最高    
+            $behavior = array_reverse($behavior);
+            foreach ($behavior as $be) {
+                \think\Hook::add($tag, $be, true);      // 所有行为都插入最前面
+            }
+        }
+    }
+}

+ 0 - 0
addons/shopro/library/Oauth.php


+ 71 - 0
addons/shopro/library/Oper.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace addons\shopro\library;
+
+use app\admin\library\Auth as AdminAuth;
+use addons\shopro\model\Store;
+use addons\shopro\model\User;
+
+class Oper
+{
+    public static function set($operType = '', $operId = 0)
+    {
+        if ($operType === '') {
+            // 自动获取操作人
+            $admin = AdminAuth::instance();     // 没有登录返回的还是这个类实例
+            if ($admin->isLogin()) {
+                // 后台管理员
+                $operType = 'admin';
+                $operId = $admin->id;
+            } else if (strpos(request()->url(), 'store.store') !== false) {
+                // 门店
+                $store = Store::info();
+                if ($store) {
+                    $operType = 'store';
+                    $operId = $store['id'];
+                }
+            } else if (strpos(request()->url(), 'addons/shopro') !== false) {
+                // 用户
+                $user = User::info();
+                if ($user) {
+                    $operType = 'user';
+                    $operId = $user->id;
+                }
+            }
+        }
+        if ($operType === '') {
+            $operType = 'system';
+        }
+        return [
+            'oper_type' => $operType,
+            'oper_id' => $operId
+        ];
+    }
+
+    public static function get($operType, $operId)
+    {
+        $operator = null;
+        if ($operType === 'admin') {
+            $operator = \app\admin\model\Admin::where('id', $operId)->field('nickname as name, avatar')->find();
+            $operator['type'] = '管理员';
+        } elseif ($operType === 'user') {
+            $operator = \addons\shopro\model\User::where('id', $operId)->field('nickname as name, avatar')->find();
+            $operator['type'] = '用户';
+        } elseif ($operType === 'store') {
+            $operator = \addons\shopro\model\Store::where('id', $operId)->field('name')->find();
+            $operator['type'] = '门店';
+            $operator['avatar'] = '';
+        } else {
+            $operator = [
+                'name' => '系统',
+                'avatar' => '',
+                'type' => '系统'
+            ];
+        }
+        if(!isset($operator['name'])) {
+            $operator['name'] = '已删除';
+            $operator['avatar'] = '';
+        }
+        return $operator;
+    }
+}

+ 272 - 0
addons/shopro/library/PayService.php

@@ -0,0 +1,272 @@
+<?php
+
+namespace addons\shopro\library;
+
+use Yansongda\Pay\Pay;
+use Yansongda\Pay\Log;
+use addons\shopro\exception\Exception;
+
+class PayService
+{
+    protected $config;
+    protected $platform;
+    protected $payment;
+    protected $notify_url;
+    public $method;
+
+
+    public function __construct($payment, $platform = '', $notify_url = '', $type = 'pay')
+    {
+        $this->platform = $platform;
+        $this->payment = $payment;
+        $this->notify_url = $notify_url;
+        $this->type = $type;
+
+        $this->setPaymentConfig();
+    }
+
+    private function setPaymentConfig()
+    {
+        $paymentConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->payment])->value, true);
+
+        // 如果是支付,并且不是 复制地址的支付宝支付
+        if ($this->type == 'pay' && $this->platform != 'url' && !in_array($this->platform, $paymentConfig['platform'])) {
+            new Exception('暂不支持该方式付款');
+        }
+
+        $this->config = $paymentConfig;
+        $this->config['notify_url'] = $this->notify_url;
+
+        if ($this->payment === 'wechat') {
+            // 根据不同平台设置相应的 appid
+            $this->setWechatAppId();
+        }
+
+        // 设置支付证书路径
+        $this->setCert();
+    }
+
+    private function setWechatAppId()
+    {
+        switch ($this->platform) {
+            case 'wxOfficialAccount':
+                $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->platform])->value, true);
+                if (isset($this->config['mode']) && $this->config['mode'] === 'service') {
+                    $this->config['sub_app_id'] = $platformConfig['app_id'];
+                } else {
+                    $this->config['app_id'] = $platformConfig['app_id'];
+                }
+                break;
+            case 'wxMiniProgram':
+                $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->platform])->value, true);
+                if (isset($this->config['mode']) && $this->config['mode'] === 'service') {
+                    $this->config['sub_miniapp_id'] = $platformConfig['app_id'];
+                    // $this->config['sub_app_id'] = $platformConfig['app_id'];
+                } else {
+                    $this->config['miniapp_id'] = $platformConfig['app_id'];
+                    $this->config['app_id'] = $platformConfig['app_id'];        // 小程序微信企业付款
+                }
+                break;
+            case 'H5':
+                $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => $this->platform])->value, true);
+                if (isset($this->config['mode']) && $this->config['mode'] === 'service') {
+                    $this->config['sub_app_id'] = $platformConfig['app_id'];
+                } else {
+                    $this->config['app_id'] = $platformConfig['app_id'];
+                }
+                break;
+            case 'App':
+                $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'App'])->value, true);
+                if (isset($this->config['mode']) && $this->config['mode'] === 'service') {
+                    $this->config['sub_appid'] = $platformConfig['app_id'];
+                    $this->config['sub_app_id'] = $platformConfig['app_id'];
+                } else {
+                    $this->config['appid'] = $platformConfig['app_id'];         // 微信 App 支付使用这个
+                    $this->config['app_id'] = $platformConfig['app_id'];        // 微信 App 支付退款使用的是这个
+                }
+
+                break;
+        }
+    }
+
+
+    // 处理证书路径
+    private function setCert()
+    {
+        // 处理证书路径
+        if ($this->payment == 'wechat') {
+            // 微信支付证书
+            $this->config['cert_client'] = ROOT_PATH . 'public' . $this->config['cert_client'];
+            $this->config['cert_key'] = ROOT_PATH . 'public' . $this->config['cert_key'];
+        } else {
+            // 支付宝证书路径
+            $end = substr($this->config['ali_public_key'], -4);
+            if ($end == '.crt') {
+                $this->config['ali_public_key'] = ROOT_PATH . 'public' . $this->config['ali_public_key'];
+            }
+            $this->config['app_cert_public_key'] = ROOT_PATH . 'public' . $this->config['app_cert_public_key'];
+            $this->config['alipay_root_cert'] = ROOT_PATH . 'public' . $this->config['alipay_root_cert'];
+        }
+    }
+
+
+    private function setPaymentMethod()
+    {
+        $method = [
+            'wechat' => [
+                'wxOfficialAccount' => 'mp',   //公众号支付 Collection
+                'wxMiniProgram' => 'miniapp', //小程序支付
+                'H5' => 'wap', //手机网站支付 Response
+                'App' => 'app' //APP 支付 JsonResponse
+            ],
+            'alipay' => [
+                'wxOfficialAccount' => 'wap',   //手机网站支付 Response
+                'wxMiniProgram' => 'wap', //小程序支付
+                'H5' => 'wap', //手机网站支付 Response
+                'url' => 'wap', //手机网站支付 Response
+                'App' => 'app' //APP 支付 JsonResponse
+            ],
+        ];
+
+        $this->method = $method[$this->payment][$this->platform];
+    }
+
+    public function create($order)
+    {
+        //        $order = [
+        //            'out_trade_no' => time(),
+        //            'total_fee' => '1', // **单位:分**
+        //            'body' => 'test body - 测试',
+        //            'openid' => 'onkVf1FjWS5SBIixxxxxxx', //微信需要带openid过来
+        //        ];
+
+        // 设置支付方式
+        $this->setPaymentMethod();
+
+        $method = $this->method;
+        switch ($this->payment) {
+            case 'wechat':
+                if (isset($this->config['mode']) && $this->config['mode'] === 'service') {
+                    $order['sub_openid'] = $order['openid'];
+                    unset($order['openid']);
+                }
+                $order['total_fee'] = $order['total_fee'] * 100;
+                $pay = Pay::wechat($this->config)->$method($order);
+
+                break;
+            case 'alipay':
+                if (in_array($this->platform, ['wxOfficialAccount', 'wxMiniProgram', 'H5'])) {
+                    // 返回支付宝支付链接
+                    $pay = request()->domain() . '/addons/shopro/pay/alipay?order_sn=' . $order['out_trade_no'];
+                } else {
+                    if ($this->method == 'wap') {
+                        // 支付宝 wap 支付,增加 return_url
+                        // 获取 h5 域名
+                        $platformConfig = json_decode(\addons\shopro\model\Config::get(['name' => 'shopro'])->value, true);
+                        // 如果域名存在,增加 return_url
+                        if ($platformConfig && isset($platformConfig['domain'])) {
+                            $start = substr($platformConfig['domain'], -1) == '/' ? "" : "/";
+                            $orderType = strpos($order['out_trade_no'], 'TO') === 0 ? 'recharge' : 'goods';
+                            $this->config['return_url'] = $platformConfig['domain'] . $start . "pages/order/payment/result?orderId=" . $order['order_id'] . "&type=alipay&payState=success&orderType=" . $orderType;
+                        }
+                    }
+
+                    $pay = Pay::alipay($this->config)->$method($order);
+                }
+
+                break;
+        }
+
+        return $pay;
+    }
+
+    // 企业付款
+    public function transfer($payload)
+    {
+        $code = 0;
+        $response = [];
+        switch ($this->payment) {
+            case 'wechat':
+                $payload['amount'] = $payload['amount'] * 100;
+                $response = Pay::wechat($this->config)->transfer($payload);
+                if ($response['return_code'] === 'SUCCESS' && $response['result_code'] === 'SUCCESS') {
+                    $code = 1;
+                }
+                break;
+            case 'alipay':
+                $response = Pay::alipay($this->config)->transfer($payload);
+                if ($response['code'] === '10000' && $response['status'] === 'SUCCESS') {
+                    $code = 1;
+                }
+                break;
+        }
+
+        return [$code, $response];
+    }
+
+
+    public function notify($callback)
+    {
+        $pay = $this->getPay();
+
+        try {
+            $data = $pay->verify(); // 是的,验签就这么简单!
+
+            $result = $callback($data, $pay);
+
+            // Log::debug('Wechat notify', $data->all());
+        } catch (\Exception $e) {
+            \think\Log::error('notify-error:' . $e->getMessage());
+            // $e->getMessage();
+        }
+
+        return $result;
+    }
+
+
+    public function refund($order_data)
+    {
+        $pay = $this->getPay();
+
+        $order_data['type'] = $this->platform == 'wxMiniProgram' ? 'miniapp' : '';
+
+        $result = $pay->refund($order_data);
+
+        return $result;
+    }
+
+
+    public function notifyRefund($callback)
+    {
+        $pay = $this->getPay();
+
+        try {
+            $data = $pay->verify(null, true); // 是的,验签就这么简单!
+
+            $result = $callback($data, $pay);
+
+            // Log::debug('Wechat notify', $data->all());
+        } catch (\Exception $e) {
+            // $e->getMessage();
+        }
+
+        return $result;
+    }
+
+
+    private function getPay()
+    {
+        switch ($this->payment) {
+            case 'wechat':
+                $pay = Pay::wechat($this->config);
+                break;
+            case 'alipay':
+                $pay = Pay::alipay($this->config);
+                break;
+            default:
+                new Exception('支付方式不支持');
+        }
+
+        return $pay;
+    }
+}

+ 68 - 0
addons/shopro/library/Redis.php

@@ -0,0 +1,68 @@
+<?php
+
+namespace addons\shopro\library;
+
+use addons\shopro\exception\Exception;
+
+class Redis
+{
+    protected $handler = null;
+
+    protected $options = [
+        'host'       => '127.0.0.1',
+        'port'       => 6379,
+        'password'   => '',
+        'select'     => 0,
+        'timeout'    => 0,
+        'expire'     => 0,
+        'persistent' => false,
+        'prefix'     => '',
+    ];
+
+    /**
+     * 构造函数
+     * @param array $options 缓存参数
+     * @access public
+     */
+    public function __construct($options = [])
+    {
+        if (!extension_loaded('redis')) {
+            throw new \BadFunctionCallException('not support: redis');
+        }
+
+        // 获取 redis 配置
+        $config = \think\Config::get('redis');
+        if (empty($config) && empty($options)) {
+            throw new \Exception('redis connection fail: no redis config');
+        } 
+
+        if (!empty($config)) {
+            $this->options = array_merge($this->options, $config);
+        }
+
+        if (!empty($options)) {
+            $this->options = array_merge($this->options, $options);
+        }
+        $this->handler = new \Redis();
+        if ($this->options['persistent']) {
+            $this->handler->pconnect($this->options['host'], $this->options['port'], $this->options['timeout'], 'persistent_id_' . $this->options['select']);
+        } else {
+            $this->handler->connect($this->options['host'], $this->options['port'], $this->options['timeout']);
+        }
+
+        if ('' != $this->options['password']) {
+            $this->handler->auth($this->options['password']);
+        }
+
+        if (0 != $this->options['select']) {
+            $this->handler->select($this->options['select']);
+        }
+
+        // 赋值全局,避免多次实例化
+        $GLOBALS['SPREDIS'] = $this->handler;
+    }
+
+    public function getRedis() {
+        return $this->handler;
+    }
+}

+ 327 - 0
addons/shopro/library/Wechat.php

@@ -0,0 +1,327 @@
+<?php
+
+namespace addons\shopro\library;
+
+use EasyWeChat\Factory;
+use addons\shopro\model\Config;
+use think\Model;
+use fast\Http;
+
+/**
+ *
+ */
+class Wechat extends Model
+{
+    protected $config;
+    protected $app;
+
+
+    public function __construct($platform)
+    {
+        $this->setConfig($platform);
+        switch ($platform) {
+            case 'wxOfficialAccount':
+                $this->app    = Factory::officialAccount($this->config);
+                break;
+            case 'wxMiniProgram':
+                $this->app    = Factory::miniProgram($this->config);
+                break;
+            case 'App':
+                $this->app    = Factory::openPlatform($this->config);
+                break;
+        }
+
+        // 重新绑定 easywechat 缓存(如果需要负载均衡,必须要开启)
+        // $this->rebindCache();
+    }
+
+    // 返回实例
+    public function getApp() {
+        return $this->app;
+    }
+
+    //小程序:获取openid&session_key
+    public function code($code)
+    {
+        return $this->app->auth->session($code);
+    }
+
+    public function oauth()
+    {
+        $oauth = $this->app->oauth;
+        return $oauth;
+    }
+
+    //解密信息
+    public function decryptData($session, $iv, $encryptData)
+    {
+        $data = $this->app->encryptor->decryptData($session, $iv, $encryptData);
+
+        return $data;
+    }
+
+    public function unify($orderBody)
+    {
+        $result = $this->app->order->unify($orderBody);
+        return $result;
+    }
+
+    public function bridgeConfig($prepayId)
+    {
+        $jssdk = $this->app->jssdk;
+        $config = $jssdk->bridgeConfig($prepayId, false);
+        return $config;
+    }
+
+    public function notify()
+    {
+        $result = $this->app;
+        return $result;
+    }
+
+    //获取accessToken
+    public function getAccessToken()
+    {
+        $accessToken = $this->app->access_token;
+        $token = $accessToken->getToken(); // token 数组  token['access_token'] 字符串
+        //$token = $accessToken->getToken(true); // 强制重新从微信服务器获取 token.
+        return $token;
+    }
+
+
+    /**
+     * 重写 jssdk buildConfig 方法
+     *
+     * @param [type] $jssdk jssdk 实例
+     * @param [type] $apis  要请求的 api 列表
+     * @param boolean $debug    debug 
+     * @param boolean $beta 
+     * @param boolean $json 是否返回 json
+     * @param array $openTagList    开放标签列表
+     * @return void
+     */
+    public function buildConfig($jssdk, $jsApiList, $debug = false, $beta = false, $json = false, $openTagList = [], $url = '')
+    {
+        $url = $url ?: $jssdk->getUrl();
+        $nonce = \EasyWeChat\Kernel\Support\Str::quickRandom(10);
+        $timestamp = time();
+
+        $signature = [
+            'appId' => $this->config['app_id'],
+            'nonceStr' => $nonce,
+            'timestamp' => $timestamp,
+            'url' => $url,
+            'signature' => $jssdk->getTicketSignature($jssdk->getTicket()['ticket'], $nonce, $timestamp, $url),
+        ];
+
+        $config = array_merge(compact('debug', 'beta', 'jsApiList', 'openTagList'), $signature);
+
+        return $json ? json_encode($config) : $config;
+    }
+
+
+    public function sendTemplateMessage($attributes)
+    {
+        extract($attributes);
+        $this->app->template_message->send([
+            'touser' => $openId,
+            'template_id' => $templateId,
+            'page' => $page,
+            'form_id' => $formId,
+            'data' => $data,
+            'emphasis_keyword' => $emphasis_keyword
+        ]);
+    }
+
+
+    /**
+     * 发送公众号订阅消息
+     *
+     * @return void
+     */
+    public function bizsendSubscribeMessage($data) {
+        $access_token = $this->getAccessToken();
+
+        $bizsendUrl = "https://api.weixin.qq.com/cgi-bin/message/subscribe/bizsend?access_token={$access_token['access_token']}";
+
+        $headers = ['Content-type: application/json'];
+        $options = [
+            CURLOPT_HTTPHEADER => $headers
+        ];
+        $result = Http::sendRequest($bizsendUrl, json_encode($data), 'POST', $options);
+
+        if (isset($result['ret']) && $result['ret']) {
+            // 请求成功
+            $result = json_decode($result['msg'], true);
+            
+            return $result;
+        }
+        
+        // 请求失败
+        return ['errcode' => -1, 'msg' => $result];
+    }
+
+    // 同步小程序直播
+    public function live(Array $params = [])
+    {
+        $default = [
+            'start' => 0,
+            'limit' => 10
+        ];
+        $params = array_merge($default, $params);
+        $default = json_encode($params);
+
+
+        $access_token = $this->app->access_token->getToken();
+        $getRoomsListUrl = "https://api.weixin.qq.com/wxa/business/getliveinfo?access_token={$access_token['access_token']}";
+        $headers = ['Content-type: application/json'];
+        $options = [
+            CURLOPT_HTTPHEADER => $headers
+        ];
+        $result = Http::sendRequest($getRoomsListUrl, $default, 'POST', $options);
+        if (isset($result['ret']) && $result['ret']) {
+            $msg = json_decode($result['msg'], true);
+            $result = $msg;
+        }
+
+//        $result = $this->app->live->getRooms(...array_values($params));
+
+        $rooms = [];
+        if ($result && $result['errcode'] == 0 && $result['errmsg'] === 'ok') {
+            $rooms = $result['room_info'];
+        }
+
+        return $rooms;
+    }
+
+    // 小程序直播回放
+    public function liveReplay(array $params = [])
+    {
+        $default = [
+            'room_id' => 0,
+            'start' => 0,
+            'limit' => 20
+        ];
+
+        $params = array_merge($default, $params);
+        $default = json_encode($params);
+        $access_token = $this->app->access_token->getToken();
+        $getPlayBackListUrl = "https://api.weixin.qq.com/wxa/business/getliveinfo?access_token={$access_token['access_token']}";
+        $headers = ['Content-type: application/json'];
+        $options = [
+            CURLOPT_HTTPHEADER => $headers
+        ];
+        $result = Http::sendRequest($getPlayBackListUrl, $default, 'POST', $options);
+        if (isset($result['ret']) && $result['ret']) {
+            $msg = json_decode($result['msg'], true);
+            $result = $msg;
+        }
+//        $result = $this->app->live->getPlaybacks(...array_values($params));
+
+        $liveReplay = [];
+        if ($result && $result['errcode'] == 0 && $result['errmsg'] === 'ok') {
+            $liveReplay = $result['live_replay'];
+        }
+
+        return $liveReplay;
+    }
+
+    public function menu($act = 'create', $buttons = '')
+    {
+        $result = $this->app->menu->$act($buttons);
+        return $result;
+
+    }
+
+    // 公众号 获取所有粉丝
+    public function asyncFans($nextOpenId = null, $currentPage = 1, $totalPage = 1)
+    {
+        $fans = $this->app->user->list($nextOpenId);
+        $openIdsArray = $fans['data']['openid'];
+        //放入最大10000条openid队列去执行
+        \think\Queue::push('\addons\shopro\job\Wechat@createQueueByOpenIdsArray', $openIdsArray, 'shopro');
+        //第一次计算总页数
+        if ($currentPage === 1) {
+            $totalPage = intval($fans['total'] % $fans['count'] === 0 ? $fans['total'] / $fans['count'] : ceil($fans['total'] / $fans['count']));
+        }
+        //有分页 递归下一页
+        if ($currentPage < $totalPage) {
+            $openIdsArray = array_merge($openIdsArray, $this->asyncFans($fans['next_openid'], $currentPage++, $totalPage));
+        }
+        if ($currentPage == $totalPage) {
+            if ($totalPage == 1) {
+                $code = 1;
+                $msg = '同步成功';
+            }else{
+                $code = 1;
+                $msg = '数据较大,请稍后再查看...';
+            }
+            return [
+                'code' => $code,
+                'msg' => $msg
+            ];
+        }
+        return $openIdsArray;
+    }
+
+    //通过openid获取已经关注的用户信息
+    public function getSubscribeUserInfoByOpenId(array $openIdsArray)
+    {
+        $result = $this->app->user->select($openIdsArray);
+        return $result;
+    }
+
+
+    /**
+     * 重新绑定 easywechat 缓存
+     *
+     * @return void
+     */
+    private function rebindCache() {
+        $options = [
+            // 'select' => 0        // 默认和活动缓存使用同一个 select 库,如需自定义,解开注释,并填写对应 select 库
+        ];
+        $redis = (new Redis($options))->getRedis();
+        $cache = new \Symfony\Component\Cache\Adapter\RedisAdapter($redis);
+
+        // 替换应用中的缓存
+        $this->app->rebind('cache', $cache);
+    }
+
+
+
+    /**
+     * 合并默认配置
+     *
+     * @param [type] $platform
+     * @return void
+     */
+    private function setConfig($platform) {
+        $debug = config('app_debug');
+
+        $defaultConfig = [
+            'log' => [
+                'default' => $debug ? 'dev' : 'prod', // 默认使用的 channel,生产环境可以改为下面的 prod
+                'channels' => [
+                    // 测试环境
+                    'dev' => [
+                        'driver' => 'single',
+                        'path' => '/tmp/easywechat.log',
+                        'level' => 'debug',
+                    ],
+                    // 生产环境
+                    'prod' => [
+                        'driver' => 'daily',
+                        'path' => '/tmp/easywechat.log',
+                        'level' => 'info',
+                    ],
+                ],
+            ],
+        ];
+
+        // 获取对应平台的配置
+        $this->config = Config::getEasyWechatConfig($platform);
+        // 根据框架 debug 合并 log 配置
+        $this->config = array_merge($this->config, $defaultConfig);
+    }
+}

+ 138 - 0
addons/shopro/library/apple-signin/ASDecoder.php

@@ -0,0 +1,138 @@
+<?php
+
+namespace AppleSignIn;
+
+use AppleSignIn\Vendor\JWK;
+use AppleSignIn\Vendor\JWT;
+
+use Exception;
+
+class ASDecoder
+{
+    /**
+     * Parse a provided Sign In with Apple identity token.
+     * @param $identityToken
+     * @return ASPayload
+     * @throws Exception
+     */
+    public static function getAppleSignInPayload($identityToken)
+    {
+        $identityPayload = self::decodeIdentityToken($identityToken);
+        return new ASPayload($identityPayload);
+    }
+
+    /**
+     * Decode the Apple encoded JWT using Apple's public key for the signing.
+     * @param $identityToken
+     * @return object
+     * @throws Exception
+     */
+    public static function decodeIdentityToken($identityToken)
+    {
+        $publicKeyData = self::fetchPublicKey($identityToken);
+
+        $publicKey = $publicKeyData['publicKey'];
+        $alg = $publicKeyData['alg'];
+        $payload = JWT::decode($identityToken, $publicKey, [$alg]);
+        return $payload;
+    }
+
+    /**
+     * Fetch Apple's public key from the auth/keys REST API to use to decode
+     * the Sign In JWT.
+     *
+     * @param $identityToken
+     * @return array
+     * @throws Exception
+     */
+    public static function fetchPublicKey($identityToken)
+    {
+        $publicKeys = file_get_contents('https://appleid.apple.com/auth/keys');
+        $decodedPublicKeys = json_decode($publicKeys, true);
+
+        if (!isset($decodedPublicKeys['keys']) || count($decodedPublicKeys['keys']) < 1) {
+            throw new Exception('Invalid key format.');
+        }
+
+        // 苹果公钥返回的 keys 内数据不是固定顺序,此处按索引取 auth keys,取正确的 key
+        // value by index
+        try {
+            $tks = explode('.', $identityToken);
+            if (count($tks) != 3) {
+                throw new Exception('Wrong number of segments');
+            }
+            list($headb64, $bodyb64, $cryptob64) = $tks;
+            $header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64));
+            $kid = $header->kid;
+
+            if (count($decodedPublicKeys['keys']) > 1) {
+                $indexPublicInfo = array_column($decodedPublicKeys['keys'], null, 'kid');
+                $parsedKeyData = isset($indexPublicInfo[$kid]) ? $indexPublicInfo[$kid] : $decodedPublicKeys['keys'][0];
+            } else {
+                $parsedKeyData = $decodedPublicKeys['keys'][0];
+            }
+        } catch (\Exception $exception) {
+            $parsedKeyData = $decodedPublicKeys['keys'][0];
+        }
+
+        $parsedPublicKey = JWK::parseKey($parsedKeyData);
+        $publicKeyDetails = openssl_pkey_get_details($parsedPublicKey);
+
+        if (!isset($publicKeyDetails['key'])) {
+            throw new Exception('Invalid public key details.');
+        }
+
+        return [
+            'publicKey' => $publicKeyDetails['key'],
+            'alg'       => $parsedKeyData['alg']
+        ];
+    }
+}
+
+/**
+ * A class decorator for the Sign In with Apple payload produced by
+ * decoding the signed JWT from a client.
+ */
+class ASPayload
+{
+    protected $_instance;
+
+    public function __construct($instance)
+    {
+        if (is_null($instance)) {
+            throw new Exception('ASPayload received null instance.');
+        }
+        $this->_instance = $instance;
+    }
+
+    public function __call($method, $args)
+    {
+        return call_user_func_array(array($this->_instance, $method), $args);
+    }
+
+    public function __get($key)
+    {
+        return $this->_instance->$key;
+    }
+
+    public function __set($key, $val)
+    {
+        return $this->_instance->$key = $val;
+    }
+
+    public function getEmail()
+    {
+        return (isset($this->_instance->email)) ? $this->_instance->email : null;
+    }
+
+    public function getUser()
+    {
+        return (isset($this->_instance->sub)) ? $this->_instance->sub : null;
+    }
+
+    public function verifyUser($user)
+    {
+        return $user === $this->getUser();
+    }
+
+}

+ 7 - 0
addons/shopro/library/apple-signin/LICENSE

@@ -0,0 +1,7 @@
+Copyright (c) 2019, Griffin Ledingham
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 8 - 0
addons/shopro/library/apple-signin/Vendor/BeforeValidException.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace AppleSignIn\Vendor;
+
+class BeforeValidException extends \UnexpectedValueException
+{
+
+}

+ 8 - 0
addons/shopro/library/apple-signin/Vendor/ExpiredException.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace AppleSignIn\Vendor;
+
+class ExpiredException extends \UnexpectedValueException
+{
+
+}

+ 158 - 0
addons/shopro/library/apple-signin/Vendor/JWK.php

@@ -0,0 +1,158 @@
+<?php
+
+namespace AppleSignIn\Vendor;
+
+use \UnexpectedValueException;
+
+/**
+ * JSON Web Key implementation, based on this spec:
+ * https://tools.ietf.org/html/draft-ietf-jose-json-web-key-41
+ *
+ * PHP version 5
+ *
+ * @package  Firebase\JWT
+ * @author   Bui Sy Nguyen <nguyenbs@gmail.com>
+ * @license  http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
+ * @link     https://github.com/fproject/php-jwt
+ */
+class JWK
+{
+    /**
+     * Parse a set of JWK keys
+     * @param $source
+     * @return array an associative array represents the set of keys
+     */
+    public static function parseKeySet($source)
+    {
+        $keys = [];
+        if (is_string($source)) {
+            $source = json_decode($source, true);
+        } else if (is_object($source)) {
+            if (property_exists($source, 'keys'))
+                $source = (array)$source;
+            else
+                $source = [$source];
+        }
+
+        if (is_array($source)) {
+            if (isset($source['keys']))
+                $source = $source['keys'];
+
+            foreach ($source as $k => $v) {
+                if (!is_string($k)) {
+                    if (is_array($v) && isset($v['kid']))
+                        $k = $v['kid'];
+                    elseif (is_object($v) && property_exists($v, 'kid'))
+                        $k = $v->{'kid'};
+                }
+                try {
+                    $v = self::parseKey($v);
+                    $keys[$k] = $v;
+                } catch (UnexpectedValueException $e) {
+                    //Do nothing
+                }
+            }
+        }
+        if (0 < count($keys)) {
+            return $keys;
+        }
+        throw new UnexpectedValueException('Failed to parse JWK');
+    }
+
+    /**
+     * Parse a JWK key
+     * @param $source
+     * @return resource|array an associative array represents the key
+     */
+    public static function parseKey($source)
+    {
+        if (!is_array($source))
+            $source = (array)$source;
+        if (!empty($source) && isset($source['kty']) && isset($source['n']) && isset($source['e'])) {
+            switch ($source['kty']) {
+                case 'RSA':
+                    if (array_key_exists('d', $source))
+                        throw new UnexpectedValueException('Failed to parse JWK: RSA private key is not supported');
+
+                    $pem = self::createPemFromModulusAndExponent($source['n'], $source['e']);
+                    $pKey = openssl_pkey_get_public($pem);
+                    if ($pKey !== false)
+                        return $pKey;
+                    break;
+                default:
+                    //Currently only RSA is supported
+                    break;
+            }
+        }
+
+        throw new UnexpectedValueException('Failed to parse JWK');
+    }
+
+    /**
+     *
+     * Create a public key represented in PEM format from RSA modulus and exponent information
+     *
+     * @param string $n the RSA modulus encoded in Base64
+     * @param string $e the RSA exponent encoded in Base64
+     * @return string the RSA public key represented in PEM format
+     */
+    private static function createPemFromModulusAndExponent($n, $e)
+    {
+        $modulus = JWT::urlsafeB64Decode($n);
+        $publicExponent = JWT::urlsafeB64Decode($e);
+
+
+        $components = array(
+            'modulus' => pack('Ca*a*', 2, self::encodeLength(strlen($modulus)), $modulus),
+            'publicExponent' => pack('Ca*a*', 2, self::encodeLength(strlen($publicExponent)), $publicExponent)
+        );
+
+        $RSAPublicKey = pack(
+            'Ca*a*a*',
+            48,
+            self::encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
+            $components['modulus'],
+            $components['publicExponent']
+        );
+
+
+        // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
+        $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
+        $RSAPublicKey = chr(0) . $RSAPublicKey;
+        $RSAPublicKey = chr(3) . self::encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
+
+        $RSAPublicKey = pack(
+            'Ca*a*',
+            48,
+            self::encodeLength(strlen($rsaOID . $RSAPublicKey)),
+            $rsaOID . $RSAPublicKey
+        );
+
+        $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
+            chunk_split(base64_encode($RSAPublicKey), 64) .
+            '-----END PUBLIC KEY-----';
+
+        return $RSAPublicKey;
+    }
+
+    /**
+     * DER-encode the length
+     *
+     * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4.  See
+     * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
+     *
+     * @access private
+     * @param int $length
+     * @return string
+     */
+    private static function encodeLength($length)
+    {
+        if ($length <= 0x7F) {
+            return chr($length);
+        }
+
+        $temp = ltrim(pack('N', $length), chr(0));
+        return pack('Ca*', 0x80 | strlen($temp), $temp);
+    }
+
+}

+ 380 - 0
addons/shopro/library/apple-signin/Vendor/JWT.php

@@ -0,0 +1,380 @@
+<?php
+
+namespace AppleSignIn\Vendor;
+use \DomainException;
+use \InvalidArgumentException;
+use \UnexpectedValueException;
+use \DateTime;
+
+/**
+ * JSON Web Token implementation, based on this spec:
+ * https://tools.ietf.org/html/rfc7519
+ *
+ * PHP version 5
+ *
+ * @category Authentication
+ * @package  Authentication_JWT
+ * @author   Neuman Vong <neuman@twilio.com>
+ * @author   Anant Narayanan <anant@php.net>
+ * @license  http://opensource.org/licenses/BSD-3-Clause 3-clause BSD
+ * @link     https://github.com/firebase/php-jwt
+ */
+class JWT
+{
+
+    /**
+     * The server leeway time in seconds, to aware the acceptable different time between clocks
+     * of token issued server and relying parties.
+     * When checking nbf, iat or expiration times, we want to provide some extra leeway time to
+     * account for clock skew.
+     */
+    public static $leeway = 0;
+
+    /**
+     * Allow the current timestamp to be specified.
+     * Useful for fixing a value within unit testing.
+     *
+     * Will default to PHP time() value if null.
+     */
+    public static $timestamp = null;
+
+    public static $supported_algs = array(
+        'HS256' => array('hash_hmac', 'SHA256'),
+        'HS512' => array('hash_hmac', 'SHA512'),
+        'HS384' => array('hash_hmac', 'SHA384'),
+        'RS256' => array('openssl', 'SHA256'),
+        'RS384' => array('openssl', 'SHA384'),
+        'RS512' => array('openssl', 'SHA512'),
+    );
+
+    /**
+     * Decodes a JWT string into a PHP object.
+     *
+     * @param string        $jwt            The JWT
+     * @param string|array  $key            The key, or map of keys.
+     *                                      If the algorithm used is asymmetric, this is the public key
+     * @param array         $allowed_algs   List of supported verification algorithms
+     *                                      Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
+     *
+     * @return object The JWT's payload as a PHP object
+     *
+     * @throws UnexpectedValueException     Provided JWT was invalid
+     * @throws SignatureInvalidException    Provided JWT was invalid because the signature verification failed
+     * @throws BeforeValidException         Provided JWT is trying to be used before it's eligible as defined by 'nbf'
+     * @throws BeforeValidException         Provided JWT is trying to be used before it's been created as defined by 'iat'
+     * @throws ExpiredException             Provided JWT has since expired, as defined by the 'exp' claim
+     *
+     * @uses jsonDecode
+     * @uses urlsafeB64Decode
+     */
+    public static function decode($jwt, $key, array $allowed_algs = array())
+    {
+        $timestamp = is_null(static::$timestamp) ? time() : static::$timestamp;
+
+        if (empty($key)) {
+            throw new InvalidArgumentException('Key may not be empty');
+        }
+        $tks = explode('.', $jwt);
+        if (count($tks) != 3) {
+            throw new UnexpectedValueException('Wrong number of segments');
+        }
+        list($headb64, $bodyb64, $cryptob64) = $tks;
+        if (null === ($header = static::jsonDecode(static::urlsafeB64Decode($headb64)))) {
+            throw new UnexpectedValueException('Invalid header encoding');
+        }
+        if (null === $payload = static::jsonDecode(static::urlsafeB64Decode($bodyb64))) {
+            throw new UnexpectedValueException('Invalid claims encoding');
+        }
+        if (false === ($sig = static::urlsafeB64Decode($cryptob64))) {
+            throw new UnexpectedValueException('Invalid signature encoding');
+        }
+        if (empty($header->alg)) {
+            throw new UnexpectedValueException('Empty algorithm');
+        }
+        if (empty(static::$supported_algs[$header->alg])) {
+            throw new UnexpectedValueException('Algorithm not supported');
+        }
+        if (!in_array($header->alg, $allowed_algs)) {
+            throw new UnexpectedValueException('Algorithm not allowed');
+        }
+        if (is_array($key) || $key instanceof \ArrayAccess) {
+            if (isset($header->kid)) {
+                if (!isset($key[$header->kid])) {
+                    throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key');
+                }
+                $key = $key[$header->kid];
+            } else {
+                throw new UnexpectedValueException('"kid" empty, unable to lookup correct key');
+            }
+        }
+
+        // Check the signature
+        if (!static::verify("$headb64.$bodyb64", $sig, $key, $header->alg)) {
+            throw new SignatureInvalidException('Signature verification failed');
+        }
+
+        // Check if the nbf if it is defined. This is the time that the
+        // token can actually be used. If it's not yet that time, abort.
+        if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) {
+            throw new BeforeValidException(
+                'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf)
+            );
+        }
+
+        // Check that this token has been created before 'now'. This prevents
+        // using tokens that have been created for later use (and haven't
+        // correctly used the nbf claim).
+        if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) {
+            throw new BeforeValidException(
+                'Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat)
+            );
+        }
+
+        // Check if this token has expired.
+        if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) {
+            throw new ExpiredException('Expired token');
+        }
+
+        return $payload;
+    }
+
+    /**
+     * Converts and signs a PHP object or array into a JWT string.
+     *
+     * @param object|array  $payload    PHP object or array
+     * @param string        $key        The secret key.
+     *                                  If the algorithm used is asymmetric, this is the private key
+     * @param string        $alg        The signing algorithm.
+     *                                  Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
+     * @param mixed         $keyId
+     * @param array         $head       An array with header elements to attach
+     *
+     * @return string A signed JWT
+     *
+     * @uses jsonEncode
+     * @uses urlsafeB64Encode
+     */
+    public static function encode($payload, $key, $alg = 'HS256', $keyId = null, $head = null)
+    {
+        $header = array('typ' => 'JWT', 'alg' => $alg);
+        if ($keyId !== null) {
+            $header['kid'] = $keyId;
+        }
+        if ( isset($head) && is_array($head) ) {
+            $header = array_merge($head, $header);
+        }
+        $segments = array();
+        $segments[] = static::urlsafeB64Encode(static::jsonEncode($header));
+        $segments[] = static::urlsafeB64Encode(static::jsonEncode($payload));
+        $signing_input = implode('.', $segments);
+
+        $signature = static::sign($signing_input, $key, $alg);
+        $segments[] = static::urlsafeB64Encode($signature);
+
+        return implode('.', $segments);
+    }
+
+    /**
+     * Sign a string with a given key and algorithm.
+     *
+     * @param string            $msg    The message to sign
+     * @param string|resource   $key    The secret key
+     * @param string            $alg    The signing algorithm.
+     *                                  Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
+     *
+     * @return string An encrypted message
+     *
+     * @throws DomainException Unsupported algorithm was specified
+     */
+    public static function sign($msg, $key, $alg = 'HS256')
+    {
+        if (empty(static::$supported_algs[$alg])) {
+            throw new DomainException('Algorithm not supported');
+        }
+        list($function, $algorithm) = static::$supported_algs[$alg];
+        switch($function) {
+            case 'hash_hmac':
+                return hash_hmac($algorithm, $msg, $key, true);
+            case 'openssl':
+                $signature = '';
+                $success = openssl_sign($msg, $signature, $key, $algorithm);
+                if (!$success) {
+                    throw new DomainException("OpenSSL unable to sign data");
+                } else {
+                    return $signature;
+                }
+        }
+    }
+
+    /**
+     * Verify a signature with the message, key and method. Not all methods
+     * are symmetric, so we must have a separate verify and sign method.
+     *
+     * @param string            $msg        The original message (header and body)
+     * @param string            $signature  The original signature
+     * @param string|resource   $key        For HS*, a string key works. for RS*, must be a resource of an openssl public key
+     * @param string            $alg        The algorithm
+     *
+     * @return bool
+     *
+     * @throws DomainException Invalid Algorithm or OpenSSL failure
+     */
+    private static function verify($msg, $signature, $key, $alg)
+    {
+        if (empty(static::$supported_algs[$alg])) {
+            throw new DomainException('Algorithm not supported');
+        }
+
+        list($function, $algorithm) = static::$supported_algs[$alg];
+        switch($function) {
+            case 'openssl':
+                $success = openssl_verify($msg, $signature, $key, $algorithm);
+                if ($success === 1) {
+                    return true;
+                } elseif ($success === 0) {
+                    return false;
+                }
+                // returns 1 on success, 0 on failure, -1 on error.
+                throw new DomainException(
+                    'OpenSSL error: ' . openssl_error_string()
+                );
+            case 'hash_hmac':
+            default:
+                $hash = hash_hmac($algorithm, $msg, $key, true);
+                if (function_exists('hash_equals')) {
+                    return hash_equals($signature, $hash);
+                }
+                $len = min(static::safeStrlen($signature), static::safeStrlen($hash));
+
+                $status = 0;
+                for ($i = 0; $i < $len; $i++) {
+                    $status |= (ord($signature[$i]) ^ ord($hash[$i]));
+                }
+                $status |= (static::safeStrlen($signature) ^ static::safeStrlen($hash));
+
+                return ($status === 0);
+        }
+    }
+
+    /**
+     * Decode a JSON string into a PHP object.
+     *
+     * @param string $input JSON string
+     *
+     * @return object Object representation of JSON string
+     *
+     * @throws DomainException Provided string was invalid JSON
+     */
+    public static function jsonDecode($input)
+    {
+        if (version_compare(PHP_VERSION, '5.4.0', '>=') && !(defined('JSON_C_VERSION') && PHP_INT_SIZE > 4)) {
+            /** In PHP >=5.4.0, json_decode() accepts an options parameter, that allows you
+             * to specify that large ints (like Steam Transaction IDs) should be treated as
+             * strings, rather than the PHP default behaviour of converting them to floats.
+             */
+            $obj = json_decode($input, false, 512, JSON_BIGINT_AS_STRING);
+        } else {
+            /** Not all servers will support that, however, so for older versions we must
+             * manually detect large ints in the JSON string and quote them (thus converting
+             *them to strings) before decoding, hence the preg_replace() call.
+             */
+            $max_int_length = strlen((string) PHP_INT_MAX) - 1;
+            $json_without_bigints = preg_replace('/:\s*(-?\d{'.$max_int_length.',})/', ': "$1"', $input);
+            $obj = json_decode($json_without_bigints);
+        }
+
+        if (function_exists('json_last_error') && $errno = json_last_error()) {
+            static::handleJsonError($errno);
+        } elseif ($obj === null && $input !== 'null') {
+            throw new DomainException('Null result with non-null input');
+        }
+        return $obj;
+    }
+
+    /**
+     * Encode a PHP object into a JSON string.
+     *
+     * @param object|array $input A PHP object or array
+     *
+     * @return string JSON representation of the PHP object or array
+     *
+     * @throws DomainException Provided object could not be encoded to valid JSON
+     */
+    public static function jsonEncode($input)
+    {
+        $json = json_encode($input);
+        if (function_exists('json_last_error') && $errno = json_last_error()) {
+            static::handleJsonError($errno);
+        } elseif ($json === 'null' && $input !== null) {
+            throw new DomainException('Null result with non-null input');
+        }
+        return $json;
+    }
+
+    /**
+     * Decode a string with URL-safe Base64.
+     *
+     * @param string $input A Base64 encoded string
+     *
+     * @return string A decoded string
+     */
+    public static function urlsafeB64Decode($input)
+    {
+        $remainder = strlen($input) % 4;
+        if ($remainder) {
+            $padlen = 4 - $remainder;
+            $input .= str_repeat('=', $padlen);
+        }
+        return base64_decode(strtr($input, '-_', '+/'));
+    }
+
+    /**
+     * Encode a string with URL-safe Base64.
+     *
+     * @param string $input The string you want encoded
+     *
+     * @return string The base64 encode of what you passed in
+     */
+    public static function urlsafeB64Encode($input)
+    {
+        return str_replace('=', '', strtr(base64_encode($input), '+/', '-_'));
+    }
+
+    /**
+     * Helper method to create a JSON error.
+     *
+     * @param int $errno An error number from json_last_error()
+     *
+     * @return void
+     */
+    private static function handleJsonError($errno)
+    {
+        $messages = array(
+            JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
+            JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
+            JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
+            JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON',
+            JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3
+        );
+        throw new DomainException(
+            isset($messages[$errno])
+            ? $messages[$errno]
+            : 'Unknown JSON error: ' . $errno
+        );
+    }
+
+    /**
+     * Get the number of bytes in cryptographic strings.
+     *
+     * @param string
+     *
+     * @return int
+     */
+    private static function safeStrlen($str)
+    {
+        if (function_exists('mb_strlen')) {
+            return mb_strlen($str, '8bit');
+        }
+        return strlen($str);
+    }
+}

+ 30 - 0
addons/shopro/library/apple-signin/Vendor/LICENSE

@@ -0,0 +1,30 @@
+Copyright (c) 2011, Neuman Vong
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Neuman Vong nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

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