qianda 9 ヶ月 前
コミット
ba40f1176c
100 ファイル変更22852 行追加0 行削除
  1. 3 0
      .bowerrc
  2. 33 0
      .gitignore
  3. 1 0
      .htaccess
  4. 7 0
      404.html
  5. 29 0
      LICENSE.md
  6. 233 0
      README.md
  7. 81 0
      Vagrantfile
  8. 5 0
      api/.htaccess
  9. 25 0
      api/controllers/AlertController.php
  10. 125 0
      api/controllers/CodeController.php
  11. 52 0
      api/controllers/DefaultController.php
  12. 643 0
      api/controllers/DownController.php
  13. 373 0
      api/controllers/MappController.php
  14. 490 0
      api/controllers/ShareController.php
  15. 117 0
      api/controllers/ShopController.php
  16. 810 0
      api/controllers/UploadController.php
  17. 1468 0
      api/controllers/UserController.php
  18. 133 0
      api/controllers/WriterController.php
  19. 81 0
      api/index.php
  20. 0 0
      api/nginx.htaccess
  21. 30 0
      assets/BootstrapAsset.php
  22. 29 0
      assets/CoreAsset.php
  23. 46 0
      assets/PcAsset.php
  24. 35 0
      assets/PluginsAsset.php
  25. 46 0
      assets/WapAsset.php
  26. 36 0
      codeception.yml
  27. 77 0
      commands/MailerController.php
  28. 1635 0
      commands/TransController.php
  29. 570 0
      commands/ValueController.php
  30. 30 0
      commands/value.log
  31. 54 0
      common/components/BaiduCpc.php
  32. 79 0
      common/components/CacheId.php
  33. 90 0
      common/components/Dozip.php
  34. 96 0
      common/components/Emailer.php
  35. 241 0
      common/components/FormElements.php
  36. 138 0
      common/components/MessageOne.php
  37. 571 0
      common/components/MultiSearchUrl.php
  38. 290 0
      common/components/Oss.php
  39. 36 0
      common/components/PinYin.php
  40. 356 0
      common/components/ResizeImage.php
  41. 239 0
      common/components/SimpleOss.php
  42. 687 0
      common/components/SiteUrl.php
  43. 158 0
      common/components/Sms.php
  44. 165 0
      common/components/Tree.php
  45. 67 0
      common/components/Unzip.php
  46. 135 0
      common/components/Upload.php
  47. 254 0
      common/components/Wallet.php
  48. 1709 0
      common/components/sphinxapi.php
  49. 274 0
      common/controllers/AController.php
  50. 899 0
      common/controllers/BController.php
  51. 454 0
      common/controllers/CController.php
  52. 678 0
      common/controllers/FController.php
  53. 47 0
      common/controllers/UController.php
  54. 112 0
      common/data/model.sql
  55. 36 0
      common/filters/BackEndAuthFilter.php
  56. 50 0
      common/filters/BackEndResourceFilter.php
  57. 41 0
      common/filters/FrontEndAuthFilter.php
  58. 22 0
      common/filters/FrontEndLoginedFilter.php
  59. 50 0
      common/filters/FrontEndTokenFilter.php
  60. 1514 0
      common/functions/cus.php
  61. 182 0
      common/functions/dir.php
  62. 1697 0
      common/functions/global.php
  63. 1631 0
      common/functions/global1.php
  64. 81 0
      common/helpers/Capcha.php
  65. 59 0
      common/helpers/Cookie.php
  66. 266 0
      common/helpers/Identify.php
  67. 88 0
      common/helpers/Session.php
  68. 304 0
      common/models/EActiveRecord.php
  69. 25 0
      common/models/EModel.php
  70. 86 0
      common/modules/EModule.php
  71. 21 0
      common/widget/CommentWidget.php
  72. 17 0
      common/widget/FieldWidget.php
  73. 268 0
      common/widget/LinkcatWidget.php
  74. 273 0
      common/widget/LinkmenuWidget.php
  75. 110 0
      common/widget/PayWidget.php
  76. 33 0
      common/widget/ShareWidget.php
  77. 48 0
      common/widget/SlideloadWidget.php
  78. 180 0
      common/widget/UeditorWidget.php
  79. 10 0
      common/widget/fields/author/config.inc.php
  80. 6 0
      common/widget/fields/author/field_add_form.inc.php
  81. 6 0
      common/widget/fields/author/field_edit_form.inc.php
  82. 16 0
      common/widget/fields/author/form.inc.php
  83. 10 0
      common/widget/fields/box/config.inc.php
  84. 112 0
      common/widget/fields/box/field_add_form.inc.php
  85. 112 0
      common/widget/fields/box/field_edit_form.inc.php
  86. 53 0
      common/widget/fields/box/form.inc.php
  87. 10 0
      common/widget/fields/cat_id/config.inc.php
  88. 1 0
      common/widget/fields/cat_id/field_add_form.inc.php
  89. 0 0
      common/widget/fields/cat_id/field_edit_form.inc.php
  90. 13 0
      common/widget/fields/cat_id/form.inc.php
  91. 96 0
      common/widget/fields/content_form.class.php
  92. 72 0
      common/widget/fields/content_input.class.php
  93. 25 0
      common/widget/fields/content_output.class.php
  94. 21 0
      common/widget/fields/content_update.class.php
  95. 10 0
      common/widget/fields/copy_from/config.inc.php
  96. 6 0
      common/widget/fields/copy_from/field_add_form.inc.php
  97. 6 0
      common/widget/fields/copy_from/field_edit_form.inc.php
  98. 19 0
      common/widget/fields/copy_from/form.inc.php
  99. 10 0
      common/widget/fields/datetime/config.inc.php
  100. 84 0
      common/widget/fields/datetime/field_add_form.inc.php

+ 3 - 0
.bowerrc

@@ -0,0 +1,3 @@
+{
+    "directory" : "vendor/bower-asset"
+}

+ 33 - 0
.gitignore

@@ -0,0 +1,33 @@
+# phpstorm project files
+.idea
+
+# netbeans project files
+nbproject
+
+# zend studio for eclipse project files
+.buildpath
+.project
+.settings
+
+# windows thumbnail cache
+Thumbs.db
+
+# composer vendor dir
+/vendor
+
+# composer itself is not needed
+composer.phar
+
+# Mac DS_Store Files
+.DS_Store
+
+# phpunit itself is not needed
+phpunit.phar
+# local phpunit config
+/phpunit.xml
+
+tests/_output/*
+tests/_support/_generated
+
+#vagrant folder
+/.vagrant

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

+ 29 - 0
LICENSE.md

@@ -0,0 +1,29 @@
+Copyright © 2008 by Yii Software LLC (http://www.yiisoft.com)
+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 Yii Software LLC nor the names of its
+   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.

+ 233 - 0
README.md

@@ -0,0 +1,233 @@
+<p align="center">
+    <a href="https://github.com/yiisoft" target="_blank">
+        <img src="https://avatars0.githubusercontent.com/u/993323" height="100px">
+    </a>
+    <h1 align="center">Yii 2 Basic Project Template</h1>
+    <br>
+</p>
+
+Yii 2 Basic Project Template is a skeleton [Yii 2](http://www.yiiframework.com/) application best for
+rapidly creating small projects.
+
+The template contains the basic features including user login/logout and a contact page.
+It includes all commonly used configurations that would allow you to focus on adding new
+features to your application.
+
+[![Latest Stable Version](https://img.shields.io/packagist/v/yiisoft/yii2-app-basic.svg)](https://packagist.org/packages/yiisoft/yii2-app-basic)
+[![Total Downloads](https://img.shields.io/packagist/dt/yiisoft/yii2-app-basic.svg)](https://packagist.org/packages/yiisoft/yii2-app-basic)
+[![Build Status](https://travis-ci.com/yiisoft/yii2-app-basic.svg?branch=master)](https://travis-ci.com/yiisoft/yii2-app-basic)
+
+DIRECTORY STRUCTURE
+-------------------
+
+      assets/             contains assets definition
+      commands/           contains console commands (controllers)
+      config/             contains application configurations
+      controllers/        contains Web controller classes
+      mail/               contains view files for e-mails
+      models/             contains model classes
+      runtime/            contains files generated during runtime
+      tests/              contains various tests for the basic application
+      vendor/             contains dependent 3rd-party packages
+      views/              contains view files for the Web application
+      web/                contains the entry script and Web resources
+
+
+
+REQUIREMENTS
+------------
+
+The minimum requirement by this project template that your Web server supports PHP 5.6.0.
+
+
+INSTALLATION
+------------
+
+### Install via Composer
+
+If you do not have [Composer](http://getcomposer.org/), you may install it by following the instructions
+at [getcomposer.org](http://getcomposer.org/doc/00-intro.md#installation-nix).
+
+You can then install this project template using the following command:
+
+~~~
+composer create-project --prefer-dist yiisoft/yii2-app-basic basic
+~~~
+
+Now you should be able to access the application through the following URL, assuming `basic` is the directory
+directly under the Web root.
+
+~~~
+http://localhost/basic/web/
+~~~
+
+### Install from an Archive File
+
+Extract the archive file downloaded from [yiiframework.com](http://www.yiiframework.com/download/) to
+a directory named `basic` that is directly under the Web root.
+
+Set cookie validation key in `config/web.php` file to some random secret string:
+
+```php
+'request' => [
+    // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
+    'cookieValidationKey' => '<secret random string goes here>',
+],
+```
+
+You can then access the application through the following URL:
+
+~~~
+http://localhost/basic/web/
+~~~
+
+
+### Install with Docker
+
+Update your vendor packages
+
+    docker-compose run --rm php composer update --prefer-dist
+    
+Run the installation triggers (creating cookie validation code)
+
+    docker-compose run --rm php composer install    
+    
+Start the container
+
+    docker-compose up -d
+    
+You can then access the application through the following URL:
+
+    http://127.0.0.1:8000
+
+**NOTES:** 
+- Minimum required Docker engine version `17.04` for development (see [Performance tuning for volume mounts](https://docs.docker.com/docker-for-mac/osxfs-caching/))
+- The default configuration uses a host-volume in your home directory `.docker-composer` for composer caches
+
+
+CONFIGURATION
+-------------
+
+### Database
+
+Edit the file `config/db.php` with real data, for example:
+
+```php
+return [
+    'class' => 'yii\db\Connection',
+    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
+    'username' => 'root',
+    'password' => '1234',
+    'charset' => 'utf8',
+];
+```
+
+**NOTES:**
+- Yii won't create the database for you, this has to be done manually before you can access it.
+- Check and edit the other files in the `config/` directory to customize your application as required.
+- Refer to the README in the `tests` directory for information specific to basic application tests.
+
+
+TESTING
+-------
+
+Tests are located in `tests` directory. They are developed with [Codeception PHP Testing Framework](http://codeception.com/).
+By default there are 3 test suites:
+
+- `unit`
+- `functional`
+- `acceptance`
+
+Tests can be executed by running
+
+```
+vendor/bin/codecept run
+```
+
+The command above will execute unit and functional tests. Unit tests are testing the system components, while functional
+tests are for testing user interaction. Acceptance tests are disabled by default as they require additional setup since
+they perform testing in real browser. 
+
+
+### Running  acceptance tests
+
+To execute acceptance tests do the following:  
+
+1. Rename `tests/acceptance.suite.yml.example` to `tests/acceptance.suite.yml` to enable suite configuration
+
+2. Replace `codeception/base` package in `composer.json` with `codeception/codeception` to install full featured
+   version of Codeception
+
+3. Update dependencies with Composer 
+
+    ```
+    composer update  
+    ```
+
+4. Download [Selenium Server](http://www.seleniumhq.org/download/) and launch it:
+
+    ```
+    java -jar ~/selenium-server-standalone-x.xx.x.jar
+    ```
+
+    In case of using Selenium Server 3.0 with Firefox browser since v48 or Google Chrome since v53 you must download [GeckoDriver](https://github.com/mozilla/geckodriver/releases) or [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/downloads) and launch Selenium with it:
+
+    ```
+    # for Firefox
+    java -jar -Dwebdriver.gecko.driver=~/geckodriver ~/selenium-server-standalone-3.xx.x.jar
+    
+    # for Google Chrome
+    java -jar -Dwebdriver.chrome.driver=~/chromedriver ~/selenium-server-standalone-3.xx.x.jar
+    ``` 
+    
+    As an alternative way you can use already configured Docker container with older versions of Selenium and Firefox:
+    
+    ```
+    docker run --net=host selenium/standalone-firefox:2.53.0
+    ```
+
+5. (Optional) Create `yii2_basic_tests` database and update it by applying migrations if you have them.
+
+   ```
+   tests/bin/yii migrate
+   ```
+
+   The database configuration can be found at `config/test_db.php`.
+
+
+6. Start web server:
+
+    ```
+    tests/bin/yii serve
+    ```
+
+7. Now you can run all available tests
+
+   ```
+   # run all available tests
+   vendor/bin/codecept run
+
+   # run acceptance tests
+   vendor/bin/codecept run acceptance
+
+   # run only unit and functional tests
+   vendor/bin/codecept run unit,functional
+   ```
+
+### Code coverage support
+
+By default, code coverage is disabled in `codeception.yml` configuration file, you should uncomment needed rows to be able
+to collect code coverage. You can run your tests and collect coverage with the following command:
+
+```
+#collect coverage for all tests
+vendor/bin/codecept run -- --coverage-html --coverage-xml
+
+#collect coverage only for unit tests
+vendor/bin/codecept run unit -- --coverage-html --coverage-xml
+
+#collect coverage for unit and functional tests
+vendor/bin/codecept run functional,unit -- --coverage-html --coverage-xml
+```
+
+You can see code coverage output under the `tests/_output` directory.

+ 81 - 0
Vagrantfile

@@ -0,0 +1,81 @@
+require 'yaml'
+require 'fileutils'
+
+required_plugins = %w( vagrant-hostmanager vagrant-vbguest )
+required_plugins.each do |plugin|
+    exec "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin
+end
+
+domains = {
+  app: 'yii2basic.test'
+}
+
+vagrantfile_dir_path = File.dirname(__FILE__)
+
+config = {
+  local: vagrantfile_dir_path + '/vagrant/config/vagrant-local.yml',
+  example: vagrantfile_dir_path + '/vagrant/config/vagrant-local.example.yml'
+}
+
+# copy config from example if local config not exists
+FileUtils.cp config[:example], config[:local] unless File.exist?(config[:local])
+# read config
+options = YAML.load_file config[:local]
+
+# check github token
+if options['github_token'].nil? || options['github_token'].to_s.length != 40
+  puts "You must place REAL GitHub token into configuration:\n/yii2-app-basic/vagrant/config/vagrant-local.yml"
+  exit
+end
+
+# vagrant configurate
+Vagrant.configure(2) do |config|
+  # select the box
+  config.vm.box = 'bento/ubuntu-16.04'
+
+  # should we ask about box updates?
+  config.vm.box_check_update = options['box_check_update']
+
+  config.vm.provider 'virtualbox' do |vb|
+    # machine cpus count
+    vb.cpus = options['cpus']
+    # machine memory size
+    vb.memory = options['memory']
+    # machine name (for VirtualBox UI)
+    vb.name = options['machine_name']
+  end
+
+  # machine name (for vagrant console)
+  config.vm.define options['machine_name']
+
+  # machine name (for guest machine console)
+  config.vm.hostname = options['machine_name']
+
+  # network settings
+  config.vm.network 'private_network', ip: options['ip']
+
+  # sync: folder 'yii2-app-advanced' (host machine) -> folder '/app' (guest machine)
+  config.vm.synced_folder './', '/app', owner: 'vagrant', group: 'vagrant'
+
+  # disable folder '/vagrant' (guest machine)
+  config.vm.synced_folder '.', '/vagrant', disabled: true
+
+  # hosts settings (host machine)
+  config.vm.provision :hostmanager
+  config.hostmanager.enabled            = true
+  config.hostmanager.manage_host        = true
+  config.hostmanager.ignore_private_ip  = false
+  config.hostmanager.include_offline    = true
+  config.hostmanager.aliases            = domains.values
+
+  # quick fix for failed guest additions installations
+  # config.vbguest.auto_update = false
+
+  # provisioners
+  config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone']]
+  config.vm.provision 'shell', path: './vagrant/provision/once-as-vagrant.sh', args: [options['github_token']], privileged: false
+  config.vm.provision 'shell', path: './vagrant/provision/always-as-root.sh', run: 'always'
+
+  # post-install message (vagrant console)
+  config.vm.post_up_message = "App URL: http://#{domains[:app]}"
+end

+ 5 - 0
api/.htaccess

@@ -0,0 +1,5 @@
+RewriteEngine on
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule . index.php [L]
+SetEnvIf Authorization .+ HTTP_AUTHORIZATION=$0

+ 25 - 0
api/controllers/AlertController.php

@@ -0,0 +1,25 @@
+<?php
+/*
+ * 系统默认接口
+ */
+namespace api\controllers;
+use Yii;
+use app\common\controllers\AController;
+class AlertController  extends AController
+{
+
+    //一个测试
+    public function actionError()
+    {
+
+        $exception = Yii::$app->errorHandler->exception;
+        $msgdata = [
+            'error' => 1,
+            'msg' => $exception->getMessage(),
+            'data'=>array(),
+            'code'=>$exception->statusCode,
+        ];
+        return $msgdata;
+    }
+
+}

+ 125 - 0
api/controllers/CodeController.php

@@ -0,0 +1,125 @@
+<?php
+/*
+ * 验证码
+ */
+namespace api\controllers;
+use app\common\components\Emailer;
+use app\common\components\Sms;
+use app\models\EmailCert;
+use app\models\MobileCert;
+use app\modules\ucenter\models\User;
+use app\common\controllers\AController;
+use Yii;
+class CodeController  extends AController
+{
+
+    public function init()
+    {
+        parent::init();
+
+    }
+
+    //发送验证码
+    public function actionSendverifycode()
+    {
+        $patternEmail = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/';
+        $patternMobile = '/^1[3456789]{1}\d{9}$/';
+        $to = $this->get['to'];
+        $action = $this->get['action'];
+        $captcha = $this->get['captcha'];
+        if(preg_match($patternEmail,$to)) $toType = 'email';
+        if(preg_match($patternMobile,$to)) $toType='mobile';
+        if($to&&$action)
+        {
+            if(empty($toType))
+            {
+                $msgdata = ['error' => 1,'msg' => '账号类型错误','data'=>array(),'code'=>'200'];
+                return $msgdata;
+            }
+
+            if($this->smsconfig['open_imgvalid']&&!empty($captcha))
+            {
+                if(!$this->validateCaptcha($captcha))
+                {
+                    $msgdata = ['error' => 1,'msg' => '校验失败','data'=>array(),'code'=>'200'];
+                    return $msgdata;
+                }
+            }
+            //如果是找回密码,判断用户是否存在
+            if($action=='forgetpwd')
+            {
+                $user = User::find()->where("mobile='".$to."' or email='".$to."'")->one();
+                if(empty($user))
+                {
+                    $msgdata = ['error' => 1,'msg' => '用户不存在','data'=>array(),'code'=>'200'];
+                    return $msgdata;
+                }
+            }
+
+            if($toType=='email')
+            {
+                $exist = EmailCert::find()->where("email='".$to."' and request_from = ".REQUEST_FROM)->orderBy(['id'=>SORT_DESC])->one();
+            }
+            else  if($toType=='mobile')
+            {
+                $exist = MobileCert::find()->where("mobile='".$to."' and request_from = ".REQUEST_FROM)->orderBy(['id'=>SORT_DESC])->one();
+            }
+
+            if($exist&&TIMESTAMP-$exist->sent_time<$this->smsconfig['certTimeOut'])
+            {
+                $msgdata = ['error' => 1,'msg' => '发送失败(两次发送时间间隔太短)','data'=>array(),'code'=>'200'];
+            }
+            else
+            {
+                $code = rand(100000,999999);
+                if($toType=='email')
+                {
+                    $mailer = new Emailer();
+                    $result = $mailer->send($action,$to,array('code'=>$code));
+                }
+                else if($toType=='mobile')
+                {
+                    $sms = new Sms();
+                    $sms->init();
+                    $result = $sms->send($action,$to,array('code'=>$code));
+                }
+                if($result)
+                {
+
+                    $msgdata = ['error' => 0,'msg' => '发送成功','data'=>var_export($result,true),'code'=>'200'];
+                }
+                else
+                {
+                    $msgdata = ['error' => 1,'msg' =>'发送失败','data'=>array(),'code'=>'200'];
+                }
+            }
+        }
+        else
+        {
+            $msgdata = ['error' => 1,'msg' => '系统错误','data'=>array(),'code'=>'200'];
+        }
+        return $msgdata;
+    }
+
+    //校验验证码
+    public function actionCheckverifycode()
+    {
+        extract($this->post);
+        if($user_name&&$code)
+        {
+            $result = $this->checkCode($user_name,$code);
+            if(!empty($result))
+            {
+                return $result;
+            }
+            $msgdata =  ['error' => 0,'msg' => '校验成功','data'=>array('hash'=>sys_auth($user_name)),'code'=>'200'];
+        }
+        else
+        {
+            $msgdata = ['error' => 1,'msg' => '系统错误','data'=>[],'code'=>'200'];
+        }
+        return $msgdata;
+    }
+
+
+}

+ 52 - 0
api/controllers/DefaultController.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace api\controllers;
+use app\common\controllers\AController;
+use app\models\Tag;
+use Yii;
+class DefaultController  extends AController
+{
+
+    public function init()
+    {
+        parent::init();
+
+    }
+
+    //获取标签(根据标题和摘要)
+    public function actionGettag()
+    {
+        $title = Yii::$app->request->get('title');
+        $description = Yii::$app->request->get('description');
+        if(!empty($title)||!empty($description))
+        {
+            $tags = [];
+            $tagResultList = Tag::find()->where("disabled=0")->all();
+            if(is_array($tagResultList))foreach($tagResultList as $tagResult)
+            {
+                if(!empty($title)&&strpos($title,$tagResult->tag)!==false) $tags[] = $tagResult->tag;
+                if(!empty($description)&&strpos($description,$tagResult->tag)!==false) $tags[] = $tagResult->tag;
+            }
+
+            $msgdata = [
+                'error' => 0,
+                'msg' => '请求成功',
+                'data'=>['tags'=>join(",",array_unique($tags))],
+                'code'=>'200',
+            ];
+        }
+        else
+        {
+            $msgdata = [
+                'error' => 1,
+                'msg' => '请求出错了',
+                'data'=>[],
+                'code'=>'200',
+            ];
+        }
+        return $msgdata;
+    }
+
+
+
+}

+ 643 - 0
api/controllers/DownController.php

@@ -0,0 +1,643 @@
+<?php
+
+namespace api\controllers;
+use app\common\controllers\AController;
+use app\modules\doc\models\DocReal;
+use app\modules\doc\models\DocPaylog;
+use app\modules\doc\models\DocDowncode;
+use app\modules\doc\models\DocMail;
+use app\common\components\MessageOne;
+use app\common\components\Wallet;
+use Yii;
+class DownController  extends AController
+{
+
+    public function init()
+    {
+        parent::init();
+
+    }
+
+    public function actionFreedownload()
+    {
+
+        $id = intval($this->post['id']);
+        $doc = \app\modules\doc\models\DocReal::findOne($id);
+        if($this->userInfo['is_delete']||$this->userInfo['is_lock'])
+        {
+            return [
+                'error' => 1,
+                'msg' => '账户已被限制,禁止下载',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+        if(empty($doc)||$doc->is_delete==1)
+        {
+            return [
+                'error' => 1,
+                'msg' => '该'.$this->docname.'不存在',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+        if(!$doc->realfree)
+        {
+            return [
+                'error' => 1,
+                'msg' => '暂无下载权限',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+        $existPayLog = DocPaylog::find()->where("user_id=".$this->user_id." and doc_id=$id")->exists();
+        if(!$existPayLog)
+        {
+            $groupRights = $this->userInfo['group_rights'];
+            $vipSettings = $this->userInfo['vip_settings']?$this->userInfo['vip_settings']:[];
+            //日期
+            $timeList = getTimeList(1);
+            $todayStart = $timeList['dayStart'];
+            $todayEnd = $timeList['dayEnd'];
+
+            //今日免费下载数量
+            $freeDownNumToday = DocPaylog::find()->where("user_id=".$this->user_id."  and (create_time>=".$todayStart." and create_time<=".$todayEnd.") and is_free=1")->count();
+
+            //免费总下载数量
+            $freeDownNumTotal = DocPaylog::find()->where("user_id=".$this->user_id."  and is_free=1")->count();
+
+            //今日下载数量
+            $downNumToday = DocPaylog::find()->where("user_id=".$this->user_id."  and (create_time>=".$todayStart." and create_time<=".$todayEnd.")")->count();
+
+            //总下载数量
+            $downNumTotal = DocPaylog::find()->where("user_id=".$this->user_id."")->count();
+
+            //所在用户组被禁止下载
+            if($groupRights['doc_downnum_day']==-1||$groupRights['doc_downnum_total']==-1)
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '您已被禁止下载',
+                    'data' => 1,
+                    'code'=>200
+                ];
+            }
+
+            //VIP下载总量限制检查
+            if(!empty($vipSettings))
+            {
+                if($vipSettings['freedoc_download_num']>0)
+                {
+                    if($freeDownNumTotal>=$vipSettings['freedoc_download_num'])
+                    {
+                        return [
+                            'error' => 1,
+                            'msg' => '您已达到免费'.$this->docname.'下载总量上限('.$vipSettings['freedoc_download_num'].'份),无法继续下载',
+                            'data' => 1,
+                            'code'=>200
+                        ];
+                    }
+                }
+            }
+
+            //如果并非VIP也不是VIP无限下载权限,需要经过用户等级总量限制检查
+            if(empty($vipSettings)||$vipSettings['freedoc_download_num']!==0)
+            {
+                if($groupRights['doc_freedownload_totalnum']>0&&$freeDownNumTotal>=$groupRights['doc_freedownload_totalnum'])
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '您已达到免费'.$this->docname.'下载总量上限('.$groupRights['doc_freedownload_totalnum'].'份),无法继续下载',
+                        'data' => 1,
+                        'code'=>200
+                    ];
+                }
+            }
+
+
+            //用户等级单日免费下载量限制检查
+            if($groupRights['doc_freedownload_num']>0&&$freeDownNumToday>=$groupRights['doc_freedownload_num'])
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '您已达到今日免费'.$this->docname.'下载总量上限('.$groupRights['doc_freedownload_num'].'份/天),无法继续下载',
+                    'data' => 1,
+                    'code'=>200
+                ];
+            }
+
+            //用户等级下载总量限制
+            if($groupRights['doc_downnum_total']>0&&$downNumTotal>=$groupRights['doc_downnum_total'])
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '您已达到'.$this->docname.'下载总量上限('.$groupRights['doc_downnum_total'].'份),无法继续下载',
+                    'data' => 1,
+                    'code'=>200
+                ];
+            }
+
+            //用户等级单日下载量限制
+            if($groupRights['doc_downnum_day']>0&&$downNumToday>=$groupRights['doc_downnum_day'])
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '您已达到今日'.$this->docname.'下载总量上限('.$groupRights['doc_downnum_day'].'份/天),无法继续下载',
+                    'data' => 1,
+                    'code'=>200
+                ];
+            }
+
+            //生成支付记录
+            $paylog = new DocPaylog();
+            $paylog->user_id = $this->user_id;
+            $paylog->doc_user_id = $doc->user_id;
+            $paylog->doc_id = $doc->id;
+            $paylog->cat_id = $doc->cat_id;
+            $paylog->cat_ids = $doc->cat_ids;
+            $paylog->doc_type = $doc->doc_type;
+            $paylog->is_free = 1;
+            $paylog->coin_price = $doc->coin_price;
+            $paylog->coin_num = 0;
+            $paylog->agent_id = intval($this->userInfo['referer_id']);
+            $paylog->agent_ids = strval($this->userInfo['referer_ids']);
+            $paylog->create_time = TIMESTAMP;
+            if($paylog->save())
+            {
+                //更新文档售出次数
+                $doc->updateCounters(['sales'=>1]);
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => $paylog->returnFirstError(),
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+
+        }
+        //输出下载码
+        $downCode = new DocDowncode();
+        $downCode->doc_id = $doc->id;
+        $downCode->openid = '';
+        $downCode->downcode = strval(getDowncode($doc->id));
+        $downCode->user_id =  $this->user_id;
+        $downCode->doc_user_id =  $doc->user_id;
+        $downCode->is_ad = $doc->is_ad;;
+        $downCode->type = 1;
+        $downCode->create_time = TIMESTAMP;
+        $downCode->save();
+        if(defined('IN_WAP')&&IN_WAP==TRUE)
+        {
+            $downurl = WEB_URL.'ajax/downdoc/?downcode='.$downCode->downcode.'&direct=1';
+        }
+        else
+        {
+            $downurl = WEB_URL.'ajax/downdoc/?downcode='.$downCode->downcode;
+        }
+        return [
+            'error' => 0,
+            'msg' => '请求下载中,请稍候...',
+            'data' => ['downcode'=>$downCode->downcode,'downurl'=>$downurl],
+            'code'=>200
+        ];
+
+    }
+
+
+    //直接下载(文档主人或者VIP特权或者购买过)
+    public function actionDirectdown()
+    {
+
+        $id = intval($this->post['id']);
+        $doc = \app\modules\doc\models\DocReal::findOne($id);
+        if($this->userInfo['is_delete']||$this->userInfo['is_lock'])
+        {
+            return [
+                'error' => 1,
+                'msg' => '账户已被限制,禁止下载',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+        if(empty($doc)||$doc->is_delete==1)
+        {
+            return [
+                'error' => 1,
+                'msg' => '该'.$this->docname.'不存在',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        $downFlag = false;
+        //不是文档主人
+        if($this->user_id!=$doc->user_id)
+        {
+
+            //判断是否购买记录
+            $existPayLog = DocPaylog::find()->where("user_id=".$this->user_id." and doc_id=$id")->exists();
+            if(!$existPayLog)
+            {
+                $groupRights = $this->userInfo['group_rights'];
+                $vipSettings = $this->userInfo['vip_settings']?$this->userInfo['vip_settings']:[];
+                //所在用户组被禁止下载
+                if($groupRights['doc_downnum_day']==-1||$groupRights['doc_downnum_total']==-1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '您已被禁止下载',
+                        'data' => 1,
+                        'code'=>200
+                    ];
+                }
+
+                //日期
+                $timeList = getTimeList(1);
+                $todayStart = $timeList['dayStart'];
+                $todayEnd = $timeList['dayEnd'];
+                //总下载数量
+                $downNumTotal = DocPaylog::find()->where("user_id=".$this->user_id."")->count();
+                //今日下载数量
+                $downNumToday = DocPaylog::find()->where("user_id=".$this->user_id."  and (create_time>=".$todayStart." and create_time<=".$todayEnd.")")->count();
+                //VIP免费下载的总量
+                $vipfreeDownNumTotal = DocPaylog::find()->where("user_id=".$this->user_id." and vip_free=1")->count();
+
+                //下载总量限制
+                if($groupRights['doc_downnum_total']>0&&$downNumTotal>=$groupRights['doc_downnum_total'])
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '您已达到'.$this->docname.'下载总量上限('.$groupRights['doc_downnum_total'].'份),无法继续下载',
+                        'data' => 1,
+                        'code'=>200
+                    ];
+                }
+
+                //今日下载数量限制
+                if($groupRights['doc_downnum_day']>0&&$downNumToday>=$groupRights['doc_downnum_day'])
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '您已达到今日'.$this->docname.'下载总量上限('.$groupRights['doc_downnum_day'].'份),无法继续下载',
+                        'data' => 1,
+                        'code'=>200
+                    ];
+                }
+
+                //VIP免费下载
+                if(($doc->vip_free&&!empty($vipSettings))||(!empty($vipSettings)&&$vipSettings['buy_doc_discount']==0))
+                {
+                    //VIP免费文档数量限制
+                    if(intval($vipSettings['vipfreedoc_download_num'])>0&&$vipfreeDownNumTotal>=$vipSettings['vipfreedoc_download_num'])
+                    {
+                        return [
+                            'error' => 1,
+                            'msg' => '您已达到VIP免费'.$this->docname.'下载总量上限('.$vipSettings['vipfreedoc_download_num'].'份),无法继续下载',
+                            'data' => 1,
+                            'code'=>200
+                        ];
+                    }
+                    //生成支付记录
+                    $paylog = new DocPaylog();
+                    $paylog->user_id = $this->user_id;
+                    $paylog->doc_user_id = $doc->user_id;
+                    $paylog->doc_id = $doc->id;
+                    $paylog->cat_id = $doc->cat_id;
+                    $paylog->cat_ids = $doc->cat_ids;
+                    $paylog->doc_type = $doc->doc_type;
+                    $paylog->vip_free = 1;
+                    $paylog->coin_price = $doc->coin_price;
+                    $paylog->coin_num = 0;
+                    $paylog->agent_id = intval($this->userInfo['referer_id']);
+                    $paylog->agent_ids = strval($this->userInfo['referer_ids']);
+                    $paylog->create_time = TIMESTAMP;
+                    if($paylog->save())
+                    {
+                        //更新文档售出次数
+                        $doc->updateCounters(['sales'=>1]);
+                    }
+                    else
+                    {
+                        return [
+                            'error' => 1,
+                            'msg' => $paylog->returnFirstError(),
+                            'data' => [],
+                            'code'=>200
+                        ];
+                    }
+                    $downFlag = true;
+                }
+                else
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '下载失败',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+
+            }
+            else
+            {
+                $downFlag = true;
+            }
+        }
+        else
+        {
+            $downFlag = true;
+        }
+        if($downFlag)
+        {
+            //输出下载码
+            $downCode = new DocDowncode();
+            $downCode->doc_id = $doc->id;
+            $downCode->openid = '';
+            $downCode->downcode = strval(getDowncode($doc->id));
+            $downCode->user_id =  $this->user_id;
+            $downCode->doc_user_id =  $doc->user_id;
+            $downCode->is_ad = $doc->is_ad;;
+            $downCode->type = 1;
+            $downCode->create_time = TIMESTAMP;
+            $downCode->save();
+            if(defined('IN_WAP')&&IN_WAP==TRUE)
+            {
+                $downurl =WEB_URL.'ajax/downdoc/?downcode='.$downCode->downcode."&direct=1";
+            }
+            else
+            {
+                $downurl = WEB_URL.'ajax/downdoc/?downcode='.$downCode->downcode;
+            }
+            return [
+                'error' => 0,
+                'msg' => '请求下载中,请稍候...',
+                'data' => ['downcode'=>$downCode->downcode,'downurl'=>$downurl],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '下载失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+    }
+
+    //金币下载
+    public function actionCoindown()
+    {
+        $id = intval($this->post['id']);
+        $doc =  DocReal::findOne($id);
+        $coin_num = $doc->coin_price;
+        $downFlag = false;
+        if($this->userInfo['is_delete']||$this->userInfo['is_lock'])
+        {
+            return [
+                'error' => 1,
+                'msg' => '账户已被限制,禁止下载',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        if(empty($doc)||$doc->is_delete==1)
+        {
+            return [
+                'error' => 1,
+                'msg' => '该'.$this->docname.'不存在',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        //判断是否购买记录
+        $existPayLog = DocPaylog::find()->where("user_id=".$this->user_id." and doc_id=$id")->exists();
+        if(!$existPayLog)
+        {
+            $groupRights = $this->userInfo['group_rights'];
+            $vipSettings = $this->userInfo['vip_settings']?$this->userInfo['vip_settings']:[];
+
+            //所在用户组被禁止下载
+            if($groupRights['doc_downnum_day']==-1||$groupRights['doc_downnum_total']==-1)
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '您已被禁止下载',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+
+            //下载总量限制(付费不限制)
+           /* $downNumTotal = DocPaylog::find()->where("user_id=".$this->user_id."")->count();
+            if($groupRights['doc_downnum_total']>0&&$downNumTotal>=$groupRights['doc_downnum_total'])
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '您已达到'.$this->docname.'下载总量上限('.$groupRights['doc_downnum_total'].'份),无法继续下载',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }*/
+
+            //VIP专享下载限制
+            if($doc->is_vip)
+            {
+
+                if(empty($vipSettings))
+                {
+                    return [
+                        'error' => 2,
+                        'msg' => '您还不是VIP,无法继续下载',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                else
+                {
+                    //VIP专享下载的总量(付费文档暂不限制)
+                    /*$vipDownNumTotal = DocPaylog::find()->where("user_id=".$this->user_id." and is_vip=1")->count();
+                    if(intval($vipSettings['vipdoc_download_num'])>0&&$vipDownNumTotal>=$vipSettings['vipdoc_download_num'])
+                    {
+                        return [
+                            'error' => 1,
+                            'msg' => '您已达到VIP专享'.$this->docname.'下载总量上限('.$vipSettings['vipdoc_download_num'].'份),无法继续下载',
+                            'data' => [],
+                            'code'=>200
+                        ];
+                    }*/
+                }
+
+            }
+
+            //VIP折扣计价
+            if($vipSettings['buy_doc_discount']<100)
+            {
+                $discount = (intval($vipSettings['buy_doc_discount'])/100);
+                $coin_num = $coin_num*$discount;
+            }
+
+            //生成支付记录
+            $paylog = new DocPaylog();
+            $paylog->user_id = intval($this->user_id);
+            $paylog->doc_user_id = intval($doc->user_id);
+            $paylog->doc_id = $doc->id;
+            $paylog->cat_id = $doc->cat_id;
+            $paylog->cat_ids = $doc->cat_ids;
+            $paylog->doc_type = $doc->doc_type;
+            $paylog->is_vip = ($doc->is_vip||($vipSettings['buy_doc_discount']<100))?1:0;
+            $paylog->coin_price = $doc->coin_price;
+            $paylog->coin_num = $coin_num;
+            $paylog->agent_id = intval($this->userInfo['referer_id']);
+            $paylog->agent_ids = strval($this->userInfo['referer_ids']);
+            $paylog->create_time = TIMESTAMP;
+            if($paylog->save())
+            {
+
+                $doc->updateCounters(['sales'=>1]);
+                $left_coin = $coin_num;
+                $point_num = intval($left_coin*Yii::$app->params['point']['coin_prize_rate']);
+                //购买方
+                $logTitleBuy = '购买'.DocReal::typeOptions($doc->doc_type);
+                Wallet::pointChange($this->user_id,$point_num,$logTitleBuy,1,'point',DocReal::shortTableName(),$doc->id);
+                Wallet::coinChange($this->user_id,$left_coin,$logTitleBuy,2,'coin',DocReal::shortTableName(),$doc->id);
+                //处理分销
+                $left_coin = Wallet::docCommission($this->user_id,$doc,$paylog,$left_coin);
+                //出售方
+                $logTitleSell = '出售'.DocReal::typeOptions($doc->doc_type);
+                if($left_coin>0&&$doc->user_id)
+                {
+                    //金币变化
+                    Wallet::coinChange($doc->user_id,$left_coin,$logTitleSell,1,'coin_income',DocReal::shortTableName(),$doc->id);
+                    //消息通知
+                    MessageOne::soldDoc($logTitleSell,$doc,$left_coin);
+                }
+                $downFlag = true;
+            }
+        }
+        else
+        {
+            $downFlag = true;
+        }
+
+        if($downFlag)
+        {
+            //输出下载码
+            $downCode = new DocDowncode();
+            $downCode->doc_id = $doc->id;
+            $downCode->openid = '';
+            $downCode->downcode = strval(getDowncode($doc->id));
+            $downCode->user_id =  $this->user_id;
+            $downCode->doc_user_id =  $doc->user_id;
+            $downCode->is_ad = $doc->is_ad;
+            $downCode->type = 1;
+            $downCode->create_time = TIMESTAMP;
+            $downCode->save();
+            if(defined('IN_WAP')&&IN_WAP==TRUE)
+            {
+                $downurl = WEB_URL.'ajax/downdoc/?downcode='.$downCode->downcode."&direct=1";
+            }
+            else
+            {
+                $downurl = WEB_URL.'ajax/downdoc/?downcode='.$downCode->downcode;
+            }
+            return [
+                'error' => 0,
+                'msg' => '请求下载中,请稍候...',
+                'data' => ['downcode'=>$downCode->downcode,'downurl'=>$downurl],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '下载失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //添加邮件转存任务
+    public function actionSavetomail()
+    {
+
+        extract($this->post);
+        if(empty($table_name)||empty($data_id))
+        {
+            return [
+                'error' => 1,
+                'msg' => '缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+
+        }
+        else
+        {
+            //判断是否有购买记录
+            $existPayLog = DocPaylog::find()->where("user_id=".$this->user_id." and doc_id=$data_id")->exists();
+            if($existPayLog)
+            {
+                //判断是否已存在任务
+                $mailModel = DocMail::find()->where("doc_id=$data_id and email='".$this->userInfo['email']."' and status=0")->one();
+                if(empty($mailModel))
+                {
+                    $mailModel = new DocMail();
+                    $mailModel->doc_id = $data_id;
+                    $mailModel->email = $this->userInfo['email'];
+                    if($mailModel->save())
+                    {
+                        return [
+                            'error' => 0,
+                            'msg' => '转存成功,请注意查收邮件!',
+                            'data' => [],
+                            'code'=>200
+                        ];
+                    }
+                    else
+                    {
+                        return [
+                            'error' => 1,
+                            'msg' => '操作失败',
+                            'data' => [],
+                            'code'=>200
+                        ];
+                    }
+
+                }
+                else
+                {
+                    return [
+                        'error' => 0,
+                        'msg' => '转存成功,请注意查收邮件!',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '请购买后再转存邮箱',
+                    'data' => [],
+                    'code'=>200
+                ];
+
+            }
+
+        }
+
+    }
+
+}

+ 373 - 0
api/controllers/MappController.php

@@ -0,0 +1,373 @@
+<?php
+namespace api\controllers;
+use app\common\controllers\AController;
+use app\common\controllers\CController;
+use app\models\Nav;
+use app\modules\admin\models\Config;
+use app\modules\ad\models\AdData;
+use app\modules\doc\models\DocReal;
+use app\modules\ucenter\models\UserNum;
+use app\assets\WapAsset;
+use app\modules\cms\models\Category;
+use app\common\components\MultiSearchUrl;
+use app\modules\cms\models\Page;
+use Yii;
+class MappController  extends AController
+{
+
+    public $assetsUrl;
+
+    public $optional1 = [
+        'config',
+        'index',
+        'catlist',
+        'catconfig',
+        'doclist',
+        'search',
+    ];
+
+
+    public function init()
+    {
+        $this->optional = array_merge($this->optional,$this->optional1);
+        $view = $this->getView();
+        $assets = WapAsset::register($view);
+        $this->assetsUrl = API_URL.ltrim($assets->baseUrl,'/').'/';
+        parent::init();
+    }
+
+    //读取小程序配置
+    public function actionConfig()
+    {
+        $request_from = $this->get['request_from'];
+        //百度小程序
+        if($request_from==3)
+        {
+            $configResult = Config::find()->where("name = 'bdapp'")->limit(1)->one();
+        }
+        //微信小程序
+        if($request_from==4)
+        {
+            $configResult = Config::find()->where("name = 'wxapp'")->limit(1)->one();
+        }
+        $config = string2array($configResult->value);
+        $config['logo'] = getFileUrl($config['logo']);
+        $config['shortlogo'] = getFileUrl($config['shortlogo']);
+        //附加配置
+        $hotWords = \app\models\SearchRecord::find()->where("recommend=1")->orderBy(['times'=>SORT_DESC])->limit(5)->all();
+        $config['hotWords'] = $hotWords;
+        $config['docname'] = $this->docconfig['docname']?$this->docconfig['docname']:'文档';
+        $config['colname'] = $this->docconfig['colname']?$this->docconfig['colname']:'合辑';
+        $config['coin_name'] = $this->coinconfig['coin_name'];
+        $config['doc_model_id'] = $this->docconfig['content_model_id'];
+        $config['assetsUrl'] =  $this->assetsUrl;
+        $config['fastAccountType'] = $this->openauthconfig['fastAccountType'];
+        $config['commonAccountType'] = $this->openauthconfig['commonAccountType'];
+        if($config['fastAccountType']=='mobile')
+        {
+            $config['fastAccountTip'] = '手机号';
+        }
+        else if($config['fastAccountType']=='email')
+        {
+            $config['fastAccountTip'] = '邮箱';
+        }
+        else if($config['fastAccountType']=='all')
+        {
+            $config['fastAccountTip'] = '手机号/邮箱';
+        }
+        if($config['commonAccountType']=='mobile')
+        {
+            $config['commonAccountTip'] = '手机号';
+        }
+        else if($config['commonAccountType']=='email')
+        {
+            $config['commonAccountTip'] = '邮箱';
+        }
+        else if($config['commonAccountType']=='all')
+        {
+            $config['commonAccountTip'] = '手机号/邮箱';
+        }
+        $config['certTimeOut'] = $this->smsconfig['certTimeOut'];
+        $config['certValidTime'] = $this->smsconfig['certValidTime'].'分钟';
+        $config['user_model_id'] = getSysconfigValue('default_user_model');
+        $config['share_arg_name'] = Yii::$app->params['shareArgName'];
+        $config['refer_page_name'] = Yii::$app->params['referPageName'];
+        $agreements = Page::findOne(getSysconfigValue('user_agreements_cat_id'));
+        $privacy = Page::findOne(getSysconfigValue('privacy_agreements_cat_id'));
+        $config['agreements'] = $agreements;
+        $config['privacy'] = $privacy;
+        return [
+            'error' => 0,
+            'msg' => '操作成功',
+            'data' => ['config'=>$config],
+            'code'=>200
+        ];
+
+    }
+
+    //首页
+    public function actionIndex()
+    {
+       $request_from = $this->get['request_from'];
+       //首页BANNER
+       $bannerList = $this->_getAdData(12);
+       if(is_array($bannerList))foreach($bannerList as $k=>$banner)
+       {
+           $bannerList[$k]['thumb'] = getFileUrl($banner['thumb']);
+       }
+
+       //文档数量
+       $totalNum = DocReal::find()->where('is_delete=0 and status=1')->count();
+       $totalNum = $totalNum + $this->docconfig['virtualnum'];
+       $preDate = get_date(strtotime("-1 day"),"Y-m-d");
+       $predayNum = UserNum::find()->where("date='".$preDate."'")->sum('doc_uploadnum');
+       $predayNum = $predayNum+$this->docconfig['virtualaddnum'];
+       //首页菜单
+       if($request_from==3)//百度小程序
+       {
+          $menuList = Nav::find()->where("type=81 and disabled=0")->orderBy(['list_order'=>SORT_ASC])->asArray()->all();
+       }
+       if($request_from==4)//微信小程序
+       {
+          $menuList = Nav::find()->where("type=91 and disabled=0")->orderBy(['list_order'=>SORT_ASC])->asArray()->all();
+       }
+       //首页横幅广告
+       $adList = $this->_getAdData(13);
+       if(is_array($adList))foreach($adList as $k=>$ad)
+       {
+           $adList[$k]['thumb'] = getFileUrl($ad['thumb']);
+       }
+       //最新文档
+       $newDocList = DocReal::find()->where("is_new=1 and status=1 and is_delete=0 and doc_type!=2")->orderBy(['create_time'=>SORT_DESC])->limit(10)->asArray()->all();
+       foreach($newDocList as $k=>$newDoc)
+       {
+          $newDocList[$k]['thumb'] = $this->makeThumb($newDoc['thumb'],320,340);
+          $newDocList[$k]['icon'] =  $this->assetsUrl.'images/icon/'.DocReal::getExtImgName($newDoc['ext']).'.png';
+          $newDocList[$k]['views'] = $this->getDocView($newDoc['views']);
+          $newDocList[$k]['downs'] = $this->getDocDowns($newDoc['downs']);
+       }
+       //最新合辑
+       $newColList = DocReal::find()->where("is_new=1 and status=1 and is_delete=0 and doc_type=2")->orderBy(['create_time'=>SORT_DESC])->limit(10)->asArray()->all();
+       foreach($newColList as $k=>$newCol)
+       {
+         $newColList[$k]['thumb'] = $this->makeThumb($newCol['thumb'],354,254);
+         $newColList[$k]['icon'] =  $this->assetsUrl.'images/icon/'.DocReal::getExtImgName($newCol['ext']).'.png';
+         $newColList[$k]['views'] = $this->getDocView($newCol['views']);
+         $newColList[$k]['downs'] = $this->getDocDowns($newCol['downs']);
+       }
+       $tabTitle[] = $this->docconfig['docname']?$this->docconfig['docname']:'文档';
+       $tabTitle[] = $this->docconfig['colname']?$this->docconfig['colname']:'合辑';
+        return [
+            'error' => 0,
+            'msg' => '操作成功',
+            'data' => ['bannerList'=>$bannerList,'adList'=>$adList,'menuList'=>$menuList,'totalNum'=>$totalNum,'predayNum'=>$predayNum,'tabTitle'=>$tabTitle,'newDocList'=>$newDocList,'newColList'=>$newColList,'assetsUrl'=>$this->assetsUrl],
+            'code'=>200
+        ];
+    }
+
+    //获取栏目列表
+    public function actionCatlist()
+    {
+        $level = $this->docconfig['catlevel'];
+        $menuList = Category::getDocCatMenus($this->docconfig['content_model_id']);
+        foreach($menuList as $i=>$menu)
+        {
+            if(empty($menu['childs']))
+            {
+                $menuList[$i]['childs'][] = ['title'=>$menu['title'],'cat_id'=>$menu['cat_id']];
+            }
+            else
+            {
+                foreach($menu['childs'] as $k=>$subMenu)
+                {
+                    if(empty($subMenu['childs']))
+                    {
+                        $menuList[$i]['childs'][$k]['childs'][] = ['title'=>$subMenu['title'],'cat_id'=>$subMenu['cat_id']];
+                    }
+                }
+            }
+        }
+        return [
+            'error' => 0,
+            'msg' => '操作成功',
+            'data' => ['menuList'=>$menuList,'level'=>$level],
+            'code'=>200
+        ];
+    }
+
+    //获取栏目配置
+    public function actionCatconfig()
+    {
+        $cat_id =  $this->get['cat_id'];
+        $controller = new \app\common\controllers\FController('default','web');
+        $controller->initFilterConfig();
+        $docFilterConfig = $controller->filterConfig['doc'];
+        if($cat_id>0)
+        {
+            $category = Category::findOne($cat_id);
+            //栏目扩展配置(加入SEO)
+            $extConfigList = $category->getExtconfig($docFilterConfig['xConfig']);
+        }
+
+        return [
+            'error' => 0,
+            'msg' => '操作成功',
+            'data' => ['extConfigList'=>$extConfigList,'spConfig'=>$docFilterConfig['spConfig'],'vpConfig'=>$docFilterConfig['vpConfig'],'sortConfig'=>$docFilterConfig['sortConfigWap']],
+            'code'=>200
+        ];
+    }
+
+    //文档列表
+    public function actionDoclist()
+    {
+
+        $doc_type = $this->get['doc_type'];
+        $searchConditions = [];
+        if(is_array($this->get))foreach($this->get as $k=>$v)
+        {
+            if($v==0)continue;
+            $searchConditions[] = $k.$v;
+        }
+        //序列化筛选条件
+        $controller = new \app\common\controllers\FController('default','web');
+        $controller->initFilterConfig();
+        $docFilterConfig = $controller->filterConfig['doc'];
+        $multiSearch = MultiSearchUrl::getSelfInstance(array('fieldConfig'=> $docFilterConfig['fieldConfig'],'sortConfig'=>$docFilterConfig['sortConfig']));
+        $multiSearch->existConditions = $searchConditions;
+        $sqlInfo  = $multiSearch->sqllizeConditions();
+        $catId = $multiSearch->getConditionValueByType($searchConditions,'c');
+        $st = $multiSearch->getConditionValueByType($searchConditions,'st');
+        if($catId)
+        {
+            $category = Category::findOne($catId);
+            //栏目扩展配置(加入SEO)
+            $extConfigList = $category->getExtconfig($docFilterConfig['xConfig']);
+            if(is_array($extConfigList))foreach($extConfigList as $extname=>$extConfig){
+                if(is_array($extConfig['options']))foreach($extConfig['options'] as $k=>$v){
+                    if(in_array($extConfig['key'].$k,$searchConditions)){
+                        $$extname = $v;
+                    }
+                }
+            }
+
+            //栏目SEO设置
+            $seosettingsPre = 'wap_';
+            $cat_name = $category->cat_name;
+            $categorySeoSettings = Category::getCatSeoSettings($catId,$seosettingsPre);
+            $_replaceconfig = array(
+                'targets'=>['{brand}','{cat_name}','{ext_type_1}','{ext_type_2}','{ext_type_3}','{ext_type_4}','{ext_type_5}'],
+                'values'=>[$this->baseconfig['brand'],$cat_name,$ext_type_1,$ext_type_2,$ext_type_3,$ext_type_4,$ext_type_5],
+                'pre'=>$seosettingsPre
+            );
+            $metaInfo = seoSettings($categorySeoSettings,$_replaceconfig);
+        }
+        else
+        {
+            $metaInfo = [$this->docconfig['meta_title'],$this->docconfig['meta_keywords'],$this->docconfig['meta_description']];
+        }
+
+        //初始化查询语句
+        $query = DocReal::find()->asArray();
+        $sql = " 1=1 ";
+        if($sqlInfo['where']) $sql.= $sqlInfo['where'];
+        if($doc_type==2)
+        {
+            $sql .= " and doc_type=2 and status=1 and is_delete=0";
+        }
+        else
+        {
+            $sql .= " and doc_type!=2 and status=1 and is_delete=0";
+        }
+        $currentPage = Yii::$app->request->get('page',1);
+        $return = $controller->doList($query,$sql,$sqlInfo,'doc',10,$this->higherconfig);
+        $pages = $return['pages'];
+        $resultList = $return['resultList'];
+        if(is_array($resultList))foreach($resultList as $k=>$result)
+        {
+            $tempDocType = $result['doc_type1']?$result['doc_type1']:$result['doc_type'];
+            if($tempDocType==2)
+            {
+                $resultList[$k]['thumb'] = $this->makeThumb($result['thumb'],354,254);
+            }
+            else
+            {
+                $resultList[$k]['thumb'] = $this->makeThumb($result['thumb'],320,340);
+            }
+            $resultList[$k]['icon'] =  $this->assetsUrl.'images/icon/'.DocReal::getExtImgName($result['ext']).'.png';
+            $resultList[$k]['views'] = $this->getDocView($result['views']);
+            $resultList[$k]['downs'] = $this->getDocDowns($result['downs']);
+            $resultList[$k]['doc_type'] = $tempDocType;
+            $resultList[$k]['doc_num'] = $result['doc_num'];
+            $resultList[$k]['coin_price'] = number_format($result['coin_price'],1);
+        }
+        return [
+            'error' => 0,
+            'msg' => '请求成功',
+            'data' => ['resultList'=>$resultList,'count'=>$pages->totalCount,'pageCount'=>$pages->getPageCount(),'currentPage'=>$currentPage,'pageSize'=>$pages->pageSize,'metaInfo'=>$metaInfo],
+            'code'=>200
+        ];
+
+    }
+
+    //搜索
+    public function actionSearch()
+    {
+
+        $kw = safe_replace(urldecode($_GET['kw']));
+        $model_id = intval($_GET['model_id']);
+        if($kw&&$model_id)
+        {
+            $controller = new \app\common\controllers\FController('default','web');
+            $controller->initFilterConfig();
+            $searchReturn = $controller->doSearch($kw,$model_id,$this->higherconfig);
+            extract($searchReturn);
+            return [
+                'error' => 0,
+                'msg' => '请求成功',
+                'data' => ['resultList'=>$resultList,'count'=>$count,'pageCount'=>$pageCount,'currentPage'=>$currentPage,'pageSize'=>$pageSize],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //获取用户信息
+    public function actionUserinfo()
+    {
+        $this->userInfo['avatar'] = getFileUrl($this->user['avatar']);
+        return [
+            'error' => 0,
+            'msg' => '请求成功',
+            'data' => ['userInfo'=>$this->userInfo],
+            'code'=>200
+        ];
+    }
+
+
+
+
+
+
+    //返回文档浏览数
+    public  function getDocView($views)
+    {
+        $virtualViews = $views+intval($this->docconfig['virtualviews']);
+        return $virtualViews>=999?'999+':$virtualViews;
+    }
+
+    //返回文档下载数
+    public  function getDocDowns($downs)
+    {
+        $virtualDowns = $downs+intval($this->docconfig['virtualdowns']);
+        return $virtualDowns>=99?'99+':$virtualDowns;
+    }
+
+    //获取广告数据
+    private function _getAdData($space_id)
+    {
+        $dataList = AdData::find()->where("space_id='".$space_id."' and status=1 and end_time>".TIMESTAMP)->orderBy(['list_order'=>SORT_ASC])->asArray()->all();
+        return $dataList;
+    }
+
+
+}

+ 490 - 0
api/controllers/ShareController.php

@@ -0,0 +1,490 @@
+<?php
+namespace api\controllers;
+use app\common\controllers\AController;
+use app\common\helpers\Identify;
+use app\modules\doc\models\DocReal;
+use app\modules\ucenter\models\User;
+use Yii;
+class ShareController  extends AController
+{
+
+    public $sharePath;
+    public $font;
+    public function init()
+    {
+        parent::init();
+        $this->sharePath = THUMB_PATH."share".DIRECTORY_SEPARATOR;
+        dir_create($this->sharePath);
+        //字体
+        $this->font = BASE_PATH.'/static/fonts/msyh.ttc';
+    }
+
+    //生成文档分享海报
+    public function actionSharedoc()
+    {
+
+        $id = $this->post['id'];
+        $doc = DocReal::findOne($id);
+        if($doc)
+        {
+            $background = getFileUrl($this->posterconfig['doc']);
+            if($this->user)
+            {
+                $avatar = getFileUrl($this->userInfo['avatar']);
+                if(empty($avatar))
+                {
+                    $avatar = getFileUrl($this->imageconfig['noavatar']);
+                }
+                $nick_name = $this->userInfo['nick_name'];
+            }
+            else
+            {
+                $avatar = getFileUrl($this->imageconfig['wapshortlogo']);
+                $nick_name = $this->baseconfig['brand'];
+            }
+
+            $title = $doc->title;
+            $thumb = Yii::$app->controller->makeThumb($doc->thumb,320,362);
+            $thumbinfo = getimagesize($thumb);
+            $thumbwidth = $thumbinfo[0];
+            $thumbheight = $thumbinfo[1];
+
+            if($thumbheight>$thumbwidth)
+            {
+                $thumbleft = 90+ intval(abs(416-256)/2);
+                $thumbtop = 296+ intval(abs(290-279)/2);
+                $thumbCofig = array(
+                    'url'=>$thumb,
+                    'stream'=>0,
+                    'left'=>$thumbleft,
+                    'top'=>$thumbtop,
+                    'right'=>0,
+                    'bottom'=>0,
+                    'width'=>256,
+                    'height'=>279,
+                    'opacity'=>100
+                );
+            }
+            else
+            {
+                $thumbleft = 90 + intval(abs(416-320)/2);
+                $thumbtop = 296 + intval(abs(290-180)/2);
+                $thumbCofig = array(
+                    'url'=>$thumb,
+                    'stream'=>0,
+                    'left'=>$thumbleft,
+                    'top'=>$thumbtop,
+                    'right'=>0,
+                    'bottom'=>0,
+                    'width'=>320,
+                    'height'=>180,
+                    'opacity'=>100
+                );
+            }
+
+
+
+
+            if($background)
+            {
+                //生成底图
+                $bgImg = $this->sharePath.'docshare.png';
+                if(!file_exists($bgImg))file_put_contents($bgImg,https_request($background));
+                //二维码
+                if($this->user)
+                {
+                    $shareLog = createShareNo(DocReal::shortTableName(),$id,$this->user->user_id);
+                    $shareUrl = safe_replace($this->post['url']).'?'.Yii::$app->params['shareArgName'].'='.$shareLog->share_no;
+                }
+                else
+                {
+                    $shareUrl = safe_replace($this->post['url']);
+                }
+                $qrcode = new \app\components\qrcode\qrcode($shareUrl);
+                $qrcodeImg = $this->sharePath.md5($shareUrl).'.png';
+                $qrcode->create($qrcodeImg);
+
+                //文案处理
+                if(!empty($title))
+                {
+                    $pos = imagettfbbox(18,0,$this->font,$title);
+                    $textConfig = array(
+                        'text' => ($pos[2]-$pos[0])>380?str_cut($title,0,16,'...'):$title,
+                        'left' => 90,
+                        'top' => 270,
+                        'fontSize' => 18,//字号
+                        'fontColor' => '65,113,179', //字体颜色
+                        'angle' => 0,
+                        'fontPath'=>$this->font,
+                    );
+                    $text1Config = array(
+                        'text'=>'手机扫一扫,立即下载',
+                        'left'=>150,
+                        'top'=>670,
+                        'fontSize'=>15,//字号
+                        'fontColor'=>'102,102,102', //字体颜色
+                        'angle'=>0,
+                        'fontPath'=>$this->font,
+                    );
+
+                }
+                else
+                {
+                    $textConfig = array();
+                    $text1Config = array();
+                }
+
+
+                //头像和昵称配置
+                $avatarConfig = [];
+                $nicknameConfig = [];
+                $avatarConfig = array(
+                    'url'=>$avatar,
+                    'stream'=>0,
+                    'left'=>50,
+                    'top'=>50,
+                    'right'=>0,
+                    'bottom'=>0,
+                    'width'=>50,
+                    'height'=>50,
+                    'opacity'=>100
+                );
+                $nicknameConfig = array(
+                    'text'=>$nick_name,
+                    'left'=>110,
+                    'top'=>90,
+                    'fontSize'=>24,       //字号
+                    'fontColor'=>'255,255,255', //字体颜色
+                    'angle'=>0,
+                    'fontPath'=>$this->font,
+                );
+                //海报目标文件
+                $posterImg = $this->sharePath.md5($shareUrl).'-1.png';
+                $noimage = 0;
+                $config = array(
+                    'image'=>array(
+                        array(
+                            'url'=>$qrcodeImg,//二维码资源
+                            'stream'=>0,
+                            'left'=>373,
+                            'top'=>620,
+                            'right'=>0,
+                            'bottom'=>0,
+                            'width'=>128,
+                            'height'=>128,
+                            'opacity'=>100
+                        )
+                    ),
+                    'avatar'=>array(
+                        $avatarConfig
+                    ),
+                    'nickname'=>array(
+                        $nicknameConfig
+                    ),
+                    'text'=>array(
+                        $textConfig
+                    ),
+                    'text1'=>array(
+                        $text1Config
+                    ),
+                    'thumb'=>array(
+                        $thumbCofig
+                    ),
+                    'background'=>$bgImg
+                );
+                //生成海报
+                if(!file_exists($posterImg))
+                {
+                    createPoster($config,$posterImg);
+                }
+                $posterUrl = APP_URL.'thumb/'.str_replace(DIRECTORY_SEPARATOR,'/',str_replace(THUMB_PATH,'',$posterImg));
+                return [
+                    'error' => 0,
+                    'msg' => '生成成功',
+                    'data' => ['posterUrl'=>$posterUrl],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '未设置海报底图',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '系统错误',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //通用分享
+    public function actionSharecom()
+    {
+        $type = $this->post['type'];
+        $url  = $this->post['url'];
+        if(empty($type)||empty($url))
+        {
+            return [
+                'error' => 1,
+                'msg' => '系统错误',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        $background = getFileUrl($this->posterconfig['common'.$type]);
+        $nick_name = '我是'.$this->userInfo['nick_name'];
+        $title  = "我为【".$this->baseconfig['brand'].'】代言';
+        //生成底图
+        $bgImg = $this->sharePath.'common_'.$type.'.png';
+        if(!file_exists($bgImg))file_put_contents($bgImg,https_request($background));
+        //二维码
+        $qrcode = new \app\components\qrcode\qrcode($url);
+        $qrcodeImg = $this->sharePath.md5($url).'.png';
+        $qrcode->create($qrcodeImg);
+        //文案处理
+        if($type==1)
+        {
+            //昵称
+            $textConfig = array(
+                'text' => $nick_name,
+                'left' => 31,
+                'top' => 945,
+                'fontSize' => 18,//字号
+                'fontColor' => '0,0,0', //字体颜色
+                'angle' => 0,
+                'fontPath'=>$this->font,
+            );
+            //标题
+            $text1Config = array(
+                'text'=> $title,
+                'left'=>31,
+                'top'=>1030,
+                'fontSize'=>18,//字号
+                'fontColor'=>'0,0,0', //字体颜色
+                'angle'=>0,
+                'fontPath'=>$this->font,
+            );
+            //二维码
+            $imageConfig = array(
+                'url'=>$qrcodeImg,
+                'stream'=>0,
+                'left'=>490,
+                'top'=>958,
+                'right'=>0,
+                'bottom'=>0,
+                'width'=>110,
+                'height'=>110,
+                'opacity'=>100
+            );
+
+        }else if($type==2){
+            $pos = imagettfbbox(18,0,$this->font,$nick_name);
+            //昵称
+            $textConfig = array(
+                'text' => $nick_name,
+                'left' => (640-($pos[2]-$pos[0]))/2,
+                'top' => 820,
+                'fontSize' => 18,//字号
+                'fontColor' => '0,0,0', //字体颜色
+                'angle' => 0,
+                'fontPath'=>$this->font,
+            );
+            $pos = imagettfbbox(18,0,$this->font,$title);
+            //标题
+            $text1Config = array(
+                'text'=> $title,
+                'left'=>(640-($pos[2]-$pos[0]))/2,
+                'top'=>870,
+                'fontSize'=>18,//字号
+                'fontColor'=>'0,0,0', //字体颜色
+                'angle'=>0,
+                'fontPath'=>$this->font,
+            );
+            //二维码
+            $imageConfig = array(
+                'url'=>$qrcodeImg,
+                'stream'=>0,
+                'left'=>(640-110)/2,
+                'top'=>925,
+                'right'=>0,
+                'bottom'=>0,
+                'width'=>110,
+                'height'=>110,
+                'opacity'=>100
+            );
+
+        }else if($type==3){
+            $pos = imagettfbbox(18,0,$this->font,$nick_name);
+            //昵称
+            $textConfig = array(
+                'text' => $nick_name,
+                'left' => -($pos[2]-$pos[0]+45),
+                'top' => 920,
+                'fontSize' => 18,//字号
+                'fontColor' => '0,0,0', //字体颜色
+                'angle' => 0,
+                'fontPath'=>$this->font,
+            );
+            $pos = imagettfbbox(18,0,$this->font,$title);
+            //标题
+            $text1Config = array(
+                'text'=> $title,
+                'left'=> -($pos[2]-$pos[0]+45),
+                'top'=>966,
+                'fontSize'=>18,//字号
+                'fontColor'=>'0,0,0', //字体颜色
+                'angle'=>0,
+                'fontPath'=>$this->font,
+            );
+            //二维码
+            $imageConfig = array(
+                'url'=>$qrcodeImg,
+                'stream'=>0,
+                'left'=>75,
+                'top'=>880,
+                'right'=>0,
+                'bottom'=>0,
+                'width'=>127,
+                'height'=>127,
+                'opacity'=>100
+            );
+        }else if($type==4){
+            $pos = imagettfbbox(18,0,$this->font,$nick_name);
+            //昵称
+            $textConfig = array(
+                'text' => $nick_name,
+                'left' => (640-($pos[2]-$pos[0]))/2,
+                'top' => 942,
+                'fontSize' => 18,//字号
+                'fontColor' => '255,255,255', //字体颜色
+                'angle' => 0,
+                'fontPath'=>$this->font,
+            );
+            $pos = imagettfbbox(18,0,$this->font,$title);
+            //标题
+            $text1Config = array(
+                'text'=> $title,
+                'left'=>(640-($pos[2]-$pos[0]))/2,
+                'top'=>985,
+                'fontSize'=>18,//字号
+                'fontColor'=>'255,255,255', //字体颜色
+                'angle'=>0,
+                'fontPath'=>$this->font,
+            );
+            //二维码
+            $imageConfig = array(
+                'url'=>$qrcodeImg,
+                'stream'=>0,
+                'left'=>(640-148)/2,
+                'top'=>744,
+                'right'=>0,
+                'bottom'=>0,
+                'width'=>148,
+                'height'=>148,
+                'opacity'=>100
+            );
+
+        }else if($type==5){
+            $avatar = getFileUrl($this->userInfo['avatar']);
+            if(empty($avatar))
+            {
+                $avatar = getFileUrl($this->imageconfig['noavatar']);
+            }
+            $nick_name = $this->userInfo['nick_name'];
+            $title = $this->posterconfig['title']?$this->posterconfig['title']:'手机扫一扫立即加入';
+            $textConfig = array(
+                'text'=>$title,
+                'left'=>185,
+                'top'=>675,
+                'fontSize'=>15,//字号
+                'fontColor'=>'255,255,255', //字体颜色
+                'angle'=>0,
+                'fontPath'=>$this->font
+            );
+
+            $nicknameConfig = array(
+                'text'=>$nick_name."推荐",
+                'left'=>190,
+                'top'=>725,
+                'fontSize'=>20,//字号
+                'fontColor'=>'255,255,255', //字体颜色
+                'angle'=>0,
+                'fontPath'=>$this->font
+            );
+
+            $avatarConfig = array(
+                'url'=>$avatar,
+                'stream'=>0,
+                'left'=>120,
+                'top'=>685,
+                'right'=>0,
+                'bottom'=>0,
+                'width'=>60,
+                'height'=>60,
+                'opacity'=>100
+            );
+            $imageConfig =  array(
+                'url'=>$qrcodeImg,//二维码资源
+                'stream'=>0,
+                'left'=>420,
+                'top'=>620,
+                'right'=>0,
+                'bottom'=>0,
+                'width'=>127,
+                'height'=>127,
+                'opacity'=>100
+            );
+        }
+
+
+        $config = array(
+            'image'=>array(
+                $imageConfig
+            ),
+
+            'text'=>array(
+                $textConfig
+            ),
+            'text1'=>array(
+                $text1Config
+            ),
+            'nickname'=>array(
+                $nicknameConfig
+            ),
+            'avatar'=>array(
+                $avatarConfig
+            ),
+            'background'=>$bgImg
+        );
+
+        //海报目标文件
+        $posterImg = $this->sharePath.md5($url.$type).'-1.png';
+        //生成海报
+        if(!file_exists($posterImg))
+        {
+            createPoster($config,$posterImg);
+        }
+        $posterUrl = APP_URL.'thumb/'.str_replace(DIRECTORY_SEPARATOR,'/',str_replace(THUMB_PATH,'',$posterImg));
+        return [
+            'error' => 0,
+            'msg' => '生成成功',
+            'data' => ['posterUrl'=>$posterUrl],
+            'code'=>200
+        ];
+
+
+    }
+
+
+
+}

+ 117 - 0
api/controllers/ShopController.php

@@ -0,0 +1,117 @@
+<?php
+namespace api\controllers;
+use app\common\controllers\AController;
+use app\modules\shopping\models\ShoppingAddress;
+use Yii;
+class ShopController  extends AController
+{
+
+    public function init()
+    {
+        parent::init();
+
+    }
+
+    //添加(修改)收货地址
+    public function actionCreateaddress()
+    {
+        if(!empty($this->post['id']))
+        {
+            $address = \app\modules\shopping\models\ShoppingAddress::findOne($this->post['id']);
+            $checkResult = $this->checkRights($this->user_id,$address);
+            if($checkResult['error']==1)
+            {
+                return  $checkResult;
+            }
+        }
+        else
+        {
+            $address = new \app\modules\shopping\models\ShoppingAddress();
+        }
+
+        if($address->load($this->post))
+        {
+            $regionList = \app\models\Linkmenu::getMenuNameRs($address->region_id);
+            $address->province = $regionList[0];
+            $address->city = $regionList[1];
+            $address->area = $regionList[2];
+            $address->user_id = $this->user_id;
+            $address->create_time = TIMESTAMP;
+            if(!$address->validate())
+            {
+                return   [
+                    'error' => 1,
+                    'msg' => $address->returnFirstError(),
+                    'data'=>[]
+                ];
+            }
+            else
+            {
+                //如果当前设置为默认,先清除所有已存在记录的默认状态
+                if($address->is_default==1)
+                {
+                    \app\modules\shopping\models\ShoppingAddress::updateAll(['is_default' => 0], ['=', 'user_id', $this->user_id]);
+                }
+
+                if($address->save())
+                {
+                    return [
+                        'error' => 0,
+                        'msg' => '操作成功',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                else
+                {
+                    return   [
+                        'error' => 1,
+                        'msg' => '操作失败',
+                        'data'=>[]
+                    ];
+                }
+            }
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '操作失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+
+    }
+
+    //删除地址
+    public function actionDeladdress()
+    {
+        $address_id = Yii::$app->request->get('address_id');
+        $model = ShoppingAddress::findOne($address_id);
+        if(empty($model))
+        {
+            $result = ['error' => 1,'msg' => '非法操作'];
+        }
+        else
+        {
+            $checkResult = $this->checkRights($this->user_id,$model);
+            if($checkResult['error']==1)
+            {
+                return $checkResult;
+            }
+            $model->is_del = 1;
+            if($model->save())
+            {
+                $result = ['error' => 0,'msg' => '操作成功'];
+            }
+            else
+            {
+                $result = ['error' => 1,'msg' => '操作失败'];
+            }
+        }
+        return $result;
+    }
+
+}

+ 810 - 0
api/controllers/UploadController.php

@@ -0,0 +1,810 @@
+<?php
+namespace api\controllers;
+use app\common\controllers\AController;
+use app\modules\admin\models\Attachment;
+use app\modules\cms\models\Category;
+use app\modules\doc\models\Doc;
+use app\modules\doc\models\DocData;
+use app\modules\doc\models\DocReal;
+use app\modules\doc\models\DocRealData;
+use app\modules\doc\models\DocCol;
+use app\modules\ucenter\models\UserNum;
+use Yii;
+class UploadController  extends AController
+{
+
+    public function init()
+    {
+        parent::init();
+    }
+
+    //发布单个文档
+    public function actionSingle()
+    {
+        $url = self::urlList('myupload');
+        $doc = new Doc();
+        $docData = new DocData();
+        if($doc->load($this->post)){
+            $result = $this->_checkRights($doc->is_ad);
+            if($result['error']==0)
+            {
+                if($doc->cat_id)
+                {
+                    $category = Category::findOne($doc->cat_id);
+                    $parent_cat_ids = explode(",",$category->arr_parent_ids);
+                    $doc->doc_type = 1;
+                    $doc->status = 0;
+                    $doc->stars = 3;
+                    $doc->parent_cat_id = intval($parent_cat_ids[1]);
+                    $doc->root_cat_id = intval($parent_cat_ids[count($parent_cat_ids)-1]);
+                    if(!empty($category->arr_parent_ids))
+                    {
+                        $doc->cat_ids = ",".join(",",array_reverse($parent_cat_ids)).",";
+                    }
+                    else
+                    {
+                        $doc->cat_ids = ",".$doc->cat_id.",";
+                    }
+                    $doc->user_id = $this->user->user_id;
+                    $doc->user_name = $this->user->user_name;
+                    $doc->create_time = TIMESTAMP;
+                    $doc->update_time = TIMESTAMP;
+                    if(!$doc->validate())
+                    {
+                        $result =  [
+                            'error' => 1,
+                            'msg' => $doc->returnFirstError(),
+                            'data'=>[]
+                        ];
+                    }
+                    else
+                    {
+                        //tag更新
+                        if(empty($doc->tags))
+                        {
+                            $doc->tags = initTags($doc);
+                        }
+                        if($doc->save())
+                        {
+                            $docData->id = $doc->id;
+                            $docData->load($this->post);
+                            if(empty($docData->content))$docData->content = '';
+                            if(!$docData->validate())
+                            {
+                                $result =  [
+                                    'error' => 1,
+                                    'msg' => $docData->returnFirstError(),
+                                    'data'=>[]
+                                ];
+                            }
+                            else
+                            {
+
+                                if($docData->save())
+                                {
+                                    if($docData->file)Attachment::relateAttachmentByTable($docData->file,$docData->shortTableName(),'file',$doc->id);
+                                    if($doc->thumb)Attachment::relateAttachmentByTable($doc->thumb,$doc->shortTableName(),'thumb',$doc->id);
+                                    if($doc->tags)refreshTag($doc->tags,$doc->shortTableName(),$doc->id,$doc->user_id);
+                                    $this->user->refreshData($this->user->user_id);
+                                    $this->_refreshNum('doc_uploadnum');
+                                    $result =  [
+                                        'error' => 0,
+                                        'msg' => '恭喜您,上传成功',
+                                        'data' => ['url'=>$url],
+                                        'code'=>200
+                                    ];
+                                }
+                                else
+                                {
+                                    $result =  [
+                                        'error' => 1,
+                                        'msg' => '上传失败',
+                                        'data'=>[]
+                                    ];
+                                }
+
+                            }
+                        }
+                        else
+                        {
+                            $result =  [
+                                'error' => 1,
+                                'msg' => '上传失败',
+                                'data'=>[]
+                            ];
+                        }
+
+                    }
+
+                }
+                else
+                {
+                    $result = [
+                        'error' => 1,
+                        'msg' => '请求出错,缺少必要参数',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+        }
+        else
+        {
+            $result = [
+                'error' => 1,
+                'msg' => '请求出错,缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+
+        }
+        return  $result;
+
+    }
+
+    //发布合辑
+    public function actionCollect()
+    {
+        $url = self::urlList('myupload');
+        $id = Yii::$app->request->post('id',0);
+        if($id)
+        {
+            $doc = DocReal::findOne($id);
+            $docData = DocRealData::findOne($id);
+            $checkResult = $this->checkRights($this->user_id,$doc);
+            if($checkResult['error']==1)
+            {
+                return $checkResult;
+            }
+        }
+        else
+        {
+            $doc = new Doc();
+            $docData = new DocData();
+        }
+
+        if($doc->load($this->post)){
+            $result = $this->_checkRights(0,$id);
+            if($result['error']==0)
+            {
+                if($doc->cat_id)
+                {
+                    $category = Category::findOne($doc->cat_id);
+                    $parent_cat_ids = explode(",",$category->arr_parent_ids);
+                    $doc->status = 0;
+                    $doc->stars = 3;
+                    $doc->parent_cat_id = intval($parent_cat_ids[1]);
+                    $doc->root_cat_id = intval($parent_cat_ids[count($parent_cat_ids)-1]);
+                    if(!empty($category->arr_parent_ids))
+                    {
+                        $doc->cat_ids = ",".join(",",array_reverse($parent_cat_ids)).",";
+
+                    }
+                    else
+                    {
+                        $doc->cat_ids = ",".$doc->cat_id.",";
+                    }
+                    $doc->user_id = $this->user->user_id;
+                    $doc->user_name = $this->user->user_name;
+                    if($id==0)$doc->create_time = TIMESTAMP;
+                    $doc->update_time = TIMESTAMP;
+                    if(!$doc->validate())
+                    {
+                        $result =  [
+                            'error' => 0,
+                            'msg' => $doc->returnFirstError(),
+                            'data'=>[]
+                        ];
+                    }
+                    else
+                    {
+                        //tag更新
+                        if(empty($doc->tags))
+                        {
+                            $doc->tags = initTags($doc);
+                        }
+
+                        if($doc->save())
+                        {
+                            $docData->id = $doc->id;
+                            $docData->load($this->post);
+                            if(empty($docData->content))$docData->content = '';
+                            if(!$docData->validate())
+                            {
+                                $result =  [
+                                    'error' => 1,
+                                    'msg' => $docData->returnFirstError(),
+                                    'data'=>[]
+                                ];
+                            }
+                            else
+                            {
+                                if($docData->save())
+                                {
+                                    //合辑关联文档数据
+                                    if(!empty($docData->docs))
+                                    {
+                                        $docIds = explode(",",$docData->docs);
+                                        $doc->doc_num = count($docIds);
+                                        //写合辑文档关联表
+                                        $multiInsertData = [];
+                                        if(is_array($docIds))foreach($docIds as $docId)
+                                        {
+                                            $multiInsertData[] = ['col_id' => $doc->id,'doc_id' => $docId];
+                                        }
+                                        if(!empty($multiInsertData))
+                                        {
+                                            Yii::$app->db->createCommand()->batchInsert(DocCol::tableName(), ['col_id', 'doc_id'], $multiInsertData)->execute();
+                                        }
+                                    }
+                                    else
+                                    {
+                                        $doc->doc_num = 0;
+                                    }
+                                    $doc->save();
+                                    if($doc->thumb)Attachment::relateAttachmentByTable($doc->thumb,$doc->shortTableName(),'thumb',$doc->id);
+                                    if($doc->tags)refreshTag($doc->tags,$doc->shortTableName(),$doc->id,$doc->user_id);
+                                    $this->user->refreshData($this->user->user_id);
+                                    if($id==0)$this->_refreshNum('doc_uploadnum');
+                                    $result =  [
+                                        'error' => 0,
+                                        'msg' => '恭喜您,发布成功',
+                                        'data' => ['url'=>$url],
+                                        'code'=>200
+                                    ];
+                                }
+                                else
+                                {
+                                    $result =  [
+                                        'error' => 1,
+                                        'msg' => '发布失败',
+                                        'data'=>[]
+                                    ];
+                                }
+
+                            }
+                        }
+                        else
+                        {
+                            $result =  [
+                                'error' => 1,
+                                'msg' => '发布失败',
+                                'data'=>[]
+                            ];
+                        }
+
+                    }
+
+                }
+                else
+                {
+                    $result = [
+                        'error' => 1,
+                        'msg' => '请求出错,缺少必要参数',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+
+        }
+        else
+        {
+            $result = [
+                'error' => 1,
+                'msg' => '请求出错,缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+        return  $result;
+
+    }
+
+
+    //发布资源
+    public function actionSource()
+    {
+        $url = self::urlList('myupload');
+        $id = Yii::$app->request->post('id',0);
+        if($id)
+        {
+            $doc = DocReal::findOne($id);
+            $docData = DocRealData::findOne($id);
+            $checkResult = $this->checkRights($this->user_id,$doc);
+            if($checkResult['error']==1)
+            {
+                return $checkResult;
+            }
+        }
+        else
+        {
+            $doc = new Doc();
+            $docData = new DocData();
+        }
+
+        if($doc->load($this->post)){
+            $result = $this->_checkRights(0,$id);
+            if($result['error']==0)
+            {
+                if($doc->cat_id)
+                {
+                    $category = Category::findOne($doc->cat_id);
+                    $parent_cat_ids = explode(",",$category->arr_parent_ids);
+                    $doc->status = 0;
+                    $doc->stars = 3;
+                    $doc->parent_cat_id = intval($parent_cat_ids[1]);
+                    $doc->root_cat_id = intval($parent_cat_ids[count($parent_cat_ids)-1]);
+                    if(!empty($category->arr_parent_ids))
+                    {
+                        $doc->cat_ids = ",".join(",",array_reverse($parent_cat_ids)).",";
+                    }
+                    else
+                    {
+                        $doc->cat_ids = ",".$doc->cat_id.",";
+                    }
+                    $doc->user_id = $this->user->user_id;
+                    $doc->user_name = $this->user->user_name;
+                    if($id==0)$doc->create_time = TIMESTAMP;
+                    $doc->update_time = TIMESTAMP;
+                    if(!$doc->validate())
+                    {
+                        $result =  [
+                            'error' => 0,
+                            'msg' => $doc->returnFirstError(),
+                            'data'=>[]
+                        ];
+                    }
+                    else
+                    {
+                        //tag更新
+                        if(empty($doc->tags))
+                        {
+                            $doc->tags = initTags($doc);
+                        }
+                        if($doc->save())
+                        {
+                            $docData->id = $doc->id;
+                            $docData->load($this->post);
+                            if(empty($docData->content))$docData->content = '';
+                            if(!$docData->validate())
+                            {
+                                $result =  [
+                                    'error' => 1,
+                                    'msg' => $docData->returnFirstError(),
+                                    'data'=>[]
+                                ];
+                            }
+                            else
+                            {
+                                if($docData->save())
+                                {
+
+                                    if($doc->thumb)Attachment::relateAttachmentByTable($doc->thumb,$doc->shortTableName(),'thumb',$doc->id);
+                                    if($doc->tags)refreshTag($doc->tags,$doc->shortTableName(),$doc->id,$doc->user_id);
+                                    $this->user->refreshData($this->user->user_id);
+                                    if($id==0)$this->_refreshNum('doc_uploadnum');
+                                    $result =  [
+                                        'error' => 0,
+                                        'msg' => '恭喜您,发布成功',
+                                        'data' => ['url'=>$url],
+                                        'code'=>200
+                                    ];
+                                }
+                                else
+                                {
+                                    $result =  [
+                                        'error' => 1,
+                                        'msg' => '发布失败',
+                                        'data'=>[]
+                                    ];
+                                }
+
+                            }
+                        }
+                        else
+                        {
+                            $result =  [
+                                'error' => 1,
+                                'msg' => '发布失败',
+                                'data'=>[]
+                            ];
+                        }
+
+                    }
+
+                }
+                else
+                {
+                    $result = [
+                        'error' => 1,
+                        'msg' => '请求出错,缺少必要参数',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+
+        }
+        else
+        {
+            $result = [
+                'error' => 1,
+                'msg' => '请求出错,缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        return  $result;
+
+    }
+
+    //批量上传
+    public function actionMulti()
+    {
+        $url = self::urlList('myupload');
+        $doc = new Doc();
+        $docData = new DocData();
+        if($doc->load($this->post)){
+            $result = $this->_checkRights($doc->is_ad);
+            if($result['error']==0)
+            {
+                $cat_id = $this->post['cat_id'];
+                if($cat_id)
+                {
+                    $category = Category::findOne($cat_id);
+                    $parent_cat_ids = explode(",",$category->arr_parent_ids);
+                    $doc->cat_id =$cat_id;
+                    $doc->doc_type = 1;
+                    $doc->status = 0;
+                    $doc->stars = 3;
+                    $doc->parent_cat_id = intval($parent_cat_ids[1]);
+                    $doc->root_cat_id = intval($parent_cat_ids[count($parent_cat_ids)-1]);
+                    if(!empty($category->arr_parent_ids))
+                    {
+                        $doc->cat_ids = ",".join(",",array_reverse($parent_cat_ids)).",";
+                    }
+                    else
+                    {
+                        $doc->cat_ids = ",".$doc->cat_id.",";
+                    }
+                    $doc->user_id = $this->user->user_id;
+                    $doc->user_name = $this->user->user_name;
+                    $doc->create_time = TIMESTAMP;
+                    $doc->update_time = TIMESTAMP;
+                    if(!$doc->validate())
+                    {
+                        $result =  [
+                            'error' => 1,
+                            'msg' => $doc->returnFirstError(),
+                            'data'=>[]
+                        ];
+                    }
+                    else
+                    {
+                        //tag更新
+                        if(empty($doc->tags))
+                        {
+                            $doc->tags = initTags($doc);
+                        }
+
+                        if($doc->save())
+                        {
+                            $docData->id = $doc->id;
+                            $docData->load($this->post);
+                            if(empty($docData->content))$docData->content = '';
+                            if(!$docData->validate())
+                            {
+                                $result =  [
+                                    'error' => 1,
+                                    'msg' => $docData->returnFirstError(),
+                                    'data'=>[]
+                                ];
+                            }
+                            else
+                            {
+                                if($docData->save())
+                                {
+                                    if($docData->file)Attachment::relateAttachmentByTable($docData->file,$docData->shortTableName(),'file',$doc->id);
+                                    if($doc->tags)refreshTag($doc->tags,$doc->shortTableName(),$doc->id,$doc->user_id);
+                                    $this->user->refreshData($this->user->user_id);
+                                    $this->_refreshNum('doc_uploadnum');
+                                    $result =  [
+                                        'error' => 0,
+                                        'msg' => '恭喜您,上传成功',
+                                        'data' => ['url'=>$url],
+                                        'code'=>200
+                                    ];
+                                }
+                                else
+                                {
+                                    $result =  [
+                                        'error' => 1,
+                                        'msg' => '上传失败',
+                                        'data'=>[]
+                                    ];
+                                }
+
+                            }
+                        }
+                        else
+                        {
+                            $result =  [
+                                'error' => 1,
+                                'msg' => '上传失败',
+                                'data'=>[]
+                            ];
+                        }
+                    }
+
+                }
+                else
+                {
+                    $result = [
+                        'error' => 1,
+                        'msg' => '请求出错,缺少必要参数',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+        }
+        else
+        {
+            $result = [
+                'error' => 1,
+                'msg' => '请求出错,缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+        return  $result;
+
+
+    }
+
+    private function _checkRights($is_ad=0,$id=0)
+    {
+        $userInfo = $this->userInfo;
+        if($userInfo['is_lock'])
+        {
+            return [
+                'error' => 1,
+                'msg' => '您的账户已被锁定,请联系管理员',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        if($userInfo['is_delete'])
+        {
+            return [
+                'error' => 1,
+                'msg' => '您的账户已被永久禁用,请联系管理员',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        if(!$userInfo['open_upload'])
+        {
+            return [
+                'error' => 1,
+                'msg' => '您没有上传权限,请联系管理员',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+        if($id==0)
+        {
+            //上传数量限制
+            $max_space = $userInfo['group_rights']['doc_max_space'];
+            $upload_limit_day = $userInfo['group_rights']['doc_uploadnum_day'];
+            $userNum = UserNum::find()->where("user_id=".$this->user_id." and date='".get_date(TIMESTAMP,'Y-m-d')."'")->one();
+            if($max_space==-1)
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '您已被禁止上传',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+            if(!empty($userNum))
+            {
+                if($upload_limit_day>0&&$userNum->doc_uploadnum>=$upload_limit_day)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '您已达到今日上传数量上限,上传失败',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+
+            //对推广文档进行限制判断
+            if($is_ad==1)
+            {
+                $org_vip_settings = $userInfo['org_vip_settings'];
+                if($org_vip_settings){
+                    $adDocNum = DocReal::find()->where("user_id=".$this->user_id."  and is_ad=1 and status=1")->count();
+                    if($adDocNum>=$org_vip_settings['ad_doc_num'])
+                    {
+                        return [
+                            'error' => 1,
+                            'msg' => '您已达到推广'.$this->docname.'发布数量上限,请升级VIP',
+                            'data' => [],
+                            'code'=>200
+                        ];
+                    }
+                }
+            }
+        }
+
+        return [
+            'error' => 0,
+            'msg' => '允许上传',
+            'data' => [],
+            'code'=>200
+        ];
+
+    }
+
+
+    public function actionDoctitlecheck()
+    {
+        if($this->docconfig['forbidden_title'])
+        {
+            $title = safe_replace(Yii::$app->request->get('title'));
+            $exist = DocReal::find()->where("title='".$title."' and is_delete=0")->one();
+            $exist1 = Doc::find()->where("title='".$title."' and is_delete=0")->one();
+            if($exist||$exist1){
+                $result =  [
+                    'error' => 2,
+                    'msg' => '已存在相同标题文件',
+                    'data'=>[]
+                ];
+            }
+            else
+            {
+                $result =  [
+                    'error' => 0,
+                    'msg' => '',
+                    'data'=>[]
+                ];
+            }
+        }
+        else
+        {
+            $result =  [
+                'error' => 0,
+                'msg' => '',
+                'data'=>[]
+            ];
+        }
+
+        return $result;
+    }
+
+    //内容md5值重复检测
+    public function actionDocmd5check()
+    {
+        $md5 = safe_replace(Yii::$app->request->get('md5'));
+        $title = safe_replace(Yii::$app->request->get('title'));
+        $exist = DocReal::find()->where("md5='".$md5."' and is_delete=0")->one();
+        $exist1 = Doc::find()->where("md5='".$md5."' and is_delete=0")->one();
+        if($exist||$exist1)
+        {
+            $result =  [
+                'error' => 1,
+                'msg' => '已存在相同内容文件',
+                'data'=>[]
+            ];
+        }
+        else
+        {
+
+            if(!empty($title))
+            {
+                if($this->docconfig['forbidden_title'])
+                {
+                    $exist = DocReal::find()->where("title='".$title."' and is_delete=0")->one();
+                    $exist1 = Doc::find()->where("title='".$title."' and is_delete=0")->one();
+                }
+
+                if($exist||$exist1){
+                    $result =  [
+                        'error' => 2,
+                        'msg' => '已存在相同标题文件',
+                        'data'=>[]
+                    ];
+                }
+                else
+                {
+                    //敏感词检测
+                    if($this->badwordconfig['open'])
+                    {
+                        $sesResult = sensitive($title);
+                    }
+                    else
+                    {
+                        $sesResult = [];
+                    }
+
+                    if(!empty($sesResult))
+                    {
+                        if($sesResult['log3'])
+                        {
+                            $result =  [
+                                'error' => 1,
+                                'msg' => $sesResult['log3'],
+                                'data'=>[]
+                            ];
+                        }
+                        else if($sesResult['log2'])
+                        {
+                            $result =  [
+                                'error' => 1,
+                                'msg' => $sesResult['log2'],
+                                'data'=>[]
+                            ];
+                        }
+                        else if($sesResult['log1'])
+                        {
+                            $result =  [
+                                'error' => 1,
+                                'msg' => $sesResult['log1'],
+                                'data'=>[]
+                            ];
+                        }
+                    }
+                    else
+                    {
+                        $result =  [
+                            'error' => 0,
+                            'msg' => '',
+                            'data'=>[]
+                        ];
+                    }
+
+                }
+
+            }
+            else
+            {
+                $result =  [
+                    'error' => 0,
+                    'msg' => '',
+                    'data'=>[]
+                ];
+            }
+        }
+        return $result;
+    }
+
+
+    private function _refreshNum($filed)
+    {
+
+        $userNum = UserNum::find()->where("user_id=".$this->user_id." and date='".get_date(TIMESTAMP,'Y-m-d')."'")->one();
+        if(!empty($userNum))
+        {
+
+            $userNum->$filed++;
+            $userNum->save();
+        }
+        else
+        {
+            $userNum = new UserNum();
+            $userNum->date = get_date(TIMESTAMP,'Y-m-d');
+            $userNum->user_id = $this->user_id;
+            $userNum->$filed = 1;
+            $userNum->save();
+        }
+
+    }
+
+
+}

+ 1468 - 0
api/controllers/UserController.php

@@ -0,0 +1,1468 @@
+<?php
+namespace api\controllers;
+use app\common\controllers\AController;
+use app\common\helpers\Identify;
+use app\modules\doc\models\DocPaylog;
+use app\modules\shopping\models\ShoppingOrder;
+use app\modules\admin\models\Attachment;
+use app\modules\ucenter\models\Message;
+use app\modules\ucenter\models\User;
+use app\modules\ucenter\models\UserApplyCert;
+use app\modules\ucenter\models\UserVipCoupon;
+use app\modules\ucenter\models\UserVipType;
+use app\modules\ucenter\models\UserVipOrder;
+use app\modules\ucenter\models\UserFavorite;
+use app\modules\ucenter\models\UserStars;
+use app\modules\ucenter\models\UserReport;
+use app\modules\ucenter\models\UserWithdraw;
+use app\modules\ucenter\models\MessageRead;
+use app\common\components\Wallet;
+use Yii;
+class UserController  extends AController
+{
+
+    public function init()
+    {
+        parent::init();
+
+    }
+
+    public function actionRegister()
+    {
+        extract($this->post);
+        if(!empty($user_name)&&!empty($user_pwd)&&!empty($confirm_pwd)&&!empty($nick_name)&&!empty($user_model_id)&&!empty($code))
+        {
+            $refer_page = $this->post[Yii::$app->params['referPageName']];
+            $patternEmail = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/';
+            $patternMobile = '/^1[3456789]{1}\d{9}$/';
+            if(preg_match($patternEmail,$user_name)) $toType = 'email';
+            if(preg_match($patternMobile,$user_name)) $toType='mobile';
+            //判断手机是否存在
+            if($toType=='mobile')
+            {
+                $user = User::find()->where("mobile='".$user_name."'")->one();
+                if($user)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该手机号已被使用',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+
+            //判断邮箱是否存在
+            if($toType=='email')
+            {
+                $user = User::find()->where("email='".$user_name."'")->one();
+                if($user)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该邮箱已被使用',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+
+            //判断昵称是否存在
+            if($nick_name){
+                $user = User::find()->where("nick_name='".$nick_name."'")->one();
+                if($user)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该昵称已被使用',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+
+            //校验2次密码
+            if($user_pwd){
+                if($user_pwd!=$confirm_pwd)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '两次密码不一致',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+
+            //验证码校验
+            $result = $this->checkCode($user_name,$code);
+            if(!empty($result))
+            {
+                return $result;
+            }
+
+            $max_user = User::find()->orderBy(['user_id'=>SORT_DESC])->one();
+            $user = new User();
+            $user->request_from = REQUEST_FROM;
+            $user->nick_name = $nick_name;
+            $user->user_name = $this->baseconfig['username_pre'].str_pad($max_user->user_id+1,10,'0',STR_PAD_LEFT);
+            if($toType=='mobile') $user->mobile = $user_name;
+            if($toType=='email') $user->email = $user_name;
+            $user->content_model_id = $user_model_id;
+            $user->group_id = getDefaultUserGroup($user_model_id);//默认用户组
+            $user->user_group_level = getDefaultUserGroupLevel($user_model_id);//默认用户等级
+            //分销推荐人之间关联
+            $share_no = $this->post[Yii::$app->params['shareArgName']];//用于分销的参数
+            if(!empty($share_no))
+            {
+                $shareResult = getReferIdsByShareNo($share_no);
+                $user->referer_id = $shareResult['referer_id'];
+                $user->referer_ids = $shareResult['referer_ids'];
+            }
+            else
+            {
+                $user->referer_id = 0;
+            }
+            $user->user_pwd = $this->post['user_pwd']?generatePwd($this->post['user_pwd']):'';
+            $user->register_time = TIMESTAMP;
+            if($user->save())
+            {
+                //邀请注册奖励积分
+                if($this->pointconfig['invite_register_prize']>0&&$user->referer_id)
+                {
+                    Wallet::pointChange($user->referer_id,$this->pointconfig['invite_register_prize'],'邀请注册',1,'point');
+                }
+
+                //绑定手机奖励积分
+                if($toType=='mobile'&&$this->pointconfig['bindmobile_prize']>0) {
+
+                    Wallet::pointChange($user->user_id,$this->pointconfig['bindmobile_prize'],'绑定手机',1,'point');
+
+                }
+
+                //绑定邮箱奖励积分
+                if($toType=='email'&&$this->pointconfig['bindemail_prize']>0) {
+                    Wallet::pointChange($user->user_id,$this->pointconfig['bindemail_prize'],'绑定邮箱',1,'point');
+                }
+
+                $tableName = userDetailTable($user_model_id);
+                $sql = "insert into $tableName set user_id=".$user->user_id."";
+                Yii::$app->db->createCommand($sql)->execute();
+                //百度竞价跟踪
+                $bd_vid =  \app\common\helpers\Cookie::getCookie('bd_vid');
+                if(!empty($bd_vid))
+                {
+                    $token = $this->higherconfig['reg_cpc_token'];
+                    if(!empty($token))
+                    {
+                        $cv = array(
+                            'logidUrl' => APP_URL.'?bd_vid='.$bd_vid, // 您的落地页url
+                            'newType' => 49 // 转化类型请按实际情况填写
+                        );
+                        $conversionTypes = array($cv);
+                        $baiducpc = new \app\common\components\BaiduCpc();
+                        $baiducpc->sendConvertData($token, $conversionTypes);
+                    }
+
+                }
+
+                $tokenObj = $user->generateAccessToken($user,REQUEST_FROM);
+                $access_token = $user->access_token;
+                return [
+                    'error' => 0,
+                    'msg' => '恭喜您,注册成功!页面跳转中...',
+                    'data' => ['refer_page'=>$refer_page,'access_token'=>$access_token,'access_token_expire_time'=>$tokenObj->create_time+Yii::$app->params['apiTokenExpire']],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '注册失败',
+                    'data' => ['refer_page'=>$refer_page],
+                    'code'=>200
+                ];
+            }
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '请完善表单',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //普通账号登录
+    public function actionLogin()
+    {
+        extract($this->post);
+        if(empty($user_name)||empty($user_pwd))
+        {
+            return [
+                'error' => 1,
+                'msg' => '请完善表单',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            //判断手机是否存在
+            $user = User::find()->where("mobile='".$user_name."' or email='".$user_name."'")->one();
+            if(!$user)
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '该用户不存在',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+                if($user->is_lock==1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户已被锁定,禁止登录',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                if($user->disabled==1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户已被禁用,禁止登录',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                if($user->is_delete==1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户已被永久禁用,禁止登录',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                if(empty($user->user_pwd))
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户没有设置密码,登录失败',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                if(validatePwd($user_pwd,$user->user_pwd))
+                {
+                    $tokenObj = $user->generateAccessToken($user,REQUEST_FROM);
+                    $access_token = $user->access_token;
+                    $refer_page = $this->post[Yii::$app->params['referPageName']];
+                    return [
+                        'error' => 0,
+                        'msg' => '恭喜您,登录成功',
+                        'data' => ['refer_page'=>$refer_page,'access_token'=>$access_token,'access_token_expire_time'=>$tokenObj->create_time+Yii::$app->params['apiTokenExpire']],
+                        'code'=>200
+                    ];
+                }
+                else{
+
+                    return [
+                        'error' => 1,
+                        'msg' => '账号或密码错误',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+
+            }
+        }
+
+    }
+
+    //快速登录
+    public function actionFastlogin()
+    {
+        extract($this->post);
+        if(!empty($fast_user_name)&&!empty($code))
+        {
+            $refer_page = $this->post[Yii::$app->params['referPageName']];
+            //验证码校验
+            $result = $this->checkCode($fast_user_name,$code);
+            if(!empty($result))
+            {
+                return $result;
+            }
+            $user = User::find()->where("mobile='".$fast_user_name."' or email='".$fast_user_name."'")->one();
+            if(!empty($user))
+            {
+                if($user->is_lock==1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户已被锁定,禁止登录',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                if($user->disabled==1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户已被禁用,禁止登录',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                if($user->is_delete==1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户已被永久禁用,禁止登录',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+            else
+            {
+                $patternEmail = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/';
+                $patternMobile = '/^1[3456789]{1}\d{9}$/';
+                if(preg_match($patternEmail,$fast_user_name)) $toType = 'email';
+                if(preg_match($patternMobile,$fast_user_name)) $toType='mobile';
+                $max_user = User::find()->orderBy(['user_id'=>SORT_DESC])->one();
+                $user = new User();
+                $user->request_from = REQUEST_FROM;
+                $user->nick_name = $nick_name?$nick_name:Yii::$app->params['defaultNickName'];
+                $user->user_name = $this->baseconfig['username_pre'].str_pad($max_user->user_id+1,10,'0',STR_PAD_LEFT);
+                if($toType=='mobile') $user->mobile = $fast_user_name;
+                if($toType=='email') $user->email = $fast_user_name;
+                $user->content_model_id = $user_model_id;
+                $user->group_id = getDefaultUserGroup($user_model_id);//默认用户组
+                $user->user_group_level = getDefaultUserGroupLevel($user_model_id);//默认用户等级
+                //分销推荐人之间关联
+                $share_no = $this->post[Yii::$app->params['shareArgName']];//用于分销的参数
+                if(!empty($share_no))
+                {
+                    $shareResult = getReferIdsByShareNo($share_no);
+                    $user->referer_id = $shareResult['referer_id'];
+                    $user->referer_ids = $shareResult['referer_ids'];
+                }
+                else
+                {
+                    $user->referer_id = 0;
+                }
+                $user->register_time = TIMESTAMP;
+                if($user->save())
+                {
+                    //邀请注册奖励积分
+                    if($this->pointconfig['invite_register_prize']>0&&$user->referer_id)
+                    {
+                        Wallet::pointChange($user->referer_id,$this->pointconfig['invite_register_prize'],'邀请注册',1,'point');
+                    }
+
+                    //绑定手机奖励积分
+                    if($toType=='mobile'&&$this->pointconfig['bindmobile_prize']>0) {
+
+                        Wallet::pointChange($user->user_id,$this->pointconfig['bindmobile_prize'],'绑定手机',1,'point');
+
+                    }
+                    //绑定邮箱奖励积分
+                    if($toType=='email'&&$this->pointconfig['bindemail_prize']>0) {
+                        Wallet::pointChange($user->user_id,$this->pointconfig['bindemail_prize'],'绑定邮箱',1,'point');
+                    }
+
+                    $tableName = userDetailTable($user_model_id);
+                    $sql = "insert into $tableName set user_id=".$user->user_id."";
+                    Yii::$app->db->createCommand($sql)->execute();
+                    //百度竞价跟踪
+                    $bd_vid =  \app\common\helpers\Cookie::getCookie('bd_vid');
+                    if(!empty($bd_vid))
+                    {
+                        $token = $this->higherconfig['reg_cpc_token'];
+                        if(!empty($token))
+                        {
+                            $cv = array(
+                                'logidUrl' => APP_URL.'?bd_vid='.$bd_vid, // 您的落地页url
+                                'newType' => 49 // 转化类型请按实际情况填写
+                            );
+                            $conversionTypes = array($cv);
+                            $baiducpc = new \app\common\components\BaiduCpc();
+                            $baiducpc->sendConvertData($token, $conversionTypes);
+                        }
+
+                    }
+                }
+                else
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => $user->returnFirstError(),
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+
+            $tokenObj = $user->generateAccessToken($user,REQUEST_FROM);
+            $access_token = $user->access_token;
+            return [
+                'error' => 0,
+                'msg' => '恭喜您,登录成功!页面跳转中...',
+                'data' => ['refer_page'=>$refer_page,'access_token'=>$access_token,'access_token_expire_time'=>$tokenObj->create_time+Yii::$app->params['apiTokenExpire']],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '请完善表单',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+
+    }
+
+    //重置密码
+    public function actionResetpwd()
+    {
+        extract($this->post);
+        if(!empty($hash)&&!empty($user_pwd))
+        {
+            $user_name = sys_auth($hash,'DECODE');
+            $user = User::find()->where("mobile='".$user_name."' or email='".$user_name."'")->one();
+            if(!empty($user))
+            {
+                if($user->is_lock==1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户已被锁定,禁止操作',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                if($user->disabled==1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户已被禁用,禁止操作',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                if($user->is_delete==1)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该用户已被永久禁用',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                $user->user_pwd = generatePwd($user_pwd);
+                if($user->save())
+                {
+                    return [
+                        'error' => 0,
+                        'msg' => '修改成功',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                else
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '修改失败',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '用户不存在',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '请完善表单',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+    }
+
+    //修改个人基本资料
+    public function actionChangeuserinfo()
+    {
+        if($this->user)
+        {
+            if($this->user->load($this->post)){
+                if($this->user->save())
+                {
+                    Attachment::relateAttachmentByTable($this->user->avatar,'user','avatar',$this->user->user_id);
+                }
+            }
+            return [
+                'error' => 0,
+                'msg' => '修改成功',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '修改失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+
+    //修改密码
+    public function actionChangepwd()
+    {
+        if($this->user)
+        {
+            if(validatePwd($this->post['old_pwd'],$this->user->user_pwd))
+            {
+                $this->user->user_pwd = generatePwd($this->post['user_pwd']);
+                if($this->user->save())
+                {
+                    return [
+                        'error' => 0,
+                        'msg' => '修改成功,请重新登录',
+                        'data' => ['url'=>self::urlList('logout')],
+                        'code'=>200
+                    ];
+                }
+                else
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '修改失败',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '原密码错误',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '修改失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //绑定手机或邮箱
+    public function actionBindemailorphone()
+    {
+        extract($this->post);
+        if(!empty($emailorphone)&&!empty($code))
+        {
+            $patternEmail = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/';
+            $patternMobile = '/^1[3456789]{1}\d{9}$/';
+            if(preg_match($patternEmail,$emailorphone)) $toType = 'email';
+            if(preg_match($patternMobile,$emailorphone)) $toType='mobile';
+            //验证码校验
+            $result = $this->checkCode($emailorphone,$code);
+            if(!empty($result))
+            {
+                return $result;
+            }
+            if($toType=='mobile') {
+                $user = User::find()->where("mobile='".$emailorphone."'")->one();
+                if($user)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该手机号已被使用',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                //绑定手机奖励积分
+                if($this->pointconfig['bindmobile_prize']>0)
+                {
+                    Wallet::pointChange($this->user_id,$this->pointconfig['bindmobile_prize'],'绑定手机',1,'point');
+                }
+
+                $this->user->mobile = $emailorphone;
+            }
+            if($toType=='email') {
+                $user = User::find()->where("email='".$emailorphone."'")->one();
+                if($user)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '该邮箱已被使用',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                //绑定邮箱积分奖励
+                if($this->pointconfig['bindemail_prize']>0)
+                {
+                    Wallet::pointChange($this->user_id,$this->pointconfig['bindemail_prize'],'绑定邮箱',1,'point');
+                }
+                $this->user->email = $emailorphone;
+            }
+            if($this->user->save())
+            {
+                return [
+                    'error' => 0,
+                    'msg' => '绑定成功',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '修改失败',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '请完善表单',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+
+    //认证申请
+    public function actionCert()
+    {
+        $cert_type = intval($this->post['cert_type']);
+        if(!empty($cert_type))
+        {
+            $model = UserApplyCert::find()->where("user_id=".$this->user->user_id." and cert_type=$cert_type")->one();
+            if(empty($model)){
+                $model = new UserApplyCert();
+                $model->create_time = TIMESTAMP;
+                $model->cert_type = $cert_type;
+            }
+            $model->user_id = $this->user->user_id;
+            $model->cert_type = $cert_type;
+            $model->cert_info = array2string($this->post['cert_info']);
+            $model->process = 0;
+            $model->process_result = 0;
+            $model->update_time = TIMESTAMP;
+            if($model->save())
+            {
+                Attachment::relateAttachmentByTable($this->post['cert_info']['idcard_img'],'user_apply_cert','idcard_img',$model->id);
+                Attachment::relateAttachmentByTable($this->post['cert_info']['idcard_img_v'],'user_apply_cert','idcard_img_v',$model->id);
+                Attachment::relateAttachmentByTable($this->post['cert_info']['com_idcard'],'user_apply_cert','com_idcard_img',$model->id);
+                $msgdata = [
+                    'error' => 0,
+                    'msg' => '操作成功',
+                    'data'=>[],
+                    'code'=>'200',
+                ];
+            }
+            else
+            {
+                $msgdata = [
+                    'error' =>1,
+                    'msg' => $model->returnFirstError(),
+                    'data'=>[],
+                    'code'=>'200',
+                ];
+            }
+
+            return $msgdata;
+
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '请完善表单',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //删除认证申请
+    public function actionDelcert()
+    {
+        $cert_type = intval($this->post['cert_type']);
+        if(!empty($cert_type))
+        {
+            $model = UserApplyCert::find()->where("user_id=".$this->user->user_id." and cert_type=$cert_type")->one();
+            if(empty($model))
+            {
+                $msgdata = [
+                    'error' =>1,
+                    'msg' => '操作失败',
+                    'data'=>[],
+                    'code'=>'200',
+                ];
+            }
+            else
+            {
+                if($model->delete())
+                {
+                    Attachment::releaseAttachmentByTable($model->id,'user_apply_cert','idcard_img');
+                    Attachment::releaseAttachmentByTable($model->id,'user_apply_cert','idcard_img_v');
+                    Attachment::releaseAttachmentByTable($model->id,'user_apply_cert','com_idcard_img');
+                    $msgdata = [
+                        'error' => 0,
+                        'msg' => '操作成功',
+                        'data'=>[],
+                        'code'=>'200',
+                    ];
+                }
+                else
+                {
+                    $msgdata = [
+                        'error' =>1,
+                        'msg' => '操作失败',
+                        'data'=>[],
+                        'code'=>'200',
+                    ];
+                }
+            }
+            return $msgdata;
+
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '请完善表单',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+
+    //兑换VIP
+    public function actionUsevipcoupon()
+    {
+        $coupon_no = intval($this->post['coupon_no']);
+        if(!empty($coupon_no))
+        {
+            $userVipCoupon = UserVipCoupon::find()->where("coupon_no='".$coupon_no."'")->one();
+
+            if($userVipCoupon&&empty($userVipCoupon->use_time)&&empty($userVipCoupon->user_id))
+            {
+                //VIP类型
+                $userVipType = UserVipType::findOne($userVipCoupon->vip_type);
+                $vipSettings = string2array($userVipType->settings);
+                //创建订单
+                $order = new ShoppingOrder();
+                $order->user_id = $this->user_id;
+                $order->order_sn = getUniOrderNo();
+                $order->pay_credit = 'uservipcoupon_'.$userVipCoupon->vip_type;
+                $order->total_price = $userVipCoupon->payed_money;
+                $order->discount_price = 0;
+                $order->remark = '兑换'.$userVipType->title;
+                $order->order_type = 3;
+                $order->status = 1;
+                $order->pay_time = TIMESTAMP;
+                $order->request_from = REQUEST_FROM;
+                $order->create_time = TIMESTAMP;
+                if($order->save())
+                {
+                    $userVipOrder = new UserVipOrder();
+                    $userVipOrder->order_id = $order->order_id;
+                    $userVipOrder->user_id = $this->user_id;
+                    $userVipOrder->vip_type = $userVipCoupon->vip_type;
+                    $userVipOrder->money = $userVipCoupon->payed_money;
+                    $userVipOrder->days = $userVipType->days;
+                    $userVipOrder->settings = $userVipType->settings;
+                    $userVipOrder->expire_time = $userVipType->forever==1?0:TIMESTAMP+$userVipType->days*24*3600;
+                    $userVipOrder->create_time = TIMESTAMP;
+                    $userVipOrder->status = 1;
+                    if($userVipOrder->save())
+                    {
+                        $userVipCoupon->user_id = $this->user_id;
+                        $userVipCoupon->used = 1;
+                        $userVipCoupon->use_time = TIMESTAMP;
+                        $userVipCoupon->save();
+                        //如果有赠送金币
+                        if(intval($vipSettings['coin_num'])>0)
+                        {
+                            Wallet::coinChange($this->user_id,$vipSettings['coin_num'],'开通会员赠送金币',1);
+                        }
+                        return [
+                            'error' => 0,
+                            'msg' => '兑换成功',
+                            'data' => [],
+                            'code'=>200
+                        ];
+                    }
+                    else
+                    {
+                        return [
+                            'error' => 1,
+                            'msg' => '兑换失败',
+                            'data' => [],
+                            'code'=>200
+                        ];
+                    }
+                }
+                else
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '兑换失败',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+
+
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '无效兑换码',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '缺少兑换码',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+    }
+
+    //加入收藏
+    public function actionDofavor()
+    {
+
+        extract($this->post);
+        if(empty($table_name)||empty($data_id)||empty($tips))
+        {
+            return [
+                'error' => 1,
+                'msg' => '缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+
+        }
+        else
+        {
+            $primaryKey = getPrikeyByTableName($table_name);
+            $model = UserFavorite::find()->where("user_id=".$this->user_id." and table_name='".$table_name."' and data_id=".$data_id)->one();
+            if($model)
+            {
+                if($primaryKey)
+                {
+                    //关注用户时候的特殊处理
+                    if($table_name=='user')
+                    {
+                        $userInfo = Identify::getUserInfo($data_id);
+                        $user_table = str_replace(Yii::$app->db->tablePrefix,'',userDetailTable($userInfo['content_model_id']));
+                        $sqlbuf = "update {{%".$user_table."}} set fans_num=fans_num-1 where $primaryKey = ".$data_id."";
+                    }
+                    else
+                    {
+                        $sqlbuf = "update {{%".$table_name."}} set favors=favors-1 where $primaryKey = ".$data_id."";
+                    }
+                    Yii::$app->db->createCommand($sqlbuf)->execute();
+                }
+                $model->delete();
+                return [
+                    'error' => 0,
+                    'msg' => '您已取消'.$tips,
+                    'data' => ['text'=>$tips],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+                $model = new UserFavorite();
+                $model->table_name = $table_name;
+                $model->data_id = $data_id;
+                $model->cat_id = intval($cat_id);
+                $model->user_id = $this->user_id;
+                $model->create_time = TIMESTAMP;
+                if($model->save())
+                {
+                    if($primaryKey)
+                    {
+                        //关注用户时候的特殊处理
+                        if($table_name=='user')
+                        {
+                            $userInfo = Identify::getUserInfo($data_id);
+                            $user_table = str_replace(Yii::$app->db->tablePrefix,'',userDetailTable($userInfo['content_model_id']));
+
+                            $sqlbuf = "update {{%".$user_table."}} set fans_num=fans_num+1 where $primaryKey = ".$data_id."";
+
+                        }
+                        else
+                        {
+                            $sqlbuf = "update {{%".$table_name."}} set favors=favors+1 where $primaryKey = ".$data_id."";
+                        }
+                        Yii::$app->db->createCommand($sqlbuf)->execute();
+                    }
+                    return [
+                        'error' => 0,
+                        'msg' => $tips.'成功',
+                        'data' => ['text'=>'已'.$tips],
+                        'code'=>200
+                    ];
+                }
+                else
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '操作失败',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+
+        }
+
+    }
+
+    //评分
+    public function actionDostars()
+    {
+        extract($this->post);
+        if(empty($table_name)||empty($data_id))
+        {
+            return [
+                'error' => 1,
+                'msg' => '缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+
+        }
+        else
+        {
+            $model = UserStars::find()->where("user_id=".$this->user_id." and table_name='".$this->post['table_name']."' and data_id=".$this->post['data_id'])->one();
+            if($model)
+            {
+                return [
+                    'error' => 0,
+                    'msg' => '您已提交过评分',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+                if($table_name=='doc_real')
+                {
+                    $payed = DocPaylog::find()->where("user_id=".$this->user_id." and doc_id=".$this->post['data_id'])->exists();
+                    if(!$payed){
+                        return [
+                            'error' => 0,
+                            'msg' => '您还没有下载该'.$this->docname.',暂无评分权限',
+                            'data' => [],
+                            'code'=>200
+                        ];
+                    }
+                }
+
+                $model = new UserStars();
+                $model->table_name = $table_name;
+                $model->data_id = $data_id;
+                $model->user_id = $this->user_id;
+                $model->score  = $this->post['stars'];
+                $model->create_time = TIMESTAMP;
+                if($model->save())
+                {
+                    $avgScore = UserStars::find()->where("table_name='".$this->post['table_name']."' and data_id=".$this->post['data_id'])->average('score');
+                    $stars = intval($avgScore);
+                    $primaryKey = getPrikeyByTableName($table_name);
+                    $sqlbuf = "update {{%".$table_name."}} set stars=$stars where $primaryKey = ".$data_id."";
+                    Yii::$app->db->createCommand($sqlbuf)->execute();
+                    return [
+                        'error' => 0,
+                        'msg' => '评分成功',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                else
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '评分失败',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+            }
+        }
+    }
+
+    //举报侵权
+    public function actionDoreport()
+    {
+        extract($this->post);
+        if(empty($table_name)||empty($data_id)||empty($type)||empty($description)||empty($contact)||empty($from_url))
+        {
+            return [
+                'error' => 1,
+                'msg' => '缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+
+        }
+        else
+        {
+
+            $model = UserReport::find()->where("user_id=".$this->user_id." and table_name='".$this->post['table_name']."' and data_id=".$this->post['data_id'])->one();
+            if($model)
+            {
+                return [
+                    'error' => 0,
+                    'msg' => '您已举报过,请勿重复提交',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+
+                $model = new UserReport();
+                $model->table_name = $table_name;
+                $model->data_id = $data_id;
+                $model->user_id = $this->user_id;
+                $model->type = $type;
+                $model->contact = $contact;
+                $model->description = $description;
+                $model->from_url = $from_url;
+                $model->create_time = TIMESTAMP;
+                if($model->save())
+                {
+                    return [
+                        'error' => 0,
+                        'msg' => '举报成功',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                else
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => $model->returnFirstError(),
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+
+            }
+        }
+    }
+
+    //积分兑换金币
+    public function actionPointswitch()
+    {
+        extract($this->post);
+        if(empty($coin_num))
+        {
+            return [
+                'error' => 1,
+                'msg' => '缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+
+        }
+        else
+        {
+            $point_num = $this->pointconfig['point2coin_rate']*$coin_num;
+            if($this->userInfo['point']<$point_num)
+            {
+                return [
+                    'error' => 1,
+                    'msg' => $this->pointconfig['point_name'].'不足,兑换失败',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+                Wallet::pointChange($this->user_id,$point_num,'兑换'.$this->coinconfig['coin_name'],2,'point');
+                Wallet::coinChange($this->user_id,$coin_num,'兑换'.$this->coinconfig['coin_name'],1,'coin');
+                return [
+                    'error' => 0,
+                    'msg' => '兑换成功',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+
+        }
+    }
+
+    //消息标记已读
+    public function actionReadmsg()
+    {
+        $ids = Yii::$app->request->get('ids');
+        $ids = !empty($ids)?explode(",",$ids):[$this->get['m_id']];
+        if(!empty($ids)){
+            foreach($ids as $m_id){
+                $message = Message::findOne($m_id);
+                if(empty($message))continue;
+                if($message->message_type==0&&$this->user_id!=$message->to_user)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '暂无操作权限',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+
+                if($message->message_type==1)
+                {
+                    $messageRead = MessageRead::find()->where("user_id=".$this->user_id." and m_id=".$m_id)->one();
+                    if(empty($messageRead))
+                    {
+                        $messageRead = new MessageRead();
+                        $messageRead->user_id = $this->user_id;
+                        $messageRead->m_id = $m_id;
+                        $messageRead->read_time = TIMESTAMP;
+                        $messageRead->save();
+                    }
+                }
+                else
+                {
+                    $message->have_read = 1;
+                    $message->save();
+                }
+
+            }
+            return [
+                'error' => 0,
+                'msg' => '操作成功',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '操作失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //删除消息
+    public function actionDelmsg()
+    {
+        $ids = Yii::$app->request->get('ids');
+        $ids = !empty($ids)?explode(",",$ids):[$this->get['m_id']];
+        if(!empty($ids)){
+            foreach($ids as $m_id){
+                $message = Message::findOne($m_id);
+                if(empty($message))continue;
+                if($message->message_type==0&&$this->user_id!=$message->to_user)
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '暂无操作权限',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+
+                if($message->message_type==1)
+                {
+                    $messageRead = MessageRead::find()->where("user_id=".$this->user_id." and m_id=".$m_id)->one();
+                    if(empty($messageRead))
+                    {
+                        $messageRead = new MessageRead();
+                        $messageRead->user_id = $this->user_id;
+                        $messageRead->m_id = $m_id;
+                        $messageRead->read_time = TIMESTAMP;
+                        $messageRead->is_delete = 1;
+                    }
+                    else
+                    {
+                        $messageRead->is_delete = 1;
+                    }
+                    $messageRead->save();
+                }
+                else
+                {
+                    $message->to_delete = 1;
+                    $message->save();
+                }
+
+            }
+            return [
+                'error' => 0,
+                'msg' => '操作成功',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '操作失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //设置提现账户
+    public function actionSetbank()
+    {
+        $tableName = userDetailTable($this->userInfo['content_model_id']);
+        if($this->post['alipay_name']&&$this->post['alipay_account'])
+        {
+            $sql = "update  $tableName set alipay_account='".$this->post['alipay_account']."',alipay_name='".$this->post['alipay_name']."' where user_id=".$this->user_id."";
+            Yii::$app->db->createCommand($sql)->execute();
+            return [
+                'error' => 0,
+                'msg' => '操作成功',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else  if($this->post['bank_real_name']&&$this->post['bank_name']&&$this->post['bank_no'])
+        {
+            $sql = "update  $tableName set bank_real_name='".$this->post['bank_real_name']."',bank_name='".$this->post['bank_name']."',bank_no='".$this->post['bank_no']."' where user_id=".$this->user_id."";
+            Yii::$app->db->createCommand($sql)->execute();
+            return [
+                'error' => 0,
+                'msg' => '操作成功',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '操作失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //申请提现
+    public function actionWithdraw()
+    {
+        $money = $this->post['money'];
+        $bank_type = $this->post['bank_type'];
+        if($money&&$bank_type)
+        {
+            if($money<$this->withdrawconfig['min_money'])
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '操作失败,最低提现金额'.$this->withdrawconfig['min_money'].'元',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+
+            if($money>$this->userInfo['money'])
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '操作失败,余额不足',
+                    'data' => $this->post,
+                    'code'=>200
+                ];
+            }
+
+            //处理提现逻辑
+            $bankInfo = getWithdrawBank($this->userInfo,$bank_type);
+            $fee = $money*($this->withdrawconfig['fee']/100);
+            $real_money = $money-$fee;
+            $withdraw = new UserWithdraw();
+            $withdraw->user_id = $this->user_id;
+            $withdraw->title = $bankInfo['title'];
+            $withdraw->real_name = $bankInfo['real_name'];
+            $withdraw->account = $bankInfo['account'];
+            $withdraw->money = $money;
+            $withdraw->real_money = $real_money;
+            $withdraw->fee = $fee;
+            $withdraw->create_time = TIMESTAMP;
+            if($withdraw->save())
+            {
+                //扣除用户可用余额
+                Wallet::moneyChange($this->user_id,$money,'申请提现',2);
+                return [
+                    'error' => 0,
+                    'msg' => '操作成功',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '操作失败',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '操作失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+    //切换个人主页开启状态
+    public function actionSwitchhome()
+    {
+        if($this->user->open_home==1)
+        {
+            $this->user->open_home = 0;
+            $text = '开启';
+        }
+        else
+        {
+            $this->user->open_home = 1;
+            $text = '关闭';
+        }
+        $this->user->save();
+        return [
+            'error' => 0,
+            'msg' => '操作成功',
+            'data' => ['text'=>$text],
+            'code'=>200
+        ];
+    }
+
+    //金币兑换现金
+    public function actionCoinswitch()
+    {
+        extract($this->post);
+        if(empty($coin_num))
+        {
+            return [
+                'error' => 1,
+                'msg' => '缺少必要参数',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            $money = $this->userInfo['group_rights']['income_rate']*$coin_num;
+            if($this->userInfo['coin_income']<$coin_num)
+            {
+                return [
+                    'error' => 1,
+                    'msg' => $this->coinconfig['coin_name'].'不足,兑换失败',
+                    'data' => [],
+                    'code'=>200
+                ];
+            }
+            else
+            {
+                if($coin_num<$this->coinconfig['min_trans_coin'])
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '每次至少兑换'.$this->coinconfig['min_trans_coin'].$this->coinconfig['coin_name'],
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+                else
+                {
+                    Wallet::coinChange($this->user_id,$coin_num,'兑换现金',2,'coin_income');
+                    Wallet::moneyChange($this->user_id,$money,$this->coinconfig['coin_name'].'兑换',1);
+                    return [
+                        'error' => 0,
+                        'msg' => '兑换成功',
+                        'data' => [],
+                        'code'=>200
+                    ];
+                }
+
+            }
+
+        }
+    }
+
+}

+ 133 - 0
api/controllers/WriterController.php

@@ -0,0 +1,133 @@
+<?php
+namespace api\controllers;
+use app\common\controllers\AController;
+use app\modules\admin\models\Attachment;
+use app\modules\admin\models\AttachmentTrash;
+use app\modules\doc\models\Doc;
+use app\modules\doc\models\DocData;
+use app\modules\doc\models\DocPackfile;
+use app\modules\doc\models\DocReal;
+use app\modules\doc\models\DocRealData;
+use Yii;
+class WriterController  extends AController
+{
+
+    public function init()
+    {
+        parent::init();
+    }
+
+    //删除文档草稿箱
+    public function actionDeldraftdoc()
+    {
+        $ids = Yii::$app->request->get('ids');
+        $ids = !empty($ids)?explode(",",$ids):[$this->get['id']];
+        if(!empty($ids)){
+            foreach($ids as $id){
+                $model = Doc::findOne($id);
+                $modelData = DocData::findOne($id);
+                if($model&&$modelData)
+                {
+                    //判断有无操作权限
+                    $checkResult = $this->checkRights($this->user_id,$model);
+                    if($checkResult['error']==1)continue;
+                    $imgcode = string2array($modelData->imgcode);
+                    $h5code = string2array($modelData->h5code);
+                    $file = $modelData->file;
+                    $path = getFileWorkPath($file);
+                    if($model->delete()&&$modelData->delete())
+                    {
+                        Attachment::releaseAttachmentByTable($id,$model->shortTableName(),'thumb');
+                        Attachment::releaseAttachmentByTable($id,$modelData->shortTableName(),'file');
+                        $trash = new AttachmentTrash();
+                        $trash->file_path = $path;
+                        $trash->is_oss = Yii::$app->params['oss']['OPEN_OSS'];
+                        $trash->create_time = TIMESTAMP;
+                        $trash->save();
+                        if(is_array($imgcode))foreach($imgcode as $img)
+                        {
+                            $trash = new AttachmentTrash();
+                            $trash->file_path = $img;
+                            $trash->is_oss = Yii::$app->params['oss']['OPEN_OSS'];
+                            $trash->create_time = TIMESTAMP;
+                            $trash->save();
+                        }
+                        if(is_array($h5code))foreach($h5code as $h5)
+                        {
+                            $trash = new AttachmentTrash();
+                            $trash->file_path = $h5;
+                            $trash->is_oss = Yii::$app->params['oss']['OPEN_OSS'];
+                            $trash->create_time = TIMESTAMP;
+                            $trash->save();
+                        }
+                        $packFileList = DocPackfile::find()->where("doc_id=$id")->all();
+                        if(is_array($packFileList))foreach($packFileList as $packFile)
+                        {
+                            $trash = new AttachmentTrash();
+                            $trash->file_path = $packFile->path;
+                            $trash->is_oss = Yii::$app->params['oss']['OPEN_OSS'];
+                            $trash->create_time = TIMESTAMP;
+                            $trash->save();
+                        }
+                    }
+                }
+            }
+            return [
+                'error' => 0,
+                'msg' => '操作成功',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '操作失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+
+    //删除文档
+    public function actionDeldoc()
+    {
+        $ids = Yii::$app->request->get('ids');
+        $ids = !empty($ids)?explode(",",$ids):[$this->get['id']];
+        if(!empty($ids)){
+            foreach($ids as $id){
+                $model = DocReal::findOne($id);
+                $modelData = DocRealData::findOne($id);
+                if($model&&$modelData)
+                {
+                    //判断有无操作权限
+                    $checkResult = $this->checkRights($this->user_id,$model);
+                    if($checkResult['error']==1)continue;
+                    $model->is_delete = 1;
+                    $model->save();
+                }
+            }
+            return [
+                'error' => 0,
+                'msg' => '操作成功',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '操作失败',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+
+    }
+
+
+}

+ 81 - 0
api/index.php

@@ -0,0 +1,81 @@
+<?php
+ini_set('pcre.backtrack_limit', 999999999);
+setlocale(LC_ALL, 'zh_CN.UTF-8');
+defined('TIMESTAMP') or define('TIMESTAMP',time());//start time of request
+defined('SYS_START_TIME') or define('SYS_START_TIME',microtime());//start time of request
+define('IN_KIIVO', true);//make the file be the only import of the app
+//KIIVOKMS框架目录,如:D:\phpStudy\PHPTutorial\WWW\kiivokms\
+defined('BASE_PATH') or define('BASE_PATH', dirname(dirname(__FILE__).DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR);
+//应用目录,如:D:\phpStudy\PHPTutorial\WWW\kiivokms\web\
+defined('APP_PATH') or define('APP_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
+$config = require __DIR__ . '/../config/config.php';
+include_once __DIR__ . '/../common/functions/global.php';
+include_once __DIR__ . '/../common/functions/dir.php';
+include_once __DIR__ . '/../common/functions/cus.php';
+defined('MYIP') or define('MYIP',ip());
+$domain = require_config('domain.php');
+defined('COOKIE_DOMAIN') or define('COOKIE_DOMAIN', $domain['cookie_domain']);//定义cookie全局域
+define('WAP_URL', $domain['wap_url']);//WAP站域名
+define('WEB_URL', $domain['web_url']);//PC站域名
+define('API_URL', $domain['api_url']);//接口域名
+define('UPLOAD_DOMAIN', $domain['upload_domain']);//附件域名
+define('CORS_DOMAIN', $domain['cors_origin']);//跨域域名
+require __DIR__ . '/../vendor/autoload.php';
+require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
+//主机协议
+define('SITE_PROTOCOL', isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://');
+//当前访问的主机名(格式:www.xxx.cn)
+define('SITE_URL', (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''));
+/*****************判断是否手机端***********************/
+if(strpos(WAP_URL,SITE_PROTOCOL.SITE_URL)!==false||check_mobile())
+{
+
+    defined('IN_WAP') or define('IN_WAP',TRUE);
+    if(check_baiduapp())
+    {
+        defined('REQUEST_FROM') or define('REQUEST_FROM',3);
+    }
+    else if(check_wxapp()){
+        defined('REQUEST_FROM') or define('REQUEST_FROM',4);
+    }
+    else if(check_micromsg())
+    {
+        defined('REQUEST_FROM') or define('REQUEST_FROM',5);
+    }
+    else
+    {
+        defined('REQUEST_FROM') or define('REQUEST_FROM',2);
+    }
+    defined('APP_URL') or define('APP_URL',WAP_URL);
+
+}
+else
+{
+    defined('IN_WAP') or define('IN_WAP',FALSE);
+    defined('REQUEST_FROM') or define('REQUEST_FROM',1);
+    defined('APP_URL') or define('APP_URL',WEB_URL);
+}
+defined("DEVICE_TYPE") or define("DEVICE_TYPE",get_device_type());
+$config = array_merge_recursive(require_config('api.php'), $config);
+$config['params']['cors_origin'] = $domain['cors_origin'];
+$params = $config['params'];
+/********************二次定义params结束*****************************************/
+defined('UPLOAD_PATH') or define('UPLOAD_PATH',$config['params']['uploadPath']);
+defined('THUMB_PATH') or define('THUMB_PATH',$config['params']['thumbPath']);
+defined('UPLOAD_URL') or define('UPLOAD_URL',$config['params']['uploadUrl']);
+defined('HTML_PATH') or define('HTML_PATH',$config['params']['htmlPath']);
+defined('CACHE_PATH') or define('CACHE_PATH',$config['params']['cachePath']);
+//定义网页编码
+defined('CHARSET') or define('CHARSET',$config['params']['charSet']);
+//定义时区
+defined('TIME_ZONE') or define('TIME_ZONE',$config['params']['timeZone']);
+//加密因子
+defined('AUTH_KEY') or define('AUTH_KEY',$config['params']['authKey']);
+//判断来源合法性
+$reurl = $_SERVER["HTTP_REFERER"]; //获取完整的来路URL
+$str = explode("//",$reurl); //去掉http://
+$strdomain = explode("/",$str[1]);  // 以“/”分开成数组
+$redomain = $str[0].'//'.trim($strdomain[0],"/");//取第一个“/”以前的字符
+if(in_array($redomain,$domain['cors_origin']))header("Access-Control-Allow-Origin: *");
+ob_clean();
+(new yii\web\Application($config))->run();

+ 0 - 0
api/nginx.htaccess


+ 30 - 0
assets/BootstrapAsset.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace app\assets;
+use yii\web\AssetBundle;
+class BootstrapAsset extends AssetBundle
+{
+    //资源文件的源文件位置
+    public $sourcePath = '@app/static/core';
+    //当前事例引入的文件
+    public $css = [
+        'css/bootstrap.min.css',
+    ];
+    public $js = [
+        'libs/bootstrap/js/bootstrap.bundle.min.js',
+    ];
+    public $jsOptions = ['position' => \yii\web\View::POS_HEAD];
+    //没有依赖
+    public $depends = [];
+
+    static function getInitCls()
+    {
+        static $initCls = NULL;
+        if(!isset($initCls)) $initCls = new BootstrapAsset();
+        return $initCls;
+    }
+
+
+
+
+}

+ 29 - 0
assets/CoreAsset.php

@@ -0,0 +1,29 @@
+<?php
+namespace app\assets;
+use yii\web\AssetBundle;
+class CoreAsset extends AssetBundle
+{
+    //资源文件的源文件位置
+    public $sourcePath = '@app/static/core';
+    //当前事例引入的文件
+    public $css = [
+
+    ];
+    public $js = [
+
+    ];
+    //没有依赖
+    public $depends = [
+    ];
+
+    static function getInitCls()
+    {
+        static $initCls = NULL;
+        if(!isset($initCls)) $initCls = new CoreAsset();
+        return $initCls;
+    }
+
+
+
+
+}

+ 46 - 0
assets/PcAsset.php

@@ -0,0 +1,46 @@
+<?php
+namespace app\assets;
+use app\modules\admin\models\Config;
+use yii\web\AssetBundle;
+use Yii;
+
+class PcAsset extends AssetBundle
+{
+    //资源文件的源文件位置
+    public $sourcePath;
+    //当前事例引入的文件
+    public $css = [
+
+    ];
+    public $js = [
+
+    ];
+    //没有依赖
+    public $depends = [
+    ];
+    public function init()
+    {
+        parent::init();
+        $baseconfigResult = Config::find()->where("name='baseconfig'")->one();
+        $baseconfig = string2array($baseconfigResult->value);
+        if(!empty($baseconfig['style']))
+        {
+            $this->sourcePath =  Yii::$app->params['themePath'].$baseconfig['theme'].'/pc/assets/'.$baseconfig['style'];
+
+        }
+        else
+        {
+            $this->sourcePath =  Yii::$app->params['themePath'].$baseconfig['theme'].'/pc/assets';
+        }
+    }
+    static function getInitCls()
+    {
+        static $initCls = NULL;
+        if(!isset($initCls)) $initCls = new PcAsset();
+        return $initCls;
+    }
+
+
+
+
+}

+ 35 - 0
assets/PluginsAsset.php

@@ -0,0 +1,35 @@
+<?php
+namespace app\assets;
+use yii\web\AssetBundle;
+class PluginsAsset extends AssetBundle
+{
+    //资源文件的源文件位置
+    public $sourcePath = '@app/static/plugins';
+    //当前事例引入的文件
+    public $css = [
+        'layui/css/layui.css',
+    ];
+    public $js = [
+        'layui/layui.js',
+        'layer_mobile/layer_mobile.js',
+        'jquery-cascading-dropdown/jquery.cascadingdropdown.js',
+    ];
+    public $jsOptions = ['position' => \yii\web\View::POS_HEAD];
+    //public $jsOptions = [];
+    //没有依赖
+    public $depends = [
+    ];
+
+
+
+    static function getInitCls()
+    {
+        static $initCls = NULL;
+        if(!isset($initCls)) $initCls = new PluginsAsset();
+        return $initCls;
+    }
+
+
+
+
+}

+ 46 - 0
assets/WapAsset.php

@@ -0,0 +1,46 @@
+<?php
+namespace app\assets;
+use app\modules\admin\models\Config;
+use yii\web\AssetBundle;
+use Yii;
+
+class WapAsset extends AssetBundle
+{
+    //资源文件的源文件位置
+    public $sourcePath;
+    //当前事例引入的文件
+    public $css = [
+
+    ];
+    public $js = [
+
+    ];
+    //没有依赖
+    public $depends = [
+    ];
+    public function init()
+    {
+        parent::init();
+        $wapconfigResult = Config::find()->where("name='wapconfig'")->one();
+        $wapconfig = string2array($wapconfigResult->value);
+        if(!empty($wapconfig['style']))
+        {
+            $this->sourcePath =  Yii::$app->params['themePath'].$wapconfig['theme'].'/h5/assets/'.$wapconfig['style'];
+
+        }
+        else
+        {
+            $this->sourcePath =  Yii::$app->params['themePath'].$wapconfig['theme'].'/h5/assets';
+        }
+    }
+    static function getInitCls()
+    {
+        static $initCls = NULL;
+        if(!isset($initCls)) $initCls = new WapAsset();
+        return $initCls;
+    }
+
+
+
+
+}

+ 36 - 0
codeception.yml

@@ -0,0 +1,36 @@
+actor: Tester
+bootstrap: _bootstrap.php
+paths:
+    tests: tests
+    log: tests/_output
+    data: tests/_data
+    helpers: tests/_support
+settings:
+    memory_limit: 1024M
+    colors: true
+modules:
+    config:
+        Yii2:
+            configFile: 'config/test.php'
+
+# To enable code coverage:
+#coverage:
+#    #c3_url: http://localhost:8080/index-test.php/
+#    enabled: true
+#    #remote: true
+#    #remote_config: '../codeception.yml'
+#    whitelist:
+#        include:
+#            - models/*
+#            - controllers/*
+#            - commands/*
+#            - mail/*
+#    blacklist:
+#        include:
+#            - assets/*
+#            - config/*
+#            - runtime/*
+#            - vendor/*
+#            - views/*
+#            - web/*
+#            - tests/*

+ 77 - 0
commands/MailerController.php

@@ -0,0 +1,77 @@
+<?php
+namespace app\commands;
+use yii\console\Controller;
+use app\modules\doc\models\DocReal;
+use app\modules\doc\models\DocRealData;
+use app\modules\doc\models\DocMail;
+use app\common\components\Emailer;
+use Yii;
+class MailerController extends Controller
+{
+    public $logFile;
+    public function init()
+    {
+        parent::init();
+        $this->logFile = Yii::getAlias('@runtime').DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'mailer_'.date("Ymd").'.log';
+    }
+
+    public function actionIndex()
+    {
+        $task = DocMail::find()->where("status=0")->orderBy(['id'=>SORT_ASC])->one();
+        if(empty($task))return;
+        $doc = DocReal::findOne($task->doc_id);
+        $docData = DocRealData::findOne($task->doc_id);
+        //处理文件
+        $docConfigResult = Yii::$app->db->createCommand("select * from {{%config}} where name='doc'")->queryOne();
+        $docConfig = string2array($docConfigResult['value']);
+        $file = sys_auth($docData->file,'DECODE',$docData->hash);
+
+        if($doc->doc_type==1)
+        {
+            $tempFile = locateFile(getFileUrl($file),'download');
+            $file = initBigfileTorent($tempFile,$doc,$docConfig);
+            $bigFileTip = '【下载说明】';
+        }
+        else if($doc->doc_type==3)//网盘资源
+        {
+            $file = initPanfile($doc,$docConfig);
+            $bigFileTip = '【提取说明】';
+        }
+        else if($doc->doc_type==2)//合辑文档
+        {
+            $allsize = 0;
+            $docIds = Yii::$app->db->createCommand("SELECT doc_id FROM {{%doc_col}} where col_id=".$doc->id)->queryColumn();
+            $resultList = DocReal::findAll($docIds);
+            foreach($resultList as $result)
+            {
+                $allsize += $result->filesize;
+                $contentList[] = array('title'=>$result->title,'ext'=>$result->ext,'file'=>sys_auth($result->data->file,'DECODE',$result->data->hash));
+            }
+            $tempFile = locateColFile($doc,$contentList);
+            $file = initBigfileTorent($tempFile,$doc,$docConfig);
+            $bigFileTip = '【下载说明】';
+        }
+        $msg = https_request($file);
+        $mailer = new Emailer();
+        if($mailer->send('download',$task->email,['title'=>$doc->title,'msg'=>$msg]))
+        {
+            $task->status = 1;
+            $task->send_time = time();
+            $task->save();
+            $this->_saveLog($task->email,$doc);
+        }
+
+    }
+
+    //写日志
+    private function _saveLog($email,$doc)
+    {
+        file_put_contents($this->logFile,$email."(".$doc->title."-".get_date(time(),'Y-m-d H:i:s').")\r\n",FILE_APPEND);
+    }
+
+
+
+
+
+
+}

+ 1635 - 0
commands/TransController.php

@@ -0,0 +1,1635 @@
+<?php
+namespace app\commands;
+use yii\console\Controller;
+use app\common\components\Unzip;
+use Smalot\PdfParser\Parser;
+use Yii;
+class TransController extends Controller
+{
+    public $logFile;
+    public $transferDir;
+    public $transferUrl;
+    public $ossConfig;
+    public $transferConfig;
+    public $attachmentConfig;
+    public $imgConfig;
+    public $oss;
+    public function init()
+    {
+        parent::init();
+        $this->logFile = Yii::getAlias('@runtime').DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'cmdtransfer_'.date("Ymd").'.log';
+        $this->transferDir = UPLOAD_PATH.'transfer'.DIRECTORY_SEPARATOR;
+        $this->transferUrl = UPLOAD_URL.'transfer/';
+        $ossConfigResult = Yii::$app->db->createCommand("select * from {{%config}} where name='oss'")->queryOne();
+        $this->ossConfig = string2array($ossConfigResult['value']);
+        $transferConfigResult = Yii::$app->db->createCommand("select * from {{%config}} where name='transfer'")->queryOne();
+        $this->transferConfig = string2array($transferConfigResult['value']);
+        $attachmentConfigResult = Yii::$app->db->createCommand("select * from {{%config}} where name='attachment'")->queryOne();
+        $this->attachmentConfig = string2array($attachmentConfigResult['value']);
+        $imgConfigResult = Yii::$app->db->createCommand("select * from {{%config}} where name='imageconfig'")->queryOne();
+        $this->imgConfig = string2array($imgConfigResult['value']);
+        if($this->ossConfig['OPEN_OSS'])
+        {
+            $this->oss = new \app\common\components\Oss();
+            $initResult = $this->oss->init($this->ossConfig['OPEN_INTERNAL']);
+            if($initResult['error'])
+            {
+                exit("OSS初始化出错");
+            }
+        }
+    }
+
+    public function actionIndex()
+    {
+        $doc = Yii::$app->db->createCommand("select * from {{%doc}} where (trans_status=0 or trans_status=99) and is_delete=0 order by id desc limit 1")->queryOne();
+        if(!empty($doc))
+        {
+            if($doc['trans_status']==99&&TIMESTAMP-$doc['transfer_start_time']>=$this->transferConfig['timeout'])
+            {
+                Yii::$app->db->createCommand("update {{%doc}} set trans_status=88 where id=".$doc['id'])->execute();
+                $this->_saveLog('timeout',$doc);
+            }
+            else
+            {
+                //只对待转换文档处理
+               if($doc['trans_status']==0)$this->_dotrans($doc['id']);
+
+            }
+        }
+
+    }
+
+
+    //执行转换
+    private function _dotrans($id)
+    {
+        set_time_limit(0);
+        $status = 5;//默认进入待自审状态
+        $audit_bak = [];//审核备注
+        $doc = Yii::$app->db->createCommand("select * from (select * from {{%doc}} where id=$id) a left join {{%doc_data}} b on a.id=b.id")->queryOne();
+        $this->_saveLog('start',$doc);
+        //获取用户组权限
+        if($doc['user_id'])
+        {
+            $user = Yii::$app->db->createCommand("select * from {{%user}} where user_id=".$doc['user_id']."")->queryOne();
+            if(!empty($user))
+            {
+                $userGroupLevel = Yii::$app->db->createCommand("select * from {{%user_group_level}} where id=".$user['user_group_level'])->queryOne();
+                if($userGroupLevel)
+                {
+                    $levelSettings = string2array($userGroupLevel['settings']);
+                    //免自审
+                    if($levelSettings['doc_auto_selfaudit']==1)
+                    {
+                        $status = 0;
+                    }
+
+                    //免审核,直接发布
+                    if($levelSettings['doc_auto_audit']==1)
+                    {
+                        $status = 1;
+                    }
+                }
+            }
+        }
+
+        //合辑,资源免转换
+        if(in_array($doc['doc_type'],[2,3,4]))
+        {
+            Yii::$app->db->createCommand("update {{%doc}} set trans_status=1,transfer_end_time=".time().",status=$status where id=$id")->execute();
+            $this->_saveLog('end',$doc);
+        }
+        else
+        {
+            $downResult = $this->_locateFile(getFileUrl($doc['file']),$doc['ext']);
+            if($downResult['error']==0)
+            {
+                $transferFolder = $downResult['data'][0];
+                $transferFile = $downResult['data'][1];
+                $relativeFolder = $downResult['data'][2];
+                $relativeFile = $downResult['data'][3];
+                Yii::$app->db->createCommand("update {{%doc}} set trans_status=99,transfer_start_time=".time()." where id=$id")->execute();
+                //图片
+                if(in_array($doc['ext'],array('jpg','jpeg','gif','png','bmp'))){
+                    $imgResult = $this->_doimg($transferFolder,$transferFile);
+                    $imgcode = $imgResult['data']['imgcode'];
+                    Yii::$app->db->createCommand("update {{%doc}} set trans_status=1,transfer_end_time=".time().",status=$status,page_num = 1,preview_num=1,thumb='".$doc['file']."' where id=".$id)->execute();
+                    Yii::$app->db->createCommand("update {{%doc_data}} set imgcode='".json_encode($imgcode)."'  where id=".$id)->execute();
+                    //封面图信息
+                    if(!empty($doc['file']))
+                    {
+                        Yii::$app->db->createCommand("insert into {{%attachment}} set status=1,file_path='".$doc['file']."',hash='".md5($doc['file'])."',is_used=1,upload_time=".time().",file_name='".basename($doc['file'])."'")->execute();
+                        Yii::$app->db->createCommand("insert into {{%attachment_index}} set table_name='doc',field='thumb',data_id=".$id.",a_id=".Yii::$app->db->getLastInsertID()."")->execute();
+                    }
+                    $result = array('error'=>0,'msg'=>'处理成功');
+
+                }
+                else if(in_array($doc['ext'],array('zip','rar')))
+                {
+
+                    $packfiles = $this->_uncompress($transferFile,$id);
+                    if(!empty($packfiles)&&is_array($packfiles))
+                    {
+                        Yii::$app->db->createCommand("update {{%doc_data}} set packfiles = '".addslashes(array2string($packfiles))."' where id=".$id)->execute();
+                        Yii::$app->db->createCommand("update {{%doc}} set trans_status=1,transfer_end_time=".time().",status=$status where id=".$id)->execute();
+                        $result = array('error'=>0,'msg'=>'处理成功');
+                    }
+                    else
+                    {
+                        $result = array('error'=>1,'msg'=>'解压失败');
+                        $audit_bak[] = "解压失败";
+                    }
+                }
+                else if(in_array($doc['ext'],array('mp3','mp4','flv','wmv')))
+                {
+                    $mediaResult = $this->_domedia($transferFolder,$transferFile);
+                    if($mediaResult['error']==0)
+                    {
+                        Yii::$app->db->createCommand("update {{%doc}} set trans_status=1,transfer_end_time=".time().", status=$status, page_num = ".$mediaResult['data']['page_num'].", preview_num=".$mediaResult['data']['preview_num']."  where id=".$id)->execute();
+                        Yii::$app->db->createCommand("update {{%doc_data}} set h5code='".json_encode($mediaResult['data']['h5code'])."' where id=".$id)->execute();
+                        $result = array('error'=>0,'msg'=>'处理成功');
+                    }
+                    else
+                    {
+                        $result = array('error'=>1,'msg'=>'音视频处理失败');
+                        $audit_bak[] = "音视频处理失败";
+                    }
+                }
+                else if(in_array(strtolower($doc['ext']),array('ppt','pptx','dps'))&&$this->transferConfig['trans_type']=='localkiivo'&&$this->transferConfig['pptimg'])//使用知沃云ppt转图片
+                {
+                    $pptResult = $this->_doppt($transferFolder,$transferFile,getFileUrl($doc['file']));
+                    if($pptResult['error']==0)
+                    {
+                        $page_num = $pptResult['data']['page_num'];
+                        $imgcode = $pptResult['data']['imgcode'];
+                        $preview_num =  $pptResult['data']['preview_num'];
+                        if(empty($doc['thumb'])){
+                            Yii::$app->db->createCommand("update {{%doc}} set page_num = $page_num,preview_num=$preview_num, thumb='".$imgcode[0]."', trans_status=1,transfer_end_time=".time().", status=$status  where id=".$id)->execute();
+                        }
+                        else
+                        {
+                            Yii::$app->db->createCommand("update {{%doc}} set page_num = $page_num,preview_num=$preview_num, trans_status=1,transfer_end_time=".time().", status=$status  where id=".$id)->execute();
+
+                        }
+
+                        Yii::$app->db->createCommand("update {{%doc_data}} set imgcode='".json_encode($imgcode)."'  where id=".$id)->execute();
+                        //封面图信息
+                        if(!empty($imgcode[0])&&empty($doc['thumb']))
+                        {
+                            Yii::$app->db->createCommand("insert into {{%attachment}} set status=1,file_path='".$imgcode[0]."',hash='".md5($imgcode[0])."',is_used=1,upload_time=".time().",file_name='".basename($imgcode[0])."'")->execute();
+                            Yii::$app->db->createCommand("insert into {{%attachment_index}} set table_name='doc',field='thumb',data_id=".$id.",a_id=".Yii::$app->db->getLastInsertID()."")->execute();
+                        }
+                        $result = array('error'=>0,'msg'=>'处理成功');
+                    }
+                    else
+                    {
+                        $result = $pptResult;
+                    }
+
+                }
+                else
+                {
+                    //只有在本地转换或本地+知沃云转换时候,需要转成PDF
+                    if($this->transferConfig['trans_type']=='local'||$this->transferConfig['trans_type']=='localkiivo')
+                    {
+                        if(in_array(strtolower($doc['ext']),array('pdf')))
+                        {
+                            $pdfFile = $transferFile;
+                        }
+                        else
+                        {
+                            $pdfFile = $this->_toPdf($transferFolder,$transferFile);
+                        }
+                    }
+                    else//云转换
+                    {
+                        $pdfFile = $transferFile;
+                    }
+
+                    if($pdfFile)
+                    {
+                        if($this->transferConfig['trans_type']=='local'||$this->transferConfig['trans_type']=='localkiivo')
+                        {
+                            //如果设定为转成图片
+                            if($this->transferConfig['dist_type']=='img')
+                            {
+                                $pdfPageInfo = $this->_pdfPageInfo($pdfFile);
+                                $page_num = $pdfPageInfo['data']['pageNum'];
+                                $h5code = [];
+                                $fullcontent = '';
+                                $content = '';
+                                //重新计算预览页数
+                                $transferPage = $pdfPageInfo['data']['transferPage'];
+                                $preview_num = $this->_getPreviewNum($page_num,$transferPage);
+                                $imgResult = $this->_pdf2img($pdfFile,$transferPage);
+                            }
+                            else  if($this->transferConfig['dist_type']=='h5')
+                            {
+                                $pdf2htmlResult = $this->_pdf2html($pdfFile);
+                                if($pdf2htmlResult['error']==0)
+                                {
+                                    $page_num = $pdf2htmlResult['data']['pageNum'];
+                                    $h5code = $pdf2htmlResult['data']['h5code'];
+                                    $preview_num = $pdf2htmlResult['data']['preview_num'];
+                                    $fullcontent =  $pdf2htmlResult['data']['fullcontent'];
+                                    $content = beforeProcessHtml($pdf2htmlResult['data']['content']);
+                                    $imgResult = $this->_pdf2img($pdfFile);
+                                }
+                                else
+                                {
+                                    //转换html失败,尝试转图片
+                                    $page_num = $pdf2htmlResult['data']['pageNum'];
+                                    $h5code = [];
+                                    $fullcontent = '';
+                                    $content = '';
+                                    //重新计算预览页数
+                                    $transferPage = $pdf2htmlResult['data']['transferPage'];
+                                    $preview_num = $this->_getPreviewNum($page_num,$transferPage);
+                                    $imgResult = $this->_pdf2img($pdfFile,$transferPage);
+                                }
+
+                            }
+                            else  if($this->transferConfig['dist_type']=='all')
+                            {
+                                $pdf2htmlResult = $this->_pdf2html($pdfFile);
+                                if($pdf2htmlResult['error']==0)
+                                {
+                                    $page_num = $pdf2htmlResult['data']['pageNum'];
+                                    $h5code = $pdf2htmlResult['data']['h5code'];
+                                    $preview_num = $pdf2htmlResult['data']['preview_num'];
+                                    $fullcontent =  $pdf2htmlResult['data']['fullcontent'];
+                                    $content = beforeProcessHtml($pdf2htmlResult['data']['content']);
+                                    $transferPage = $pdf2htmlResult['data']['transferPage'];
+                                    $imgResult = $this->_pdf2img($pdfFile,$transferPage);
+                                }
+                                else
+                                {
+                                    //转换html失败,尝试转图片
+                                    $page_num = $pdf2htmlResult['data']['pageNum'];
+                                    $h5code = [];
+                                    $fullcontent = '';
+                                    $content = '';
+                                    //重新计算预览页数
+                                    $transferPage = $pdf2htmlResult['data']['transferPage'];
+                                    $preview_num = $this->_getPreviewNum($page_num,$transferPage);
+                                    $imgResult = $this->_pdf2img($pdfFile,$transferPage);
+                                }
+
+                            }
+
+                        }
+                        else
+                        {
+                            //云转换
+                            $imgResult = $this->_doRemoteTrans($pdfFile);
+                            $page_num = $imgResult['data']['pageNum'];
+                            $h5code = [];
+                            $fullcontent = '';
+                            $content = '';
+                            $transferPage = $imgResult['data']['transferPage'];
+                            $preview_num = $this->_getPreviewNum($page_num,$transferPage);
+
+                        }
+
+                        if($imgResult['error']==0)
+                        {
+                            //生成封面
+                            $imgcode = $imgResult['data']['imgcode'];
+                            //页数超限
+                            if($page_num>50)
+                            {
+                                $status = 6;
+                                $audit_bak[] = '页数超限(超过50页需重点审核)';
+                            }
+
+                            //pdf二审
+                            if($doc['ext']=='pdf'){
+
+                                $status = 7;
+                                $audit_bak[] = 'PDF需要二审';
+                            }
+
+                            if(!empty($fullcontent))
+                            {
+                                //敏感词检测
+                                $sesResult = sensitive($fullcontent);
+                                if(!empty($sesResult))
+                                {
+                                    if($sesResult['log2'])
+                                    {
+                                        $status = 8;//非法资源
+                                        $audit_bak[] = $sesResult['log2'];
+                                    }
+                                    if($sesResult['log1'])
+                                    {
+                                        $status = 8;//非法资源
+                                        $audit_bak[] = $sesResult['log1'];
+                                    }
+                                    if($sesResult['log3'])
+                                    {
+                                        $status = 8;//非法资源
+                                        $audit_bak[] = $sesResult['log3'];
+                                    }
+                                }
+                            }
+
+                            if(empty($doc['thumb']))
+                            {
+                                Yii::$app->db->createCommand("update {{%doc}} set page_num = $page_num,preview_num=$preview_num, thumb='".$imgcode[0]."', trans_status=1,transfer_end_time=".time().", status=$status  where id=".$id)->execute();
+                            }
+                            else
+                            {
+                                Yii::$app->db->createCommand("update {{%doc}} set page_num = $page_num,preview_num=$preview_num, trans_status=1,transfer_end_time=".time().", status=$status  where id=".$id)->execute();
+                            }
+
+                            Yii::$app->db->createCommand("update {{%doc_data}} set h5code='".json_encode($h5code)."',imgcode='".json_encode($imgcode)."',content='".addslashes($content)."'  where id=".$id)->execute();
+                            //封面图信息
+                            if(!empty($imgcode[0])&&empty($doc['thumb']))
+                            {
+                                Yii::$app->db->createCommand("insert into {{%attachment}} set status=1,file_path='".$imgcode[0]."',hash='".md5($imgcode[0])."',is_used=1,upload_time=".time().",file_name='".basename($imgcode[0])."'")->execute();
+                                Yii::$app->db->createCommand("insert into {{%attachment_index}} set table_name='doc',field='thumb',data_id=".$id.",a_id=".Yii::$app->db->getLastInsertID()."")->execute();
+                            }
+                            $result = array('error'=>0,'msg'=>'处理成功');
+
+                        }
+                        else
+                        {
+                            $result = $imgResult;
+                        }
+                    }
+                    else
+                    {
+                        $result = array('error'=>1,'msg'=>'文件转化成PDF失败');
+                    }
+
+                }
+            }
+            else
+            {
+                $result = array('error'=>1,'msg'=>'文件下载到本地失败');
+            }
+
+        }
+
+        //标记失败状态
+        if($result['error']==1)
+        {
+            Yii::$app->db->createCommand("update {{%doc}} set trans_status=88 where id=$id")->execute();
+        }
+        else
+        {
+
+            //转换日志
+            Yii::$app->db->createCommand("delete from {{%doc_auditlog}} where doc_id=$id")->execute();
+            if(is_array($audit_bak))foreach($audit_bak as $abak)
+            {
+                Yii::$app->db->createCommand("insert into {{%doc_auditlog}} set doc_id=$id,log='".$abak."',create_time=".time()."")->execute();
+            }
+            $this->_saveLog('end',$doc);
+            //免审核,直接上架
+            if($levelSettings['doc_auto_audit']==1&&$status==1)
+            {
+                //此处写上架代码
+                $this->_autoAudit($id);
+            }
+        }
+
+    }
+
+    //转化成pdf
+    private function _toPdf($transferFolder,$transferFile)
+    {
+
+        $baseFile = basename($transferFile);
+        $pdfFile =  str_replace(".".fileext($baseFile),".pdf",$baseFile);
+        $targetFile = $transferFolder.$pdfFile;
+        //云转换
+        if($this->transferConfig['trans_type']=='localkiivo'&&in_array(fileext($transferFile),['doc','docx','wps','ppt','pptx','dps']))
+        {
+            $fileUrl = $this->transferUrl.str_replace(DIRECTORY_SEPARATOR,'/',str_replace($this->transferDir,'',$transferFile));
+            $data = ['file'=>$fileUrl,'appkey'=>$this->transferConfig['cloudpwd'],'action'=>'topdf'];
+            $options['time_out'] = 300;
+            $result = https_request($this->transferConfig['cloudurl'],$options,$data);
+            $result = json_decode($result,true);
+            $pdf = $result['data']['pdf'];
+            if(!empty($pdf)&&file_put_contents($targetFile,file_get_contents($pdf))){
+                return $targetFile;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        else
+        {
+            $command = "cd $transferFolder&&/opt/libreoffice7.1/program/soffice --headless --invisible --convert-to pdf $baseFile";
+            if(!empty($command))
+            {
+                //file_put_contents($this->logFile,$command."\r\n",FILE_APPEND);
+                passthru($command,$return);
+                if(file_exists($targetFile)&&$return==0)
+                {
+                    return $targetFile;
+                }
+                else
+                {
+                    return false;
+                }
+
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+    }
+
+    //将pdf转化成h5
+    private function _pdf2html($pdf)
+    {
+        $workPath = $this->_initWorkPath($pdf);
+        $pageNum = $this->_getPdfPageNum($pdf);
+        $pdfcontent = '';
+        if($pageNum>=1)
+        {
+            if($this->transferConfig['fullpage'])
+            {
+                $transferPage = $pageNum;
+            }
+            else
+            {
+                if($this->transferConfig['transferpage_type']=='page')
+                {
+                    $transferPage = $this->transferConfig['transferpage'];
+                }
+                else
+                {
+                    $transferPagePercent = (float)$this->transferConfig['transferpage']/100;
+                    $transferPage = ceil($transferPagePercent*$pageNum);
+                }
+            }
+
+            if($this->transferConfig['transfermaxpage']>0&&$transferPage>$this->transferConfig['transfermaxpage'])
+            {
+
+                $transferPage = $this->transferConfig['transfermaxpage'];
+            }
+
+            if($transferPage>$pageNum)$transferPage = $pageNum;
+            if($transferPage==0)$transferPage = 1;
+            $toHtmlCmd = "pdf2htmlEX  -l $transferPage --split-pages 1 --dest-dir ".$workPath." --css-filename pdf.css --embed-css 0  --fit-width 800 --optimize-text 1 --process-outline 0 --use-cropbox 0 --page-filename page%d.html ".$pdf;
+            //file_put_contents($this->logFile,$toHtmlCmd."\r\n",FILE_APPEND);
+            passthru($toHtmlCmd,$return);
+            if($return==0)
+            {
+                @unlink($workPath.'base.min.css');
+                @unlink($workPath.'fancy.min.css');
+                $h5code = [];
+                $allFileList = [];
+                $allFileList[] = $workPath.'pdf.css';
+                for($i=1;$i<=$transferPage;$i++)
+                {
+                    $allFileList[] = $workPath.'page'.$i.'.html';
+                    //如果页数太多,只取10页内容
+                    if($pageNum>10&&$i<=10)
+                    {
+                        $pdfcontent .= strip_tags(file_get_contents($workPath.'page'.$i.'.html'));
+                    }
+                }
+                if(is_array($allFileList))foreach ($allFileList as $unitFile)
+                {
+                    if($this->ossConfig['OPEN_OSS'])
+                    {
+                        $result = $this->oss->Upload($unitFile,str_replace($this->transferDir,'',$unitFile));
+                        if($result['error']==0)
+                        {
+
+                            if($this->attachmentConfig['absolute_url'])
+                            {
+                                $h5code[] = str_replace($this->ossConfig['OSS_INTERNAL_ENDPOINT'],$this->ossConfig['OSS_ENDPOINT'],$result['data']['url']);
+                            }
+                            else
+                            {
+                                $h5code[] = $result['data']['path'];
+                            }
+
+                        }
+                        else
+                        {
+
+                            return [
+                                'error' => 1,
+                                'msg' => $result['msg']
+                            ];
+                        }
+                    }
+                    else
+                    {
+                        $relativeFile = str_replace($this->transferDir,'',$unitFile);
+                        $targetFile = UPLOAD_PATH.$relativeFile;
+                        dir_create(dirname($targetFile));
+                        if(copy($unitFile,$targetFile))
+                        {
+                            if($this->attachmentConfig['absolute_url'])
+                            {
+                                $h5code[] = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                            }
+                            else
+                            {
+                                $h5code[] = str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                            }
+                        }
+                        else
+                        {
+                            return [
+                                'error' => 1,
+                                'msg' => '复制失败'
+                            ];
+                        }
+
+                    }
+
+                }
+                //获取文字内容
+                if($this->transferConfig['gettext'])
+                {
+                    //如果页数少,直接用插件读取内容
+                    if($pageNum<=10)
+                    {
+                        $parser = new Parser();
+                        $pdfParer = $parser->parseFile($pdf);
+                        $pdfcontent = $pdfParer->getText();
+                    }
+
+                    $fullcontent = $pdfcontent;
+                    if(!empty($pdfcontent)&&$this->transferConfig['textlength']>0)
+                    {
+                        $pdfcontent =  str_cut($pdfcontent,0,$this->transferConfig['textlength'],'');
+                    }
+                }
+                else
+                {
+                    $pdfcontent = '';
+                }
+
+                if($this->transferConfig['previewfullpage'])
+                {
+                    $preview_num = $pageNum;
+                }
+                else
+                {
+                    if($this->transferConfig['previewmaxpage_type']=='page')
+                    {
+                        $preview_num = $this->transferConfig['previewmaxpage'];
+                    }
+                    else
+                    {
+                        $previewPagePercent = (float)$this->transferConfig['previewmaxpage']/100;
+                        $preview_num = ceil($previewPagePercent*$pageNum);
+                    }
+                }
+                if($preview_num>$pageNum)$preview_num = $pageNum;
+                if($preview_num==0)$preview_num = 1;
+                if($this->transferConfig['transfermaxpage']>0&&$preview_num>$this->transferConfig['transfermaxpage']){
+                    $preview_num = $this->transferConfig['transfermaxpage'];
+                }
+                if($preview_num>$transferPage)$preview_num = $transferPage;
+                return [
+                    'error' => 0,
+                    'msg' => '处理成功',
+                    'data'=>['h5code'=>$h5code,'pageNum'=>$pageNum,'transferPage'=>$transferPage,'preview_num'=>$preview_num,'fullcontent'=>$fullcontent,'content'=>$pdfcontent]
+                ];
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '转化html失败'
+                ];
+            }
+
+
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '文档页数异常'
+            ];
+        }
+
+    }
+    //将PDF转换成图片
+    private function _pdf2img($pdf,$transferPage=0)
+    {
+        $result = [];
+        if(!extension_loaded('imagick'))
+        {
+            $result = array('error'=>1,'msg'=>'imagick加载失败');
+        }
+        if(!file_exists($pdf))
+        {
+            $result = array('error'=>1,'msg'=>'pdf不存在');
+        }
+        if(!is_readable($pdf))
+        {
+            $result = array('error'=>1,'msg'=>'pdf不可读');
+        }
+        if(empty($result))
+        {
+            $workPath = $this->_initWorkPath($pdf);//dirname($pdf).DIRECTORY_SEPARATOR.md5(basename($pdf)).DIRECTORY_SEPARATOR;
+            dir_create($workPath);
+            $imgcode = [];
+            $im = new \Imagick();
+            $im->setResolution(300, 300);
+            $im->setCompressionQuality(100);
+            //$page = 0;//只读取首页
+            //$im->readImage($pdf."[".$page."]");
+            if($transferPage==0)
+            {
+                $page = 0;//只读取首页
+                $im->readImage($pdf."[".$page."]");
+            }
+            else
+            {
+                $im->readImage($pdf);
+            }
+            foreach ($im as $key => $var)
+            {
+                if($transferPage>0&&($key+1)>$transferPage)continue;
+                $var->setImageFormat('png');
+                $unitFile = $workPath.$key.'.png';
+                if(@$var->writeImage($unitFile) == true)
+                {
+                    //打水印
+                    if($this->attachmentConfig['open_watermark']&&!empty($this->imgConfig['watermark']))
+                    {
+                        $watermark = $this->_locateWatermark();
+                        set_img_water($unitFile,$watermark,$this->attachmentConfig['watermark_quality'],$this->attachmentConfig['watermark_pos']);
+                    }
+
+                    if($this->ossConfig['OPEN_OSS'])
+                    {
+                        $result = $this->oss->Upload($unitFile,str_replace($this->transferDir,'',$unitFile));
+                        if($result['error']==0)
+                        {
+
+                            if($this->attachmentConfig['absolute_url'])
+                            {
+                                $imgcode[] = str_replace($this->ossConfig['OSS_INTERNAL_ENDPOINT'],$this->ossConfig['OSS_ENDPOINT'],$result['data']['url']);
+                            }
+                            else
+                            {
+                                $imgcode[] = $result['data']['path'];
+                            }
+
+                        }
+                        else
+                        {
+
+                            return [
+                                'error' => 1,
+                                'msg' => $result['msg']
+                            ];
+                        }
+                    }
+                    else
+                    {
+                        $targetFile = str_replace($this->transferDir,'',$unitFile);
+                        dir_create(dirname(UPLOAD_PATH.$targetFile));
+                        if(copy($unitFile,UPLOAD_PATH.$targetFile))
+                        {
+                            if($this->attachmentConfig['absolute_url'])
+                            {
+                                $imgcode[] = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$targetFile);
+                            }
+                            else
+                            {
+                                $imgcode[] = str_replace(DIRECTORY_SEPARATOR,'/',$targetFile);
+                            }
+                        }
+                        else
+                        {
+                            return [
+                                'error' => 1,
+                                'msg' => '复制图片失败'
+                            ];
+                        }
+
+                    }
+
+
+                }
+                else
+                {
+                    return array('error'=>1,'msg'=>'PDF转图片失败');
+                }
+            }
+            $im->destroy();
+            return array('error'=>0,'msg'=>'PDF转图片成功','data'=>['imgcode'=>$imgcode]);
+
+        }
+        else
+        {
+            return  $result;
+        }
+
+    }
+
+    //获取预览页数
+    private function _getPreviewNum($pageNum,$transferPage)
+    {
+        if($this->transferConfig['previewfullpage'])
+        {
+            $preview_num = $pageNum;
+        }
+        else
+        {
+            if($this->transferConfig['previewmaxpage_type']=='page')
+            {
+                $preview_num = $this->transferConfig['previewmaxpage'];
+            }
+            else
+            {
+                $previewPagePercent = (float)$this->transferConfig['previewmaxpage']/100;
+                $preview_num = ceil($previewPagePercent*$pageNum);
+            }
+        }
+        if($preview_num>$pageNum)$preview_num = $pageNum;
+        if($preview_num==0)$preview_num = 1;
+        if($this->transferConfig['transfermaxpage']>0&&$preview_num>$this->transferConfig['transfermaxpage']){
+            $preview_num = $this->transferConfig['transfermaxpage'];
+        }
+        if($preview_num>$transferPage)$preview_num = $transferPage;
+        return $preview_num;
+    }
+
+    private function _getPdfPageNum($file) {
+        if(!file_exists($file))
+        {
+            return $this->_getPdfPageNum($file);
+        }
+        else
+        {
+            exec(sprintf('gs -q -dNODISPLAY -c "(%s) (r) file runpdfbegin pdfpagecount = quit"', $file), $res, $ret);
+            if(0 == $ret) {
+                return (int) $res[0];
+            }
+            return 0;
+        }
+
+    }
+
+    //获取PDF总页数和转换页数
+    private function _pdfPageInfo($pdf)
+    {
+        $pageNum = $this->_getPdfPageNum($pdf);
+        if($pageNum>=1)
+        {
+            if($this->transferConfig['fullpage'])
+            {
+                $transferPage = $pageNum;
+            }
+            else
+            {
+                if($this->transferConfig['transferpage_type']=='page')
+                {
+                    $transferPage = $this->transferConfig['transferpage'];
+                }
+                else
+                {
+                    $transferPagePercent = (float)$this->transferConfig['transferpage']/100;
+                    $transferPage = ceil($transferPagePercent*$pageNum);
+                }
+            }
+
+            if($this->transferConfig['transfermaxpage']>0&&$transferPage>$this->transferConfig['transfermaxpage'])
+            {
+
+                $transferPage = $this->transferConfig['transfermaxpage'];
+            }
+
+            if($transferPage>$pageNum)$transferPage = $pageNum;
+            if($transferPage==0)$transferPage = 1;
+            return [
+                'error' => 0,
+                'msg' => '获取pdf页数成功',
+                'data'=>['pageNum'=>$pageNum,'transferPage'=>$transferPage]
+            ];
+        }
+        else
+        {
+            return [
+                'error' => 1,
+                'msg' => '文档页数异常'
+            ];
+        }
+    }
+
+
+    //PPT云转换
+    private function _doppt($transferFolder,$transferFile)
+    {
+        $ext = fileext($transferFile);
+        $workPath = $this->_initWorkPath($transferFile);
+        $fileUrl = $this->transferUrl.str_replace(DIRECTORY_SEPARATOR,'/',str_replace($this->transferDir,'',$transferFile));
+        $data = ['file'=>$fileUrl,'appkey'=>$this->transferConfig['cloudpwd'],'action'=>'ppt2img'];
+        $options['time_out'] = 300;
+        $pptresult = https_request($this->transferConfig['cloudurl'],$options,$data);
+        $pptresult = json_decode($pptresult,true);
+        if($pptresult['error']==0)
+        {
+            $images = $pptresult['data']['imgs'];
+            $imgcode = [];
+            if(is_array($images))foreach($images as $image)
+            {
+                $imgfile = $workPath.basename($image);
+                if(file_put_contents($imgfile,file_get_contents($image)))
+                {
+                    $unitFile = $imgfile;
+                    //打水印
+                    if($this->attachmentConfig['open_watermark']&&!empty($this->imgConfig['watermark']))
+                    {
+                        $watermark = $this->_locateWatermark();
+                        set_img_water($unitFile,$watermark,$this->attachmentConfig['watermark_quality'],$this->attachmentConfig['watermark_pos']);
+                    }
+                    if($this->ossConfig['OPEN_OSS'])
+                    {
+                        $result = $this->oss->Upload($unitFile,str_replace($this->transferDir,'',$unitFile));
+                        if($result['error']==0)
+                        {
+
+                            if($this->attachmentConfig['absolute_url'])
+                            {
+                                $imgcode[] = str_replace($this->ossConfig['OSS_INTERNAL_ENDPOINT'],$this->ossConfig['OSS_ENDPOINT'],$result['data']['url']);
+                            }
+                            else
+                            {
+                                $imgcode[] = $result['data']['path'];
+                            }
+
+                        }
+                        else
+                        {
+
+                            return [
+                                'error' => 1,
+                                'msg' => $result['msg']
+                            ];
+                        }
+                    }
+                    else
+                    {
+                        $relativeFile = str_replace($this->transferDir,'',$unitFile);
+                        $targetFile = UPLOAD_PATH.$relativeFile;
+                        dir_create(dirname($targetFile));
+                        if(copy($unitFile,$targetFile))
+                        {
+                            if($this->attachmentConfig['absolute_url'])
+                            {
+                                $imgcode[] = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                            }
+                            else
+                            {
+                                $imgcode[] = str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                            }
+                        }
+                        else
+                        {
+                            return [
+                                'error' => 1,
+                                'msg' => 'PPT单元页上传失败'
+                            ];
+                        }
+
+                    }
+
+
+                }
+            }
+            $page_num = count($imgcode);
+            if($this->transferConfig['previewfullpage'])
+            {
+                $preview_num = $page_num;
+            }
+            else
+            {
+                if($this->transferConfig['previewmaxpage_type']=='page')
+                {
+                    $preview_num = $this->transferConfig['previewmaxpage'];
+                }
+                else
+                {
+                    $previewPagePercent = (float)$this->transferConfig['previewmaxpage']/100;
+                    $preview_num = ceil($previewPagePercent*$page_num);
+                }
+            }
+            //预览页数不应该迟超过转换页数上线
+            if($this->transferConfig['transfermaxpage']>0&&$preview_num>$this->transferConfig['transfermaxpage']){
+                $preview_num = $this->transferConfig['transfermaxpage'];
+            }
+            if($preview_num>$page_num)$preview_num = $page_num;
+            if($preview_num==0)$preview_num = 1;
+            return [
+                'error' => 0,
+                'msg' => '处理成功',
+                'data'=>['imgcode'=>$imgcode,'page_num'=>$page_num,'preview_num'=>$preview_num]
+            ];
+        }
+        else
+        {
+            return   array('error'=>1,'msg'=>'PPT远程处理失败');
+        }
+
+    }
+
+
+    private function _domedia($transferFolder,$transferFile)
+    {
+
+        $ext = fileext($transferFile);
+        $workPath = $this->_initWorkPath($transferFile);
+        $videoInfo = $this->_getVideoInfo($transferFile);
+        //预览和截断时间(秒)
+        if($videoInfo['all_time']<=30)
+        {
+            $preview_num = 30;
+        }
+        else
+        {
+            if($this->transferConfig['previewfullmedia'])
+            {
+                $preview_num = $videoInfo['all_time'];
+            }
+            else
+            {
+                if($this->transferConfig['mediatime_type']=='seconds')
+                {
+                    $preview_num = $this->transferConfig['mediatime'];
+                }
+                else
+                {
+                    $previewMediaPercent = (float)$this->transferConfig['mediatime']/100;
+                    $preview_num = ceil($previewMediaPercent*$videoInfo['all_time']);
+                }
+            }
+        }
+        if($preview_num>$videoInfo['all_time'])$preview_num = $videoInfo['all_time'];
+        $cuttedFile = $workPath.md5(basename($transferFile)).'_'.$preview_num.'.'.$ext;
+        $cuttedDir = dirname($cuttedFile);
+        $cutto =  $this->changeTimeType($preview_num);
+        dir_create($cuttedDir);
+        $cutVideoCmd = "/usr/bin/ffmpeg  -i $transferFile -vcodec copy -acodec copy -ss 00:00:00 -to $cutto $cuttedFile -y";
+        passthru($cutVideoCmd,$return);
+        if($return==0)
+        {
+            $unitFile = $cuttedFile;
+            $h5code = [];
+            if($this->ossConfig['OPEN_OSS'])
+            {
+                $result = $this->oss->Upload($unitFile,str_replace($this->transferDir,'',$unitFile));
+                if($result['error']==0)
+                {
+                    if($this->attachmentConfig['absolute_url'])
+                    {
+                        $h5code[] = str_replace($this->ossConfig['OSS_INTERNAL_ENDPOINT'],$this->ossConfig['OSS_ENDPOINT'],$result['data']['url']);
+                    }
+                    else
+                    {
+                        $h5code[] = $result['data']['path'];
+                    }
+
+
+                }
+                else
+                {
+
+                    return [
+                        'error' => 1,
+                        'msg' => $result['msg']
+                    ];
+                }
+            }
+            else
+            {
+                $relativeFile = str_replace($this->transferDir,'',$unitFile);
+                $targetFile = UPLOAD_PATH.$relativeFile;
+                dir_create(dirname($targetFile));
+                if(copy($unitFile,$targetFile))
+                {
+                    if($this->attachmentConfig['absolute_url'])
+                    {
+                        $h5code[] = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                    }
+                    else
+                    {
+                        $h5code[] = str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                    }
+                }
+                else
+                {
+                    return [
+                        'error' => 1,
+                        'msg' => '音视频文件上传失败'
+                    ];
+                }
+
+            }
+            return [
+                'error' => 0,
+                'msg' => '处理成功',
+                'data'=>['h5code'=>$h5code,'page_num'=>$videoInfo['all_time'],'preview_num'=>$preview_num]
+            ];
+
+        }
+        else
+        {
+            return   array('error'=>1,'msg'=>'音视频裁剪失败');
+        }
+
+    }
+
+    //获取文档总页数和转换页数
+    private function _doRemoteTrans($file)
+    {
+        $workPath = $this->_initWorkPath($file);//dirname($pdf).DIRECTORY_SEPARATOR.md5(basename($pdf)).DIRECTORY_SEPARATOR;
+        dir_create($workPath);
+        $imgcode = [];
+        if($this->transferConfig['OSS_ACCESS_KEY'])
+        {
+            //腾讯云
+            $object = str_replace($this->transferDir,'',$file);
+            $protocol = str_replace("://","",SITE_PROTOCOL);
+            $ossClient = new \Qcloud\Cos\Client(
+                array(
+                    'region' => $this->transferConfig['OSS_REGION'],
+                    'schema' => $protocol, //协议头部,默认为http
+                    'credentials'=> array(
+                        'secretId'  => $this->transferConfig['OSS_ACCESS_KEY'] ,
+                        'secretKey' => $this->transferConfig['OSS_ACCESS_SECRET'])));
+            $fileContent = fopen($file, "rb");
+            if ($fileContent) {
+                $ossresult =  $ossClient->putObject(array(
+                    'Bucket' => $this->transferConfig['OSS_BUCKET'],
+                    'Key' => $object,
+                    'Body' => $fileContent));
+                //远程文件地址
+                $remoteFileUrl = SITE_PROTOCOL.$ossresult['Location'];
+            }
+            $pageInfo  = $this->_getRemoteFilePage($remoteFileUrl);
+            if($remoteFileUrl)
+            {
+                for($i=1;$i<=$pageInfo['data']['transferPage'];$i++)
+                {
+                    $tempUrl = $remoteFileUrl.'?ci-process=doc-preview&page='.$i;
+                    $requestData = https_request($tempUrl);
+                    //写图片到平台存储
+                    $unitFile = $workPath.$i.'.jpg';
+                    if(file_put_contents($unitFile,$requestData))
+                    {
+                        //打水印
+                        if($this->attachmentConfig['open_watermark']&&!empty($this->imgConfig['watermark']))
+                        {
+                            $watermark = $this->_locateWatermark();
+                            set_img_water($unitFile,$watermark,$this->attachmentConfig['watermark_quality'],$this->attachmentConfig['watermark_pos']);
+                        }
+                        if($this->ossConfig['OPEN_OSS'])
+                        {
+                            $result = $this->oss->Upload($unitFile,str_replace($this->transferDir,'',$unitFile));
+                            if($result['error']==0)
+                            {
+                                if($this->attachmentConfig['absolute_url'])
+                                {
+                                    $imgcode[] = str_replace($this->ossConfig['OSS_INTERNAL_ENDPOINT'],$this->ossConfig['OSS_ENDPOINT'],$result['data']['url']);
+                                }
+                                else
+                                {
+                                    $imgcode[] = $result['data']['path'];
+                                }
+
+                            }
+                            else
+                            {
+
+                                return [
+                                    'error' => 1,
+                                    'msg' => $result['msg']
+                                ];
+                            }
+                        }
+                        else
+                        {
+                            $targetFile = str_replace($this->transferDir,'',$unitFile);
+                            dir_create(dirname(UPLOAD_PATH.$targetFile));
+                            if(copy($unitFile,UPLOAD_PATH.$targetFile))
+                            {
+                                if($this->attachmentConfig['absolute_url'])
+                                {
+                                    $imgcode[] = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$targetFile);
+                                }
+                                else
+                                {
+                                    $imgcode[] = str_replace(DIRECTORY_SEPARATOR,'/',$targetFile);
+                                }
+                            }
+                            else
+                            {
+                                return [
+                                    'error' => 1,
+                                    'msg' => '复制图片失败'
+                                ];
+                            }
+
+                        }
+
+                    }
+                }
+
+                //删除转换容器中的文件
+                $ossClient->deleteObject(array(
+                    'Bucket' => $this->transferConfig['OSS_BUCKET'], //存储桶名称
+                    'Key' => $object
+                ));
+                return [
+                    'error' => 0,
+                    'msg' => '远程转换成功',
+                    'data'=>['pageNum'=>$pageInfo['data']['pageNum'],'transferPage'=>$pageInfo['data']['transferPage'],'imgcode'=>$imgcode]
+                ];
+
+            }
+            else
+            {
+                return array('error'=>1,'msg'=>'上传到对象存储失败');
+            }
+        }
+        else
+        {
+            return array('error'=>1,'msg'=>'远程转换配置错误');
+        }
+
+    }
+
+
+    //获取远程文件总页数
+    private  function _getRemoteFilePage($remoteFileUrl)
+    {
+        $max_page = 1000;
+        for($i=1;$i<=$max_page;$i++)
+        {
+            $tempUrl = $remoteFileUrl.'?ci-process=doc-preview&page='.$i;
+            $requestData = https_request($tempUrl);
+            if($this->iss_xml($requestData))
+            {
+                //格式化XML
+                libxml_disable_entity_loader(true);
+                $requestObj = simplexml_load_string($requestData, 'SimpleXMLElement', LIBXML_NOCDATA);
+                if($requestObj->Code=='NoSuchPage')
+                {
+                    $pageNum =  ($i-1);
+                    if($this->transferConfig['fullpage'])
+                    {
+                        $transferPage = $pageNum;
+                    }
+                    else
+                    {
+                        if($this->transferConfig['transferpage_type']=='page')
+                        {
+                            $transferPage = $this->transferConfig['transferpage'];
+                        }
+                        else
+                        {
+                            $transferPagePercent = (float)$this->transferConfig['transferpage']/100;
+                            $transferPage = ceil($transferPagePercent*$pageNum);
+                        }
+                    }
+
+                    if($this->transferConfig['transfermaxpage']>0&&$transferPage>$this->transferConfig['transfermaxpage'])
+                    {
+
+                        $transferPage = $this->transferConfig['transfermaxpage'];
+                    }
+
+                    if($transferPage>$pageNum)$transferPage = $pageNum;
+                    if($transferPage==0)$transferPage = 1;
+                    return [
+                        'error' => 0,
+                        'msg' => '获取页数成功',
+                        'data'=>['pageNum'=>$pageNum,'transferPage'=>$transferPage]
+                    ];
+                }
+
+            }
+
+        }
+
+    }
+
+    //判断是否是XML
+    function iss_xml($content){    //判断返回的内容是不是 xml 格式
+        $xml_parser = xml_parser_create();
+        $res = xml_parse($xml_parser, $content, true);
+        xml_parser_free($xml_parser);    return $res;
+    }
+    //获取文件信息
+    private function _getVideoInfo($file) {
+        $command = " ffmpeg -i $file 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//";
+        ob_start();
+        passthru($command);
+        $info = ob_get_contents();
+        ob_end_clean();
+        $data = array();
+        $duration = explode(":",$info);
+        $duration_in_seconds = $duration[0]*3600 + $duration[1]*60+ round($duration[2]);//转化为秒
+        $data['all_time'] = $duration_in_seconds;
+        $data['size'] = filesize($file); //文件大小
+        return $data;
+    }
+
+    function changeTimeType($seconds)
+    {
+        if ($seconds > 3600) {
+            $hours = intval($seconds / 3600);
+            $time = $hours . ":" . gmstrftime('%M:%S', $seconds);
+        } else {
+            $time = gmstrftime('%H:%M:%S', $seconds);
+        }
+        return $time;
+
+    }
+
+    //解压缩压缩包文件
+    private function _uncompress($transferFile,$id)
+    {
+        $ext = fileext($transferFile);
+        $workPath = $this->_initWorkPath($transferFile);
+        if($ext=='zip')
+        {
+            $z = new Unzip();
+            $z->unzip($transferFile,$workPath, true, true);
+        }
+        else if($ext=='rar')
+        {
+            $rar_file = rar_open($transferFile) or die("Failed to open Rar archive");
+            $entries = rar_list($rar_file);
+            foreach ($entries as $entry) {
+                $entry->extract($workPath);
+            }
+            rar_close($rar_file);
+        }
+        $filelist = $this->scanDir($workPath,$this->transferDir);
+        if($this->transferConfig['previewpack'])
+        {
+            $this->initPackFile($filelist,$id);
+        }
+        return $filelist;
+    }
+
+    //初始化压缩包待转换数据
+    function initPackFile($arr,$id)
+    {
+        $packexts = $this->transferConfig['packexts']?explode("|",$this->transferConfig['packexts']):['ppt','pptx','doc','docx','xls','xlsx','pdf','jpeg','jpg','png','gif','bmp','txt'];
+        Yii::$app->db->createCommand("delete from {{%doc_packfile}} where doc_id=$id")->execute();
+        if(is_array($arr))foreach($arr as $key=>$val) {
+            if(is_array($arr[$key])) {
+                $this->initPackFile($arr[$key],$id);
+            }
+            else
+            {
+                if(!in_array(fileext($arr[$key]),$packexts))continue;
+                $unitFile = $this->transferDir.$arr[$key];
+                if($this->ossConfig['OPEN_OSS'])
+                {
+                    $result = $this->oss->Upload($unitFile,str_replace($this->transferDir,'',$unitFile));
+                    if($result['error']==0)
+                    {
+                        if($this->attachmentConfig['absolute_url'])
+                        {
+                            $realPath = str_replace($this->ossConfig['OSS_INTERNAL_ENDPOINT'],$this->ossConfig['OSS_ENDPOINT'],$result['data']['url']);
+                        }
+                        else
+                        {
+                            $realPath = $result['data']['path'];
+                        }
+
+                    }
+                }
+                else
+                {
+                    $relativeFile = str_replace($this->transferDir,'',$unitFile);
+                    $targetFile = UPLOAD_PATH.$relativeFile;
+                    $targetPath = dirname($targetFile);
+                    dir_create($targetPath);
+                    if(copy($unitFile,$targetFile))
+                    {
+                        if($this->attachmentConfig['absolute_url'])
+                        {
+                            $realPath = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                        }
+                        else
+                        {
+                            $realPath = str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                        }
+                    }
+                }
+                if(!empty($realPath))
+                {
+                    $ext = fileext($arr[$key]);
+                    Yii::$app->db->createCommand("insert into {{%doc_packfile}} set doc_id=$id,name='".addslashes(basename($arr[$key],'.'.$ext))."',ext='".$ext."',path='".addslashes($arr[$key])."',path_md5='".md5($arr[$key])."',realpath='".addslashes($realPath)."'")->execute();
+
+                }
+            }
+        }
+    }
+
+    //获取压缩包目录树(全路径)
+    function scanDir($pathName,$transferDir) {
+        //将结果保存在result变量中
+        $result = array();
+        $temp = array();
+        //判断传入的变量是否是目录
+        if(!is_dir($pathName) || !is_readable($pathName)) {
+            return null;
+        }
+        $pathName = rtrim($pathName,'/');
+        //取出目录中的文件和子目录名,使用scandir函数
+        $allFiles = scandir($pathName);
+
+        //遍历他们
+        foreach($allFiles as $fileName) {
+            //判断是否是.和..因为这两个东西神马也不是。。。
+            if(in_array($fileName, array('.', '..'))) {
+                continue;
+            }
+            //路径加文件名
+            $fullName = $pathName.'/'.$fileName;
+            //如果是目录的话就继续遍历这个目录
+            if(is_dir($fullName)) {
+                //将这个目录中的文件信息存入到数组中
+                $result[$fullName] = $this->scanDir($fullName,$transferDir);
+            }else {
+                //如果是文件就先存入临时变量
+                $temp[] = $fullName;
+            }
+        }
+        //取出文件
+        if($temp) {
+            foreach($temp as $f) {
+                $result[] = $f;
+            }
+        }
+        $result = string2array(str_replace($transferDir,'',array2string($result)));
+        return $result;
+    }
+
+
+    //处理图片
+    private function _doimg($transferFolder,$transferFile)
+    {
+        $workPath = $this->_initWorkPath($transferFile);
+        $newname = time();
+        $unitFile = $workPath.$newname.'.'.fileext($transferFile);
+        copy($transferFile,$unitFile);
+        //$resize = new \app\common\components\ResizeImage($transferFile, 2000, 2000,$newname, 0,0,$workPath);
+        //$unitFile = $resize->dstimg;
+        //打水印
+        if($this->attachmentConfig['open_watermark']&&!empty($this->imgConfig['watermark']))
+        {
+            $watermark = $this->_locateWatermark();
+            set_img_water($unitFile,$watermark,$this->attachmentConfig['watermark_quality'],$this->attachmentConfig['watermark_pos']);
+        }
+
+        if($this->ossConfig['OPEN_OSS'])
+        {
+            $result = $this->oss->Upload($unitFile,str_replace($this->transferDir,'',$unitFile));
+            if($result['error']==0)
+            {
+                if($this->attachmentConfig['absolute_url'])
+                {
+                    $imgcode[] = str_replace($this->ossConfig['OSS_INTERNAL_ENDPOINT'],$this->ossConfig['OSS_ENDPOINT'],$result['data']['url']);
+                }
+                else
+                {
+                    $imgcode[] = $result['data']['path'];
+                }
+
+
+            }
+            else
+            {
+
+                return [
+                    'error' => 1,
+                    'msg' => $result['msg']
+                ];
+            }
+        }
+        else
+        {
+            $relativeFile = str_replace($this->transferDir,'',$unitFile);
+            $targetFile = UPLOAD_PATH.$relativeFile;
+            $targetPath = dirname(UPLOAD_PATH.$relativeFile);
+            dir_create($targetPath);
+            if(copy($unitFile,$targetFile))
+            {
+                if($this->attachmentConfig['absolute_url'])
+                {
+                    $imgcode[] = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                }
+                else
+                {
+                    $imgcode[] = str_replace(DIRECTORY_SEPARATOR,'/',$relativeFile);
+                }
+            }
+            else
+            {
+                return [
+                    'error' => 1,
+                    'msg' => '转换图片失败'
+                ];
+            }
+
+        }
+        return array('error'=>0,'msg'=>'图片转换成功','data'=>['imgcode'=>$imgcode]);
+    }
+
+
+
+    //本地化水印图片
+    private function _locateWatermark()
+    {
+        $watermarkPath = UPLOAD_PATH.'watermark'.DIRECTORY_SEPARATOR;
+        dir_create($watermarkPath);
+        $watermark = $watermarkPath.basename($this->imgConfig['watermark']);
+        //本地存储水印
+        if(!file_exists($watermark))
+        {
+            file_put_contents($watermark,file_get_contents(getFileUrl($this->imgConfig['watermark'])));
+        }
+        return $watermark;
+    }
+
+
+    //根据临时转换文件路径,生成目标子目录
+    private function _initWorkPath($transferFile)
+    {
+        $ext = fileext($transferFile);
+        $basename = basename($transferFile,'.'.$ext);
+        $workPath = dirname($transferFile).DIRECTORY_SEPARATOR.md5($basename).DIRECTORY_SEPARATOR;
+        dir_create($workPath);
+        return $workPath;
+    }
+    //下载文件到转码目录
+    private function _locateFile($file,$ext)
+    {
+        if(!check_remote_file_exists($file))return array('error'=>1,'msg'=>'文件不存在');
+        $result = parse_url($file);
+        $result['path'] = str_replace('/upload/','',$result['path']);
+        $relativeFile = ltrim(str_replace('/',DIRECTORY_SEPARATOR,$result['path']),DIRECTORY_SEPARATOR);
+        $relativeFolder = dirname($relativeFile).DIRECTORY_SEPARATOR;
+        $transferFile = $this->transferDir.$relativeFile;
+        $transferFolder = dirname($transferFile).DIRECTORY_SEPARATOR;
+        dir_create($transferFolder);
+        if(file_exists($transferFile))
+        {
+            return   array('error'=>0,'msg'=>'下载成功','data'=>[$transferFolder,$transferFile,$relativeFolder,$relativeFile]);
+        }
+        if($this->ossConfig['OPEN_OSS'])
+        {
+            $downresult = $this->oss->downLoad($transferFile,$relativeFile);
+            if($downresult['error']==0)
+            {
+                return   array('error'=>0,'msg'=>'下载成功','data'=>[$transferFolder,$transferFile,$relativeFolder,$relativeFile]);
+            }
+            else
+            {
+                return   array('error'=>1,'msg'=>$downresult['msg']);
+            }
+        }
+        else
+        {
+            if(is_net_file($file))
+            {
+                file_put_contents($transferFile,file_get_contents($file));
+            }
+            else
+            {
+                file_put_contents($transferFile,file_get_contents(UPLOAD_URL.ltrim($result['path'],'/')));
+            }
+            return   array('error'=>0,'msg'=>'下载成功','data'=>[$transferFolder,$transferFile,$relativeFolder,$relativeFile]);
+        }
+
+
+    }
+    //写日志
+    private function _saveLog($title,$doc)
+    {
+        file_put_contents($this->logFile,$doc['title']."(".$title."-".get_date(time(),'Y-m-d H:i:s').")\r\n",FILE_APPEND);
+
+    }
+
+    //自动上架
+    private function _autoAudit($id)
+    {
+        $doc = Yii::$app->db->createCommand("select * from {{%doc}} where id=".$id)->queryOne();
+        $docData = Yii::$app->db->createCommand("select * from {{%doc_data}} where id=".$id)->queryOne();
+        //把表从草稿表复制到正式表
+        $docFields = [];
+        if(is_array($doc))foreach($doc as $k=>$v)
+        {
+            if($k=='id'||$k=='status')continue;
+            if($k=='description')
+            {
+                //文档摘要处理
+                if((empty($doc['description'])||$doc['title']==$doc['description'])&&!empty($docData['content']))
+                {
+                    $length = $this->transferConfig['desclength']>0?$this->transferConfig['desclength']:'350';
+                    $description = str_cut(removeHtml($docData['content'],0),0,$length);
+                }
+                else
+                {
+                    $description = $doc['description'];
+                }
+                $docFields[] = "description ='".$description."'";
+            }
+            else
+            {
+                $docFields[] = "$k ='".$v."'";
+            }
+
+        }
+        $docFields[] = "status=1";
+        $result = Yii::$app->db->createCommand("insert into {{%doc_real}} set ".join(",",$docFields))->execute();
+        $newId = getLastInsertId();
+        if($result)
+        {
+            $docDataFields=  [];
+            if(is_array($docData))foreach($docData as $k=>$v)
+            {
+                if($k=='id'||$k=='hash')continue;
+                if($k=='file'&&$doc['doc_type']==1)
+                {
+                    $hash = randString(8);
+                    $docDataFields[] = "hash='".$hash."'";
+                    $docDataFields[] = "file='".sys_auth($docData['file'],'ENCODE',$hash)."'";
+                }
+                else
+                {
+                    $docDataFields[] = "$k ='".$v."'";
+                }
+            }
+
+            $docDataFields[] = "id='".$newId."'";
+            if($doc['doc_type']==1&&!in_array($doc['ext'],['rar','zip','mp3','mp4']))$docDataFields[] = "content=''";
+            $result1 = Yii::$app->db->createCommand("insert into {{%doc_real_data}} set ".join(",",$docDataFields))->execute();
+            if($result1)
+            {
+                //更新附件关联信息,将草稿表的记录改成正式表
+                $sql = "update {{%attachment_index}} set data_id=$newId,table_name='doc_real' where table_name='doc' and field='thumb' and data_id=$id";
+                Yii::$app->db->createCommand($sql)->execute();
+                $sql = "update {{%attachment_index}} set data_id=$newId,table_name='doc_real_data' where table_name='doc_data' and field='file' and data_id=$id";
+                Yii::$app->db->createCommand($sql)->execute();
+                //更新tag标签.将草稿表的记录改成正式表
+                $sql = "update {{%tag_data}} set data_id=$newId,table_name='doc_real' where table_name='doc' and data_id=$id";
+                Yii::$app->db->createCommand($sql)->execute();
+                //更新审核记录表
+                $sql = "update {{%doc_auditlog}} set doc_real_id=$newId  where doc_id=$id";
+                Yii::$app->db->createCommand($sql)->execute();
+                //更新压缩包细节目录
+                $sql = "update {{%doc_packfile}} set doc_real_id=$newId  where doc_id=$id";
+                Yii::$app->db->createCommand($sql)->execute();
+                //更新合辑
+                if($doc['doc_type']==2)
+                {
+                    $sql = "update {{%doc_col}} set col_id=$newId  where col_id=$id";
+                    Yii::$app->db->createCommand($sql)->execute();
+                }
+                $sql = "delete from {{%doc}} where id=$id";
+                $dResult =  Yii::$app->db->createCommand($sql)->execute();
+                $sql = "delete from {{%doc_data}} where id=$id";
+                $dResult1 =  Yii::$app->db->createCommand($sql)->execute();
+
+                //把草稿删除
+                if(!$dResult||!$dResult1)
+                {
+
+                    return ['error' => 1,'msg' => '操作失败'];
+                }
+                else
+                {
+                    return ['error' => 0,'msg' => '操作成功'];
+                }
+            }
+            else
+            {
+                return ['error' => 1,'msg' => '操作失败'];
+            }
+        }
+        else
+        {
+            return ['error' => 1,'msg' => '操作失败'];
+        }
+    }
+
+
+}

+ 570 - 0
commands/ValueController.php

@@ -0,0 +1,570 @@
+<?php
+namespace app\commands;
+use app\models\Linkmenu;
+use app\modules\car\models\FCarInfo;
+use app\modules\car\models\FCarsDetailData;
+use app\modules\car\models\FOneCarOneTable;
+use yii\console\Controller;
+use Yii;
+class ValueController extends Controller
+{
+    public $carTypes;
+    public $cityOptions;
+    public $carUseTypes;
+    public $carSourceTypes;
+    public $carCity;
+    public $carYears;
+    public $province = '河北';//默认省份
+    public $provinceOptions;
+    public function init()
+    {
+        $this->cityOptions = ['石家庄','机动局','保定','唐山','廊坊','张家口','承德','沧州','秦皇岛','衡水','邢台','邯郸','雄安','省本部'];
+        //北十省份
+        $provinceResult = Yii::$app->db->createCommand("select distinct(province) from wz_f_ten_northern_provinces_stat")->queryAll();
+        foreach($provinceResult as $uprovince)
+        {
+            $this->provinceOptions[] = $uprovince['province'];
+        }
+
+        $carUseTypesResult = FCarInfo::find()->select('distinct(using_tag)')->orderBy(['using_tag'=>SORT_ASC])->all();
+        foreach($carUseTypesResult as $unit)
+        {
+            $this->carUseTypes[] = $unit['using_tag'];
+        }
+        $carSourceTypesResult = FCarInfo::find()->select('distinct(self_rent)')->orderBy(['self_rent'=>SORT_ASC])->all();
+        foreach($carSourceTypesResult as $unit)
+        {
+            $this->carSourceTypes[] = $unit['self_rent'];
+        }
+    }
+
+    public function actionIndex()
+    {
+        $this->_doreport();
+        $this->_dowave();
+    }
+
+    //车辆专题报告
+    private  function _doreport()
+    {
+        $url = $this->createRealUrl('car/default/report');
+
+        https_request($url);
+    }
+
+    //波动分析缓存
+    private function _dowave()
+    {
+
+        $url = $this->createRealUrl('car/wave/index');
+        for($i=1;$i<=9;$i++)
+        {
+            for($j=1;$j<=2;$j++)
+            {
+                $params[] = "type=$i";
+                $params[] = "start_month=1";
+                $params[] = "end_month=".intval(date('m'));
+                $params[] = "datatype=".$j;
+                $params[] = "year=".date('Y');
+                $cacheurl = $url.'&'.join('&',$params);
+                https_request($cacheurl);
+            }
+        }
+
+
+
+
+
+    }
+    //生成含入口脚本的URL地址
+    public function createRealUrl($params)
+    {
+        $url = WEB_URL.'index.html' ;
+        return  $url.'?r='.$params.'&docache=1';
+    }
+
+    public function getWhere($query, $params=[], $isnull = [])
+    {
+        $where = [];
+        $tables = [];
+        $tablefrom = $query->getTablesUsedInFrom();
+        foreach ($tablefrom as $v){
+            $tables[] = str_replace(array('{{%','}}'),"",$v);
+        }
+        foreach ((array)$query->join as $v){
+            $tables[] = str_replace(array('{{%','}}'),"",$v[1]);
+        }
+
+        $yeartables = [
+            'f_car_condition'=>'year',
+            'f_cars_detail_data'=>'year',
+            'f_deta_illegal_using_car'=>'year',
+            'f_fluc_cost_hkm'=>'year',
+            'f_fluc_fuel_hkm'=>'year',
+            'f_fluc_illegal_using_car'=>'year',
+            'f_fluc_inefficient_car'=>'year',
+            'f_fuel_hkm'=>'year',
+            'f_mileage_attend'=>'year',
+            'f_one_car_cost'=>'year',
+            'f_one_car_one_table'=>'year_info',
+            'f_operating_cost_monitor'=>'year',
+            'f_rent_car_cost'=>'year',
+            'f_stats_cost_avg'=>'year',
+            'f_stats_cost_hkm'=>'year',
+            'f_stats_fuel_hkm'=>'year',
+            'f_stats_illegal_using_car'=>'year',
+            'f_stats_inefficient_car'=>'year',
+            'f_t_car_status'=>'year',
+            'f_t_car_status_fuel'=>'year',
+            'f_t_one_car_avg'=>'year',
+            'f_violating_order'=>'year',
+            'f_year_car_cost'=>'year',
+        ];
+
+        $citytables = [
+            'f_car_info'=>'city',
+            'f_cars_detail_data'=>'city',
+            'f_cost_abn_order'=>'city',
+            'f_fluc_cost_hkm'=>'city',
+            'f_fluc_fuel_hkm'=>'city',
+            'f_fluc_illegal_using_car'=>'city',
+            'f_fluc_inefficient_car'=>'city',
+            'f_stats_cost_avg'=>'city',
+            'f_stats_cost_hkm'=>'city',
+            'f_stats_fuel_hkm'=>'city',
+            'f_stats_illegal_using_car'=>'city',
+            'f_stats_inefficient_car'=>'city',
+            'f_t_car_status'=>'city',
+            'f_t_one_car_avg'=>'city',
+            'f_year_car_cost'=>'city',
+        ];
+        //序列化查询语句
+        $_where = [];
+        foreach ($tables as $v){
+            if($this->carCity && in_array($v,array_keys($citytables))){
+                $_where[$citytables[$v]] = $this->carCity;
+            }
+            if($this->carYears && in_array($v,array_keys($yeartables))){
+                $_where[$yeartables[$v]] = $this->carYears;
+            }
+        }
+        foreach ($_where as $k=>$v){
+            $where[] =  $k . (is_array($v) ? ( count($v)>1 ? " in ('".implode("','",$v)."')" : " = '".current($v)."'") : " = '".$v."'");
+        }
+
+
+
+        //日期选择
+        $yearField = 'year';
+        $monthField = 'month';
+        foreach ($tables as $v){
+            if($v=='f_one_car_one_table') {
+                $yearField = 'year_info';
+                $monthField = 'month_info';
+            }
+        }
+        if(!empty($params['start_date'])&&!empty($params['end_date']))
+        {
+            $startdateInfo = explode('-',$params['start_date']);
+            $start_year =   $startdateInfo[0];
+            $start_month = intval($startdateInfo[1]);
+            $enddateInfo = explode('-',$params['end_date']);
+            $end_year =    $enddateInfo[0];
+            $end_month = intval($enddateInfo[1]);
+            if(!empty($start_year)&&!empty($end_year))$where[] = " ($yearField>=$start_year and $yearField<=$end_year) ";
+            if(!empty($start_month)&&!empty($end_month))$where[] = " ($monthField>=$start_month and $monthField<=$end_month) ";
+        }
+        if(!empty($params['date'])) {
+            $dateInfo = explode('-', $params['date']);
+            $year = $dateInfo[0];
+            $month = intval($dateInfo[1]);
+            if(!empty($year))$where[] = " $yearField = $year ";
+            if(!empty($month))$where[] = " $monthField = $month ";
+        }
+
+        //地市选择
+        if(!empty($params['city'])||!empty($params['city_1'])||!empty($params['city_2'])||!empty($params['city_3']))
+        {
+            if($params['city_3'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_3']);
+            }
+            else if($params['city_2'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_2']);
+            }
+            else if($params['city_1'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_1']);
+            }
+            if(!empty($cityInfo[0]))$where[] = " city = '".$cityInfo[0]."' ";
+            if(!empty($cityInfo[1])){
+                $where[] = " dpt_sec = '".$cityInfo[1]."' ";
+            }elseif(in_array('dpt_sec',$isnull)){
+                $where[] = !empty($cityInfo[0]) ? " dpt_sec is not null " : " dpt_sec is null ";
+            }
+            if(!empty($cityInfo[2])){
+                $where[] = " grid = '".$cityInfo[2]."' ";
+            }elseif(in_array('grid',$isnull)){
+                $where[] = !empty($cityInfo[1]) ? " grid is not null " : " grid is null ";
+            }
+        }
+
+        if(!empty($params['card_num']))$where[] = " card_num = '".$params['card_num']."' ";
+
+        if(!empty($params['car_type'])){
+            $where[] = " car_type = '".$params['car_type']."' ";
+        }elseif(in_array('car_type',$isnull)){
+            $where[] = " car_type is null ";
+        }
+
+        if(!empty($params['using_tag'])){
+            $where[] = " using_tag = '".$params['using_tag']."' ";
+        }elseif(in_array('using_tag',$isnull)){
+            $where[] = " using_tag is null ";
+        }
+        if(!empty($params['self_rent'])){
+            $where[] = " self_rent = '".$params['self_rent']."' ";
+        }elseif(in_array('self_rent',$isnull)){
+            $where[] = " self_rent is null ";
+        }
+        if(!empty($params['car_src'])){
+            $where[] = " car_src = '".$params['car_src']."' ";
+        }elseif(in_array('car_src',$isnull)){
+            $where[] = " car_src is null ";
+        }
+        return $where;
+    }
+
+
+    /*
+     * 取得一车一表SQL语句或数据
+     */
+    public function getOneCarOneTable($params=[],$field = '*',$setYears=true,$ressql = true)
+    {
+        $params = $params ? $params : Yii::$app->request->get();
+
+        $tableschema = FOneCarOneTable::getTableSchema();
+        $columns = array_keys($tableschema->columns);
+        $query = FOneCarOneTable::find();
+        $where = [];
+
+        //限定年份数据
+        if($setYears && $this->carYears && $this->role_id>1 && in_array('year_info',$columns)){
+            $where[] =  'year_info' . (is_array($this->carYears) ? ( count($this->carYears)>1 ? " in ('".implode("','",$this->carYears)."')" : " = '".current($this->carYears)."'") : " = '".$this->carYears."'");
+        }
+        //没有设定年份,取当年
+        if(!empty($params['start_date'])&&!empty($params['end_date']))
+        {
+            $startdateInfo = explode('-',$params['start_date']);
+            $start_year =   $startdateInfo[0];
+            $start_month = intval($startdateInfo[1]);
+            $enddateInfo = explode('-',$params['end_date']);
+            $end_year =    $enddateInfo[0];
+            $end_month = intval($enddateInfo[1]);
+            if(!empty($start_year)&&!empty($end_year))$where[] = " (year_info>=$start_year and year_info<=$end_year) ";
+            if(!empty($start_month)&&!empty($end_month))$where[] = " (month_info>=$start_month and month_info<=$end_month) ";
+        }
+
+        if(!empty($params['date'])) {
+            $dateInfo = explode('-', $params['date']);
+            $year = $dateInfo[0];
+            $month = intval($dateInfo[1]);
+            if(!empty($year))$where[] = " year_info = $year ";
+            if(!empty($month))$where[] = " month_info = $month ";
+        }
+
+        foreach ($params as $k=>$v){
+            if(in_array($k,$columns) && trim($v)!==''&&$k!='city'){
+                if ($tableschema->columns[$k]->phpType=='string'){
+                    $where[] = $k . " = '".$v."'";
+                }else{
+                    $where[] = $k . " = ".$v;
+                }
+            }
+        }
+
+
+
+        if(!empty($where)){
+            $sql = join(" and ",$where);
+            $query->where($sql);
+        }
+        $query->select($field);
+        if($ressql){
+            return $query->createCommand()->getRawSql();
+        }else{
+            return $query->asArray()->all();
+        }
+
+    }
+
+    /*
+    * 取得车辆基础表SQL或数据
+    */
+    public function getCarInfo($params=[],$field = '*',$setCity=true,$ressql = true)
+    {
+        $params = $params ? $params : Yii::$app->request->get();
+        $tableschema = FCarInfo::getTableSchema();
+        $columns = array_keys($tableschema->columns);
+        $query = FCarInfo::find();
+        $where = [];
+        if($setCity && $this->carCity && $this->role_id>1 && in_array('city',$columns)){
+            $where[] =  'city' . (is_array($this->carCity) ? ( count($this->carCity)>1 ? " in ('".implode("','",$this->carCity)."')" : " = '".current($this->carCity)."'") : " = '".$this->carCity."'");
+        }
+        foreach ($params as $k=>$v){
+            if(in_array($k,$columns) && trim($v)!==''&&$k!='city'){
+                if($k=='card_num'){
+                    $where[] = $k . " LIKE '%".$v."%'";
+                }elseif ($tableschema->columns[$k]->phpType=='string'){
+                    $where[] = $k . " = '".$v."'";
+                }else{
+                    $where[] = $k . " = ".$v;
+                }
+            }
+        }
+        //地市选择
+        if(!empty($params['city'])||!empty($params['city_1'])||!empty($params['city_2'])||!empty($params['city_3']))
+        {
+            if($params['city_3'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_3']);
+            }
+            else if($params['city_2'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_2']);
+            }
+            else if($params['city_1'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_1']);
+            }
+            if(!empty($cityInfo[0]))$where[] = " city = '".$cityInfo[0]."' ";
+            if(!empty($cityInfo[1])) $where[] = " dpt_sec = '".$cityInfo[1]."' ";
+            if(!empty($cityInfo[2]))$where[] = " grid = '".$cityInfo[2]."' ";
+        }
+        //附加的地市条件
+        if(!empty($params['city_name_1'])||!empty($params['city_name_2'])||!empty($params['city_name_3']))
+        {
+            if(!empty($params['city_name_1']))$where[] = " city = '".$params['city_name_1']."' ";
+            if(!empty($params['city_name_2'])) $where[] = " dpt_sec = '".$params['city_name_2']."' ";
+            if(!empty($params['city_name_3']))$where[] = " grid = '".$params['city_name_3']."' ";
+        }
+
+        if(!empty($where)){
+            $sql = join(" and ",$where);
+            $query->where($sql);
+        }
+        $query->select($field);
+        if($ressql){
+            return $query->createCommand()->getRawSql();
+        }else{
+            return $query->asArray()->all();;
+        }
+
+    }
+    /*
+    * 拼接评价报表SQL及取得分页数据
+    */
+    public function getPingjiaData($table,$field='*',$params=[],$all=0)
+    {
+        $params = $params ? $params : Yii::$app->request->get();
+        if(!empty($params['city_1'])||!empty($params['city_2'])||!empty($params['city_3']))
+        {
+            if($params['city_3'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_3']);
+            }
+            else if($params['city_2'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_2']);
+            }
+            else if($params['city_1'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_1']);
+            }
+            $params['city'] = $cityInfo[0];
+            $params['dpt_sec'] = $cityInfo[1];
+            $params['grid'] = $cityInfo[2];
+        }
+        $groupby = 'ci.city';
+
+        if(!empty($params['city'])){
+            $groupby = 'ci.dpt_sec';
+            $field .= ',ci.dpt_sec';
+        }
+
+        if(!empty($params['dpt_sec'])){
+            $groupby = 'ci.grid';
+            $field .= ',ci.grid';
+        }
+
+        if(!empty($params['card_num'])){
+            $groupby = 'ci.card_num';
+            $field .= ',ci.card_num,ci.self_rent,ci.car_type,ci.using_tag';
+        }
+
+        if(!empty($params['grid']) && stripos($table,'card_num')!==false){
+            $groupby = 'ci.card_num';
+            $field .= ',ci.card_num,ci.self_rent,ci.car_type,ci.using_tag';
+        }
+
+        if(!empty($params['car_type'])){
+            $field .= ',ci.car_type';
+        }
+
+        if(!empty($params['using_tag'])){
+            $field .= ',ci.using_tag';
+        }
+
+        if(!empty($params['self_rent'])){
+            $field .= ',ci.self_rent';
+        }
+
+        if($all==0)
+        {
+            $count_sql = 'SELECT `city` FROM '.$table. ' GROUP BY ' . $groupby;
+
+            $connection = Yii::$app->db;
+            $count = count($connection->createCommand($count_sql)->queryAll());
+
+            $sql = 'SELECT '. $field .' FROM '.$table. ' GROUP BY ' . $groupby;
+        }
+        else
+        {
+            $count_sql = 'SELECT `city` FROM '.$table;
+
+            $connection = Yii::$app->db;
+            $count = count($connection->createCommand($count_sql)->queryAll());
+
+            $sql = 'SELECT '. $field .' FROM '.$table;
+        }
+        //没有设定年份,取当年
+        if(!empty($params['start_date'])&&!empty($params['end_date']))
+        {
+            $startdateInfo = explode('-',$params['start_date']);
+            $start_year =   $startdateInfo[0];
+            $start_month = intval($startdateInfo[1]);
+            $enddateInfo = explode('-',$params['end_date']);
+            $end_year =    $enddateInfo[0];
+            $end_month = intval($enddateInfo[1]);
+            $year = !empty($end_year) ? $end_year : date('Y');
+        }
+        else
+        {
+            $year = !empty($params['year']) ? $params['year'] : date('Y');
+            $start_month = intval($params['start_month'])?intval($params['start_month']):1;
+            $end_month = intval($params['end_month'])?intval($params['end_month']):12;
+        }
+
+
+
+
+        $sql = str_replace(['年份','起始月份','终止月份'],[$year,$start_month,$end_month],$sql);
+
+        //排序
+        if(isset($params['sort']))
+        {
+            $sql .= ' ORDER BY ' .$params['sort'].' '.(isset($params['sortOrder']) && $params['sortOrder']=='asc'?'ASC':'DESC');
+        }
+
+        //分页
+        if(isset($params['limit'])){
+            $sql .= ' LIMIT ';
+            if(isset($params['offset'])){
+                $sql .= $params['offset']. ',';
+            }
+            $sql .= $params['limit'];
+        }
+
+
+        $data = $connection->createCommand($sql)->queryAll();
+        if(!empty($data[0]['city']))
+        {
+            $data = $this->arrayByArraySort($data,$this->cityOptions,'city');
+        }
+
+
+        return ["total"=>$count,"totalNotFiltered"=>$count,"rows"=>$data];
+
+    }
+    function arrayByArraySort($data,$sort,$column=null){
+        $temp = [];
+        if (!is_null($column)){
+            foreach ($data as $item){
+                $temp[$item[$column]][] = $item;
+            }
+        }else{
+            foreach ($data as $key => $item){
+                $temp[$key] = [$item];
+            }
+        }
+
+        $ret = [];
+        foreach ($sort as $sortum){
+            if (isset($temp[$sortum])){
+                $ret = array_merge($ret,$temp[$sortum]);
+            }
+        }
+        $ret = array_values($ret);
+        return $ret;
+
+    }
+
+    /*
+    * 取得车辆详情表SQL或数据
+    */
+    public function getCarsDetailData($params=[],$field = '*',$setYears=true,$ressql = true)
+    {
+        $params = $params ? $params : Yii::$app->request->get();
+        $tableschema = FCarsDetailData::getTableSchema();
+        $columns = array_keys($tableschema->columns);
+        $query = FCarsDetailData::find();
+        $where = [];
+        if($setYears && $this->carYears && $this->role_id>1 && in_array('year',$columns)){
+            $where[] =  'year' . (is_array($this->carYears) ? ( count($this->carYears)>1 ? " in ('".implode("','",$this->carYears)."')" : " = '".current($this->carYears)."'") : " = '".$this->carYears."'");
+        }
+        foreach ($params as $k=>$v){
+            if(in_array($k,$columns) && trim($v)!==''){
+                if ($tableschema->columns[$k]->phpType=='string'){
+                    $where[] = $k . " = '".$v."'";
+                }else{
+                    $where[] = $k . " = ".$v;
+                }
+            }
+        }
+
+        //没有设定年份,取当年
+        if(!empty($params['start_date'])&&!empty($params['end_date']))
+        {
+            $startdateInfo = explode('-',$params['start_date']);
+            $start_year =   $startdateInfo[0];
+            $start_month = intval($startdateInfo[1]);
+            $enddateInfo = explode('-',$params['end_date']);
+            $end_year =    $enddateInfo[0];
+            $end_month = intval($enddateInfo[1]);
+            if(!empty($start_year)&&!empty($end_year))$where[] = " (year>=$start_year and year<=$end_year) ";
+            if(!empty($start_month)&&!empty($end_month))$where[] = " (month>=$start_month and month<=$end_month) ";
+        }
+
+        if(!empty($params['date'])) {
+            $dateInfo = explode('-', $params['date']);
+            $year = $dateInfo[0];
+            $month = intval($dateInfo[1]);
+            if(!empty($year))$where[] = " year = $year ";
+            if(!empty($month))$where[] = " month = $month ";
+        }
+
+        if(!empty($where)){
+            $sql = join(" and ",$where);
+            $query->where($sql);
+        }
+        $query->select($field);
+        if($ressql){
+            return $query->createCommand()->getRawSql();
+        }else{
+            return $query->asArray()->all();
+        }
+
+    }
+
+}

+ 30 - 0
commands/value.log

@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 54 - 0
common/components/BaiduCpc.php

@@ -0,0 +1,54 @@
+<?php
+namespace app\common\components;
+use Yii;
+/**
+ * Class APIDemo API回传数据Demo
+ */
+class BaiduCpc {
+
+    const BAIDU_OCPC_URL = 'https://ocpc.baidu.com/ocpcapi/api/uploadConvertData';
+    const RETRY_TIMES = 3;
+
+    /**
+     * @param $token
+     * @param $conversionTypes
+     * @return bool 发送成功返回true,失败返回false
+     */
+    public function sendConvertData($token, $conversionTypes) {
+        $reqData = array('token' => $token, 'conversionTypes' => $conversionTypes);
+        $reqData = json_encode($reqData);
+        // 发送完整的请求数据
+        // do some log
+        //print_r('req data: ' . $reqData . "\n");
+        // 向百度发送数据
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_POST, 1);
+        curl_setopt($ch, CURLOPT_URL, self::BAIDU_OCPC_URL);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $reqData);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
+                'Content-Type: application/json; charset=utf-8',
+                'Content-Length: ' . strlen($reqData)
+            )
+        );
+        // 添加重试,重试次数为3
+        for ($i = 0; $i < self::RETRY_TIMES; $i++) {
+            $response = curl_exec($ch);
+            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+            if ($httpCode === 200) {
+                // 打印返回结果
+                // do some log
+                //print_r('retry times: ' . $i . ' res: ' . $response . "\n");
+                $res = json_decode($response, true);
+                // status为4,代表服务端异常,可添加重试
+                $status = $res['header']['status'];
+                if ($status !== 4) {
+                    curl_close($ch);
+                    return $status === 0;
+                }
+            }
+        }
+        curl_close($ch);
+        return false;
+    }
+}

+ 79 - 0
common/components/CacheId.php

@@ -0,0 +1,79 @@
+<?php
+namespace app\common\components;
+use Yii;
+class CacheId 
+{
+	static function getInitCls()
+	{
+		static $initCls = NULL;
+		if(!isset($initCls)) $initCls = new CacheId();
+		return $initCls;
+	
+	}
+
+    //模型字段缓存文件
+    static function modelFieldCacheId($model_id)
+    {
+        return 'modelfield_'.$model_id;
+    }
+
+    //内容模型缓存文件
+    static function modelListCacheId()
+    {
+        return 'modellist';
+    }
+
+    //栏目缓存文件ID
+    static function categoryCacheId()
+    {
+        return 'categorys';
+    }
+
+    //内容模型下的栏目Item缓存
+    static function categoryItemsCacheId($model_id)
+    {
+        return 'category_items_'.$model_id;
+    }
+
+    //来源
+    static function copyFromCacheId()
+    {
+        return 'copyfrom';
+    }
+
+    //用户组
+    static function groupCacheId()
+    {
+        return 'grouplist';
+    }
+
+    //联动菜单数据缓存
+    static function linkMenuCacheId($id)
+    {
+        return 'linkmenu_'.$id;
+    }
+
+    //导航
+    static function navCacheId()
+    {
+        return 'nav';
+    }
+
+    //推荐位
+    static function positionCacheId()
+    {
+        return 'position';
+    }
+
+    static function typeCacheId()
+    {
+        return 'typelist';
+    }
+
+    //系统配置
+    static function siteConfigCacheId()
+    {
+        return 'siteconfig';
+    }
+
+}

+ 90 - 0
common/components/Dozip.php

@@ -0,0 +1,90 @@
+<?php
+namespace app\common\components;
+use Yii;
+/*
+*   $res = new MakeZip($dir,$zipName);
+*@ $dir是被压缩的文件夹名称,可使用路径,例 'a'或者'a/test.txt'或者'test.txt'
+*@ $zipName是压缩后的压缩包名称,可使用路径,例 'a/test.zip'或者'test.zip'
+**/
+class Dozip {
+    private $_dir;
+    private $_zipDir;
+    private $_zipName;
+
+    public function __construct($dir,$zipName) {
+        $this->_dir = $dir;
+        $this->_zipDir = basename($dir);
+        $this->_zipName = $zipName;
+        $this->mkdirs();
+        $this->creat();
+    }
+    //检测并生成目录
+    private function mkdirs() {
+        if (!is_dir(dirname($this->_zipName))) {
+            $arr = explode('/', dirname($this->_zipName));
+            $arrs = '';
+            foreach($arr as $value) {
+                if (!is_dir($arrs.$value)) {
+                    if (!!mkdir($arrs.$value)) {
+                        $arrs .= $value.'/';
+                    }
+                }
+            }
+        }
+    }
+    //生成Zip压缩包
+    private function creat() {
+        $zip = new \ZipArchive;
+        if (is_dir($this->_dir)) {
+            $this->readDir($this->_dir,$files);
+            if ($zip->open($this->_zipName,\ZipArchive::OVERWRITE|\ZipArchive::CREATE)) {
+                foreach ($files as $value) {
+                    preg_match('/\/('.$this->_zipDir.'\/.*)/', $value, $match);
+                    if (is_dir($value)) {
+                        $zip->addEmptyDir($value, $match[1]);
+                    } else {
+                        $zip->addFile($value, $match[1]);
+                        $zip->renameName($value,$this->_zipDir);
+                    }
+                }
+                $zip->close();
+            }
+        } else {
+            if ($zip->open($this->_zipName,\ZipArchive::OVERWRITE|\ZipArchive::CREATE)) {
+                $zip->addFile($this->_dir, basename($this->_dir));
+            }
+        }
+    }
+
+    //读取文件夹所有文件
+    private function readDir($dir,&$arr) {
+        if ($dirs = opendir($dir)) {
+            while (($file=readdir($dirs)) != false) {
+                if ($file == '.' || $file == '..') continue;
+                $files = $dir .'/'. $file;
+                if (is_dir($files) && $this->isEmpty($files)) {
+                    $this->readDir($files,$arr);
+                } else {
+                    $arr[] = $files;
+                }
+            }
+        }
+        closedir($dirs);
+    }
+
+    //判断文件夹是否为空
+    private function isEmpty($dir) {
+        if ($dirs = opendir($dir)) {
+            while (($file=readdir($dirs)) != false) {
+                if($file != '.' && $file != '..') {
+                    closedir($dirs);
+                    return true;
+                    break;
+                }
+            }
+            closedir($dirs);
+            return false;
+        }
+    }
+}
+?>

+ 96 - 0
common/components/Emailer.php

@@ -0,0 +1,96 @@
+<?php
+//邮件发送集成
+namespace app\common\components;
+use app\models\EmailTpl;
+use app\models\EmailRecord;
+use app\models\EmailCert;
+use Yii;
+class Emailer
+{
+
+    /*
+     * $key:邮件模板key
+     * $mailAddress:可以是单个邮箱地址,也可以是数组形式的多个邮箱地址,如:['222@mail.com','333@mail.com']
+     * $args:模板参数示例:['name'=>'小知','code'=>'666666']
+     * $attachments:附件
+     * 代码示例: $mailer->send('sendcode',['171760754@qq.com','2629045294@qq.com'],array('code'=>222111,'brand'=>'知沃技术'),['https://www.test.com/upload/2022/05/22/16531799421b6dua.docx','https://www.test.com/upload/2022/05/22/1653179959jn0mu0.docx']);
+     */
+    public static function send($key,$mailAddress,$args=[],$attachments=[])
+    {
+        if(is_array($mailAddress)){
+            $addressList = $mailAddress;
+        }
+        else
+        {
+            $addressList[] = $mailAddress;
+        }
+        //生成邮件内容
+        $tpl = EmailTpl::find()->alias('a')->where("a.key='".$key."'")->one();
+        $msgcontent = $tpl->tpl;
+        if(is_array($args))foreach($args as $k=>$v)
+        {
+            $msgcontent = str_replace('${'.$k.'}',$v,$msgcontent);
+        }
+        //批量发送
+        $messages = [];
+        foreach ($addressList as $address) {
+            $mail =  Yii::$app->mailer->compose('default', [
+                'html' => 'html', //key固定,value是模版文件名
+                'title'=>$tpl->title,
+                'msgcontent' => $msgcontent,
+                'thbgcolor' => Yii::$app->params['mailer']['thbgcolor'],
+                'logo' => getFileUrl(Yii::$app->params['mailer']['logo']),
+                'fromtitle' => Yii::$app->params['mailer']['fromtitle'],
+                'team' => Yii::$app->params['mailer']['team'],
+                'app_url' => WEB_URL,
+            ]);
+            $mail->setTo($address);
+            if(is_array($attachments))foreach($attachments as $attachment)
+            {
+                $mail->attach($attachment);
+            }
+            $mail->setSubject($tpl->title);
+            $messages[] = $mail;
+            //写邮件发送记录
+            $record = new EmailRecord();
+            $record->title = $tpl->title;
+            $record->address = $address;
+            $record->content = $msgcontent;
+            $record->type = $tpl->type;
+            $record->sent_time = TIMESTAMP;;
+            $record->save();
+            if($tpl->type==1)
+            {
+                $mobileCert = new EmailCert();
+                $mobileCert->email = $address;
+                $mobileCert->user_id = 0;
+                $mobileCert->cert_key = strval($args['code']);
+                $mobileCert->request_from = REQUEST_FROM;
+                $mobileCert->sent_time = TIMESTAMP;
+                $mobileCert->save();
+            }
+        }
+        Yii::$app->mailer->sendMultiple($messages);
+        return true;
+       /* Yii::$app->mailer->compose('default', [
+            'html' => 'html', //key固定,value是模版文件名
+            'title'=>$tpl->title,
+            'msgcontent' => $msgcontent,
+            'thbgcolor' => Yii::$app->params['mailer']['thbgcolor'],
+            'logo' => getFileUrl(Yii::$app->params['mailer']['logo']),
+            'fromtitle' => Yii::$app->params['mailer']['fromtitle'],
+            'team' => Yii::$app->params['mailer']['team'],
+            'app_url' => WEB_URL,
+        ])
+        ->setTo('171760754@qq.com')
+        ->setSubject($tpl->title)
+        ->send();*/
+
+
+    }
+
+
+
+}
+
+?>

+ 241 - 0
common/components/FormElements.php

@@ -0,0 +1,241 @@
+<?php
+namespace app\common\components;
+use Yii;
+class FormElements
+{
+    static function getInstCls(){
+        static $m_instCls = null;
+        if (!isset($m_instCls)){$m_instCls = new FormElements();}
+        return $m_instCls;
+    }
+
+    /**树状父级选择栏
+     * @param $datas
+     * @param int $top_id  顶级Id
+     * @param int $menu_id 当前选中菜单ID
+     * @param string $name  对应显示标题的字段
+     * @param string $alt
+     * @param string $id
+     * @param string $property
+     * @return string
+     */
+    public static function tree_select($datas,$top_id = 0, $menu_id = 0, $select_name = 'parent_id', $alt = '' , $select_id ='', $property = 'class=\'\'')
+    {
+        $tree = new Tree;
+        $select_id = $select_id ? $select_id : $select_name;
+        $string = "<select  name='$select_name' id='$select_id'  $property>\n<option value=''>$alt</option>\n";
+        $str  = "<option value='\$id' \$selected>\$spacer \$name</option>";
+        $tree->init($datas);
+        $string .= $tree->get_tree($top_id, $str, $menu_id);
+        $string .= '</select>';
+        return $string;
+    }
+
+
+    //模型字段管理的一些初始参数
+    public static function getFieldsInfo($arg)
+    {
+        $info=array(
+            'types' => array(
+                'text'=>'单行文本',
+                'textarea'=>'多行文本',
+                'editor'=>'编辑器',
+                'cat_id'=>'栏目',
+                'title'=>'标题',
+                'box'=>'选项',
+                'image'=>'图片',
+                'images'=>'多图片',
+                'number'=>'数字',
+                'datetime'=>'日期和时间',
+                'pos_id'=>'推荐位',
+                'keywords'=>'关键词',
+                'author'=>'作者',
+                'copy_from'=>'来源',
+                'group_id'=>'用户组',
+                'is_link'=>'转向链接',
+                'template'=>'模板',
+                'pages'=>'分页选择',
+                'type_id'=>'类别',
+                'read_price'=>'金额、金币、积分',
+                'linkmenu'=>'联动菜单',
+                'downfiles'=>'多文件上传',
+                'map'=>'地图',
+                'omnipotent'=>'万能字段',
+                'sysconfig'=>'系统参数',
+                'ext_type'=>'扩展配置',
+            ),
+            //不允许添加的字段类型,这些字段讲不会在字段添加处显示
+            'not_allow_fields' => array('cat_id','type_id','title','keywords','pos_id','template','user_name'),
+            //允许添加但必须唯一的字段
+            'unique_fields' => array('pages','read_price','author','copy_from','is_link'),
+            //禁止被禁用的字段列表
+            'forbid_fields' => array('cat_id','title','url','template','user_name','create_time','update_time','list_order','status','ext_type'),
+            //禁止被删除的字段列表
+            'forbid_delete' => array('cat_id','type_id','title','thumb','keywords','description','is_position','url','status','template','user_name','list_order','update_time','create_time','ext_type'),
+            //可以追加 JS和CSS 的字段
+            'att_css_js' => array('text','textarea','box','number')
+        );
+
+        return $info[$arg];
+    }
+
+
+    /**
+     * 下拉选择框
+     */
+
+    public static function select($array = array(), $id = 0,  $default_option = '请选择' , $property = 'class=\'\'' )
+    {
+        $string = '<select '.$property.'>';
+        $default_selected = (empty($id) && $default_option) ? 'selected' : '';
+        if($default_option) $string .= "<option value='' $default_selected>$default_option</option>";
+        if(!is_array($array) || count($array)== 0) return false;
+        $ids = array();
+        if(isset($id)) $ids = explode(',', $id);
+        foreach($array as $key=>$value) {
+            $selected = in_array($key, $ids) ? 'selected' : '';
+            $string .= '<option value="'.$key.'" '.$selected.'>'.$value.'</option>';
+        }
+        $string .= '</select>';
+        return $string;
+    }
+
+    /**
+     * 单选框
+     *
+     * @param $array 选项 二维数组
+     * @param $id 默认选中值
+     * @param $property 属性
+     * @param $inlayui 使用 layui 样式
+     */
+
+    public static  function radio($array = array(), $id = 0, $property = '',$inlayui=0)
+    {
+        $string = '';
+        foreach($array as $key=>$value) {
+            $checked = trim($id)==trim($key) ? 'checked' : '';
+            if($inlayui==1)
+            {
+                $string .= '<input type="radio" '.$property.'  '.$checked.' value="'.$key.'" title="'.$value.'">';
+            }
+            else
+            {
+                $string .= '<div class="col-sm-auto">';
+                $string .= '<div class="form-check mt10">';
+                $string .= '<input type="radio" '.$property.'  '.$checked.' value="'.$key.'" >';
+                $string .= '<div class="form-check-label">'.$value.'</div>';
+                $string .= '</div>';
+                $string .= '</div>';
+            }
+        }
+        return $string;
+    }
+
+    /**
+     * 复选框
+     *
+     * @param $array 选项 二维数组
+     * @param $id 默认选中值,多个用 '逗号'分割
+     * @param $property 属性
+     * @param $inlayui 使用 layui 样式
+     */
+
+    public static function checkbox($array = array(), $id = '', $property = '',$inlayui=0)
+    {
+        $string = '';
+        $id = trim($id);
+        if($id != '') $id = strpos($id, ',') ? explode(',', $id) : array($id);
+        $i = 1;
+        foreach($array as $key=>$value) {
+            $key = trim($key);
+            $checked = ($id && in_array($key, $id)) ? 'checked' : '';
+            if($inlayui==1)
+            {
+                $string .= '<input type="checkbox" '.$property.' '.$checked.' value="'.htmlspecialchars($key).'" title="'.htmlspecialchars($value).'">';
+            }
+            else
+            {
+                $string .= '<div class="col-sm-auto">';
+                $string .= '<div class="form-check mt10">';
+                $string .= '<input type="checkbox" '.$property.'  '.$checked.' value="'.$key.'" >';
+                $string .= '<div class="form-check-label">'.$value.'</div>';
+                $string .= '</div>';
+                $string .= '</div>';
+            }
+            $i++;
+        }
+        return $string;
+    }
+
+    public static function switchbox($options = array(), $id = '', $property = '',$fieldname)
+    {
+        $string = '';
+        $checked =  $id ? 'checked' : '';
+        $string .='<div class="col-sm-auto  ">';
+        $string .= '<input  value="1"  '.$property.'  '.$checked.'  type="checkbox" switch="success" class="row-switch" id="'.$fieldname.'" >';
+        $string .= '<label class="switch-check-label mt10" for="'.$fieldname.'" data-on-label="'.$options[1].'" data-off-label="'.$options[0].'"></label>';
+        $string .= '</div>';
+        return $string;
+    }
+
+    //获得日期输入控件(依赖layui)
+    public static function dateForm($name,$value,$array)
+    {
+        $name = $array['name']?$array['name']:$name;
+        $dateFmt = $array['dateFmt'];
+        $minDate = $array['minDate'];
+        $maxDate = $array['maxDate'];
+        $vel = $array['vel'];
+        $velName = $array['velName'];
+        $readOnly = $array['readOnly']==1?"readonly":'';
+        $id = $array['id']?$array['id']:$array['defaultId'];
+        $string = '<input type="text" '.$readOnly.' value="'.$value.'" class="layui-input chooseDate form-control '.$array['require'].'" id="'.$id.'" name="'.$name.'" data-format="'.$dateFmt.'" autocomplete="off" data-pattern = "'.$array['pattern'].'" data-errtips = "'.$array['errortips'].'" >';
+        return $string;
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    //详情页模板选择
+    public static function select_template($themename, $device, $module, $id = '', $str = '', $pre = '') {
+        $themePath = Yii::$app->params['themePath'];
+        $templatedir  = $themePath.$themename.DIRECTORY_SEPARATOR.$device.DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.$module.DIRECTORY_SEPARATOR;
+        $config_path =  $themePath.$themename.DIRECTORY_SEPARATOR.'config.php';
+        $localdir = 'themes|'.$themename.'|'.$device.'|views|'.$module;
+        $templates = glob($templatedir.$pre.'*.php');
+        if(empty($templates)) return '<span style="color: #ff0000">没有可用模板</span>';
+        $files = @array_map('basename', $templates);
+        $names = array();
+        if(file_exists($config_path)) {
+            $names = include $config_path;
+        }
+        $templates = array();
+        if(is_array($files)) {
+            foreach($files as $file) {
+                $key = substr($file, 0, -4);
+                $templates[$key] = isset($names['file_explain'][$localdir][$file]) && !empty($names['file_explain'][$localdir][$file]) ? $names['file_explain'][$localdir][$file].'('.$file.')' : $file;
+            }
+        }
+        ksort($templates);
+        return self::select($templates, $id, '', $str);
+    }
+}
+
+?>

+ 138 - 0
common/components/MessageOne.php

@@ -0,0 +1,138 @@
+<?php
+namespace app\common\components;
+use app\common\components\SiteUrl;
+use app\modules\ucenter\models\Message;
+use app\modules\ucenter\models\User;
+use app\modules\ucenter\models\UserOpenAuth;
+use app\modules\doc\models\DocPaylog;
+use app\modules\plugins\models\MpMsgTpl;
+use app\modules\plugins\models\MpMsg;
+use app\components\WeiXin\WeiXin;
+use app\modules\ucenter\models\UserVipType;
+use Yii;
+class MessageOne
+{
+
+    //文档出售通知
+    public static function soldDoc($title,$doc,$left_coin)
+    {
+        if($doc->user_id)
+        {
+            $url = $doc->doc_type==2?SiteUrl::colDetail($doc->id):SiteUrl::docDetail($doc->id);
+            $msg = $title."<a href='".$url."' target='_blank'>《".$doc->title."》</a>";
+            self::sentMsg($doc->user_id,$title,$msg);
+            //微信模板消息
+            if(Yii::$app->params['mp']['openmsg'])
+            {
+                $args = [
+                    'title'=>$doc->title,
+                    'datetime'=>get_date(time()),
+                    'sellPrice'=>number_format($doc->coin_price,2).Yii::$app->params['coin']['coin_name'],
+                    'incomePrice'=>number_format($left_coin,2).Yii::$app->params['coin']['coin_name']
+                ];
+                self::sentWxMsg('sold_doc',$doc->user_id,$args,$url);
+            }
+        }
+
+    }
+    //文档分销通知
+    public static function commissionDoc($referer_id,$doc,$coin_num,$commission)
+    {
+        if($referer_id)
+        {
+            $url = $doc->doc_type==2?SiteUrl::colDetail($doc->id):SiteUrl::docDetail($doc->id);
+            //微信模板消息
+            if(Yii::$app->params['mp']['openmsg'])
+            {
+                $args = [
+                    'title'=>$doc->title,
+                    'datetime'=>get_date(time()),
+                    'sellPrice'=>number_format($coin_num,2).Yii::$app->params['coin']['coin_name'],
+                    'incomePrice'=>number_format($commission,2).Yii::$app->params['coin']['coin_name']
+                ];
+                self::sentWxMsg('commission_success',$referer_id,$args,$url);
+            }
+        }
+
+   }
+    //VIP分销通知
+    public static function commissionVip($referer_id,$userVipOrder,$commission)
+    {
+        if($referer_id)
+        {
+            $url = SiteUrl::vip();
+            $userVipType = UserVipType::findOne($userVipOrder->vip_type);
+            //微信模板消息
+            if(Yii::$app->params['mp']['openmsg'])
+            {
+                $args = [
+                    'title'=>$userVipType->title,
+                    'datetime'=>get_date(time()),
+                    'sellPrice'=>number_format($userVipOrder->money,2).'元',
+                    'incomePrice'=>number_format($commission,2).'元'
+                ];
+                self::sentWxMsg('commission_success',$referer_id,$args,$url);
+            }
+        }
+
+    }
+   //发送消息
+   public static function sentMsg($to_user,$subject,$content,$sent_user=0,$message_type=0,$to_group=0)
+   {
+       $msg = new Message();
+       $msg->to_user = $to_user;
+       $msg->subject = $subject;
+       $msg->content = $content;
+       $msg->sent_user = $sent_user;
+       $msg->message_type = $message_type;
+       $msg->to_group = $to_group;
+       $msg->sent_time = TIMESTAMP;
+       $msg->save();
+       return true;
+   }
+
+   //发送微信消息
+   public static function sentWxMsg($key,$user_id,$args,$url)
+   {
+       $openAuth = UserOpenAuth::find()->where("user_id=".$user_id." and app='mpmsg'")->one();
+       $openid = $openAuth->app_uid;
+       $tpl = MpMsgTpl::find()->alias('a')->where("a.key='".$key."'")->one();
+       if($openid&&$tpl)
+       {
+           $tplSettings = string2array($tpl->settings);
+           foreach($tplSettings as $tplSetting)
+           {
+               foreach($args as $k=>$v)
+               {
+                   $ks[] = '${'.$k.'}';
+                   $vs[] = $v;
+               }
+               $msgdata[$tplSetting['key']] = ['value'=>str_replace($ks,$vs,$tplSetting['value']),'color'=>$tplSetting['color']];
+           }
+           $wxargs = array(
+               'appId'=>Yii::$app->params['mp']['mpAppId'],
+               'appSecret'=>Yii::$app->params['mp']['mpAppSecret'],
+               'token'=>Yii::$app->params['mp']['mpToken'],
+           );
+           $weixin = new WeiXin($wxargs);
+           $weixin->init();
+           $result = $weixin->sendTemplateMsg($openid,$tpl->tpl_no,$msgdata,$url);
+           //写发送记录
+           $mpmsg = new MpMsg();
+           $mpmsg->subject = $key;
+           $mpmsg->user_id = $user_id;
+           $mpmsg->openid = $openid;
+           $mpmsg->content = array2string($msgdata);
+           $mpmsg->sent_time = TIMESTAMP;
+           $mpmsg->save();
+       }
+   }
+
+    //未读消息数
+    public static function msgNum($to_user)
+    {
+        $num = Message::find()->where("to_user=$to_user and have_read=0 and to_delete=0")->count();
+        return $num;
+    }
+
+}

+ 571 - 0
common/components/MultiSearchUrl.php

@@ -0,0 +1,571 @@
+<?php
+namespace app\common\components;
+use Yii;
+/**
+ * author: Jack.Chen
+ * create time: 15-3-31 上午9:46
+ * description: 多条件搜索URL处理
+ */
+class MultiSearchUrl{
+
+    public $url;//基础URL
+    public $conditions;//新传入的搜索条件
+    public $existConditions;//已经存在的搜索条件
+    public $keywordName = 'kw';//关键词参数名称keywordName
+    public $filterTypes;//待过滤搜索条件类型
+    public $conditionParamName='sch';
+    public $splitFlag = '-';//条件之间的分割符
+    public $orderTypeName = 'st';//排序条件键名
+    public $keyword='';
+    public $fieldConfig  =[];
+    public $sortConfig  =[];
+    public $filterAll = false;
+    //初始化实例
+    public static function getSelfInstance($params)
+    {
+        static $instance = null;
+        if(is_null($instance))
+        {
+            $instance = new MultiSearchUrl();
+        }
+        if(is_array($params)) extract($params);
+        if(isset($url))$instance->url = $url;
+        if(isset($fieldConfig))$instance->fieldConfig = $fieldConfig;
+        if(isset($sortConfig))$instance->sortConfig = $sortConfig;
+        if(isset($conditions)&&!empty($conditions)){
+            $instance->conditions = $conditions;
+        }
+        else
+        {
+            $instance->conditions = array();
+        }
+        foreach($instance->conditions as $k=>$v)
+        {
+            if($v==null)unset($instance->conditions[$k]);
+        }
+        if(isset($keywordName))$instance->keywordName = $keywordName;
+        if(isset($filterAll))$instance->filterAll = $filterAll;
+        if(!isset($filterAll))$instance->filterAll = false;
+        if(isset($filterTypes)&&!empty($filterTypes)){
+            $instance->filterTypes = $filterTypes;
+        }
+        else
+        {
+            $instance->filterTypes = array();
+        }
+        if(isset($_GET[$instance->keywordName]))$instance->keyword = safe_replace($_GET[$instance->keywordName]);
+        $instance->existConditions = $instance->getSearchConditions();
+        return $instance;
+    }
+    /**根据搜索条件组合后的Url(格式 a1-b2-c10)
+     * @param $conditions
+     * @return string
+     */
+    public function createSimpleSearchCondition()
+    {
+        $conditionStr = '';
+        $conditionList = array();
+        if(is_array($this->conditions))
+        {
+            foreach($this->conditions as $key=>$value)
+            {
+                $conditionList[] = $key.$value;
+            }
+        }
+        asort($conditionList);
+        if(!empty($conditionList))
+        {
+            $conditionStr = join($this->splitFlag,$conditionList);
+            $this->url .= $conditionStr.'/';
+        }
+        return $this->url;
+    }
+    /**在已有搜索条件上组合传入的搜索条件生成新的Url
+     * @return string
+     */
+    public function createSearchCondition()
+    {
+        //条件类型
+        $types = array();
+        $diffTypes = array();
+        $inputTypes = array();
+        if(is_array($this->existConditions))
+        {
+            foreach($this->existConditions as $condition)
+            {
+                $types[] = $this->_getTypeFromCondition($condition);
+            }
+        }
+
+
+        //排除掉传入的相同选项类型
+        if(!empty($types))$types = array_unique($types);
+        if(!empty($this->conditions))$inputTypes = array_keys($this->conditions);
+        if(isset($inputTypes)&&isset($diffTypes))$diffTypes = array_unique(array_diff($types,$inputTypes));
+        //排除掉已经存在的搜索条件中不满足条件的项目(被过滤的项目和被新传入条件替换的项目)
+        if(is_array($this->existConditions))
+        {
+            foreach($this->existConditions as $key=>$condition)
+            {
+                $type =$this->_getTypeFromCondition($condition);
+                if(empty($diffTypes)||(!in_array($type,$diffTypes)&&!empty($diffTypes))||in_array($type,$this->filterTypes)||$this->filterAll==true)
+                {
+                    unset($this->existConditions[$key]);
+                }
+            }
+        }
+        //对新传入条件排序
+        $conditionStr = '';
+        if(!empty($this->conditions))ksort($this->conditions);
+        $conditionList = array();
+        if(is_array($this->conditions))
+        {
+            foreach($this->conditions as $key=>$value)
+            {
+                if(!in_array($key,$diffTypes)||empty($this->existConditions))
+                {
+                    $conditionList[] = $key.$value;
+                }
+            }
+        }
+        //合并已有条件和新条件
+        if(is_array($this->existConditions)&&!empty($this->existConditions))
+        {
+            $conditionList = array_merge($conditionList,$this->existConditions);
+        }
+
+
+        return $this->_createUrl($conditionList);
+    }
+
+    /**选择不限帅选条件时候Url重新生成
+     * @return string
+     */
+    public function stickOut()
+    {
+        $conditionList = array();
+        if(!empty($this->existConditions))
+        {
+            foreach($this->existConditions as $condition)
+            {
+                $type = $this->_getTypeFromCondition($condition);
+                if(!in_array($type,$this->filterTypes))
+                {
+                    $conditionList[] = $condition;
+                }
+            }
+        }
+        return $this->_createUrl($conditionList);
+    }
+    /**获取当前帅选条件
+     * @return array|mixed
+     */
+    public function getSearchConditions()
+    {
+        $searchCondition = isset($_GET[$this->conditionParamName])?safe_replace($_GET[$this->conditionParamName]):array();
+        if(!empty($searchCondition))
+        {
+            $searchCondition = explode($this->splitFlag,$searchCondition);
+        }
+        return $searchCondition;
+    }
+    //当前条件类型
+    public function getConditionsTypes()
+    {
+
+        //条件类型
+        $types = array();
+        if(is_array($this->existConditions))
+        {
+            foreach($this->existConditions as $condition)
+            {
+                $types[] = $this->_getTypeFromCondition($condition);
+            }
+        }
+        return $types;
+    }
+
+    /**反序列化筛选条件
+     * @return array
+     */
+    public function sqllizeConditions()
+    {
+        $where = '';
+        $order = '';
+        $sortValue=null;//当前排序条件键值
+        $typeField = $this->getTypeFieldConfig();  //搜索条件键名和字段值对应关系
+
+        if(is_array($this->existConditions))
+        {
+            foreach($this->existConditions as $condition)
+            {
+                if(strpos($condition,$this->keywordName) === 0){
+                    $type = $this->keywordName;
+                    $value =  str_replace($this->keywordName,'',$condition);
+                }
+                else
+                {
+                    $type = $this->_getTypeFromCondition($condition);
+                    $value = $this->_getValueFromCondition($condition);
+                }
+
+                if($type==$this->orderTypeName)//如果为排序条件
+                {
+                    $sortInfo = $this->getSortConditionConfig($value);
+                    $order = " order by ".$sortInfo['order'];
+                    $sortValue = $value;
+                }
+                else
+                {
+                    if(isset($typeField[$type]))
+                    {
+                        $field = $typeField[$type]['field'];
+                        $flag = $typeField[$type]['flag'];
+                        $sqlType = $typeField[$type]['type'];
+                        switch($sqlType)
+                        {
+                            case 'cat_id':
+                                $where .= " and $field $flag $value ";
+                                break;
+                            case 'cat_ids':
+                                $where .= " and $field $flag '%,".$value.",%' ";
+                                break;
+                            case 'boollist':
+                                $field = $field[$value-1];
+                                $where .= " and $field = 1 ";
+                                break;
+                            case 'commonlike':
+                                $where .= " and $field like '%".$value."%'";
+                                break;
+                            case 'leftlike':
+                                $where .= " and $field like '%".$value."'";
+                                break;
+                            case 'rightlike':
+                                $where .= " and $field like '".$value."%'";
+                                break;
+                            case 'equals':
+                                $fieldRs = explode(",",$field);
+                                $kk = 0;
+                                $songwhere = '';
+                                foreach($fieldRs as $frs)
+                                {
+                                    if($kk==0){
+                                        $songwhere = " $frs $flag $value ";
+                                    }
+                                    else
+                                    {
+                                        $songwhere .= " or $frs $flag $value ";
+                                    }
+                                    $kk++;
+                                }
+                                $where .= " and ($songwhere) ";
+                                break;
+                            case 'equal':
+                                $where .= " and $field $flag $value ";
+                                break;
+                            case 'gt':
+                                $where .= " and $field $flag $value ";
+                                break;
+                            case 'lt':
+                                $where .= " and $field $flag $value ";
+                                break;
+                            case 'linkmenu':
+                                $menu = \app\models\Linkmenu::findOne($value);
+                                $childIds = $menu->arr_child_ids;
+                                $where .= !empty($childIds)?" and $field in($childIds) ":" and $field $flag $value ";
+                                break;
+                            case 'day':
+                                $starttime = TIMESTAMP-$value*24*3600;
+                                $where .= " and $field $flag $starttime ";
+                                break;
+                        }
+                    }
+                }
+            }
+        }
+        return array('order'=>$order,'where'=>$where,'sortValue'=>$sortValue);
+    }
+    //根据搜索选项类型获取搜索选项值
+    public function getSearchConditionValue($key,$onCondition)
+    {
+        if($onCondition)return;
+        if(!empty($this->existConditions))
+        {
+            foreach($this->existConditions as $condition)
+            {
+                $type = $this->_getTypeFromCondition($condition);
+                if($type==$key)
+                {
+                    return $this->_getValueFromCondition($condition);
+                    //return preg_replace('/'.$key.'+/','',$condition);
+                }
+            }
+        }
+    }
+
+    //根据最终的搜索条件生成URL
+    private function _createUrl($conditionList)
+    {
+        asort($conditionList);
+        if(strpos($this->url,'.html')!==false)
+        {
+            $this->url = str_replace('.html','',$this->url).'/';
+            $suffix = '.html';
+        }
+        if(!empty($conditionList))
+        {
+            $conditionStr = join("-",$conditionList);
+            $this->url.=$conditionStr.'/';
+            /*if(!empty($this->keyword))//如果有关键词,在搜索条件后增加关键词条件
+            {
+                $this->url .= $this->keywordName.'/'.$this->keyword.'/';
+            }*/
+        }
+        else
+        {
+            /*if(!empty($this->keyword))//如果有关键词,在搜索条件后增加关键词条件
+            {
+                $this->url .= $this->keywordName.'/'.$this->keyword.'/';
+            }*/
+        }
+        if($suffix!='')
+        {
+            return rtrim($this->url,'/').$suffix;
+        }
+        else
+        {
+            return $this->url;
+        }
+    }
+    //根据条件获取条件类型(如传入a1返回a)
+    public function _getTypeFromCondition($condition)
+    {
+        return preg_replace('/[0-9_]+/','',$condition);
+    }
+    //根据条件获取条件值(如传入a1返回1)
+    public function _getValueFromCondition($condition)
+    {
+        return preg_replace('/[a-zA-Z]+/','',$condition);
+    }
+    //根据搜索条件类型获取条件值
+    public function getConditionValueByType($searchConditions,$searchType)
+    {
+        if(is_array($searchConditions))foreach($searchConditions as $condition)
+        {
+            $type =   preg_replace('/[0-9]+/','',$condition);
+            $value = preg_replace('/[a-zA-Z]+/','',$condition);
+            if($type==$searchType)
+            {
+                return $value;
+            }
+        }
+    }
+
+    //获取搜索关键词
+    public function getKeyword($searchConditions)
+    {
+        if(is_array($searchConditions))foreach($searchConditions as $condition)
+        {
+            if(strpos($condition,$this->keywordName) === 0){
+                return str_replace($this->keywordName,'',$condition);
+            }
+        }
+    }
+
+    //搜索条件字段对应值配置
+    public function getTypeFieldConfig()
+    {
+        $array  = $this->fieldConfig;
+        /*$array = array(
+            'r'=>array('type'=>'linkmenu','flag'=>'=', 'field'=>'region_id'),
+            'c'=>array('type'=>'equal','flag'=>'=','field'=>'cat_id'),
+            't'=>array('type'=>'equal','flag'=>'=','field'=>'doc_type'),
+            't1'=>array('type'=>'equal','flag'=>'=','field'=>'ext_type1'),
+            't2'=>array('type'=>'equal','flag'=>'=','field'=>'ext_type2'),
+            't3'=>array('type'=>'equal','flag'=>'=','field'=>'ext_type3'),
+        );*/
+        return $array;
+    }
+
+    //排序条件配置
+    public function getSortConditionConfig($value = NULL)
+    {
+        $array  = $this->sortConfig;
+       /* $array =  array(
+            //文库
+            '1'=>array('value'=>1, 'order'=>'create_time desc','title'=>'按发布时间排序','tips'=>'点击按发布时间排序'),
+            '2'=>array('value'=>2, 'order'=>'down_num desc','title'=>'按下载数量排序','tips'=>'点击按下载数量排序'),
+            '3'=>array('value'=>3, 'order'=>'views desc','title'=>'按浏览数排序','tips'=>'点击按浏览数排序'),
+            //商城
+            '7'=>array('value'=>7, 'order'=>'sales desc','title'=>'按销量排序','tips'=>'按销量排序'),
+            '8'=>array('value'=>8, 'order'=>'sales asc','title'=>'按销量排序','tips'=>'按销量排序'),
+            '9'=>array('value'=>9, 'order'=>'market_price desc','title'=>'按价格排序','tips'=>'按价格排序'),
+            '10'=>array('value'=>10, 'order'=>'market_price asc','title'=>'按价格排序','tips'=>'按价格排序'),
+            '11'=>array('value'=>11, 'order'=>'create_time desc','title'=>'按上架时间排序','tips'=>'按销量排序'),
+            '12'=>array('value'=>12, 'order'=>'create_time asc','title'=>'按上架时间排序','tips'=>'按销量排序'),
+            '999'=>array('value'=>999, 'order'=>'is_recommend desc','title'=>'推荐','tips'=>'推荐'),
+            '1000'=>array('value'=>1000, 'order'=>'is_recommend asc','title'=>'推荐','tips'=>'推荐'),
+            //论坛
+            '13'=>array('value'=>13, 'order'=>'create_time desc','title'=>'按最新','tips'=>'按最新'),
+            '14'=>array('value'=>14, 'order'=>'post_num desc','title'=>'按热议','tips'=>'按热议'),
+            '15'=>array('value'=>15, 'order'=>'reward desc','title'=>'按报酬排序','tips'=>'按报酬排序'),
+            '16'=>array('value'=>16, 'order'=>'reward asc','title'=>'按报酬排序','tips'=>'按报酬排序'),
+            '17'=>array('value'=>17, 'order'=>'stock desc','title'=>'按需求数量排序','tips'=>'按需求数量排序'),
+            '18'=>array('value'=>18, 'order'=>'stock asc','title'=>'按需求数量排序','tips'=>'按需求数量排序'),
+        );*/
+        if(!is_null($value))
+        {
+            return $array[$value];
+        }
+        else
+        {
+            return $array;
+        }
+    }
+
+}
+/* HTML 示例:
+<div class="ts_header">
+    <div class="ts_head_grade">
+        <p>所在年级:</p>
+        <li <?php if(!in_array('c',$conditionsTypes)){ ?>class="on" <?php }?>> <a  href="<?php echo MultiSearchUrl::getSelfInstance(array('url'=>Url::allCourse(),'filterTypes'=>array('c')))->createSearchCondition();?>">全部</a></li>
+        <?php if(!empty($catList)&&is_array($catList))foreach($catList as $cat){?>
+        <li <?php if(in_array('c'.$cat['cat_id'],$searchConditions)){?> class="on" <?php }?>><a  href="<?php echo MultiSearchUrl::getSelfInstance(array('url'=>Url::allCourse(),'conditions'=>array('c'=>$cat['cat_id'])))->createSearchCondition();?>"><?php echo $cat['cat_name'];?>
+            </a></li>
+        <?php }?>
+        <div class="clear"></div>
+    </div>
+    <?php if($childCatList){?>
+    <div class="ts_head_hig" >
+        <div class="ts_head_hig_cot" style="padding-left: 104px;">
+
+            <?php if(!empty($childCatList)&&is_array($childCatList))foreach($childCatList as $cat){?>
+                <li <?php if(in_array('c'.$cat['cat_id'],$searchConditions)){?> class="on" <?php }?>><a  href="<?php echo MultiSearchUrl::getSelfInstance(array('url'=>Url::allCourse(),'conditions'=>array('c'=>$cat['cat_id'])))->createSearchCondition();?>"><?php echo $cat['cat_name'];?>
+                    </a></li>
+            <?php }?>
+
+            <div class="clear"></div>
+        </div>
+    </div>
+    <?php }?>
+    <?php if($getTypeList){?>
+    <div class="ts_head_class">
+        <div class="ts_head_class_cot">
+            <p>课程分类:</p>
+            <li <?php if(!in_array('t',$conditionsTypes)){ ?>class="on" <?php }?>> <a  href="<?php echo MultiSearchUrl::getSelfInstance(array('url'=>Url::allCourse(),'filterTypes'=>array('t')))->createSearchCondition();?>">全部</a></li>
+            <?php if(!empty($getTypeList)&&is_array($getTypeList))foreach($getTypeList as $type){?>
+                <li <?php if(in_array('t'.$type['type_id'],$searchConditions)){?> class="on" <?php }?>><a  href="<?php echo MultiSearchUrl::getSelfInstance(array('url'=>Url::allCourse(),'conditions'=>array('t'=>$type['type_id'])))->createSearchCondition();?>"><?php echo $type['name'];?></a></li>
+            <?php }?>
+            <div class="clear"></div>
+        </div>
+    </div>
+    <?php }?>
+    <div class="ts_head_class">
+        <div class="ts_head_class_cot">
+        <p>授课方式:</p>
+        <li <?php if(!in_array('tt',$conditionsTypes)){ ?>class="on" <?php }?>> <a  href="<?php echo MultiSearchUrl::getSelfInstance(array('url'=>Url::allCourse(),'filterTypes'=>array('tt')))->createSearchCondition();?>">全部</a></li>
+        <?php if($teachTypeList)foreach($teachTypeList as $key=>$name){
+              if($key==Yii::app()->params['weiCourseTypeId'])continue;
+         ?>
+            <li <?php if(in_array('tt'.$key,$searchConditions)){?> class="on" <?php }?>><a  href="<?php echo MultiSearchUrl::getSelfInstance(array('url'=>Url::allCourse(),'conditions'=>array('tt'=>$key)))->createSearchCondition();?>"><?php echo $name;?></a></li>
+        <?php }?>
+        </div>
+     </div>
+</div>
+
+*/
+
+
+/*php示例
+
+ public function actionAllCourse()
+    {
+        //初始化栏目信息
+        $topCat = $this->categorys[Yii::app()->params['teacherCatId']];
+        $catList =  array();
+        $catIds = explode(",",$topCat['arr_child_id']);
+        if(is_array($catIds))foreach($catIds as $id)
+        {
+            $cat = $this->categorys[$id];
+            if($cat['cat_id']!=$topCat['cat_id'])
+            {
+                $catList[] = $cat;
+            }
+        }
+        //解析组合条件
+        $searchConditions = MultiSearchUrl::getSelfInstance(array())->getSearchConditions();
+        $childCatList = array();
+        $currentCatId = $this->_getCatId($searchConditions);
+        if($this->categorys[$currentCatId]['arr_child_id'])
+        {
+            $catIds = explode(",", $this->categorys[$currentCatId]['arr_child_id']);
+            if(is_array($catIds))foreach($catIds as $id)
+            {
+                $cat = $this->categorys[$id];
+                if($cat['cat_id']!=$currentCatId)
+                {
+                    $childCatList[] = $cat;
+                }
+            }
+        }
+        //当选取三级栏目时候的处理
+        if($currentCatId&&!$childCatList)
+        {
+            $catIds = explode(",", $this->categorys[$this->categorys[$currentCatId]['parent_id']]['arr_child_id']);
+            if(is_array($catIds))foreach($catIds as $id)
+            {
+                $cat = $this->categorys[$id];
+                if($cat['cat_id']!=$this->categorys[$currentCatId]['parent_id'])
+                {
+                    $childCatList[] = $cat;
+                }
+            }
+        }
+        //类别
+        if($currentCatId)
+        {
+
+             $typeList = json_decode(Yii::app()->filecache->get(CacheId::typeCacheId($this->siteId)),true);
+
+             if($this->categorys[$currentCatId]['usable_type'])
+             {
+                 $types = explode(",",$this->categorys[$currentCatId]['usable_type']);
+                 if(is_array($types))foreach($types as $typeId)
+                 {
+                     $getTypeList[] = $typeList[$typeId];
+                 }
+             }
+        }
+        $teachTypeList = Yii::app()->params['options']['teachType'];
+
+        $keyword = isset($_GET[MultiSearchUrl::getSelfInstance()->keywordName])?safe_replace($_GET[MultiSearchUrl::getSelfInstance()->keywordName]):'';
+       //获取搜索条件类型
+        $conditionsTypes = MultiSearchUrl::getSelfInstance()->getConditionsTypes();
+        //分页参数
+        $page = isset($_GET['page'])?intval($_GET['page']):1;
+        $pageSize = Yii::app()->params['teacherPageSize'];
+        $offset = ($page-1)*$pageSize;
+        //解析SQL
+        $sqlInfo  = MultiSearchUrl::getSelfInstance(array())->sqllizeConditions();
+        $where = " where  status=1 ";
+
+        $where .= !empty($sqlInfo['where'])?$sqlInfo['where']:'';
+        $likeStr  = !empty($keyword)?" and (title like '%".$keyword."%')":'';
+        $orderStr = !empty($sqlInfo['order'])?$sqlInfo['order']:' order by point desc';
+
+
+        $sqlCount = "select count(distinct(user_name)) as count from {{cource}} $where $likeStr";
+
+        $sqlList = "select * from (select * from {{user}} where user_name in(select distinct(user_name) from {{cource}} $where ) $orderStr limit $offset,$pageSize ) a left join {{user_teacher}} b on a.user_id=b.user_id ";
+        $countModel = Yii::app()->db->createCommand($sqlCount);
+        $result = $countModel->queryAll();
+        $count = $result[0]['count'];
+        $listModel = Yii::app()->db->createCommand($sqlList);
+        $resultlist = $listModel->queryAll();
+        $pages = new CPagination($count);
+        $pages->pageSize = intval($pageSize);
+        $this->render('allcourse',array('resultlist'=>$resultlist,'pages'=>$pages,'catList'=>$catList,'searchConditions'=>$searchConditions,'conditionsTypes'=>$conditionsTypes,'childCatList'=>$childCatList,'getTypeList'=>$getTypeList,'teachTypeList'=>$teachTypeList));
+    }
+*/
+
+

+ 290 - 0
common/components/Oss.php

@@ -0,0 +1,290 @@
+<?php
+namespace app\common\components;
+define('__BOS_CLIENT_ROOT', dirname(__DIR__));
+include BASE_PATH.'components'.DIRECTORY_SEPARATOR.'bce'.DIRECTORY_SEPARATOR.'BaiduBce.phar';
+use OSS\OssClient;
+use OSS\Core\OssException;
+use Aws\S3\S3Client;
+use Aws\S3\MultipartUploader;
+use Aws\S3\Exception\S3Exception;
+use Aws\Exception\AwsException;
+use Aws\Exception\MultipartUploadException;
+use Aws\S3\ObjectUploader;
+use \BaiduBce\BceClientConfigOptions;
+use \BaiduBce\Util\MimeTypes;
+use \BaiduBce\Http\HttpHeaders;
+use \BaiduBce\Services\Bos\BosClient;
+use Yii;
+class Oss
+{
+    public $ossClient;
+    public $ossUrl;
+    public $ossInerUrl;
+    public $accessKeyId;
+    public $accessKeySecret;
+    public $endpoint;
+    public $bucket;
+    public $region;
+    public $type;
+    public $cname;
+    public function init($internal=0)
+    {
+        $this->ossUrl = getOssUrl();
+        $this->ossInerUrl = getOssInterUrl();
+        $this->accessKeyId = Yii::$app->params['oss']['OSS_ACCESS_KEY'];
+        $this->accessKeySecret = Yii::$app->params['oss']['OSS_ACCESS_SECRET'];
+        $this->endpoint = $internal?Yii::$app->params['oss']['OSS_INTERNAL_ENDPOINT']:Yii::$app->params['oss']['OSS_ENDPOINT'];
+        $this->bucket = Yii::$app->params['oss']['OSS_BUCKET'];
+        $this->region = Yii::$app->params['oss']['OSS_REGION'];
+        $this->type = Yii::$app->params['oss']['OSS_TYPE'];
+        $this->cname = FALSE;
+        $result = [];
+        if($this->type=='ali')
+        {
+            try {
+                $this->ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint,$this->cname);
+                $result = array('error'=>0);
+            } catch (OssException $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='tencent')
+        {
+            $protocol = str_replace("://","",SITE_PROTOCOL);
+            $this->ossClient = new \Qcloud\Cos\Client(
+                array(
+                    'region' => $this->region,
+                    'schema' => $protocol, //协议头部,默认为http
+                    'credentials'=> array(
+                        'secretId'  => $this->accessKeyId ,
+                        'secretKey' => $this->accessKeySecret)));
+
+            $result = array('error'=>0);
+        }
+        else if($this->type=='baidu')
+        {
+             $this->ossClient = new BosClient(array(
+                'credentials' => array(
+                    'accessKeyId' => $this->accessKeyId,
+                    'secretAccessKey' => $this->accessKeySecret,
+                ),
+                'endpoint' => $this->endpoint
+            ));
+            $result = array('error'=>0);
+        }
+        else if($this->type=='s3')
+        {
+            $this->ossClient = new S3Client([
+                'version' => 'latest',
+                'region' => $this->region,
+                'endpoint' => 'https://' . str_replace(array('https://','http://'),'',$this->endpoint),
+                'credentials' => [
+                    'key' => $this->accessKeyId,
+                    'secret' => $this->accessKeySecret,
+                ]
+            ]);
+
+        }
+        return $result;
+    }
+
+    /*
+     * $file:完整文件路径
+     * $object:文件存放到OSS的相对路径
+     */
+    public function Upload($file,$object)
+    {
+        $result = [];
+        $data = [];
+        if($this->type=='ali')
+        {
+            try{
+                $ossresult = $this->ossClient->uploadFile($this->bucket, $object, $file);
+                $ossresult['info']['url'] = str_replace(Yii::$app->params['oss']['OSS_INTERNAL_ENDPOINT'],Yii::$app->params['oss']['OSS_ENDPOINT'],$ossresult['info']['url']);
+                $data['url'] =  str_replace(array('https://','http://'),SITE_PROTOCOL,$ossresult['info']['url']);
+                $data['path'] = $object;
+                $data['size'] = $ossresult['info']['upload_content_length'];
+                $result = array('error'=>0,'data'=>$data);
+            } catch(OssException $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='tencent')
+        {
+            try {
+                $fileContent = fopen($file, "rb");
+                if ($fileContent) {
+                    $ossresult =  $this->ossClient->putObject(array(
+                        'Bucket' => $this->bucket,
+                        'Key' => $object,
+                        'Body' => $fileContent));
+                    $data['url'] = SITE_PROTOCOL.$ossresult['Location'];
+                    $data['path'] = $object;
+                    $data['size'] = filesize($file);
+                    $result = array('error'=>0,'data'=>$data);
+                }
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='baidu')
+        {
+            try {
+                $this->ossClient->putObjectFromFile($this->bucket,$object,$file);
+                $data['url'] = SITE_PROTOCOL.$this->bucket.'.'.$this->endpoint.'/'.$object;
+                $data['path'] = $object;
+                $data['size'] = filesize($file);
+                $result = array('error'=>0,'data'=>$data);
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='s3')
+        {
+            try {
+                $key = $object;
+                $source = fopen($file, 'rb');
+                $acl = 'public-read';
+                $uploader = new ObjectUploader(
+                    $this->ossClient,
+                    $this->bucket,
+                    $key,
+                    $source,
+                    $acl
+                );
+                $ossresult = $uploader->upload();
+                if ($ossresult["@metadata"]["statusCode"] == '200') {
+                    $data['url'] = $ossresult["ObjectURL"];
+                    $data['path'] = $object;
+                    $data['size'] = filesize($file);
+                    $result = array('error'=>0,'data'=>$data);
+                }
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+        }
+        return $result;
+    }
+
+
+    /**
+     * @param $localfile
+     * @param $object
+     */
+    public function downLoad($localfile,$object)
+    {
+        $object = str_replace($this->ossUrl,'',$object);
+        $object=  str_replace($this->ossInerUrl,'',$object);
+        $result = [];
+        if($this->type=='ali')
+        {
+            try{
+                $options = array(
+                    OssClient::OSS_FILE_DOWNLOAD => $localfile
+                );
+                $this->ossClient->getObject($this->bucket, $object, $options);
+                $result = array('error'=>0);
+            } catch(OssException $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+        }
+        else if($this->type=='tencent')
+        {
+            try {
+                $key = $object;  //此处的 key 为对象键,对象键是对象在存储桶中的唯一标识
+                $this->ossClient->getObject(array('Bucket' => $this->bucket,'Key' => $key,'SaveAs' => $localfile));
+                $result = array('error'=>0);
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='baidu')
+        {
+            try {
+                $this->ossClient->getObjectToFile($this->bucket, $object, $localfile);
+                $result = array('error'=>0);
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='s3')
+        {
+            try {
+                $result = $this->ossClient->getObject([
+                    'Bucket' => $this->bucket,
+                    'Key'    => $object
+                ]);
+                //header("Content-Type: {$result['ContentType']}");
+                file_put_contents($localfile,$result['Body']);
+                $result = array('error'=>0);
+            } catch (S3Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        return $result;
+
+    }
+
+    //删除单个文件
+    public function delete($object){
+        $object = str_replace($this->ossUrl,'',$object);
+        $object=  str_replace($this->ossInerUrl,'',$object);
+        if($this->type=='ali')
+        {
+            try{
+                $ossresult = $this->ossClient->deleteObject($this->bucket, $object);
+                $result = array('error'=>0,'data'=>'删除成功');
+            } catch(OssException $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='tencent')
+        {
+            try {
+                $ossresult = $this->ossClient->deleteObject(array(
+                    'Bucket' => $this->bucket, //存储桶名称
+                    'Key' => $object
+                ));
+                $result = array('error'=>0,'data'=>'删除成功');
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='baidu')
+        {
+            try {
+                $ossresult = $this->ossClient->deleteObject($this->bucket, $object);
+                $result = array('error'=>0,'data'=>'删除成功');
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='s3')
+        {
+            try {
+                $ossresult = $this->ossClient->deleteObject([
+                    'Bucket' => $this->bucket,
+                    'Key'    => $object
+                ]);
+                $result = array('error'=>0,'data'=>'删除成功');
+            } catch (S3Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        return $result;
+    }
+        
+}
+
+?>

+ 36 - 0
common/components/PinYin.php

@@ -0,0 +1,36 @@
+<?php
+namespace app\common\components;
+use Yii;
+use yii\base\Model;
+use Overtrue\Pinyin\Pinyin as py;
+
+/**
+ * 汉字转拼音
+ * @property integer
+ */
+class PinYin extends Model
+{
+    private $py;
+    public function __construct(){
+        $this->py = new py();
+    }
+
+    /**
+     * 将中文编码成拼音
+     * @param string $utf8Data utf8字符集数据
+     * @param string $sRetFormat 返回格式 [head:首字母|all:全拼音]
+     * @return string
+     */
+    public  function encode($utf8Data, $sRetFormat='all'){
+        if($sRetFormat=='all')
+        {
+            return $this->py->permalink($utf8Data,'');
+        }
+        else
+        {
+
+            return $this->py->abbr($utf8Data);
+        }
+    }
+
+}

+ 356 - 0
common/components/ResizeImage.php

@@ -0,0 +1,356 @@
+<?php
+/*  
+ * ResizeImage.php  
+ * 缩略图    
+ * 更新: Jacky.Chen 2013/10/21 21:26  
+ *  
+ */
+namespace app\common\components;
+use Yii;
+class ResizeImage
+{
+    //图片类型
+    private $type;
+    //实际宽度
+    public $width;
+    //实际高度
+    public $height;
+    //改变后的宽度
+    private $resizeWidth;
+    //改变后的高度
+    private $resizeHeight;
+    //是否裁图
+    public $cut;//0:等比缩放 1:从左上角裁切 2:裁切中间核心内容 3: 按照目标大小,填白缩放
+    //源图象
+    public $srcimg;
+    //目标图象地址
+    public $dstimg;
+    //临时创建的图象
+    var $im;
+	//是否使用缓存
+	public $usecache;
+	//文件名
+	private $filename;
+    //文件路径hash
+    private $hash;
+    function __construct($srcimg, $resizewidth, $resizeheight, $hash, $cut, $usecache, $dstrootdir)
+    {
+        dir_create($dstrootdir);
+        if ($srcimg == '') {return false;}
+        $this->srcimg = $srcimg;
+        $this->resizeWidth = $resizewidth;
+        $this->resizeHeight = $resizeheight;
+        $this->cut = $cut;
+        $this->usecache = $usecache;
+        $this->hash = $hash;
+        //图片的类型
+        $this->type = 'jpg';//所有的缩略图都为jpg后缀
+		//$this->type = strtolower(substr(strrchr($this->srcimg,"."),1));
+		//目标图象地址
+		$this -> dstImg($dstrootdir);
+		if ($this->usecache && file_exists($this->dstimg)){
+
+			return true;
+		}
+		else 
+		{
+
+	        //初始化图象
+	        $this->initImg();
+	        //尺寸
+	        $this->width = imagesx($this->im);
+	        $this->height = imagesy($this->im);
+	        //生成图象
+	        $this->newImg();
+	        ImageDestroy($this->im);
+		}
+    }
+    //返回缩略图相关信息
+    function getDstImgInfo()
+    {
+    	$info = getimagesize($this->dstimg);
+    	$array = array('width'=>$info[0],'height'=>$info[1],'type'=>$this->type,'dstimg'=>$this->dstimg);
+    	return $array;
+    }
+    private function newImg()
+    {
+        //改变后的图象的比例
+        $resize_ratio = ($this->resizeWidth)/($this->resizeHeight);
+        //实际图象的比例
+        $ratio = ($this->width)/($this->height);
+        if(($this->cut)=="1")
+        //裁图
+        {
+            if($ratio>=$resize_ratio)
+            //高度优先
+            {
+                $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);
+                $color=imagecolorallocate($newimg,255,255,255);
+                imagecolortransparent($newimg,$color);
+                imagefill($newimg,0,0,$color);
+                imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resizeWidth,$this->resizeHeight, (($this->height)*$resize_ratio), $this->height);
+          	    $this->createImg($newimg);
+            }
+            if($ratio<$resize_ratio)
+            //宽度优先
+            {
+                $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);
+                $color=imagecolorallocate($newimg,255,255,255);
+                imagecolortransparent($newimg,$color);
+                imagefill($newimg,0,0,$color);
+                imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resizeWidth, $this->resizeHeight, $this->width, (($this->width)/$resize_ratio));
+            	$this->createImg($newimg);
+            }
+        }
+        else if($this->cut==2)//取最核心的中间内容
+        {
+        		
+        		if($this->width>=$this->resizeWidth)//如果原图宽度大于目标宽度
+        		{
+        			//目标偏移量
+        			$src_y = 0;
+        			$src_x = 0;
+        			//以原图比例为基础,宽度优先计算出的缩略目标图尺寸
+        			$resize_width = $this->resizeWidth;
+        			$resize_height = ceil($this->resizeWidth/$ratio);
+        			//原图以宽度优先,按照缩略图宽高比计算出的高度
+        			$cal_height = ceil($this->width/$resize_ratio);
+        			if($this->height>$cal_height)//缩略时进行位置偏移
+        			{
+        				$src_y = ceil(($this->height-$cal_height)/2);
+        				$final_height = $cal_height;
+        				$final_width= $this->width;
+        			}
+        			else//原图高度不足
+        			{
+        				$resize_height = $this->height;
+        				$resize_width =  ceil($resize_height*$resize_ratio);
+        				//原图以高度优先,按照缩略图宽高比计算出的宽度
+        				$cal_width = ceil($this->height*$resize_ratio);
+        				//位置偏移
+        				$src_x = ceil(($this->width-$cal_width)/2);
+        				$final_width = $cal_width;
+        				$final_height = $this->height;
+        			}
+        			$newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight); imagefill($newimg, 0, 0, 0xFFFFFF);
+                    $color=imagecolorallocate($newimg,255,255,255);
+                    imagecolortransparent($newimg,$color);
+                    imagefill($newimg,0,0,$color);
+
+        			$dst_x = $dst_y = 0;
+        			if ($resize_width < $this->resizeWidth){$dst_x = ($this->resizeWidth-$resize_width)/2;}
+        			if ($resize_height < $this->resizeHeight){ $dst_y = ($this->resizeHeight - $resize_height)/2;}
+        			imagecopyresampled($newimg, $this->im, $dst_x, $dst_y, $src_x, $src_y, $this->resizeWidth, $this->resizeHeight,$final_width,$final_height);
+        			$this->createImg($newimg);
+        		}
+        		else
+        		{
+        			//目标偏移量
+        			$src_y = 0;
+        			$src_x = 0;
+        			if($this->height>=$this->resizeHeight)//如果原图高度大于目标高度
+        			{
+        				//以原图比例为基础,高度优先计算出的缩略目标图宽度
+        				$resize_width = ceil($this->resizeHeight*$ratio);
+        				$resize_height = $this->resizeHeight;
+        				
+        				$newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);imagefill($newimg, 0, 0, 0xFFFFFF);
+        				$dst_x = $dst_y = 0;
+        				if ($resize_width < $this->resizeWidth){$dst_x = ($this->resizeWidth-$resize_width)/2;}
+        				if ($resize_height < $this->resizeHeight){ $dst_y = ($this->resizeHeight - $resize_height)/2;}
+        				imagecopyresampled($newimg, $this->im, $dst_x, $dst_y, $src_x, $src_y, $resize_width, $resize_height,$this->width,$this->height);
+        				$this->createImg($newimg);
+        			}
+        			else
+        			{
+        				$src_y = 0;
+        				$src_x = 0;
+        				$newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);imagefill($newimg, 0, 0, 0xFFFFFF);
+        				$dst_x = $dst_y = 0;
+        				$resize_width = $this->width;
+        				$resize_height = $this->height;
+        				if ($resize_width < $this->resizeWidth){$dst_x = ($this->resizeWidth-$resize_width)/2;}
+        				if ($resize_height < $this->resizeHeight){ $dst_y = ($this->resizeHeight - $resize_height)/2;}
+        				imagecopyresampled($newimg, $this->im, $dst_x, $dst_y, $src_x, $src_y, $resize_width, $resize_height,$this->width,$this->height);
+        				$this->createImg($newimg);
+        			}	
+        		}
+        }
+        else if($this->cut==3)
+        {
+           if($ratio>=$resize_ratio)
+            {
+                $newimg = imagecreatetruecolor($this->resizeWidth,($this->resizeWidth)/$ratio);
+                $color=imagecolorallocate($newimg,255,255,255);
+                imagecolortransparent($newimg,$color);
+                imagefill($newimg,0,0,$color);
+                imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resizeWidth, ($this->resizeWidth)/$ratio, $this->width, $this->height);
+                $this->createImg($newimg);
+                $this->srcimg = $this->dstimg;
+                $this->initImg();
+                $this->width = imagesx($this->im);
+                $this->height = imagesy($this->im);
+                $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);
+                $whites = imagecolorallocate($newimg,255,255,255);
+                imagefill($newimg,0,0,$whites);
+                $dst_x = 0;
+                $dst_y = ($this->resizeHeight-$this->height)/2;
+                imagecopy($newimg, $this->im, $dst_x, $dst_y, 0, 0, $this->width, $this->height);
+                $this->createImg($newimg);
+                
+            }
+            if($ratio<$resize_ratio)
+            {
+                $newimg = imagecreatetruecolor(($this->resizeHeight)*$ratio,$this->resizeHeight);
+                $color=imagecolorallocate($newimg,255,255,255);
+                imagecolortransparent($newimg,$color);
+                imagefill($newimg,0,0,$color);
+                imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, ($this->resizeHeight)*$ratio, $this->resizeHeight, $this->width, $this->height);
+                $this->createImg($newimg);
+                $this->srcimg = $this->dstimg;
+                $this->initImg();
+                $this->width = imagesx($this->im);
+                $this->height = imagesy($this->im);
+                $newimg = imagecreatetruecolor($this->resizeWidth,$this->resizeHeight);
+                $whites = imagecolorallocate($newimg,255,255,255);
+                imagefill($newimg,0,0,$whites);
+                $dst_x = ($this->resizeWidth-$this->width)/2;
+                $dst_y = 0;
+                imagecopy($newimg, $this->im, $dst_x, $dst_y, 0, 0, $this->width, $this->height);
+                $this->createImg($newimg);
+            }
+        }
+        else
+        {
+            if($ratio>=$resize_ratio)
+            {
+                $newimg = imagecreatetruecolor($this->resizeWidth,($this->resizeWidth)/$ratio);
+
+                $color=imagecolorallocate($newimg,255,255,255);
+                imagecolortransparent($newimg,$color);
+                imagefill($newimg,0,0,$color);
+
+
+                imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, $this->resizeWidth, ($this->resizeWidth)/$ratio, $this->width, $this->height);
+           		 $this->createImg($newimg);
+            }
+            if($ratio<$resize_ratio)
+            {
+                $newimg = imagecreatetruecolor(($this->resizeHeight)*$ratio,$this->resizeHeight);
+                $color=imagecolorallocate($newimg,255,255,255);
+                imagecolortransparent($newimg,$color);
+                imagefill($newimg,0,0,$color);
+                imagecopyresampled($newimg, $this->im, 0, 0, 0, 0, ($this->resizeHeight)*$ratio, $this->resizeHeight, $this->width, $this->height);
+                $this->createImg($newimg);
+            }
+        }
+    }
+    //初始化图象
+    private function initImg()
+    {
+    	$srcInfo = getimagesize($this->srcimg);
+    	switch ($srcInfo[2])
+    	{
+    		case 1:
+    			 $this->im = imagecreatefromgif($this->srcimg);  break;
+    		case 2:
+    			$this->im = imagecreatefromjpeg($this->srcimg); break;
+    		case 3:
+    			 $this->im = imagecreatefrompng($this->srcimg);  break;
+            case 6:
+                $this->im = imagecreatefrombmp($this->srcimg);  break;
+    		default:
+    			die('Unsupport the file type'); exit();
+    	}
+    }
+    //生成目标文件
+    private function createImg(&$newimg)
+    {
+    	
+    	$srcInfo = @getimagesize($this->srcimg);
+    	switch ($srcInfo[2])
+    	{
+    		case 1:
+    			imagegif($newimg,$this->dstimg);  break;
+    		case 2:
+    			imagejpeg($newimg,$this->dstimg); break;
+    		case 3:
+    			imagepng($newimg,$this->dstimg);  break;
+            case 6:
+                file_put_contents($this->dstimg,file_get_contents($this->srcimg)); break;
+    		default:
+    			die('unsupport file type'); exit();
+    	}
+    	imagedestroy($newimg);
+    }
+    
+    
+    //图象目标地址
+    private function dstImg($dstrootdir)
+    {
+
+        /*
+        *以源文件名基础,获取缩略图文件名
+        $basename = basename($this->srcimg);
+    	$this->filename  = substr($basename,strrpos($basename,DIRECTORY_SEPARATOR)+1,0-(strlen($basename)-strpos($basename,'.')));
+    	if (strlen($this->filename)<4){return false;}
+        */
+        $this->filename = $this->hash;
+    	if ($this->resizeWidth<=0 || $this->resizeHeight<=0){return false;}
+   		if(!empty($dstrootdir))
+    	{
+    		$this->dstimg = rtrim($dstrootdir,DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$this->resizeWidth.'_'.$this->resizeHeight.'_'.$this->filename.'.'.$this->type;
+    	}
+    	else
+    	{
+    		$this->dstimg = $this->resizeWidth.'_'.$this->resizeHeight.'_'.$this->filename.'.'.$this->type;
+    	}
+    }
+}
+function imagecreatefrombmp($p_sFile)
+{
+    $file    =    fopen($p_sFile,"rb");
+    $read    =    fread($file,10);
+    while(!feof($file)&&($read<>""))
+        $read    .=    fread($file,1024);
+    $temp    =    unpack("H*",$read);
+    $hex    =    $temp[1];
+    $header    =    substr($hex,0,108);
+    if (substr($header,0,4)=="424d")
+    {
+        $header_parts    =    str_split($header,2);
+        $width            =    hexdec($header_parts[19].$header_parts[18]);
+        $height            =    hexdec($header_parts[23].$header_parts[22]);
+        unset($header_parts);
+    }
+    $x                =    0;
+    $y                =    1;
+    $image            =    imagecreatetruecolor($width,$height);
+    $body            =    substr($hex,108);
+    $body_size        =    (strlen($body)/2);
+    $header_size    =    ($width*$height);
+    $usePadding        =    ($body_size>($header_size*3)+4);
+    for ($i=0;$i<$body_size;$i+=3)
+    {
+        if ($x>=$width)
+        {
+            if ($usePadding)
+                $i    +=    $width%4;
+            $x    =    0;
+            $y++;
+            if ($y>$height)
+                break;
+        }
+        $i_pos    =    $i*2;
+        $r        =    hexdec($body[$i_pos+4].$body[$i_pos+5]);
+        $g        =    hexdec($body[$i_pos+2].$body[$i_pos+3]);
+        $b        =    hexdec($body[$i_pos].$body[$i_pos+1]);
+        $color    =    imagecolorallocate($image,$r,$g,$b);
+        imagesetpixel($image,$x,$height-$y,$color);
+        $x++;
+    }
+    unset($body);
+    return $image;
+}
+
+?>

+ 239 - 0
common/components/SimpleOss.php

@@ -0,0 +1,239 @@
+<?php
+namespace app\common\components;
+define('__BOS_CLIENT_ROOT', dirname(__DIR__));
+include BASE_PATH.'components'.DIRECTORY_SEPARATOR.'bce'.DIRECTORY_SEPARATOR.'BaiduBce.phar';
+use OSS\OssClient;
+use OSS\Core\OssException;
+use Aws\S3\S3Client;
+use Aws\S3\MultipartUploader;
+use Aws\S3\Exception\S3Exception;
+use Aws\Exception\AwsException;
+use Aws\Exception\MultipartUploadException;
+use Aws\S3\ObjectUploader;
+use \BaiduBce\BceClientConfigOptions;
+use \BaiduBce\Util\MimeTypes;
+use \BaiduBce\Http\HttpHeaders;
+use \BaiduBce\Services\Bos\BosClient;
+use Yii;
+class SimpleOss
+{
+    public $ossClient;
+    public $ossUrl;
+    public $ossInerUrl;
+    public $accessKeyId;
+    public $accessKeySecret;
+    public $endpoint;
+    public $bucket;
+    public $region;
+    public $type;
+    public $cname;
+    public $args;
+    public function init($args,$type='tencent')
+    {
+        $this->args = $args;
+        $this->ossUrl =  SITE_PROTOCOL.$args['OSS_BUCKET'].'.'.$args['OSS_ENDPOINT'].'/';
+        $this->ossInerUrl = SITE_PROTOCOL.$args['OSS_BUCKET'].'.'.$args['OSS_INTERNAL_ENDPOINT'].'/';
+        $this->accessKeyId = $args['OSS_ACCESS_KEY'];
+        $this->accessKeySecret = $args['OSS_ACCESS_SECRET'];
+        $this->endpoint = $args['OPEN_INTERNAL']?$args['OSS_INTERNAL_ENDPOINT']:$args['OSS_ENDPOINT'];;
+        $this->bucket = $args['OSS_BUCKET'];
+        $this->region = $args['OSS_REGION'];
+        $this->type = $args['OSS_TYPE']?$args['OSS_TYPE']:$type;
+        $this->cname = FALSE;
+        $result = [];
+        if($this->type=='ali')
+        {
+            try {
+                $this->ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint,$this->cname);
+                $result = array('error'=>0);
+            } catch (OssException $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='tencent')
+        {
+            $protocol = str_replace("://","",SITE_PROTOCOL);
+            $this->ossClient = new \Qcloud\Cos\Client(
+                array(
+                    'region' => $this->region,
+                    'schema' => $protocol, //协议头部,默认为http
+                    'credentials'=> array(
+                        'secretId'  => $this->accessKeyId ,
+                        'secretKey' => $this->accessKeySecret)));
+
+            $result = array('error'=>0);
+        }
+        else if($this->type=='baidu')
+        {
+             $this->ossClient = new BosClient(array(
+                'credentials' => array(
+                    'accessKeyId' => $this->accessKeyId,
+                    'secretAccessKey' => $this->accessKeySecret,
+                ),
+                'endpoint' => $this->endpoint
+            ));
+            $result = array('error'=>0);
+        }
+        else if($this->type=='s3')
+        {
+            $this->ossClient = new S3Client([
+                'version' => 'latest',
+                'region' => $this->region,
+                'endpoint' => 'https://' . str_replace(array('https://','http://'),'',$this->endpoint),
+                'credentials' => [
+                    'key' => $this->accessKeyId,
+                    'secret' => $this->accessKeySecret,
+                ]
+            ]);
+
+        }
+        return $result;
+    }
+
+    /*
+     * $file:完整文件路径
+     * $object:文件存放到OSS的相对路径
+     */
+    public function Upload($file,$object)
+    {
+        $result = [];
+        $data = [];
+        if($this->type=='ali')
+        {
+            try{
+                $ossresult = $this->ossClient->uploadFile($this->bucket, $object, $file);
+                $ossresult['info']['url'] = str_replace($this->args['OSS_INTERNAL_ENDPOINT'],$this->args['OSS_ENDPOINT'],$ossresult['info']['url']);
+                $data['url'] =  str_replace(array('https://','http://'),SITE_PROTOCOL,$ossresult['info']['url']);
+                $data['path'] = $object;
+                $data['size'] = $ossresult['info']['upload_content_length'];
+                $result = array('error'=>0,'data'=>$data);
+            } catch(OssException $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+        }
+        else if($this->type=='tencent')
+        {
+            try {
+                $fileContent = fopen($file, "rb");
+                if ($fileContent) {
+                    $ossresult =  $this->ossClient->putObject(array(
+                        'Bucket' => $this->bucket,
+                        'Key' => $object,
+                        'Body' => $fileContent));
+                    $data['url'] = SITE_PROTOCOL.$ossresult['Location'];
+                    $data['path'] = $object;
+                    $data['size'] = filesize($file);
+                    $result = array('error'=>0,'data'=>$data);
+                }
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='baidu')
+        {
+            try {
+                $this->ossClient->putObjectFromFile($this->bucket,$object,$file);
+                $data['url'] = SITE_PROTOCOL.$this->bucket.'.'.$this->endpoint.'/'.$object;
+                $data['path'] = $object;
+                $data['size'] = filesize($file);
+                $result = array('error'=>0,'data'=>$data);
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='s3')
+        {
+            try {
+                $key = $object;
+                $source = fopen($file, 'rb');
+                $acl = 'public-read';
+                $uploader = new ObjectUploader(
+                    $this->ossClient,
+                    $this->bucket,
+                    $key,
+                    $source,
+                    $acl
+                );
+                $ossresult = $uploader->upload();
+                if ($ossresult["@metadata"]["statusCode"] == '200') {
+                    $data['url'] = $ossresult["ObjectURL"];
+                    $data['path'] = $object;
+                    $data['size'] = filesize($file);
+                    $result = array('error'=>0,'data'=>$data);
+                }
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+        }
+        return $result;
+    }
+
+    //删除单个文件
+    public function delete($object){
+        $object = str_replace($this->ossUrl,'',$object);
+        $object=  str_replace($this->ossInerUrl,'',$object);
+        if($this->type=='ali')
+        {
+            try{
+                $ossresult = $this->ossClient->deleteObject($this->bucket, $object);
+                $result = array('error'=>0,'data'=>'删除成功');
+            } catch(OssException $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='tencent')
+        {
+            try {
+                $ossresult = $this->ossClient->deleteObject(array(
+                    'Bucket' => $this->bucket, //存储桶名称
+                    'Key' => $object
+                ));
+                $result = array('error'=>0,'data'=>'删除成功');
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='baidu')
+        {
+            try {
+                $ossresult = $this->ossClient->deleteObject($this->bucket, $object);
+                $result = array('error'=>0,'data'=>'删除成功');
+            } catch (\Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        else if($this->type=='s3')
+        {
+            try {
+                $ossresult = $this->ossClient->deleteObject([
+                    'Bucket' => $this->bucket,
+                    'Key'    => $object
+                ]);
+                $result = array('error'=>0,'data'=>'删除成功');
+            } catch (S3Exception $e) {
+                $result = array('error'=>1,'msg'=>$e->getMessage());
+            }
+
+        }
+        return $result;
+    }
+
+    //转换图片
+    public function previewImg($remoteFileUrl,$i)
+    {
+        if($this->type=='tencent')
+        {
+            return $remoteFileUrl.'?ci-process=doc-preview&page='.$i;
+        }
+
+
+    }
+}
+
+?>

+ 687 - 0
common/components/SiteUrl.php

@@ -0,0 +1,687 @@
+<?php
+/*****初始路由*************/
+namespace app\common\components;
+use Yii;
+use yii\helpers\Url;
+class SiteUrl {
+
+    //首页
+    public static  function home($share_no='')
+    {
+        if(!empty($share_no))
+        {
+            return  Url::to(['/web/default/index',Yii::$app->params['shareArgName']=>$share_no],true);
+        }
+        else
+        {
+            return Url::to(['/web/default/index'],true);
+        }
+
+    }
+
+    //栏目展示
+    public static function catlist()
+    {
+        return Url::to(['/web/default/catlist'],true);
+    }
+
+    //用户中心首页
+    public static function ucenter()
+    {
+        $url =  Url::to(['/ucenter/default/index'],true);
+        return $url;
+    }
+
+    public static function loginhome($refer_page='')
+    {
+
+        if(!empty($refer_page))
+        {
+            $url =  Url::to(['/ucenter/default/loginhome',Yii::$app->params['referPageName']=>$refer_page],true);
+        }
+        else
+        {
+            return Url::to(['/ucenter/default/loginhome'],true);
+        }
+        return $url;
+    }
+
+    public static function login($refer_page='')
+    {
+        if(!empty($refer_page))
+        {
+            $url =  Url::to(['/ucenter/default/login',Yii::$app->params['referPageName']=>$refer_page],true);
+        }
+        else
+        {
+            $url =  Url::to(['/ucenter/default/login'],true);
+        }
+        return $url;
+    }
+
+    public static function logout()
+    {
+        return Url::to(['/ucenter/default/logout'],true);
+    }
+
+    public static function register()
+    {
+        return Url::to(['/ucenter/default/register'],true);
+    }
+
+    public static function forgetpwd()
+    {
+        return Url::to(['/ucenter/default/forgetpwd'],true);
+    }
+
+    //账号设置
+    public static function myaccount($tab=null)
+    {
+        if(empty($tab))
+        {
+            return Url::to(['/ucenter/default/account'],true);
+        }
+        else
+        {
+            return Url::to(['/ucenter/default/account','tab'=>$tab],true);
+        }
+    }
+
+    //实名认证
+    public static function certindex()
+    {
+        return Url::to(['/ucenter/default/certindex'],true);
+    }
+
+    //个人认证
+    public static function certuser()
+    {
+        return Url::to(['/ucenter/default/certuser'],true);
+    }
+
+    //企业认证
+    public static function certorg()
+    {
+        return Url::to(['/ucenter/default/certorg'],true);
+    }
+
+    //充值金币
+    public static function coincharge($refer_page='')
+    {
+        if(!empty($refer_page))
+        {
+            $url =  Url::to(['/ucenter/default/coincharge',Yii::$app->params['referPageName']=>$refer_page],true);
+        }
+        else
+        {
+            $url =  Url::to(['/ucenter/default/coincharge'],true);
+        }
+        return $url;
+    }
+
+    //金币日志
+    public static function coinlog($type=1)
+    {
+        $url =  Url::to(['/ucenter/default/coinlog','type'=>$type],true);
+        return $url;
+    }
+
+    //现金日志
+    public static function moneylog()
+    {
+        $url =  Url::to(['/ucenter/default/moneylog'],true);
+        return $url;
+    }
+
+    //积分日志
+    public static function pointlog()
+    {
+        $url =  Url::to(['/ucenter/default/pointlog'],true);
+        return $url;
+    }
+
+    //我的下载
+    public static function docpaylog()
+    {
+        $url =  Url::to(['/ucenter/default/docpaylog'],true);
+        return $url;
+    }
+
+    //我的收藏
+    public static function myfavorite()
+    {
+        $url =  Url::to(['/ucenter/default/myfavorite'],true);
+        return $url;
+    }
+
+    //我的关注
+    public static function myfocus()
+    {
+        $url =  Url::to(['/ucenter/default/myfocus'],true);
+        return $url;
+    }
+
+    //我的足迹
+    public static function myhistory()
+    {
+        $url =  Url::to(['/ucenter/default/myhistory'],true);
+        return $url;
+    }
+
+
+    //我的订单
+    public static function myorder($status=null)
+    {
+        if($status!=null)
+        {
+            $url =  Url::to(['/ucenter/default/myorder','status'=>$status],true);
+        }
+        else
+        {
+            $url =  Url::to(['/ucenter/default/myorder'],true);
+        }
+        return $url;
+    }
+
+    //收货地址
+    public static function myaddress()
+    {
+        $url =  Url::to(['/ucenter/default/myaddress'],true);
+        return $url;
+    }
+
+    //我的邀请注册
+    public static  function myinvite($tab=1)
+    {
+        if($tab!=null)
+        {
+            $url =  Url::to(['/ucenter/default/myinvite','tab'=>$tab],true);
+        }
+        else
+        {
+            $url =  Url::to(['/ucenter/default/myinvite'],true);
+        }
+        return $url;
+    }
+
+    //我的消息
+    public static function mymsg($type=1)
+    {
+        $url =  Url::to(['/ucenter/default/mymsg','type'=>$type],true);
+        return $url;
+    }
+
+    //提现账户
+    public static function setbank($type=1)
+    {
+        $url =  Url::to(['/ucenter/default/setbank','type'=>$type],true);
+        return $url;
+    }
+
+    //余额提现
+    public static function withdraw($tab=1)
+    {
+        $url =  Url::to(['/ucenter/default/withdraw','tab'=>$tab],true);
+        return $url;
+    }
+
+    //联系我们
+    public static function contact()
+    {
+        $url =  Url::to(['/ucenter/default/contact'],true);
+        return $url;
+    }
+
+    //我的钱包
+    public static function wallet()
+    {
+        $url =  Url::to(['/ucenter/default/wallet'],true);
+        return $url;
+    }
+
+    //上传文档
+    public static function upload()
+    {
+        $url =  Url::to(['/ucenter/uploader/single'],true);
+        return $url;
+    }
+
+    //上传合辑
+    public static function uploadcol()
+    {
+        $url =  Url::to(['/ucenter/uploader/collect'],true);
+        return $url;
+    }
+
+    //批量上传
+    public static function multiupload()
+    {
+        $url =  Url::to(['/ucenter/uploader/multi'],true);
+        return $url;
+    }
+
+    //发布资源
+    public static function uploadsource()
+    {
+        $url =  Url::to(['/ucenter/uploader/source'],true);
+        return $url;
+    }
+
+    //开通VIP
+    public static function vip($refer_page='')
+    {
+        if(!empty($refer_page))
+        {
+            $url =  Url::to(['/web/default/vip',Yii::$app->params['referPageName']=>$refer_page],true);
+        }
+        else
+        {
+            $url =  Url::to(['/web/default/vip'],true);
+        }
+
+        return $url;
+    }
+
+    //生成关注公众号二维码(PC右侧浮动)
+    public static  function mpSubCode()
+    {
+        $url =  Url::to(['/openauth/mpsub'],true);
+        return $url;
+    }
+
+
+    //公众号授权登录(h5)
+    public static function mpLogin($scene_id=NULL,$redirect=0,$uauth=null)
+    {
+        $bd_vid =  \app\common\helpers\Cookie::getCookie('bd_vid');
+        if($redirect>0)
+        {
+            if(!empty($uauth))
+            {
+                if(!empty($bd_vid))
+                {
+                    $url =  Url::to(['/ucenter/default/mplogin','scene_id'=>$scene_id,'redirect'=>$redirect,'uauth'=>$uauth,'bd_vid'=>$bd_vid],true);
+                }
+                else
+                {
+                    $url =  Url::to(['/ucenter/default/mplogin','scene_id'=>$scene_id,'redirect'=>$redirect,'uauth'=>$uauth],true);
+                }
+
+            }
+            else
+            {
+                if(!empty($bd_vid))
+                {
+                    $url = Url::to(['/ucenter/default/mplogin', 'scene_id' => $scene_id, 'redirect' => $redirect,'bd_vid'=>$bd_vid], true);
+                }
+                else
+                {
+                    $url = Url::to(['/ucenter/default/mplogin', 'scene_id' => $scene_id, 'redirect' => $redirect], true);
+                }
+            }
+
+
+        }
+        else
+        {
+            if(!empty($uauth))
+            {
+                if(!empty($bd_vid))
+                {
+                    $url =  Url::to(['/ucenter/default/mplogin','scene_id'=>$scene_id,'uauth'=>$uauth,'bd_vid'=>$bd_vid],true);
+                }
+                else
+                {
+                    $url =  Url::to(['/ucenter/default/mplogin','scene_id'=>$scene_id,'uauth'=>$uauth],true);
+                }
+
+            }
+            else
+            {
+                if(!empty($bd_vid))
+                {
+                    $url = Url::to(['/ucenter/default/mplogin', 'scene_id' => $scene_id,'bd_vid'=>$bd_vid], true);
+                }
+                else
+                {
+                    $url = Url::to(['/ucenter/default/mplogin', 'scene_id' => $scene_id], true);
+                }
+            }
+
+        }
+        return $url;
+    }
+
+    //绑定公众号(h5)
+    public static function bindmp($hash=NULL)
+    {
+        $url =  Url::to(['/ucenter/default/bindmp',Yii::$app->params['authHashName']=>$hash],true);
+        return $url;
+    }
+
+
+    //搜索中转
+    public static  function searchSwitch()
+    {
+        return Url::to(['/web/default/searchswitch'],true);
+    }
+
+    //搜索
+    public static function search($model_id,$keywords='')
+    {
+        return Url::to(['/web/default/search', 'model_id' => $model_id,'kw'=>urlencode($keywords)],true);
+
+    }
+
+    //搜索
+    public static function searchForWeixin($model_id,$keywords='')
+    {
+        return Url::to(['/web/default/search', 'model_id' => $model_id,'kw'=>$keywords],true);
+
+    }
+
+    //文档列表
+    public static function docList($cat_id=null)
+    {
+        if(empty($cat_id))
+        {
+            $url =  Url::to(['/doc/default/list'],true);
+        }
+        else
+        {
+            $url =  Url::to(['/doc/default/list'],true);
+            $url = MultiSearchUrl::getSelfInstance(array('url'=>$url,'conditions'=>array('c'=>$cat_id),'filterAll'=>true))->createSearchCondition();
+        }
+        return $url;
+    }
+
+
+
+    //文档详情
+    public static function docDetail($id,$order_sn='')
+    {
+
+        if(!empty($order_sn))
+        {
+            $url =  Url::to(['/doc/default/detail','id'=>$id,'order_sn'=>$order_sn],true);
+        }
+        else
+        {
+            $url =  Url::to(['/doc/default/detail','id'=>$id],true);
+        }
+        return $url;
+    }
+
+
+    //合辑列表
+    public static function colList($cat_id=null)
+    {
+        if(empty($cat_id))
+        {
+            $url =  Url::to(['/doc/default/collist'],true);
+        }
+        else
+        {
+            $url =  Url::to(['/doc/default/collist'],true);
+            $url = MultiSearchUrl::getSelfInstance(array('url'=>$url,'conditions'=>array('c'=>$cat_id),'filterAll'=>true))->createSearchCondition();
+        }
+        return $url;
+    }
+
+    //合辑详情
+    public static function colDetail($id,$order_sn='')
+    {
+        if(!empty($order_sn))
+        {
+            $url =  Url::to(['/doc/default/coldetail','id'=>$id,'order_sn'=>$order_sn],true);
+        }
+        else
+        {
+            $url =  Url::to(['/doc/default/coldetail','id'=>$id],true);
+        }
+        return $url;
+    }
+
+    //个人主页
+    public static function uHome($user_id)
+    {
+        $url =  Url::to(['/web/default/uhome','user_id'=>$user_id],true);
+        return $url;
+    }
+
+    //tag链接
+    public static function tagLink($pinyin,$model_id=null)
+    {
+        if($model_id)
+        {
+            $url = Url::to(['/web/default/tag', 'model_id' => $model_id,'pinyin'=>$pinyin],true);
+        }
+        else
+        {
+            $url =  Url::to(['/web/default/tag','pinyin'=>$pinyin],true);
+        }
+        return $url;
+    }
+
+    //资讯首页
+    public static function newsHome()
+    {
+        $url =  Url::to(['/cms/news/home'],true);
+        return $url;
+    }
+
+    //资讯列表
+    public static function newsList($cat_id=null)
+    {
+        if(empty($cat_id))
+        {
+            $url =  Url::to(['/cms/news/list'],true);
+        }
+        else
+        {
+            $url =  Url::to(['/cms/news/list'],true);
+            $url = MultiSearchUrl::getSelfInstance(array('url'=>$url,'conditions'=>array('c'=>$cat_id),'filterAll'=>true))->createSearchCondition();
+        }
+        return $url;
+    }
+
+    //资讯详情
+    public static function newsDetail($id)
+    {
+        $url =  Url::to(['/cms/news/detail','id'=>$id],true);
+        return $url;
+    }
+
+
+    //生成带下载码的链接(用于微信回复消息)
+    public static function downByLink($downcode,$direct=0)
+    {
+        if(!empty($direct))
+        {
+            $downurl =  Url::to(['/ajax/downdoc','downcode'=>$downcode,'direct'=>$direct],true);
+        }
+        else
+        {
+            $downurl =  Url::to(['/ajax/downdoc','downcode'=>$downcode],true);
+        }
+        $url =  Url::to(['/web/default/linkdown','downurl'=>base64_encode($downurl)],true);
+        return $url;
+    }
+
+    //生成文档下载链接
+    public static function docDownByCode($downcode,$direct=0)
+    {
+        if(!empty($direct))
+        {
+            $downurl =  Url::to(['/ajax/downdoc','downcode'=>$downcode,'direct'=>$direct],true);
+        }
+        else
+        {
+            $downurl =  Url::to(['/ajax/downdoc','downcode'=>$downcode],true);
+        }
+        return $downurl;
+    }
+
+    //单页
+    public static function page($cat_id=0)
+    {
+        if($cat_id>0)
+        {
+            $url =  Url::to(['/web/default/page','cat_id'=>$cat_id],true);
+        }
+        else
+        {
+            $url =  Url::to(['/web/default/page'],true);
+        }
+
+        return $url;
+    }
+
+    //公告详情
+    public static  function announce($id=0)
+    {
+        if($id>0)
+        {
+            $url =  Url::to(['/web/default/announce','id'=>$id],true);
+        }
+        else
+        {
+            $url =  Url::to(['/web/default/announce'],true);
+        }
+        return $url;
+    }
+
+    //创作首页
+    public static function writerindex()
+    {
+        $url =  Url::to(['/ucenter/writer/index'],true);
+        return $url;
+    }
+
+    //我的上传
+    public static  function myupload()
+    {
+        return Url::to(['/ucenter/writer/myupload'],true);
+    }
+
+    //管理文档
+    public static  function mydoc()
+    {
+        return Url::to(['/ucenter/writer/mydoc'],true);
+    }
+
+    //我的出售
+    public static  function mysales()
+    {
+        return Url::to(['/ucenter/writer/mysales'],true);
+    }
+
+    /*********************分销中心**********************/
+    public static function mycommission()
+    {
+        return Url::to(['/ucenter/commission/index'],true);
+
+    }
+
+    public static function commissionteam($level=1)
+    {
+        return Url::to(['/ucenter/commission/team','level'=>$level],true);
+
+    }
+
+    public static function commissionorders()
+    {
+        return Url::to(['/ucenter/commission/orders'],true);
+
+    }
+
+    public static function commissionlogs($type=1)
+    {
+        $url =  Url::to(['/ucenter/commission/logs','type'=>$type],true);
+        return $url;
+    }
+
+    /******************下面是只用在手机端****************/
+
+    public static function myinfo()
+    {
+        return Url::to(['/ucenter/default/myinfo'],true);
+    }
+
+    public static function changepwd()
+    {
+        return Url::to(['/ucenter/default/changepwd'],true);
+    }
+
+    public static function bindaccount()
+    {
+        return Url::to(['/ucenter/default/bindaccount'],true);
+    }
+
+    //绑定微信登录
+    public static function tobindmp($scene_id)
+    {
+        $url =  Url::to(['/ucenter/default/tobindmp','scene_id'=>$scene_id],true);
+        return $url;
+    }
+
+    //绑定微信消息
+    public static function bindmpmsg($scene_id)
+    {
+        $url =  Url::to(['/ucenter/default/bindmpmsg','scene_id'=>$scene_id],true);
+        return $url;
+    }
+
+    //绑定手机号
+    public static function bindmob()
+    {
+        return Url::to(['/ucenter/default/bindmob'],true);
+    }
+
+    //绑定邮箱
+    public static function bindemail($refer_page = '')
+    {
+        if(!empty($refer_page))
+        {
+            $url =  Url::to(['/ucenter/default/bindemail',Yii::$app->params['referPageName']=>$refer_page],true);
+        }
+        else
+        {
+            $url =  Url::to(['/ucenter/default/bindemail'],true);
+        }
+        return $url;
+    }
+
+    //收益中心
+    public static function income()
+    {
+        return Url::to(['/ucenter/default/income'],true);
+    }
+
+    //积分兑换金币
+    public static function point2coin()
+    {
+        return Url::to(['/ucenter/default/point2coin'],true);
+    }
+
+    //金币兑换现金
+    public static function coin2money()
+    {
+        return Url::to(['/ucenter/default/coin2money'],true);
+    }
+
+    //问题帮助
+    public static function help()
+    {
+        return Url::to(['/ucenter/default/help'],true);
+    }
+
+    //举报
+    public static function report($table_name,$data_id)
+    {
+        $url =  Url::to(['/ucenter/default/report','table_name'=>$table_name,'data_id'=>$data_id],true);
+        return $url;
+    }
+
+
+}

+ 158 - 0
common/components/Sms.php

@@ -0,0 +1,158 @@
+<?php
+//短信发送集成
+namespace app\common\components;
+use app\modules\admin\models\Config;
+use app\models\MobileMsgTpl;
+use app\models\MobileMsg;
+use app\models\MobileCert;
+// 导入对应产品模块的client
+use TencentCloud\Sms\V20210111\SmsClient;
+// 导入要请求接口对应的Request类
+use TencentCloud\Sms\V20210111\Models\SendSmsRequest;
+use TencentCloud\Common\Exception\TencentCloudSDKException;
+use TencentCloud\Common\Credential;
+// 导入可选配置类
+use TencentCloud\Common\Profile\ClientProfile;
+use TencentCloud\Common\Profile\HttpProfile;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
+use Darabonba\OpenApi\Models\Config as aliConfig;
+use AlibabaCloud\Tea\Utils\Utils;
+use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest as aliSendSmsRequest;
+use Yii;
+class Sms
+{
+    private $sign;
+    private $accessKeyId;
+    private $accessKeySecret;
+    private $region;
+    private $appid;
+    private $apitype;
+    private $client;
+    private $certTimeOut;//验证码有效时间
+    public function init()
+    {
+        $configModel = Config::find()->where("name='sms'")->limit(1)->one();
+        check_record_exists($configModel);
+        $config = string2array($configModel->value);
+        $this->sign = $config['sign'];
+        $this->accessKeyId = $config['accesskeyid'];
+        $this->accessKeySecret = $config['accesskeysecret'];
+        $this->region = $config['region']?$config['region']:'ap-guangzhou';
+        $this->appid = $config['appid'];
+        $this->certTimeOut = $config['certTimeOut'];
+        $this->apitype = $config['sms_type'];
+        if($this->apitype=='ali')
+        {
+            $config = new aliConfig([
+                "accessKeyId" => $this->accessKeyId,
+                "accessKeySecret" =>  $this->accessKeySecret
+            ]);
+            // 访问的域名
+            $config->endpoint = "dysmsapi.aliyuncs.com";
+            $this->client =  new Dysmsapi($config);
+        }
+        else if($this->apitype=='tencent')
+        {
+            $cred = new Credential($this->accessKeyId, $this->accessKeySecret);
+            $this->client = new SmsClient($cred, $this->region);
+        }
+        else
+        {
+
+        }
+
+    }
+
+    /*
+     * $key:短信配置中短信模板key
+     * $mobile:可以是单个手机号,也可以是数组形式的多个手机号
+     * $args:模板参数,数字类型,示例:['name'=>'小知','code'=>'666666']
+     */
+    public function send($key,$mobile,$args=[],$user_id=0)
+    {
+        $tpl = MobileMsgTpl::find()->alias('a')->where("a.key='".$key."'")->one();
+        $toMobileList = is_array($mobile)?$mobile:array($mobile);
+        if($this->apitype=='ali')
+        {
+            $msgcontent = $tpl->tpl;
+            if(is_array($args))foreach($args as $k=>$v)
+            {
+                $msgcontent = str_replace('${'.$k.'}',$v,$msgcontent);
+            }
+            $sendReq = new aliSendSmsRequest([
+                "phoneNumbers" => join(",",$toMobileList),
+                "signName" => $this->sign,
+                "templateCode" => $tpl->code,
+                "templateParam" =>  json_encode($args, JSON_UNESCAPED_UNICODE)
+            ]);
+            $sendResp = $this->client->sendSms($sendReq);
+            $code = $sendResp->body->code;
+            $remark = $sendResp->body->bizId;
+            if (Utils::equalString($code, "OK")) {
+                $return = true;
+            }
+            else
+            {
+                $return = false;
+            }
+        }
+        else if($this->apitype=='tencent'){
+            $msgcontent = $tpl->tpl;
+            $params = [];
+            $i = 1;
+            if(is_array($args))foreach($args as $k=>$v)
+            {
+                $params[]=  strval($v);
+                $msgcontent = str_replace('{'.$i.'}',$v,$msgcontent);
+                $i++;
+            }
+
+            $req = new SendSmsRequest();
+            $req->SmsSdkAppId =  $this->appid;
+            $req->SignName = $this->sign;
+            $req->TemplateId = $tpl->code;
+            $req->TemplateParamSet = $params;
+            $req->PhoneNumberSet = $toMobileList;
+            $resp = $this->client->SendSms($req);
+            // 输出json格式的字符串回包
+            $result = json_decode($resp->toJsonString(),true);
+            $remark = $result['RequestId'];
+            if($result['SendStatusSet'][0]['Code']=='Ok')
+            {
+                $return = true;
+
+            }
+            else
+            {
+                $return = false;
+            }
+
+        }
+        foreach($toMobileList as $mobile)
+        {
+            $mobileMsg = new MobileMsg();
+            $mobileMsg->mobile = $mobile;
+            $mobileMsg->content = $msgcontent;
+            $mobileMsg->remarks = $remark;
+            $mobileMsg->type = $tpl->type;
+            $mobileMsg->sent_time = TIMESTAMP;
+            $mobileMsg->save();
+            if($mobileMsg->type==1)
+            {
+                $mobileCert = new MobileCert();
+                $mobileCert->mobile = $mobile;
+                $mobileCert->user_id = $user_id;
+                $mobileCert->cert_key = strval($args['code']);
+                $mobileCert->request_from = REQUEST_FROM;
+                $mobileCert->sent_time = TIMESTAMP;
+                $mobileCert->save();
+            }
+        }
+        return $return;
+    }
+
+
+
+}
+
+?>

+ 165 - 0
common/components/Tree.php

@@ -0,0 +1,165 @@
+<?php
+namespace app\common\components;
+/**
+* 通用的树型类,可以生成任何树型结构
+*/
+class Tree {
+	/**
+	* 生成树型结构所需要的2维数组
+	* @var array
+	*/
+	public $arr = array();
+
+	/**
+	* 生成树型结构所需修饰符号,可以换成图片
+	* @var array
+	*/
+	public $icon = array('│','├','└');
+	public $nbsp = "&nbsp;";
+
+	/**
+	* @access private
+	*/
+	public $ret = '';
+
+	/**
+	* 构造函数,初始化类
+	* @param array 2维数组,例如:
+	* array(
+	*      1 => array('id'=>'1','parent_id'=>0,'name'=>'一级栏目一'),
+	*      2 => array('id'=>'2','parent_id'=>0,'name'=>'一级栏目二'),
+	*      3 => array('id'=>'3','parent_id'=>1,'name'=>'二级栏目一'),
+	*      4 => array('id'=>'4','parent_id'=>1,'name'=>'二级栏目二'),
+	*      5 => array('id'=>'5','parent_id'=>2,'name'=>'二级栏目三'),
+	*      6 => array('id'=>'6','parent_id'=>3,'name'=>'三级栏目一'),
+	*      7 => array('id'=>'7','parent_id'=>3,'name'=>'三级栏目二')
+	*      )
+	*/
+	public function init($arr=array()){
+       $this->arr = $arr;
+	   $this->ret = '';
+	   return is_array($arr);
+	}
+
+    /**
+	* 得到父级数组
+	* @param int
+	* @return array
+	*/
+	public function get_parent($myid){
+		$newarr = array();
+		if(!isset($this->arr[$myid])) return false;
+		$pid = $this->arr[$myid]['parent_id'];
+		$pid = $this->arr[$pid]['parent_id'];
+		if(is_array($this->arr)){
+			foreach($this->arr as $id => $a){
+				if($a['parent_id'] == $pid) $newarr[$id] = $a;
+			}
+		}
+		return $newarr;
+	}
+
+    /**
+	* 得到子级数组
+	* @param int
+	* @return array
+	*/
+	public function get_child($myid){
+		
+		$a = $newarr = array();
+		if(is_array($this->arr)){
+			foreach($this->arr as $id => $a){
+				if($a['parent_id'] == $myid) $newarr[$id] = $a;
+			}
+		}
+		return $newarr ? $newarr : false;
+	}
+
+    /**
+	* 得到当前位置数组
+	* @param int
+	* @return array
+	*/
+	public function get_pos($myid,&$newarr){
+		$a = array();
+		if(!isset($this->arr[$myid])) return false;
+        $newarr[] = $this->arr[$myid];
+		$pid = $this->arr[$myid]['parent_id'];
+		if(isset($this->arr[$pid])){
+		    $this->get_pos($pid,$newarr);
+		}
+		if(is_array($newarr)){
+			krsort($newarr);
+			foreach($newarr as $v){
+				$a[$v['id']] = $v;
+			}
+		}
+		return $a;
+	}
+
+    /**
+	* 得到树型结构
+	* @param $tid int ID,表示获得这个ID下的所有子级
+	* @param $str string 生成树型结构的基本代码,例如:"<option value=\$id \$selected>\$spacer\$name</option>"
+	* @param $sid int 被选中的ID,比如在做树型下拉框的时候需要用到
+	* @return string
+	*/
+	public  function get_tree($tid, $str, $sid = 0, $adds = '', $str_group = ''){
+		$number=1;
+		$child = $this->get_child($tid);
+		if(is_array($child)){
+		    $total = count($child);
+			foreach($child as $id=>$value){
+				$j=$k='';
+				if($number==$total){
+					$j .= $this->icon[2];
+				}else{
+					$j .= $this->icon[1];
+					$k = $adds ? $this->icon[0] : '';
+				}
+				$spacer = $adds ? $adds.$j : '';
+				$selected = $id==$sid ? 'selected' : '';
+				@extract($value);
+				$parent_id == 0 && $str_group ? eval("\$nstr = \"$str_group\";") : eval("\$nstr = \"$str\";");
+				$this->ret .= $nstr;
+				$nbsp = $this->nbsp;
+				$this->get_tree($id, $str, $sid, $adds.$k.$nbsp,$str_group);
+				$number++;
+			}
+		}
+		return $this->ret;
+	}
+    /**
+	* 同上一方法类似,但允许多选
+	*/
+	public function get_tree_multi($tid, $str, $sid = 0, $adds = ''){
+		$number=1;
+		$child = $this->get_child($tid);
+		if(is_array($child)){
+		    $total = count($child);
+			foreach($child as $id=>$a){
+				$j=$k='';
+				if($number==$total){
+					$j .= $this->icon[2];
+				}else{
+					$j .= $this->icon[1];
+					$k = $adds ? $this->icon[0] : '';
+				}
+				$spacer = $adds ? $adds.$j : '';
+				
+				$selected = $this->have($sid,$id) ? 'selected' : '';
+				@extract($a);
+				eval("\$nstr = \"$str\";");
+				$this->ret .= $nstr;
+				$this->get_tree_multi($id, $str, $sid, $adds.$k.'&nbsp;');
+				$number++;
+			}
+		}
+		return $this->ret;
+	}
+
+	private function have($list,$item){
+		return(strpos(',,'.$list.',',','.$item.','));
+	}
+}
+?>

+ 67 - 0
common/components/Unzip.php

@@ -0,0 +1,67 @@
+<?php
+/**
+ * function: 解压zip 格式的文件
+ * author:friker
+ * date:2015-15-14
+ * reference:http://php.net/manual/zh/ref.zip.php
+ * all rights reserved:wujiangwei123@126.com
+ */
+namespace app\common\components;
+class Unzip{
+    public function __construct(){
+        //init code here...
+        //header("content-type:text/html;charset=utf8");
+    }
+
+
+    function transcoding($fileName){
+        $encoding = mb_detect_encoding($fileName,['UTF-8','GBK','BIG5','CP936']);
+        if (DIRECTORY_SEPARATOR == '/'){    //linux
+            $filename = iconv($encoding,'UTF-8',$fileName);
+        }else{  //win
+            $filename = iconv($encoding,'GBK',$fileName);
+        }
+        return $filename;
+    }
+
+    /**
+     * 解压文件到指定目录
+     *
+     * @param  string  zip压缩文件的路径
+     * @param  string  解压文件的目的路径
+     * @param  boolean 是否以压缩文件的名字创建目标文件夹
+     * @param  boolean 是否重写已经存在的文件
+     *
+     * @return boolean 返回成功 或失败
+     */
+    public function unzip($src_file, $dest_dir=false, $create_zip_name_dir=true, $overwrite=true){
+        $fileList = array();
+        $zip = new \ZipArchive;
+        if ($zip->open($src_file) === TRUE) {
+            if(!is_dir($dest_dir)) mkdir($dest_dir,0775,true);
+            $docnum = $zip->numFiles;
+            for($i = 0; $i < $docnum; $i++) {
+                $statInfo = $zip->statIndex($i,\ZipArchive::FL_ENC_RAW);
+                $filename = $this->transcoding($statInfo['name']);
+                if($statInfo['crc'] == 0) {
+                    //新建目录
+                    if(!is_dir($dest_dir.'/'.substr($filename, 0,-1))) mkdir($dest_dir.'/'.substr($filename, 0,-1),0775,true);
+                } else {
+                    //拷贝文件
+                    $fileList[] = $dest_dir.'/'.$filename;
+                    @copy('zip://'.$src_file.'#'.$zip->getNameIndex($i), $dest_dir.'/'.$filename);
+                }
+            }
+            $zip->close();
+            return $fileList;
+        }else{
+            return false;
+        }
+
+
+    }
+
+}
+
+
+?>

+ 135 - 0
common/components/Upload.php

@@ -0,0 +1,135 @@
+<?php
+namespace app\common\components;
+use Yii;
+use yii\base\Model;
+use yii\web\UploadedFile;
+use yii\helpers\FileHelper;
+use app\modules\admin\models\Attachment;
+
+/**
+ * 文件上传处理
+ */
+class Upload extends Model
+{
+    public $file;
+    private $_appendRules;
+    public function init ()
+    {
+        parent::init();
+        if(!empty(Yii::$app->params['webuploader']['baseConfig']['accept']['extensions']))
+        {
+            $extensions = Yii::$app->params['webuploader']['baseConfig']['accept']['extensions'];
+        }
+        else
+        {
+            $extensions = 'ico,gif,jpg,jpeg,bmp,png,pdf,doc,docx,ppt,pptx,xls,xlsx,rar,zip,7z,tar.gz,war,txt,mp4,mp3,flv,wps,et,dps';
+        }
+        $this->_appendRules = [
+            [['file'], 'file', 'extensions' => $extensions],
+        ];
+    }
+    public function rules()
+    {
+        $baseRules = [];
+        return array_merge($baseRules, $this->_appendRules);
+    }
+    /**
+     *
+     */
+    public function upImage ()
+    {
+        $model = new static;
+        $model->file = UploadedFile::getInstanceByName('file');
+        if (!$model->file) {
+            return false;
+        }
+        $targetPath = '';
+        if ($model->validate()) {
+            $childPath = date('Y',TIMESTAMP).DIRECTORY_SEPARATOR.date('m',TIMESTAMP).DIRECTORY_SEPARATOR.date('d',TIMESTAMP).DIRECTORY_SEPARATOR;
+            $targetPath = UPLOAD_PATH.$childPath;
+            $fileName = get_unique_file_name($targetPath,$model->file->extension);//文件重命名
+            if (!is_dir($targetPath)) {
+                FileHelper::createDirectory($targetPath);
+            }
+            $targetFile = $targetPath . $fileName;
+            $model->file->saveAs($targetFile);
+            $params = Yii::$app->params;
+            //上传设置(判断是否采用全路径)
+            $attConfigInfo = \app\modules\admin\models\Config::find()->where("name='attachment'")->one();
+            $attConfig = string2array($attConfigInfo->value);
+            $ossConfigResult = \app\modules\admin\models\Config::find()->where("name='oss'")->one();
+            $ossConfig = string2array($ossConfigResult['value']);
+            $filePath = str_replace(DIRECTORY_SEPARATOR,'/',$childPath.$fileName);
+            $fileUrl =  UPLOAD_URL.$filePath;
+            if($params['oss']['OPEN_OSS']==1)//如果开启了云存储,初始化存储对象
+            {
+                $oss = new \app\common\components\Oss();
+                $initResult = $oss->init($ossConfig['OPEN_INTERNAL']);
+                if($initResult['error']==0)
+                {
+                    $result = $oss->Upload($targetFile,$filePath);
+                    if($result['error']==0)
+                    {
+                        $fileUrl = $result['data']['url'];
+                        $filePath =  $attConfig['absolute_url']?$result['data']['url']:$result['data']['path'];
+                        @unlink($targetFile);
+                    }
+                    else
+                    {
+                        return [
+                            'code' => 1,
+                            'msg' => $result['msg']
+                        ];
+                    }
+
+                }
+                else
+                {
+                    return [
+                        'code' => 1,
+                        'msg' => $initResult['msg']
+                    ];
+                }
+            }
+            else
+            {
+                $filePath =  $attConfig['absolute_url']?$fileUrl:$filePath;
+            }
+
+            //写入附件表
+            $attachment = new Attachment();
+            $attachment->file_name = $model->file->name;
+            $attachment->file_path = $filePath;
+            $attachment->file_size = $model->file->size;
+            $attachment->file_ext = $model->file->extension;
+            $attachment->hash = md5($filePath);
+            $attachment->upload_time = TIMESTAMP;
+            $attachment->upload_ip = MYIP;
+            if(!empty($_POST['md5'])){$attachment->md5 = safe_replace($_POST['md5']);}
+            $attachment->status = 1;
+            $attachment->list_order = 0;
+            $attachment->folder = Yii::$app->request->post('folder','');
+            $attachment->save();
+
+            return [
+                'code' => 0,
+                'url' =>$fileUrl,
+                'attachment' => $filePath,
+                'name'=>$model->file->name,
+                'size'=>$model->file->size
+            ];
+        } else {
+            $errorsInfo = $model->getFirstErrors();
+            if(is_array($errorsInfo))foreach($errorsInfo as $k=>$v)
+            {
+                $errors[] = $v;
+            }
+            return [
+                'code' => 1,
+                'msg' => $errors[0]
+            ];
+        }
+
+
+    }
+}

+ 254 - 0
common/components/Wallet.php

@@ -0,0 +1,254 @@
+<?php
+namespace app\common\components;
+use app\modules\ucenter\models\User;
+use app\modules\ucenter\models\UserCoinLog;
+use app\modules\ucenter\models\UserPointLog;
+use app\modules\ucenter\models\UserMoneyLog;
+use app\modules\shopping\models\ShoppingCommissionLog;
+use app\modules\shopping\models\ShoppingStore;
+use app\modules\Doc\models\DocReal;
+use Yii;
+class Wallet
+{
+
+   //金币变化
+   public static function coinChange($user_id,$change_num,$bak,$change_type=1,$field='coin',$table_name='',$data_id=0)
+   {
+       $userInfo =  User::findOne($user_id);
+       $before_num = $userInfo[$field];
+       $after_num = $change_type==1?$before_num + $change_num:(($before_num - $change_num)>0?($before_num - $change_num):0);
+       $log = new UserCoinLog();
+       $log->user_id = $userInfo['user_id'];
+       $log->before_num = $before_num;
+       $log->after_num = $after_num;
+       $log->change_num = $change_num;
+       $log->change_type = $change_type;
+       $log->table_name = $table_name;
+       $log->data_id = $data_id;
+       $log->field = $field;
+       $log->bak = $bak;
+       $log->create_time = TIMESTAMP;
+       if($log->save())
+       {
+           $updateNum =  $change_type==1?$change_num:0-$change_num;
+           User::findOne($user_id)->updateCounters([$field=>$updateNum]);
+           //更新用户累计金币收入
+           if($field=='coin_income'&&$change_type==1)
+           {
+               User::findOne($user_id)->updateCounters(['amount_coin_income'=>$updateNum]);
+           }
+           return true;
+
+       }
+       else
+       {
+           return false;
+       }
+
+   }
+
+    //金币变化
+    public static function pointChange($user_id,$change_num,$bak,$change_type=1,$field='point',$table_name='',$data_id=0)
+    {
+        if($change_num==0)return true;
+        $userInfo =  User::findOne($user_id);
+        $before_num = intval($userInfo[$field]);
+        $after_num = $change_type==1?$before_num + $change_num:(($before_num - $change_num)>0?($before_num - $change_num):0);
+        $log = new UserPointLog();
+        $log->user_id = $userInfo['user_id'];
+        $log->before_num = $before_num;
+        $log->after_num = $after_num;
+        $log->change_num = $change_num;
+        $log->table_name = $table_name;
+        $log->data_id = $data_id;
+        $log->change_type = $change_type;
+        $log->bak = $bak;
+        $log->create_time = TIMESTAMP;
+        if($log->save())
+        {
+            $updateNum =  $change_type==1?$change_num:0-$change_num;
+            User::findOne($user_id)->updateCounters([$field=>$updateNum]);
+            //更新用户累计积分
+            if($field=='point'&&$change_type==1)
+            {
+                User::findOne($user_id)->updateCounters(['allpoint'=>$updateNum]);
+            }
+            return true;
+        }
+        else
+        {
+            file_put_contents(UPLOAD_PATH.'log.txt',$log->returnFirstError(),FILE_APPEND);
+
+        }
+
+    }
+
+
+   //文档分销
+   public static function docCommission($user_id,$doc,$paylog,$coin_num)
+   {
+       $leftCoin = $coin_num;
+       $commissionconfigResult = Yii::$app->db->createCommand("select * from {{%config}} where name='commission'")->queryOne();
+       $commissionConfig = string2array($commissionconfigResult['value']);
+       if($commissionConfig['on'])
+       {
+           $user = User::findOne($user_id);
+           if(!empty($user->referer_ids))
+           {
+               $paylog->agent_id = $user->referer_id;
+               $paylog->agent_ids = $user->referer_ids;
+               $paylog->save();
+               $referer_ids = explode(",",trim($user->referer_ids,","));
+               if(is_array($referer_ids))foreach(array_slice($referer_ids,0,Yii::$app->params['level']) as $k=>$referer_id)
+               {
+                   $level = $k+1;
+                   $tempUser = User::findOne($referer_id);
+                   $vipSettings = [];
+                   $commissionRate = 0;
+
+                   if($tempUser->vipInfo())
+                   {
+                       $vipSettings = $tempUser->vipSettings();
+                       $commissionRate = $vipSettings?$vipSettings['doc_commission_level'.$level.'_rate']:$commissionConfig['doc_commission_level'.$level.'_rate'];
+                   }
+                   else
+                   {
+                       $commissionRate = $commissionConfig['doc_commission_level'.$level.'_rate'];
+
+                   }
+
+                   if($commissionRate>0)
+                   {
+                       $store = ShoppingStore::find()->where("user_id=$referer_id")->one();
+                       $commissionLog = new ShoppingCommissionLog();
+                       if(!empty($store))
+                       {
+                           $commissionLog->store_id = $store->store_id;
+                       }
+                       $commissionLog->user_id = $user_id;
+                       $commissionLog->order_id = 0;
+                       $commissionLog->goods_id = $paylog->log_id;
+                       $commissionLog->referer_id = $referer_id;
+                       $commissionLog->referer_level = $level;
+                       $commissionLog->commission = round(($commissionRate/100)*$coin_num,2);
+                       $commissionLog->type = 2;
+                       $commissionLog->bak = '分销文档';
+                       $commissionLog->create_time = TIMESTAMP;
+                       if($commissionLog->save())
+                       {
+                           Wallet::coinChange($referer_id,$commissionLog->commission,'分销返佣',1,'coin_income',DocReal::shortTableName(),$doc->id);
+                           $leftCoin -= $commissionLog->commission;
+                           //公众号消息推送
+                           MessageOne::commissionDoc($referer_id,$doc,$paylog->coin_num,$commissionLog->commission);
+
+                       }
+
+                   }
+
+               }
+
+           }
+
+       }
+       return $leftCoin;
+
+   }
+
+    //VIP分销
+    public static function vipCommission($user_id,$userVipOrder)
+    {
+        $commissionconfigResult = Yii::$app->db->createCommand("select * from {{%config}} where name='commission'")->queryOne();
+        $commissionConfig = string2array($commissionconfigResult['value']);
+        if($commissionConfig['on'])
+        {
+            $user = User::findOne($user_id);
+            if(!empty($user->referer_ids))
+            {
+                $referer_ids = explode(",",trim($user->referer_ids,","));
+                if(is_array($referer_ids))foreach(array_slice($referer_ids,0,Yii::$app->params['level']) as $k=>$referer_id)
+                {
+                    $level = $k+1;
+                    $tempUser = User::findOne($referer_id);
+                    $vipSettings = [];
+                    $commissionRate = 0;
+                    if($tempUser->vipInfo())
+                    {
+                        $vipSettings = $tempUser->vipSettings();
+                        $commissionRate = $vipSettings?$vipSettings['docvip_commission_level'.$level.'_rate']:$commissionConfig['docvip_commission_level'.$level.'_rate'];
+                    }
+                    else
+                    {
+                        $commissionRate = $commissionConfig['docvip_commission_level'.$level.'_rate'];
+
+                    }
+                    if($commissionRate>0)
+                    {
+                        $store = ShoppingStore::find()->where("user_id=$referer_id")->one();
+                        $commissionLog = new ShoppingCommissionLog();
+                        if(!empty($store))
+                        {
+                            $commissionLog->store_id = $store->store_id;
+                        }
+                        $commissionLog->user_id = $user_id;
+                        $commissionLog->order_id = $userVipOrder->order_id;
+                        $commissionLog->goods_id = $userVipOrder->vip_type;
+                        $commissionLog->referer_id = $referer_id;
+                        $commissionLog->referer_level = $level;
+                        $commissionLog->commission = round(($commissionRate/100)*$userVipOrder->money,2);
+                        $commissionLog->type = 1;
+                        $commissionLog->bak = '分销VIP';
+                        $commissionLog->create_time = TIMESTAMP;
+                        if($commissionLog->save())
+                        {
+                            Wallet::moneyChange($referer_id,$commissionLog->commission,'分销返佣',1);
+                            //公众号消息推送
+                            MessageOne::commissionVip($referer_id,$userVipOrder,$commissionLog->commission);
+                        }
+
+                    }
+
+                }
+            }
+        }
+
+    }
+
+
+
+    //余额变化
+    public static function moneyChange($user_id,$change_num,$bak,$change_type=1,$field='money',$status=1)
+    {
+        if($change_num==0)return true;
+        $userInfo =  User::findOne($user_id);
+        $before_num = intval($userInfo[$field]);
+        $after_num = $change_type==1?$before_num + $change_num:(($before_num - $change_num)>0?($before_num - $change_num):0);
+        $log = new UserMoneyLog();
+        $log->user_id = $userInfo['user_id'];
+        $log->before_num = $before_num;
+        $log->after_num = $after_num;
+        $log->change_num = $change_num;
+        $log->change_type = $change_type;
+        $log->field = $field;
+        $log->bak = $bak;
+        $log->status = $status;
+        $log->create_time = TIMESTAMP;
+        if($log->save())
+        {
+            $updateNum =  $change_type==1?$change_num:0-$change_num;
+            User::findOne($user_id)->updateCounters([$field=>$updateNum]);
+            //更新用户累计收益
+            if($field=='money'&&$change_type==1&&$status==1)
+            {
+                User::findOne($user_id)->updateCounters(['amount_money_income'=>$updateNum]);
+            }
+            return true;
+        }
+        else
+        {
+            file_put_contents(UPLOAD_PATH.'log.txt',$log->returnFirstError(),FILE_APPEND);
+
+        }
+
+    }
+
+}

+ 1709 - 0
common/components/sphinxapi.php

@@ -0,0 +1,1709 @@
+<?php
+//
+// $Id$
+//
+
+//
+// Copyright (c) 2001-2011, Andrew Aksyonoff
+// Copyright (c) 2008-2011, Sphinx Technologies Inc
+// All rights reserved
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License. You should have
+// received a copy of the GPL license along with this program; if you
+// did not, you can find it at http://www.gnu.org/
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// PHP version of Sphinx searchd client (PHP API)
+/////////////////////////////////////////////////////////////////////////////
+
+/// known searchd commands
+define ( "SEARCHD_COMMAND_SEARCH",		0 );
+define ( "SEARCHD_COMMAND_EXCERPT",		1 );
+define ( "SEARCHD_COMMAND_UPDATE",		2 );
+define ( "SEARCHD_COMMAND_KEYWORDS",	3 );
+define ( "SEARCHD_COMMAND_PERSIST",		4 );
+define ( "SEARCHD_COMMAND_STATUS",		5 );
+define ( "SEARCHD_COMMAND_FLUSHATTRS",	7 );
+
+/// current client-side command implementation versions
+define ( "VER_COMMAND_SEARCH",		0x119 );
+define ( "VER_COMMAND_EXCERPT",		0x103 );
+define ( "VER_COMMAND_UPDATE",		0x102 );
+define ( "VER_COMMAND_KEYWORDS",	0x100 );
+define ( "VER_COMMAND_STATUS",		0x100 );
+define ( "VER_COMMAND_QUERY",		0x100 );
+define ( "VER_COMMAND_FLUSHATTRS",	0x100 );
+
+/// known searchd status codes
+define ( "SEARCHD_OK",				0 );
+define ( "SEARCHD_ERROR",			1 );
+define ( "SEARCHD_RETRY",			2 );
+define ( "SEARCHD_WARNING",			3 );
+
+/// known match modes
+define ( "SPH_MATCH_ALL",			0 );
+define ( "SPH_MATCH_ANY",			1 );
+define ( "SPH_MATCH_PHRASE",		2 );
+define ( "SPH_MATCH_BOOLEAN",		3 );
+define ( "SPH_MATCH_EXTENDED",		4 );
+define ( "SPH_MATCH_FULLSCAN",		5 );
+define ( "SPH_MATCH_EXTENDED2",		6 );	// extended engine V2 (TEMPORARY, WILL BE REMOVED)
+
+/// known ranking modes (ext2 only)
+define ( "SPH_RANK_PROXIMITY_BM25",	0 );	///< default mode, phrase proximity major factor and BM25 minor one
+define ( "SPH_RANK_BM25",			1 );	///< statistical mode, BM25 ranking only (faster but worse quality)
+define ( "SPH_RANK_NONE",			2 );	///< no ranking, all matches get a weight of 1
+define ( "SPH_RANK_WORDCOUNT",		3 );	///< simple word-count weighting, rank is a weighted sum of per-field keyword occurence counts
+define ( "SPH_RANK_PROXIMITY",		4 );
+define ( "SPH_RANK_MATCHANY",		5 );
+define ( "SPH_RANK_FIELDMASK",		6 );
+define ( "SPH_RANK_SPH04",			7 );
+define ( "SPH_RANK_EXPR",			8 );
+define ( "SPH_RANK_TOTAL",			9 );
+
+/// known sort modes
+define ( "SPH_SORT_RELEVANCE",		0 );
+define ( "SPH_SORT_ATTR_DESC",		1 );
+define ( "SPH_SORT_ATTR_ASC",		2 );
+define ( "SPH_SORT_TIME_SEGMENTS", 	3 );
+define ( "SPH_SORT_EXTENDED", 		4 );
+define ( "SPH_SORT_EXPR", 			5 );
+
+/// known filter types
+define ( "SPH_FILTER_VALUES",		0 );
+define ( "SPH_FILTER_RANGE",		1 );
+define ( "SPH_FILTER_FLOATRANGE",	2 );
+
+/// known attribute types
+define ( "SPH_ATTR_INTEGER",		1 );
+define ( "SPH_ATTR_TIMESTAMP",		2 );
+define ( "SPH_ATTR_ORDINAL",		3 );
+define ( "SPH_ATTR_BOOL",			4 );
+define ( "SPH_ATTR_FLOAT",			5 );
+define ( "SPH_ATTR_BIGINT",			6 );
+define ( "SPH_ATTR_STRING",			7 );
+define ( "SPH_ATTR_MULTI",			0x40000001 );
+define ( "SPH_ATTR_MULTI64",			0x40000002 );
+
+/// known grouping functions
+define ( "SPH_GROUPBY_DAY",			0 );
+define ( "SPH_GROUPBY_WEEK",		1 );
+define ( "SPH_GROUPBY_MONTH",		2 );
+define ( "SPH_GROUPBY_YEAR",		3 );
+define ( "SPH_GROUPBY_ATTR",		4 );
+define ( "SPH_GROUPBY_ATTRPAIR",	5 );
+
+// important properties of PHP's integers:
+//  - always signed (one bit short of PHP_INT_SIZE)
+//  - conversion from string to int is saturated
+//  - float is double
+//  - div converts arguments to floats
+//  - mod converts arguments to ints
+
+// the packing code below works as follows:
+//  - when we got an int, just pack it
+//    if performance is a problem, this is the branch users should aim for
+//
+//  - otherwise, we got a number in string form
+//    this might be due to different reasons, but we assume that this is
+//    because it didn't fit into PHP int
+//
+//  - factor the string into high and low ints for packing
+//    - if we have bcmath, then it is used
+//    - if we don't, we have to do it manually (this is the fun part)
+//
+//    - x64 branch does factoring using ints
+//    - x32 (ab)uses floats, since we can't fit unsigned 32-bit number into an int
+//
+// unpacking routines are pretty much the same.
+//  - return ints if we can
+//  - otherwise format number into a string
+
+/// pack 64-bit signed
+function sphPackI64 ( $v )
+{
+	assert ( is_numeric($v) );
+	
+	// x64
+	if ( PHP_INT_SIZE>=8 )
+	{
+		$v = (int)$v;
+		return pack ( "NN", $v>>32, $v&0xFFFFFFFF );
+	}
+
+	// x32, int
+	if ( is_int($v) )
+		return pack ( "NN", $v < 0 ? -1 : 0, $v );
+
+	// x32, bcmath	
+	if ( function_exists("bcmul") )
+	{
+		if ( bccomp ( $v, 0 ) == -1 )
+			$v = bcadd ( "18446744073709551616", $v );
+		$h = bcdiv ( $v, "4294967296", 0 );
+		$l = bcmod ( $v, "4294967296" );
+		return pack ( "NN", (float)$h, (float)$l ); // conversion to float is intentional; int would lose 31st bit
+	}
+
+	// x32, no-bcmath
+	$p = max(0, strlen($v) - 13);
+	$lo = abs((float)substr($v, $p));
+	$hi = abs((float)substr($v, 0, $p));
+
+	$m = $lo + $hi*1316134912.0; // (10 ^ 13) % (1 << 32) = 1316134912
+	$q = floor($m/4294967296.0);
+	$l = $m - ($q*4294967296.0);
+	$h = $hi*2328.0 + $q; // (10 ^ 13) / (1 << 32) = 2328
+
+	if ( $v<0 )
+	{
+		if ( $l==0 )
+			$h = 4294967296.0 - $h;
+		else
+		{
+			$h = 4294967295.0 - $h;
+			$l = 4294967296.0 - $l;
+		}
+	}
+	return pack ( "NN", $h, $l );
+}
+
+/// pack 64-bit unsigned
+function sphPackU64 ( $v )
+{
+	assert ( is_numeric($v) );
+	
+	// x64
+	if ( PHP_INT_SIZE>=8 )
+	{
+		assert ( $v>=0 );
+		
+		// x64, int
+		if ( is_int($v) )
+			return pack ( "NN", $v>>32, $v&0xFFFFFFFF );
+						  
+		// x64, bcmath
+		if ( function_exists("bcmul") )
+		{
+			$h = bcdiv ( $v, 4294967296, 0 );
+			$l = bcmod ( $v, 4294967296 );
+			return pack ( "NN", $h, $l );
+		}
+		
+		// x64, no-bcmath
+		$p = max ( 0, strlen($v) - 13 );
+		$lo = (int)substr ( $v, $p );
+		$hi = (int)substr ( $v, 0, $p );
+	
+		$m = $lo + $hi*1316134912;
+		$l = $m % 4294967296;
+		$h = $hi*2328 + (int)($m/4294967296);
+
+		return pack ( "NN", $h, $l );
+	}
+
+	// x32, int
+	if ( is_int($v) )
+		return pack ( "NN", 0, $v );
+	
+	// x32, bcmath
+	if ( function_exists("bcmul") )
+	{
+		$h = bcdiv ( $v, "4294967296", 0 );
+		$l = bcmod ( $v, "4294967296" );
+		return pack ( "NN", (float)$h, (float)$l ); // conversion to float is intentional; int would lose 31st bit
+	}
+
+	// x32, no-bcmath
+	$p = max(0, strlen($v) - 13);
+	$lo = (float)substr($v, $p);
+	$hi = (float)substr($v, 0, $p);
+	
+	$m = $lo + $hi*1316134912.0;
+	$q = floor($m / 4294967296.0);
+	$l = $m - ($q * 4294967296.0);
+	$h = $hi*2328.0 + $q;
+
+	return pack ( "NN", $h, $l );
+}
+
+// unpack 64-bit unsigned
+function sphUnpackU64 ( $v )
+{
+	list ( $hi, $lo ) = array_values ( unpack ( "N*N*", $v ) );
+
+	if ( PHP_INT_SIZE>=8 )
+	{
+		if ( $hi<0 ) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again
+		if ( $lo<0 ) $lo += (1<<32);
+
+		// x64, int
+		if ( $hi<=2147483647 )
+			return ($hi<<32) + $lo;
+
+		// x64, bcmath
+		if ( function_exists("bcmul") )
+			return bcadd ( $lo, bcmul ( $hi, "4294967296" ) );
+
+		// x64, no-bcmath
+		$C = 100000;
+		$h = ((int)($hi / $C) << 32) + (int)($lo / $C);
+		$l = (($hi % $C) << 32) + ($lo % $C);
+		if ( $l>$C )
+		{
+			$h += (int)($l / $C);
+			$l  = $l % $C;
+		}
+
+		if ( $h==0 )
+			return $l;
+		return sprintf ( "%d%05d", $h, $l );
+	}
+
+	// x32, int
+	if ( $hi==0 )
+	{
+		if ( $lo>0 )
+			return $lo;
+		return sprintf ( "%u", $lo );
+	}
+
+	$hi = sprintf ( "%u", $hi );
+	$lo = sprintf ( "%u", $lo );
+
+	// x32, bcmath
+	if ( function_exists("bcmul") )
+		return bcadd ( $lo, bcmul ( $hi, "4294967296" ) );
+	
+	// x32, no-bcmath
+	$hi = (float)$hi;
+	$lo = (float)$lo;
+	
+	$q = floor($hi/10000000.0);
+	$r = $hi - $q*10000000.0;
+	$m = $lo + $r*4967296.0;
+	$mq = floor($m/10000000.0);
+	$l = $m - $mq*10000000.0;
+	$h = $q*4294967296.0 + $r*429.0 + $mq;
+
+	$h = sprintf ( "%.0f", $h );
+	$l = sprintf ( "%07.0f", $l );
+	if ( $h=="0" )
+		return sprintf( "%.0f", (float)$l );
+	return $h . $l;
+}
+
+// unpack 64-bit signed
+function sphUnpackI64 ( $v )
+{
+	list ( $hi, $lo ) = array_values ( unpack ( "N*N*", $v ) );
+
+	// x64
+	if ( PHP_INT_SIZE>=8 )
+	{
+		if ( $hi<0 ) $hi += (1<<32); // because php 5.2.2 to 5.2.5 is totally fucked up again
+		if ( $lo<0 ) $lo += (1<<32);
+
+		return ($hi<<32) + $lo;
+	}
+
+	// x32, int
+	if ( $hi==0 )
+	{
+		if ( $lo>0 )
+			return $lo;
+		return sprintf ( "%u", $lo );
+	}
+	// x32, int
+	elseif ( $hi==-1 )
+	{
+		if ( $lo<0 )
+			return $lo;
+		return sprintf ( "%.0f", $lo - 4294967296.0 );
+	}
+	
+	$neg = "";
+	$c = 0;
+	if ( $hi<0 )
+	{
+		$hi = ~$hi;
+		$lo = ~$lo;
+		$c = 1;
+		$neg = "-";
+	}	
+
+	$hi = sprintf ( "%u", $hi );
+	$lo = sprintf ( "%u", $lo );
+
+	// x32, bcmath
+	if ( function_exists("bcmul") )
+		return $neg . bcadd ( bcadd ( $lo, bcmul ( $hi, "4294967296" ) ), $c );
+
+	// x32, no-bcmath
+	$hi = (float)$hi;
+	$lo = (float)$lo;
+	
+	$q = floor($hi/10000000.0);
+	$r = $hi - $q*10000000.0;
+	$m = $lo + $r*4967296.0;
+	$mq = floor($m/10000000.0);
+	$l = $m - $mq*10000000.0 + $c;
+	$h = $q*4294967296.0 + $r*429.0 + $mq;
+	if ( $l==10000000 )
+	{
+		$l = 0;
+		$h += 1;
+	}
+
+	$h = sprintf ( "%.0f", $h );
+	$l = sprintf ( "%07.0f", $l );
+	if ( $h=="0" )
+		return $neg . sprintf( "%.0f", (float)$l );
+	return $neg . $h . $l;
+}
+
+
+function sphFixUint ( $value )
+{
+	if ( PHP_INT_SIZE>=8 )
+	{
+		// x64 route, workaround broken unpack() in 5.2.2+
+		if ( $value<0 ) $value += (1<<32);
+		return $value;
+	}
+	else
+	{
+		// x32 route, workaround php signed/unsigned braindamage
+		return sprintf ( "%u", $value );
+	}
+}
+
+
+/// sphinx searchd client class
+class SphinxClient
+{
+	var $_host;			///< searchd host (default is "localhost")
+	var $_port;			///< searchd port (default is 9312)
+	var $_offset;		///< how many records to seek from result-set start (default is 0)
+	var $_limit;		///< how many records to return from result-set starting at offset (default is 20)
+	var $_mode;			///< query matching mode (default is SPH_MATCH_ALL)
+	var $_weights;		///< per-field weights (default is 1 for all fields)
+	var $_sort;			///< match sorting mode (default is SPH_SORT_RELEVANCE)
+	var $_sortby;		///< attribute to sort by (defualt is "")
+	var $_min_id;		///< min ID to match (default is 0, which means no limit)
+	var $_max_id;		///< max ID to match (default is 0, which means no limit)
+	var $_filters;		///< search filters
+	var $_groupby;		///< group-by attribute name
+	var $_groupfunc;	///< group-by function (to pre-process group-by attribute value with)
+	var $_groupsort;	///< group-by sorting clause (to sort groups in result set with)
+	var $_groupdistinct;///< group-by count-distinct attribute
+	var $_maxmatches;	///< max matches to retrieve
+	var $_cutoff;		///< cutoff to stop searching at (default is 0)
+	var $_retrycount;	///< distributed retries count
+	var $_retrydelay;	///< distributed retries delay
+	var $_anchor;		///< geographical anchor point
+	var $_indexweights;	///< per-index weights
+	var $_ranker;		///< ranking mode (default is SPH_RANK_PROXIMITY_BM25)
+	var $_rankexpr;		///< ranking mode expression (for SPH_RANK_EXPR)
+	var $_maxquerytime;	///< max query time, milliseconds (default is 0, do not limit)
+	var $_fieldweights;	///< per-field-name weights
+	var $_overrides;	///< per-query attribute values overrides
+	var $_select;		///< select-list (attributes or expressions, with optional aliases)
+
+	var $_error;		///< last error message
+	var $_warning;		///< last warning message
+	var $_connerror;		///< connection error vs remote error flag
+
+	var $_reqs;			///< requests array for multi-query
+	var $_mbenc;		///< stored mbstring encoding
+	var $_arrayresult;	///< whether $result["matches"] should be a hash or an array
+	var $_timeout;		///< connect timeout
+
+	/////////////////////////////////////////////////////////////////////////////
+	// common stuff
+	/////////////////////////////////////////////////////////////////////////////
+
+	/// create a new client object and fill defaults
+	function __construct ()
+	{
+		// per-client-object settings
+		$this->_host		= "localhost";
+		$this->_port		= 9312;
+		$this->_path		= false;
+		$this->_socket		= false;
+
+		// per-query settings
+		$this->_offset		= 0;
+		$this->_limit		= 20;
+		$this->_mode		= SPH_MATCH_ALL;
+		$this->_weights		= array ();
+		$this->_sort		= SPH_SORT_RELEVANCE;
+		$this->_sortby		= "";
+		$this->_min_id		= 0;
+		$this->_max_id		= 0;
+		$this->_filters		= array ();
+		$this->_groupby		= "";
+		$this->_groupfunc	= SPH_GROUPBY_DAY;
+		$this->_groupsort	= "@group desc";
+		$this->_groupdistinct= "";
+		$this->_maxmatches	= 1000;
+		$this->_cutoff		= 0;
+		$this->_retrycount	= 0;
+		$this->_retrydelay	= 0;
+		$this->_anchor		= array ();
+		$this->_indexweights= array ();
+		$this->_ranker		= SPH_RANK_PROXIMITY_BM25;
+		$this->_rankexpr	= "";
+		$this->_maxquerytime= 0;
+		$this->_fieldweights= array();
+		$this->_overrides 	= array();
+		$this->_select		= "*";
+
+		$this->_error		= ""; // per-reply fields (for single-query case)
+		$this->_warning		= "";
+		$this->_connerror	= false;
+
+		$this->_reqs		= array ();	// requests storage (for multi-query case)
+		$this->_mbenc		= "";
+		$this->_arrayresult	= false;
+		$this->_timeout		= 0;
+	}
+
+	function __destruct()
+	{
+		if ( $this->_socket !== false )
+			fclose ( $this->_socket );
+	}
+
+	/// get last error message (string)
+	function GetLastError ()
+	{
+		return $this->_error;
+	}
+
+	/// get last warning message (string)
+	function GetLastWarning ()
+	{
+		return $this->_warning;
+	}
+
+	/// get last error flag (to tell network connection errors from searchd errors or broken responses)
+	function IsConnectError()
+	{
+		return $this->_connerror;
+	}
+
+	/// set searchd host name (string) and port (integer)
+	function SetServer ( $host, $port = 0 )
+	{
+		assert ( is_string($host) );
+		if ( $host[0] == '/')
+		{
+			$this->_path = 'unix://' . $host;
+			return;
+		}
+		if ( substr ( $host, 0, 7 )=="unix://" )
+		{
+			$this->_path = $host;
+			return;
+		}
+				
+		assert ( is_int($port) );
+		$this->_host = $host;
+		$this->_port = $port;
+		$this->_path = '';
+
+	}
+
+	/// set server connection timeout (0 to remove)
+	function SetConnectTimeout ( $timeout )
+	{
+		assert ( is_numeric($timeout) );
+		$this->_timeout = $timeout;
+	}
+
+
+	function _Send ( $handle, $data, $length )
+	{
+		if ( feof($handle) || fwrite ( $handle, $data, $length ) !== $length )
+		{
+			$this->_error = 'connection unexpectedly closed (timed out?)';
+			$this->_connerror = true;
+			return false;
+		}
+		return true;
+	}
+
+	/////////////////////////////////////////////////////////////////////////////
+
+	/// enter mbstring workaround mode
+	function _MBPush ()
+	{
+		$this->_mbenc = "";
+		if ( ini_get ( "mbstring.func_overload" ) & 2 )
+		{
+			$this->_mbenc = mb_internal_encoding();
+			mb_internal_encoding ( "latin1" );
+		}
+    }
+
+	/// leave mbstring workaround mode
+	function _MBPop ()
+	{
+		if ( $this->_mbenc )
+			mb_internal_encoding ( $this->_mbenc );
+	}
+
+	/// connect to searchd server
+	function _Connect ()
+	{
+		if ( $this->_socket!==false )
+		{
+			// we are in persistent connection mode, so we have a socket
+			// however, need to check whether it's still alive
+			if ( !@feof ( $this->_socket ) )
+				return $this->_socket;
+
+			// force reopen
+			$this->_socket = false;
+		}
+
+		$errno = 0;
+		$errstr = "";
+		$this->_connerror = false;
+
+		if ( $this->_path )
+		{
+			$host = $this->_path;
+			$port = 0;
+		}
+		else
+		{
+			$host = $this->_host;
+			$port = $this->_port;
+		}
+
+		if ( $this->_timeout<=0 )
+			$fp = @fsockopen ( $host, $port, $errno, $errstr );
+		else
+			$fp = @fsockopen ( $host, $port, $errno, $errstr, $this->_timeout );
+		
+		if ( !$fp )
+		{
+			if ( $this->_path )
+				$location = $this->_path;
+			else
+				$location = "{$this->_host}:{$this->_port}";
+			
+			$errstr = trim ( $errstr );
+			$this->_error = "connection to $location failed (errno=$errno, msg=$errstr)";
+			$this->_connerror = true;
+			return false;
+		}
+
+		// send my version
+		// this is a subtle part. we must do it before (!) reading back from searchd.
+		// because otherwise under some conditions (reported on FreeBSD for instance)
+		// TCP stack could throttle write-write-read pattern because of Nagle.
+		if ( !$this->_Send ( $fp, pack ( "N", 1 ), 4 ) )
+		{
+			fclose ( $fp );
+			$this->_error = "failed to send client protocol version";
+			return false;
+		}
+
+		// check version
+		list(,$v) = unpack ( "N*", fread ( $fp, 4 ) );
+		$v = (int)$v;
+		if ( $v<1 )
+		{
+			fclose ( $fp );
+			$this->_error = "expected searchd protocol version 1+, got version '$v'";
+			return false;
+		}
+
+		return $fp;
+	}
+
+	/// get and check response packet from searchd server
+	function _GetResponse ( $fp, $client_ver )
+	{
+		$response = "";
+		$len = 0;
+
+		$header = fread ( $fp, 8 );
+		if ( strlen($header)==8 )
+		{
+			list ( $status, $ver, $len ) = array_values ( unpack ( "n2a/Nb", $header ) );
+			$left = $len;
+			while ( $left>0 && !feof($fp) )
+			{
+				$chunk = fread ( $fp, min ( 8192, $left ) );
+				if ( $chunk )
+				{
+					$response .= $chunk;
+					$left -= strlen($chunk);
+				}
+			}
+		}
+		if ( $this->_socket === false )
+			fclose ( $fp );
+
+		// check response
+		$read = strlen ( $response );
+		if ( !$response || $read!=$len )
+		{
+			$this->_error = $len
+				? "failed to read searchd response (status=$status, ver=$ver, len=$len, read=$read)"
+				: "received zero-sized searchd response";
+			return false;
+		}
+
+		// check status
+		if ( $status==SEARCHD_WARNING )
+		{
+			list(,$wlen) = unpack ( "N*", substr ( $response, 0, 4 ) );
+			$this->_warning = substr ( $response, 4, $wlen );
+			return substr ( $response, 4+$wlen );
+		}
+		if ( $status==SEARCHD_ERROR )
+		{
+			$this->_error = "searchd error: " . substr ( $response, 4 );
+			return false;
+		}
+		if ( $status==SEARCHD_RETRY )
+		{
+			$this->_error = "temporary searchd error: " . substr ( $response, 4 );
+			return false;
+		}
+		if ( $status!=SEARCHD_OK )
+		{
+			$this->_error = "unknown status code '$status'";
+			return false;
+		}
+
+		// check version
+		if ( $ver<$client_ver )
+		{
+			$this->_warning = sprintf ( "searchd command v.%d.%d older than client's v.%d.%d, some options might not work",
+				$ver>>8, $ver&0xff, $client_ver>>8, $client_ver&0xff );
+		}
+
+		return $response;
+	}
+
+	/////////////////////////////////////////////////////////////////////////////
+	// searching
+	/////////////////////////////////////////////////////////////////////////////
+
+	/// set offset and count into result set,
+	/// and optionally set max-matches and cutoff limits
+	function SetLimits ( $offset, $limit, $max=0, $cutoff=0 )
+	{
+		assert ( is_int($offset) );
+		assert ( is_int($limit) );
+		assert ( $offset>=0 );
+		assert ( $limit>0 );
+		assert ( $max>=0 );
+		$this->_offset = $offset;
+		$this->_limit = $limit;
+		if ( $max>0 )
+			$this->_maxmatches = $max;
+		if ( $cutoff>0 )
+			$this->_cutoff = $cutoff;
+	}
+
+	/// set maximum query time, in milliseconds, per-index
+	/// integer, 0 means "do not limit"
+	function SetMaxQueryTime ( $max )
+	{
+		assert ( is_int($max) );
+		assert ( $max>=0 );
+		$this->_maxquerytime = $max;
+	}
+
+	/// set matching mode
+	function SetMatchMode ( $mode )
+	{
+		assert ( $mode==SPH_MATCH_ALL
+			|| $mode==SPH_MATCH_ANY
+			|| $mode==SPH_MATCH_PHRASE
+			|| $mode==SPH_MATCH_BOOLEAN
+			|| $mode==SPH_MATCH_EXTENDED
+			|| $mode==SPH_MATCH_FULLSCAN
+			|| $mode==SPH_MATCH_EXTENDED2 );
+		$this->_mode = $mode;
+	}
+
+	/// set ranking mode
+	function SetRankingMode ( $ranker, $rankexpr="" )
+	{
+		assert ( $ranker>=0 && $ranker<SPH_RANK_TOTAL );
+		assert ( is_string($rankexpr) );
+		$this->_ranker = $ranker;
+		$this->_rankexpr = $rankexpr;
+	}
+
+	/// set matches sorting mode
+	function SetSortMode ( $mode, $sortby="" )
+	{
+		assert (
+			$mode==SPH_SORT_RELEVANCE ||
+			$mode==SPH_SORT_ATTR_DESC ||
+			$mode==SPH_SORT_ATTR_ASC ||
+			$mode==SPH_SORT_TIME_SEGMENTS ||
+			$mode==SPH_SORT_EXTENDED ||
+			$mode==SPH_SORT_EXPR );
+		assert ( is_string($sortby) );
+		assert ( $mode==SPH_SORT_RELEVANCE || strlen($sortby)>0 );
+
+		$this->_sort = $mode;
+		$this->_sortby = $sortby;
+	}
+
+	/// bind per-field weights by order
+	/// DEPRECATED; use SetFieldWeights() instead
+	function SetWeights ( $weights )
+	{
+		assert ( is_array($weights) );
+		foreach ( $weights as $weight )
+			assert ( is_int($weight) );
+
+		$this->_weights = $weights;
+	}
+
+	/// bind per-field weights by name
+	function SetFieldWeights ( $weights )
+	{
+		assert ( is_array($weights) );
+		foreach ( $weights as $name=>$weight )
+		{
+			assert ( is_string($name) );
+			assert ( is_int($weight) );
+		}
+		$this->_fieldweights = $weights;
+	}
+
+	/// bind per-index weights by name
+	function SetIndexWeights ( $weights )
+	{
+		assert ( is_array($weights) );
+		foreach ( $weights as $index=>$weight )
+		{
+			assert ( is_string($index) );
+			assert ( is_int($weight) );
+		}
+		$this->_indexweights = $weights;
+	}
+
+	/// set IDs range to match
+	/// only match records if document ID is beetwen $min and $max (inclusive)
+	function SetIDRange ( $min, $max )
+	{
+		assert ( is_numeric($min) );
+		assert ( is_numeric($max) );
+		assert ( $min<=$max );
+		$this->_min_id = $min;
+		$this->_max_id = $max;
+	}
+
+	/// set values set filter
+	/// only match records where $attribute value is in given set
+	function SetFilter ( $attribute, $values, $exclude=false )
+	{
+		assert ( is_string($attribute) );
+		assert ( is_array($values) );
+		assert ( count($values) );
+
+		if ( is_array($values) && count($values) )
+		{
+			foreach ( $values as $value )
+				assert ( is_numeric($value) );
+
+			$this->_filters[] = array ( "type"=>SPH_FILTER_VALUES, "attr"=>$attribute, "exclude"=>$exclude, "values"=>$values );
+		}
+	}
+
+	/// set range filter
+	/// only match records if $attribute value is beetwen $min and $max (inclusive)
+	function SetFilterRange ( $attribute, $min, $max, $exclude=false )
+	{
+		assert ( is_string($attribute) );
+		assert ( is_numeric($min) );
+		assert ( is_numeric($max) );
+		assert ( $min<=$max );
+
+		$this->_filters[] = array ( "type"=>SPH_FILTER_RANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max );
+	}
+
+	/// set float range filter
+	/// only match records if $attribute value is beetwen $min and $max (inclusive)
+	function SetFilterFloatRange ( $attribute, $min, $max, $exclude=false )
+	{
+		assert ( is_string($attribute) );
+		assert ( is_float($min) );
+		assert ( is_float($max) );
+		assert ( $min<=$max );
+
+		$this->_filters[] = array ( "type"=>SPH_FILTER_FLOATRANGE, "attr"=>$attribute, "exclude"=>$exclude, "min"=>$min, "max"=>$max );
+	}
+
+	/// setup anchor point for geosphere distance calculations
+	/// required to use @geodist in filters and sorting
+	/// latitude and longitude must be in radians
+	function SetGeoAnchor ( $attrlat, $attrlong, $lat, $long )
+	{
+		assert ( is_string($attrlat) );
+		assert ( is_string($attrlong) );
+		assert ( is_float($lat) );
+		assert ( is_float($long) );
+
+		$this->_anchor = array ( "attrlat"=>$attrlat, "attrlong"=>$attrlong, "lat"=>$lat, "long"=>$long );
+	}
+
+	/// set grouping attribute and function
+	function SetGroupBy ( $attribute, $func, $groupsort="@group desc" )
+	{
+		assert ( is_string($attribute) );
+		assert ( is_string($groupsort) );
+		assert ( $func==SPH_GROUPBY_DAY
+			|| $func==SPH_GROUPBY_WEEK
+			|| $func==SPH_GROUPBY_MONTH
+			|| $func==SPH_GROUPBY_YEAR
+			|| $func==SPH_GROUPBY_ATTR
+			|| $func==SPH_GROUPBY_ATTRPAIR );
+
+		$this->_groupby = $attribute;
+		$this->_groupfunc = $func;
+		$this->_groupsort = $groupsort;
+	}
+
+	/// set count-distinct attribute for group-by queries
+	function SetGroupDistinct ( $attribute )
+	{
+		assert ( is_string($attribute) );
+		$this->_groupdistinct = $attribute;
+	}
+
+	/// set distributed retries count and delay
+	function SetRetries ( $count, $delay=0 )
+	{
+		assert ( is_int($count) && $count>=0 );
+		assert ( is_int($delay) && $delay>=0 );
+		$this->_retrycount = $count;
+		$this->_retrydelay = $delay;
+	}
+
+	/// set result set format (hash or array; hash by default)
+	/// PHP specific; needed for group-by-MVA result sets that may contain duplicate IDs
+	function SetArrayResult ( $arrayresult )
+	{
+		assert ( is_bool($arrayresult) );
+		$this->_arrayresult = $arrayresult;
+	}
+
+	/// set attribute values override
+	/// there can be only one override per attribute
+	/// $values must be a hash that maps document IDs to attribute values
+	function SetOverride ( $attrname, $attrtype, $values )
+	{
+		assert ( is_string ( $attrname ) );
+		assert ( in_array ( $attrtype, array ( SPH_ATTR_INTEGER, SPH_ATTR_TIMESTAMP, SPH_ATTR_BOOL, SPH_ATTR_FLOAT, SPH_ATTR_BIGINT ) ) );
+		assert ( is_array ( $values ) );
+
+		$this->_overrides[$attrname] = array ( "attr"=>$attrname, "type"=>$attrtype, "values"=>$values );
+	}
+
+	/// set select-list (attributes or expressions), SQL-like syntax
+	function SetSelect ( $select )
+	{
+		assert ( is_string ( $select ) );
+		$this->_select = $select;
+	}
+
+	//////////////////////////////////////////////////////////////////////////////
+
+	/// clear all filters (for multi-queries)
+	function ResetFilters ()
+	{
+		$this->_filters = array();
+		$this->_anchor = array();
+	}
+
+	/// clear groupby settings (for multi-queries)
+	function ResetGroupBy ()
+	{
+		$this->_groupby		= "";
+		$this->_groupfunc	= SPH_GROUPBY_DAY;
+		$this->_groupsort	= "@group desc";
+		$this->_groupdistinct= "";
+	}
+
+	/// clear all attribute value overrides (for multi-queries)
+	function ResetOverrides ()
+    {
+    	$this->_overrides = array ();
+    }
+
+	//////////////////////////////////////////////////////////////////////////////
+
+	/// connect to searchd server, run given search query through given indexes,
+	/// and return the search results
+	function Query ( $query, $index="*", $comment="" )
+	{
+		assert ( empty($this->_reqs) );
+
+		$this->AddQuery ( $query, $index, $comment );
+		$results = $this->RunQueries ();
+		$this->_reqs = array (); // just in case it failed too early
+
+		if ( !is_array($results) )
+			return false; // probably network error; error message should be already filled
+
+		$this->_error = $results[0]["error"];
+		$this->_warning = $results[0]["warning"];
+		if ( $results[0]["status"]==SEARCHD_ERROR )
+			return false;
+		else
+			return $results[0];
+	}
+
+	/// helper to pack floats in network byte order
+	function _PackFloat ( $f )
+	{
+		$t1 = pack ( "f", $f ); // machine order
+		list(,$t2) = unpack ( "L*", $t1 ); // int in machine order
+		return pack ( "N", $t2 );
+	}
+
+	/// add query to multi-query batch
+	/// returns index into results array from RunQueries() call
+	function AddQuery ( $query, $index="*", $comment="" )
+	{
+		// mbstring workaround
+		$this->_MBPush ();
+
+		// build request
+		$req = pack ( "NNNN", $this->_offset, $this->_limit, $this->_mode, $this->_ranker );
+		if ( $this->_ranker==SPH_RANK_EXPR )
+			$req .= pack ( "N", strlen($this->_rankexpr) ) . $this->_rankexpr;
+		$req .= pack ( "N", $this->_sort ); // (deprecated) sort mode
+		$req .= pack ( "N", strlen($this->_sortby) ) . $this->_sortby;
+		$req .= pack ( "N", strlen($query) ) . $query; // query itself
+		$req .= pack ( "N", count($this->_weights) ); // weights
+		foreach ( $this->_weights as $weight )
+			$req .= pack ( "N", (int)$weight );
+		$req .= pack ( "N", strlen($index) ) . $index; // indexes
+		$req .= pack ( "N", 1 ); // id64 range marker
+		$req .= sphPackU64 ( $this->_min_id ) . sphPackU64 ( $this->_max_id ); // id64 range
+
+		// filters
+		$req .= pack ( "N", count($this->_filters) );
+		foreach ( $this->_filters as $filter )
+		{
+			$req .= pack ( "N", strlen($filter["attr"]) ) . $filter["attr"];
+			$req .= pack ( "N", $filter["type"] );
+			switch ( $filter["type"] )
+			{
+				case SPH_FILTER_VALUES:
+					$req .= pack ( "N", count($filter["values"]) );
+					foreach ( $filter["values"] as $value )
+						$req .= sphPackI64 ( $value );
+					break;
+
+				case SPH_FILTER_RANGE:
+					$req .= sphPackI64 ( $filter["min"] ) . sphPackI64 ( $filter["max"] );
+					break;
+
+				case SPH_FILTER_FLOATRANGE:
+					$req .= $this->_PackFloat ( $filter["min"] ) . $this->_PackFloat ( $filter["max"] );
+					break;
+
+				default:
+					assert ( 0 && "internal error: unhandled filter type" );
+			}
+			$req .= pack ( "N", $filter["exclude"] );
+		}
+
+		// group-by clause, max-matches count, group-sort clause, cutoff count
+		$req .= pack ( "NN", $this->_groupfunc, strlen($this->_groupby) ) . $this->_groupby;
+		$req .= pack ( "N", $this->_maxmatches );
+		$req .= pack ( "N", strlen($this->_groupsort) ) . $this->_groupsort;
+		$req .= pack ( "NNN", $this->_cutoff, $this->_retrycount, $this->_retrydelay );
+		$req .= pack ( "N", strlen($this->_groupdistinct) ) . $this->_groupdistinct;
+
+		// anchor point
+		if ( empty($this->_anchor) )
+		{
+			$req .= pack ( "N", 0 );
+		} else
+		{
+			$a =& $this->_anchor;
+			$req .= pack ( "N", 1 );
+			$req .= pack ( "N", strlen($a["attrlat"]) ) . $a["attrlat"];
+			$req .= pack ( "N", strlen($a["attrlong"]) ) . $a["attrlong"];
+			$req .= $this->_PackFloat ( $a["lat"] ) . $this->_PackFloat ( $a["long"] );
+		}
+
+		// per-index weights
+		$req .= pack ( "N", count($this->_indexweights) );
+		foreach ( $this->_indexweights as $idx=>$weight )
+			$req .= pack ( "N", strlen($idx) ) . $idx . pack ( "N", $weight );
+
+		// max query time
+		$req .= pack ( "N", $this->_maxquerytime );
+
+		// per-field weights
+		$req .= pack ( "N", count($this->_fieldweights) );
+		foreach ( $this->_fieldweights as $field=>$weight )
+			$req .= pack ( "N", strlen($field) ) . $field . pack ( "N", $weight );
+
+		// comment
+		$req .= pack ( "N", strlen($comment) ) . $comment;
+
+		// attribute overrides
+		$req .= pack ( "N", count($this->_overrides) );
+		foreach ( $this->_overrides as $key => $entry )
+		{
+			$req .= pack ( "N", strlen($entry["attr"]) ) . $entry["attr"];
+			$req .= pack ( "NN", $entry["type"], count($entry["values"]) );
+			foreach ( $entry["values"] as $id=>$val )
+			{
+				assert ( is_numeric($id) );
+				assert ( is_numeric($val) );
+
+				$req .= sphPackU64 ( $id );
+				switch ( $entry["type"] )
+				{
+					case SPH_ATTR_FLOAT:	$req .= $this->_PackFloat ( $val ); break;
+					case SPH_ATTR_BIGINT:	$req .= sphPackI64 ( $val ); break;
+					default:				$req .= pack ( "N", $val ); break;
+				}
+			}
+		}
+
+		// select-list
+		$req .= pack ( "N", strlen($this->_select) ) . $this->_select;
+
+		// mbstring workaround
+		$this->_MBPop ();
+
+		// store request to requests array
+		$this->_reqs[] = $req;
+		return count($this->_reqs)-1;
+	}
+
+	/// connect to searchd, run queries batch, and return an array of result sets
+	function RunQueries ()
+	{
+		if ( empty($this->_reqs) )
+		{
+			$this->_error = "no queries defined, issue AddQuery() first";
+			return false;
+		}
+
+		// mbstring workaround
+		$this->_MBPush ();
+
+		if (!( $fp = $this->_Connect() ))
+		{
+			$this->_MBPop ();
+			return false;
+		}
+
+		// send query, get response
+		$nreqs = count($this->_reqs);
+		$req = join ( "", $this->_reqs );
+		$len = 8+strlen($req);
+		$req = pack ( "nnNNN", SEARCHD_COMMAND_SEARCH, VER_COMMAND_SEARCH, $len, 0, $nreqs ) . $req; // add header
+
+		if ( !( $this->_Send ( $fp, $req, $len+8 ) ) ||
+			 !( $response = $this->_GetResponse ( $fp, VER_COMMAND_SEARCH ) ) )
+		{
+			$this->_MBPop ();
+			return false;
+		}
+
+		// query sent ok; we can reset reqs now
+		$this->_reqs = array ();
+
+		// parse and return response
+		return $this->_ParseSearchResponse ( $response, $nreqs );
+	}
+
+	/// parse and return search query (or queries) response
+	function _ParseSearchResponse ( $response, $nreqs )
+	{
+		$p = 0; // current position
+		$max = strlen($response); // max position for checks, to protect against broken responses
+
+		$results = array ();
+		for ( $ires=0; $ires<$nreqs && $p<$max; $ires++ )
+		{
+			$results[] = array();
+			$result =& $results[$ires];
+
+			$result["error"] = "";
+			$result["warning"] = "";
+
+			// extract status
+			list(,$status) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+			$result["status"] = $status;
+			if ( $status!=SEARCHD_OK )
+			{
+				list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+				$message = substr ( $response, $p, $len ); $p += $len;
+
+				if ( $status==SEARCHD_WARNING )
+				{
+					$result["warning"] = $message;
+				} else
+				{
+					$result["error"] = $message;
+					continue;
+				}
+			}
+
+			// read schema
+			$fields = array ();
+			$attrs = array ();
+
+			list(,$nfields) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+			while ( $nfields-->0 && $p<$max )
+			{
+				list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+				$fields[] = substr ( $response, $p, $len ); $p += $len;
+			}
+			$result["fields"] = $fields;
+
+			list(,$nattrs) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+			while ( $nattrs-->0 && $p<$max  )
+			{
+				list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+				$attr = substr ( $response, $p, $len ); $p += $len;
+				list(,$type) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+				$attrs[$attr] = $type;
+			}
+			$result["attrs"] = $attrs;
+
+			// read match count
+			list(,$count) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+			list(,$id64) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+
+			// read matches
+			$idx = -1;
+			while ( $count-->0 && $p<$max )
+			{
+				// index into result array
+				$idx++;
+
+				// parse document id and weight
+				if ( $id64 )
+				{
+					$doc = sphUnpackU64 ( substr ( $response, $p, 8 ) ); $p += 8;
+					list(,$weight) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+				}
+				else
+				{
+					list ( $doc, $weight ) = array_values ( unpack ( "N*N*",
+						substr ( $response, $p, 8 ) ) );
+					$p += 8;
+					$doc = sphFixUint($doc);
+				}
+				$weight = sprintf ( "%u", $weight );
+
+				// create match entry
+				if ( $this->_arrayresult )
+					$result["matches"][$idx] = array ( "id"=>$doc, "weight"=>$weight );
+				else
+					$result["matches"][$doc]["weight"] = $weight;
+
+				// parse and create attributes
+				$attrvals = array ();
+				foreach ( $attrs as $attr=>$type )
+				{
+					// handle 64bit ints
+					if ( $type==SPH_ATTR_BIGINT )
+					{
+						$attrvals[$attr] = sphUnpackI64 ( substr ( $response, $p, 8 ) ); $p += 8;
+						continue;
+					}
+
+					// handle floats
+					if ( $type==SPH_ATTR_FLOAT )
+					{
+						list(,$uval) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+						list(,$fval) = unpack ( "f*", pack ( "L", $uval ) ); 
+						$attrvals[$attr] = $fval;
+						continue;
+					}
+
+					// handle everything else as unsigned ints
+					list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+					if ( $type==SPH_ATTR_MULTI )
+					{
+						$attrvals[$attr] = array ();
+						$nvalues = $val;
+						while ( $nvalues-->0 && $p<$max )
+						{
+							list(,$val) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+							$attrvals[$attr][] = sphFixUint($val);
+						}
+					} else if ( $type==SPH_ATTR_MULTI64 )
+					{
+						$attrvals[$attr] = array ();
+						$nvalues = $val;
+						while ( $nvalues>0 && $p<$max )
+						{
+							$val = sphUnpackU64 ( substr ( $response, $p, 8 ) ); $p += 8;
+							$attrvals[$attr][] = strval( $val ); // FIXME!!! sphFixUint returns MVA values as string so It to
+							$nvalues -= 2;
+						}
+					} else if ( $type==SPH_ATTR_STRING )
+					{
+						$attrvals[$attr] = substr ( $response, $p, $val );
+						$p += $val;						
+					} else
+					{
+						$attrvals[$attr] = sphFixUint($val);
+					}
+				}
+
+				if ( $this->_arrayresult )
+					$result["matches"][$idx]["attrs"] = $attrvals;
+				else
+					$result["matches"][$doc]["attrs"] = $attrvals;
+			}
+
+			list ( $total, $total_found, $msecs, $words ) =
+				array_values ( unpack ( "N*N*N*N*", substr ( $response, $p, 16 ) ) );
+			$result["total"] = sprintf ( "%u", $total );
+			$result["total_found"] = sprintf ( "%u", $total_found );
+			$result["time"] = sprintf ( "%.3f", $msecs/1000 );
+			$p += 16;
+
+			while ( $words-->0 && $p<$max )
+			{
+				list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+				$word = substr ( $response, $p, $len ); $p += $len;
+				list ( $docs, $hits ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8;
+				$result["words"][$word] = array (
+					"docs"=>sprintf ( "%u", $docs ),
+					"hits"=>sprintf ( "%u", $hits ) );
+			}
+		}
+
+		$this->_MBPop ();
+		return $results;
+	}
+
+	/////////////////////////////////////////////////////////////////////////////
+	// excerpts generation
+	/////////////////////////////////////////////////////////////////////////////
+
+	/// connect to searchd server, and generate exceprts (snippets)
+	/// of given documents for given query. returns false on failure,
+	/// an array of snippets on success
+	function BuildExcerpts ( $docs, $index, $words, $opts=array() )
+	{
+		assert ( is_array($docs) );
+		assert ( is_string($index) );
+		assert ( is_string($words) );
+		assert ( is_array($opts) );
+
+		$this->_MBPush ();
+
+		if (!( $fp = $this->_Connect() ))
+		{
+			$this->_MBPop();
+			return false;
+		}
+
+		/////////////////
+		// fixup options
+		/////////////////
+
+		if ( !isset($opts["before_match"]) )		$opts["before_match"] = "<b>";
+		if ( !isset($opts["after_match"]) )			$opts["after_match"] = "</b>";
+		if ( !isset($opts["chunk_separator"]) )		$opts["chunk_separator"] = " ... ";
+		if ( !isset($opts["limit"]) )				$opts["limit"] = 256;
+		if ( !isset($opts["limit_passages"]) )		$opts["limit_passages"] = 0;
+		if ( !isset($opts["limit_words"]) )			$opts["limit_words"] = 0;
+		if ( !isset($opts["around"]) )				$opts["around"] = 5;
+		if ( !isset($opts["exact_phrase"]) )		$opts["exact_phrase"] = false;
+		if ( !isset($opts["single_passage"]) )		$opts["single_passage"] = false;
+		if ( !isset($opts["use_boundaries"]) )		$opts["use_boundaries"] = false;
+		if ( !isset($opts["weight_order"]) )		$opts["weight_order"] = false;
+		if ( !isset($opts["query_mode"]) )			$opts["query_mode"] = false;
+		if ( !isset($opts["force_all_words"]) )		$opts["force_all_words"] = false;
+		if ( !isset($opts["start_passage_id"]) )	$opts["start_passage_id"] = 1;
+		if ( !isset($opts["load_files"]) )			$opts["load_files"] = false;
+		if ( !isset($opts["html_strip_mode"]) )		$opts["html_strip_mode"] = "index";
+		if ( !isset($opts["allow_empty"]) )			$opts["allow_empty"] = false;
+		if ( !isset($opts["passage_boundary"]) )	$opts["passage_boundary"] = "none";
+		if ( !isset($opts["emit_zones"]) )			$opts["emit_zones"] = false;
+
+		/////////////////
+		// build request
+		/////////////////
+
+		// v.1.2 req
+		$flags = 1; // remove spaces
+		if ( $opts["exact_phrase"] )	$flags |= 2;
+		if ( $opts["single_passage"] )	$flags |= 4;
+		if ( $opts["use_boundaries"] )	$flags |= 8;
+		if ( $opts["weight_order"] )	$flags |= 16;
+		if ( $opts["query_mode"] )		$flags |= 32;
+		if ( $opts["force_all_words"] )	$flags |= 64;
+		if ( $opts["load_files"] )		$flags |= 128;
+		if ( $opts["allow_empty"] )		$flags |= 256;
+		if ( $opts["emit_zones"] )		$flags |= 512;
+		$req = pack ( "NN", 0, $flags ); // mode=0, flags=$flags
+		$req .= pack ( "N", strlen($index) ) . $index; // req index
+		$req .= pack ( "N", strlen($words) ) . $words; // req words
+
+		// options
+		$req .= pack ( "N", strlen($opts["before_match"]) ) . $opts["before_match"];
+		$req .= pack ( "N", strlen($opts["after_match"]) ) . $opts["after_match"];
+		$req .= pack ( "N", strlen($opts["chunk_separator"]) ) . $opts["chunk_separator"];
+		$req .= pack ( "NN", (int)$opts["limit"], (int)$opts["around"] );
+		$req .= pack ( "NNN", (int)$opts["limit_passages"], (int)$opts["limit_words"], (int)$opts["start_passage_id"] ); // v.1.2
+		$req .= pack ( "N", strlen($opts["html_strip_mode"]) ) . $opts["html_strip_mode"];
+		$req .= pack ( "N", strlen($opts["passage_boundary"]) ) . $opts["passage_boundary"];
+
+		// documents
+		$req .= pack ( "N", count($docs) );
+		foreach ( $docs as $doc )
+		{
+			assert ( is_string($doc) );
+			$req .= pack ( "N", strlen($doc) ) . $doc;
+		}
+
+		////////////////////////////
+		// send query, get response
+		////////////////////////////
+
+		$len = strlen($req);
+		$req = pack ( "nnN", SEARCHD_COMMAND_EXCERPT, VER_COMMAND_EXCERPT, $len ) . $req; // add header
+		if ( !( $this->_Send ( $fp, $req, $len+8 ) ) ||
+			 !( $response = $this->_GetResponse ( $fp, VER_COMMAND_EXCERPT ) ) )
+		{
+			$this->_MBPop ();
+			return false;
+		}
+
+		//////////////////
+		// parse response
+		//////////////////
+
+		$pos = 0;
+		$res = array ();
+		$rlen = strlen($response);
+		for ( $i=0; $i<count($docs); $i++ )
+		{
+			list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) );
+			$pos += 4;
+
+			if ( $pos+$len > $rlen )
+			{
+				$this->_error = "incomplete reply";
+				$this->_MBPop ();
+				return false;
+			}
+			$res[] = $len ? substr ( $response, $pos, $len ) : "";
+			$pos += $len;
+		}
+
+		$this->_MBPop ();
+		return $res;
+	}
+
+
+	/////////////////////////////////////////////////////////////////////////////
+	// keyword generation
+	/////////////////////////////////////////////////////////////////////////////
+
+	/// connect to searchd server, and generate keyword list for a given query
+	/// returns false on failure,
+	/// an array of words on success
+	function BuildKeywords ( $query, $index, $hits )
+	{
+		assert ( is_string($query) );
+		assert ( is_string($index) );
+		assert ( is_bool($hits) );
+
+		$this->_MBPush ();
+
+		if (!( $fp = $this->_Connect() ))
+		{
+			$this->_MBPop();
+			return false;
+		}
+
+		/////////////////
+		// build request
+		/////////////////
+
+		// v.1.0 req
+		$req  = pack ( "N", strlen($query) ) . $query; // req query
+		$req .= pack ( "N", strlen($index) ) . $index; // req index
+		$req .= pack ( "N", (int)$hits );
+
+		////////////////////////////
+		// send query, get response
+		////////////////////////////
+
+		$len = strlen($req);
+		$req = pack ( "nnN", SEARCHD_COMMAND_KEYWORDS, VER_COMMAND_KEYWORDS, $len ) . $req; // add header
+		if ( !( $this->_Send ( $fp, $req, $len+8 ) ) ||
+			 !( $response = $this->_GetResponse ( $fp, VER_COMMAND_KEYWORDS ) ) )
+		{
+			$this->_MBPop ();
+			return false;
+		}
+
+		//////////////////
+		// parse response
+		//////////////////
+
+		$pos = 0;
+		$res = array ();
+		$rlen = strlen($response);
+		list(,$nwords) = unpack ( "N*", substr ( $response, $pos, 4 ) );
+		$pos += 4;
+		for ( $i=0; $i<$nwords; $i++ )
+		{
+			list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) );	$pos += 4;
+			$tokenized = $len ? substr ( $response, $pos, $len ) : "";
+			$pos += $len;
+
+			list(,$len) = unpack ( "N*", substr ( $response, $pos, 4 ) );	$pos += 4;
+			$normalized = $len ? substr ( $response, $pos, $len ) : "";
+			$pos += $len;
+
+			$res[] = array ( "tokenized"=>$tokenized, "normalized"=>$normalized );
+
+			if ( $hits )
+			{
+				list($ndocs,$nhits) = array_values ( unpack ( "N*N*", substr ( $response, $pos, 8 ) ) );
+				$pos += 8;
+				$res [$i]["docs"] = $ndocs;
+				$res [$i]["hits"] = $nhits;
+			}
+
+			if ( $pos > $rlen )
+			{
+				$this->_error = "incomplete reply";
+				$this->_MBPop ();
+				return false;
+			}
+		}
+
+		$this->_MBPop ();
+		return $res;
+	}
+
+	function EscapeString ( $string )
+	{
+		$from = array ( '\\', '(',')','|','-','!','@','~','"','&', '/', '^', '$', '=' );
+		$to   = array ( '\\\\', '\(','\)','\|','\-','\!','\@','\~','\"', '\&', '\/', '\^', '\$', '\=' );
+
+		return str_replace ( $from, $to, $string );
+	}
+
+	/////////////////////////////////////////////////////////////////////////////
+	// attribute updates
+	/////////////////////////////////////////////////////////////////////////////
+
+	/// batch update given attributes in given rows in given indexes
+	/// returns amount of updated documents (0 or more) on success, or -1 on failure
+	function UpdateAttributes ( $index, $attrs, $values, $mva=false )
+	{
+		// verify everything
+		assert ( is_string($index) );
+		assert ( is_bool($mva) );
+
+		assert ( is_array($attrs) );
+		foreach ( $attrs as $attr )
+			assert ( is_string($attr) );
+
+		assert ( is_array($values) );
+		foreach ( $values as $id=>$entry )
+		{
+			assert ( is_numeric($id) );
+			assert ( is_array($entry) );
+			assert ( count($entry)==count($attrs) );
+			foreach ( $entry as $v )
+			{
+				if ( $mva )
+				{
+					assert ( is_array($v) );
+					foreach ( $v as $vv )
+						assert ( is_int($vv) );
+				} else
+					assert ( is_int($v) );
+			}
+		}
+
+		// build request
+		$this->_MBPush ();
+		$req = pack ( "N", strlen($index) ) . $index;
+
+		$req .= pack ( "N", count($attrs) );
+		foreach ( $attrs as $attr )
+		{
+			$req .= pack ( "N", strlen($attr) ) . $attr;
+			$req .= pack ( "N", $mva ? 1 : 0 );
+		}
+
+		$req .= pack ( "N", count($values) );
+		foreach ( $values as $id=>$entry )
+		{
+			$req .= sphPackU64 ( $id );
+			foreach ( $entry as $v )
+			{
+				$req .= pack ( "N", $mva ? count($v) : $v );
+				if ( $mva )
+					foreach ( $v as $vv )
+						$req .= pack ( "N", $vv );
+			}
+		}
+
+		// connect, send query, get response
+		if (!( $fp = $this->_Connect() ))
+		{
+			$this->_MBPop ();
+			return -1;
+		}
+
+		$len = strlen($req);
+		$req = pack ( "nnN", SEARCHD_COMMAND_UPDATE, VER_COMMAND_UPDATE, $len ) . $req; // add header
+		if ( !$this->_Send ( $fp, $req, $len+8 ) )
+		{
+			$this->_MBPop ();
+			return -1;
+		}
+
+		if (!( $response = $this->_GetResponse ( $fp, VER_COMMAND_UPDATE ) ))
+		{
+			$this->_MBPop ();
+			return -1;
+		}
+
+		// parse response
+		list(,$updated) = unpack ( "N*", substr ( $response, 0, 4 ) );
+		$this->_MBPop ();
+		return $updated;
+	}
+
+	/////////////////////////////////////////////////////////////////////////////
+	// persistent connections
+	/////////////////////////////////////////////////////////////////////////////
+
+	function Open()
+	{
+		if ( $this->_socket !== false )
+		{
+			$this->_error = 'already connected';
+			return false;
+		}
+		if ( !$fp = $this->_Connect() )
+			return false;
+
+		// command, command version = 0, body length = 4, body = 1
+		$req = pack ( "nnNN", SEARCHD_COMMAND_PERSIST, 0, 4, 1 );
+		if ( !$this->_Send ( $fp, $req, 12 ) )
+			return false;
+
+		$this->_socket = $fp;
+		return true;
+	}
+
+	function Close()
+	{
+		if ( $this->_socket === false )
+		{
+			$this->_error = 'not connected';
+			return false;
+		}
+
+		fclose ( $this->_socket );
+		$this->_socket = false;
+		
+		return true;
+	}
+
+	//////////////////////////////////////////////////////////////////////////
+	// status
+	//////////////////////////////////////////////////////////////////////////
+
+	function Status ()
+	{
+		$this->_MBPush ();
+		if (!( $fp = $this->_Connect() ))
+		{
+			$this->_MBPop();
+			return false;
+		}
+
+		$req = pack ( "nnNN", SEARCHD_COMMAND_STATUS, VER_COMMAND_STATUS, 4, 1 ); // len=4, body=1
+		if ( !( $this->_Send ( $fp, $req, 12 ) ) ||
+			 !( $response = $this->_GetResponse ( $fp, VER_COMMAND_STATUS ) ) )
+		{
+			$this->_MBPop ();
+			return false;
+		}
+
+		$res = substr ( $response, 4 ); // just ignore length, error handling, etc
+		$p = 0;
+		list ( $rows, $cols ) = array_values ( unpack ( "N*N*", substr ( $response, $p, 8 ) ) ); $p += 8;
+
+		$res = array();
+		for ( $i=0; $i<$rows; $i++ )
+			for ( $j=0; $j<$cols; $j++ )
+		{
+			list(,$len) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
+			$res[$i][] = substr ( $response, $p, $len ); $p += $len;
+		}
+
+		$this->_MBPop ();
+		return $res;
+	}
+
+	//////////////////////////////////////////////////////////////////////////
+	// flush
+	//////////////////////////////////////////////////////////////////////////
+
+	function FlushAttributes ()
+	{
+		$this->_MBPush ();
+		if (!( $fp = $this->_Connect() ))
+		{
+			$this->_MBPop();
+			return -1;
+		}
+
+		$req = pack ( "nnN", SEARCHD_COMMAND_FLUSHATTRS, VER_COMMAND_FLUSHATTRS, 0 ); // len=0
+		if ( !( $this->_Send ( $fp, $req, 8 ) ) ||
+			 !( $response = $this->_GetResponse ( $fp, VER_COMMAND_FLUSHATTRS ) ) )
+		{
+			$this->_MBPop ();
+			return -1;
+		}
+
+		$tag = -1;
+		if ( strlen($response)==4 )
+			list(,$tag) = unpack ( "N*", $response );
+		else
+			$this->_error = "unexpected response length";
+
+		$this->_MBPop ();
+		return $tag;
+	}
+}
+
+//
+// $Id$
+//

+ 274 - 0
common/controllers/AController.php

@@ -0,0 +1,274 @@
+<?php
+/*
+ *   1,在postman中选择验证方式为no auth.
+ *
+ *   2,添加header,key为:Authrization,value为Bearer xxxxxxxxxxxxx.
+ *
+ *      注意:key的拼写必须一样(包括大小写),value中的Bearer和xxxxxxxx之间至少要有一个空格,xxxxxx为发送的access_token。
+ */
+namespace app\common\controllers;
+use app\common\helpers\Identify;
+use app\modules\admin\models\Attachment;
+use app\modules\admin\models\AttachmentIndex;
+use app\modules\admin\models\Config;
+use app\modules\ad\models\AdData;
+use app\models\EmailCert;
+use app\models\MobileCert;
+use app\modules\ucenter\models\User;
+use yii\rest\ActiveController;
+use yii\filters\Cors;
+use yii\filters\auth\CompositeAuth;
+use yii\filters\auth\HttpBasicAuth;
+use yii\filters\auth\HttpBearerAuth;
+use yii\filters\auth\QueryParamAuth;
+use Yii;
+class AController extends ActiveController
+{
+    public $modelClass = 'app\modules\ucenter\models\User';
+    public $post;
+    public $get;
+    public $user;
+    public $user_id;
+    public $userInfo;
+    public $attconfig;
+    public $ossconfig;
+    public $baseconfig;
+    public $wapconfig;
+    public $imageconfig;
+    public $csrconfig;
+    public $higherconfig;
+    public $payconfig;
+    public $coinconfig;
+    public $pointconfig;
+    public $baiduconfig;
+    public $openauthconfig;
+    public $smsconfig;
+    public $mailerconfig;
+    public $ueditorconfig;
+    public $docconfig;
+    public $mpconfig;
+    public $wxappconfig;
+    public $bdappconfig;
+    public $transferconfig;
+    public $withdrawconfig;
+    public $commissionconfig;
+    public $shoppingconfig;
+    public $cmsconfig;
+    public $badwordconfig;
+    public $posterconfig;
+    public $docname = '文档';
+    public $colname = '合辑';
+    public $optional = [
+        'sendverifycode',//发送验证码
+        'checkverifycode',//校验验证码
+        'register',//注册
+        'login',//登录
+        'fastlogin',//快速登录
+        'resetpwd',//重置密码
+        'docmd5check',
+        'doctitlecheck',
+        'sharedoc',
+        'gettag',
+        'error',
+    ];
+    public function behaviors()
+    {
+
+        $behaviors = parent::behaviors();
+        // remove authentication filter
+        unset($behaviors['authenticator']);
+        // 这个是跨域配置
+        $behaviors['corsFilter'] = [
+            'class' => Cors::class,
+            'cors' => [
+                'Origin' => CORS_DOMAIN,
+                'Access-Control-Request-Method' => ['GET','POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
+                // Allow only POST and PUT methods
+                'Access-Control-Request-Headers' => ['*'],
+                // Allow only headers 'X-Wsse'
+                'Access-Control-Allow-Credentials' => true,
+                // Allow OPTIONS caching
+                'Access-Control-Max-Age' => 0,
+                // Allow the X-Pagination-Current-Page header to be exposed to the browser.
+                'Access-Control-Expose-Headers' => ['X-Pagination-Current-Page'],
+            ],
+        ];
+        $behaviors['authenticator'] = [
+            'class' => CompositeAuth::class,
+            'authMethods' => [
+                //HttpBasicAuth::className(),
+                HttpBearerAuth::class,
+                //QueryParamAuth::className(),
+            ],
+            'optional' =>$this->optional,
+            'except'=> ['options'] //认证排除OPTIONS请求
+        ];
+        return $behaviors;
+    }
+
+    public function init()
+    {
+        parent::init();
+        //加入全局配置
+        $configResultList = Config::find()->all();
+        if(is_array($configResultList))foreach($configResultList as $configResult)
+        {
+            $configName = str_replace('config','',$configResult->name);
+            $configName = str_replace('attachment','att',$configName).'config';
+            $this->$configName = string2array($configResult->value);
+        }
+        $this->docname = $this->docconfig['docname']?$this->docconfig['docname']:'文档';
+        $this->colname = $this->docconfig['colname']?$this->docconfig['colname']:'合辑';
+        if(empty($this->cmsconfig['news_breadname']))$this->cmsconfig['news_breadname'] = '资讯';
+        if(empty($this->cmsconfig['news_contentname']))$this->cmsconfig['news_contentname'] = '资讯';
+        if(empty($this->docconfig['breadname']))$this->docconfig['breadname'] = '文档';
+        if(empty($this->docconfig['docname']))$this->docconfig['docname'] = '文档';
+        if(empty($this->docconfig['colname']))$this->docconfig['colname'] = '合辑';
+        if(Yii::$app->request->headers->get('Authorization'))$this->user = User::findIdentityByAccessToken(Yii::$app->request->headers->get('Authorization'));
+    }
+
+    //验证码校验
+    function checkCode($to,$code)
+    {
+        $patternEmail = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/';
+        $patternMobile = '/^1[3456789]{1}\d{9}$/';
+        if(preg_match($patternEmail,$to)) $toType = 'email';
+        if(preg_match($patternMobile,$to)) $toType='mobile';
+        if($toType=='mobile')
+        {
+            $exist = \app\models\MobileCert::find()->where("mobile='".$to."' and request_from = ".REQUEST_FROM)->orderBy(['id'=>SORT_DESC])->one();
+        }
+        else if($toType=='email')
+        {
+            $exist = \app\models\EmailCert::find()->where("email='".$to."' and request_from = ".REQUEST_FROM)->orderBy(['id'=>SORT_DESC])->one();
+        }
+        //判断验证码有效期
+        if($exist&&(TIMESTAMP-$exist->sent_time>$this->smsconfig['certValidTime']*60||$exist->cert==1))
+        {
+            return [
+                'error' => 1,
+                'msg' => '验证码无效',
+                'data' => [],
+                'code'=>200
+            ];
+
+        }
+        //判断验证码正确行
+        if($exist->cert_key!=$code)
+        {
+            return [
+                'error' => 1,
+                'msg' => '验证码错误',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        $exist->cert = 1;
+        $exist->cert_time = TIMESTAMP;
+        $exist->save();
+    }
+
+    //当前用户是否有权限访问和操作所请求的资源
+    public function checkRights($user_id,$model,$fild_name='user_id')
+    {
+        if ($model->$fild_name != $user_id){
+            return [
+                'error' => 1,
+                'msg' => '你只能操作你自己创作的数据',
+                'data' => [],
+                'code'=>200
+            ];
+        }
+        else
+        {
+            return true;
+        }
+    }
+    //当前用户是否有权限访问和操作所请求的资源
+    public function checkAccess($action, $model = null, $params = [])
+    {
+        /* // check if the user can access $action and $model
+         // throw ForbiddenHttpException if access should be denied
+         if ($action === 'update' || $action === 'delete') {
+             if ($model->user_id !== \Yii::$app->user->id)
+                 throw new \yii\web\ForbiddenHttpException(sprintf('You can only %s articles that you\'ve created.', $action));
+         }*/
+    }
+    //禁用一些操作
+    public function actions()
+    {
+        $action= parent::actions(); // TODO: Change the autogenerated stub
+        unset($action['index']);
+        unset($action['create']);
+        unset($action['update']);
+        unset($action['delete']);
+    }
+
+    /**
+     * @param $action
+     * @return bool
+     * @throws \yii\web\BadRequestHttpException
+     */
+    public function beforeAction($action)
+    {
+        parent::beforeAction($action);
+        $this->post = Yii::$app->request->post();
+        $this->get = Yii::$app->request->get();
+        if(!empty(Yii::$app->user))
+        {
+            $this->user = Yii::$app->user->identity;
+            $this->user_id = Yii::$app->user->id;
+            $this->userInfo = Identify::getUserInfo(Yii::$app->user->id);
+        }
+        return $action;
+    }
+
+
+    /**
+     * validateValue
+     * @return bool
+     */
+    public function validateCaptcha($value)
+    {
+        $data = unserialize(Yii::$app->security->decryptByKey(base64_decode($value),Yii::$app->params['authKey']));
+
+        if(empty($data['ip']) || $data['ip'] != Yii::$app->request->getUserIP()){
+            return false;
+        }
+
+        if(empty($data['ua']) || $data['ua'] != crc32(Yii::$app->request->getUserAgent())){
+            return false;
+        }
+
+        if(empty($data['ttl']) || time() > $data['ttl']) {
+            return false;
+        }
+        return true;
+    }
+    //缩略图
+    public function makeThumb($imagePath,$width,$height)
+    {
+        $hash = $imagePath?md5($imagePath):'noimage';
+        return WEB_URL.'p/'.$width.'/'.$height.'/'.$hash.'.jpg';
+    }
+
+
+
+    //对接前端Url
+    public static function urlList($page)
+    {
+
+        $urls['home'] =  REQUEST_FROM==1? WEB_URL: WAP_URL;
+        $urls['login'] = REQUEST_FROM==1? WEB_URL.'login/': WAP_URL.'login/';
+        $urls['logout'] = REQUEST_FROM==1? WEB_URL.'logout/': WAP_URL.'logout/';
+        $urls['ucenter'] = REQUEST_FROM==1? WEB_URL.'ucenter/': WAP_URL.'ucenter/';
+        $urls['myupload'] = REQUEST_FROM==1? WEB_URL.'myupload/': WAP_URL.'myupload/';
+        return $urls[$page];
+    }
+
+
+
+
+
+}
+

+ 899 - 0
common/controllers/BController.php

@@ -0,0 +1,899 @@
+<?php
+namespace app\common\controllers;
+use app\models\Linkmenu;
+use app\modules\car\models\FCarInfo;
+use app\modules\car\models\FCarsDetailData;
+use app\modules\car\models\FOneCarOneTable;
+use Yii;
+use \app\modules\admin\models\Resource;
+use \app\modules\admin\models\Adminlog;
+use app\modules\admin\models\Lang;
+/**
+ * 后台基类
+ */
+class BController extends CController
+{
+
+    public $resourceBlock;
+    public $currentResource;//当前资源
+    public $tableConfig;//列表页配置
+    public $tableTitle;//列表页表头
+    public $topLeftTableMenu;
+    public $topRightTableMenu;
+    public $operTableMenu;
+    public $admin_id;
+    public $carTypes;
+    public $colors;
+    public $cityOptions;
+    public $citySort;
+    public $carUseTypes;
+    public $carSourceTypes;
+    public $carCity;
+    public $carYears;
+    public $role_id;
+    public $province = '河北';//默认省份
+    public $result = [];
+    public function init()
+    {
+        parent::init();
+        $this->resourceBlock = array('main'=>'主体');
+        $this->admin_id = $this->getIdentityInfo('admin_id');
+        $this->carTypes = ['皮卡车','微型面包车','越野车','轿车','其他'];
+        $this->colors = ['#485ec4','#2ca67a','#cd9941','#cf5a5a','#ff0000','#ff9900','#8f9a79','#b3b3a4','#c89063','#50be34','#efded4'];
+       /* $cityResult = FCarInfo::find()->select('distinct(city)')->orderBy(['city'=>SORT_ASC])->all();
+        foreach($cityResult as $ucity)
+        {
+            $this->cityOptions[] = $ucity['city'];
+        }*/
+        $this->cityOptions = ['石家庄','唐山','秦皇岛','邯郸','邢台','保定','张家口','承德','廊坊','沧州','衡水','雄安','机动局','省公司本部'];
+        //排序
+        $this->citySort = ' CASE "city"';
+        foreach ($this->cityOptions as $k=>$v){
+            $this->citySort .= " WHEN '".$v."' THEN ".$k;
+        }
+        $this->citySort .= " ELSE ".($k+1)." END";
+
+        $carUseTypesResult = FCarInfo::find()->select('distinct(using_tag)')->orderBy(['using_tag'=>SORT_ASC])->all();
+        foreach($carUseTypesResult as $unit)
+        {
+            $this->carUseTypes[] = $unit['using_tag'];
+        }
+        $carSourceTypesResult = FCarInfo::find()->select('distinct(self_rent)')->orderBy(['self_rent'=>SORT_ASC])->all();
+        foreach($carSourceTypesResult as $unit)
+        {
+            $this->carSourceTypes[] = $unit['self_rent'];
+        }
+
+    }
+
+    public function behaviors()
+    {
+
+        parent::behaviors();
+        $module =  $this->moduleName;
+        $controller = $this->controllerName;
+        $actionName = $this->actionName;
+        //获取当前管理页面的菜单
+        $this->currentResource = Resource::find()->where('module = :module and controller=:controller and action=:action', [':module' => $module,':controller' => $controller,':action' => $actionName])->one();
+        $userInfo = $this->getIdentityInfo();
+        if($this->currentResource&&!empty($userInfo['role_id']))
+        {
+            if($userInfo['role_id']==1)
+            {
+                $this->topLeftTableMenu = Resource::find()->where("parent_hash=:parent_hash and menu_type in(2,3,4,10) and disabled=0",[':parent_hash'=>$this->currentResource->hash])->orderBy(['list_order' => SORT_ASC])->all();
+                $this->topRightTableMenu = Resource::find()->where("parent_hash=:parent_hash and menu_type in(5,6,7,8,9) and disabled=0",[':parent_hash'=>$this->currentResource->hash])->orderBy(['list_order' => SORT_ASC])->all();
+                $this->operTableMenu = Resource::find()->where("parent_hash=:parent_hash and menu_type in(11,12,13,14,15,16,17) and disabled=0",[':parent_hash'=>$this->currentResource->hash])->orderBy(['list_order' => SORT_ASC])->all();
+            }
+            else
+            {
+                $this->topLeftTableMenu = Resource::find()->where("parent_hash=:parent_hash and menu_type in(2,3,4,10) and disabled=0 and hash in(select hash from {{%role_resource}} where role_id=".$userInfo['role_id'].")",[':parent_hash'=>$this->currentResource->hash])->orderBy(['list_order' => SORT_ASC])->all();
+                $this->topRightTableMenu = Resource::find()->where("parent_hash=:parent_hash and menu_type in(5,6,7,8,9) and disabled=0 and hash in(select hash from {{%role_resource}} where role_id=".$userInfo['role_id'].")",[':parent_hash'=>$this->currentResource->hash])->orderBy(['list_order' => SORT_ASC])->all();
+                $this->operTableMenu = Resource::find()->where("parent_hash=:parent_hash and menu_type in(11,12,13,14,15,16,17) and disabled=0 and hash in(select hash from {{%role_resource}} where role_id=".$userInfo['role_id'].")",[':parent_hash'=>$this->currentResource->hash])->orderBy(['list_order' => SORT_ASC])->all();
+            }
+        }
+        //写后台操作日志
+        if(!empty($this->admin_id))
+        {
+            $log = new Adminlog();
+            $log->module = $this->moduleName;
+            $log->controller = $this->controllerName;
+            $log->action = $this->actionName;
+            $log->query_string = $_SERVER["QUERY_STRING"];
+            $log->admin_id = $this->admin_id;
+            $log->ip = MYIP;
+            $log->create_time = TIMESTAMP;
+            $log->save();
+        }
+        //如果不是生成缓存,需要权限校验
+        if($_GET['docache'])
+        {
+            return  [];
+        }
+        else
+        {
+            return [
+                [
+                    'class' => 'app\common\filters\BackEndAuthFilter',
+                    'except' => ['login','logout','lockscreen','syndata']
+                ],
+                [
+                    'class' => 'app\common\filters\BackEndResourceFilter',
+                    'except' => ['login','logout','lockscreen','testfunction','fieldsetting','syndata']
+                ],
+            ];
+        }
+
+
+
+    }
+
+    public function getMyResource()
+    {
+
+        $userInfo = $this->getIdentityInfo();
+        //获取左侧菜单
+        if($userInfo['role_id'])
+        {
+            if($userInfo['role_id']==1)
+            {
+                $resultList = Resource::find()->where('disabled = :disabled', [':disabled' => 0])->orderBy(['list_order' => SORT_ASC])->all();
+            }
+            else
+            {
+                $resultList = Resource::findBySql('SELECT * FROM {{%resource}} where hash in(select hash from {{%role_resource}} where role_id='.$userInfo['role_id'].' order by role_resource_id asc) order by list_order asc' )->all();
+
+            }
+
+        }
+
+        $resourceList = [];
+        if(is_array($resultList))foreach($resultList as $result){
+
+            $resourceList[$result['hash']] = single_object_to_array($result);
+
+        }
+
+        foreach($resourceList as $k=>$resource)
+        {
+            $sonList = [];
+            $menuSonList = [];
+            foreach($resourceList as $temp)
+            {
+                if($temp['parent_hash']==$resource['hash'])
+                {
+                    $sonList[] = $temp;
+                    if($temp['menu_type']==1)
+                    {
+                        $menuSonList[] = $temp;
+                    }
+                }
+            }
+            $resourceList[$k]['sonList'] = $sonList;
+            $resourceList[$k]['menuSonList'] = $menuSonList;
+        }
+        return $resourceList;
+
+    }
+
+    //更新语言表
+    public function updateLang($key,$value,$file)
+    {
+        $lang = Yii::$app->language;
+        //更新语言表数据
+        $model = Lang::find()->where("lang='".$lang."' and lang_key='".$key."' and lang_file='".$file."'")->one();
+        if(!$model)$model = new Lang;
+        $model->lang  = $lang;
+        $model->lang_key = $key;
+        $model->lang_value = $value;
+        $model->lang_file = $file;
+        $model->save();
+    }
+
+    //更新语言包文件
+    public function updateMessageFile($file)
+    {
+        $resourceDir = BASE_PATH.'messages'.DIRECTORY_SEPARATOR.Yii::$app->language.DIRECTORY_SEPARATOR;
+        $resourcefile = $resourceDir.$file.'.php';
+        if(!dir_writeable($resourceDir)) exit('Please chmod '.$resourceDir.' to 0777 !');
+        $resourceList = Lang::find()->where("lang='".Yii::$app->language."' and lang_file='".$file."'")->all();
+        $array = array();
+        if(is_array($resourceList))foreach($resourceList as $resource) {
+
+            $array[$resource['lang_key']] = trim($resource['lang_value']);
+        }
+        $resourceStr ="<?php ".PHP_EOL.'return '. array2string($array).';'.PHP_EOL."?>";
+        Yii::$app->params['lockEx'] ? file_put_contents($resourcefile, $resourceStr, LOCK_EX) : file_put_contents($resourcefile, $resourceStr);
+    }
+
+    //单元格修改
+    public function actionSetfield()
+    {
+
+        $table = strtolower(safe_replace($_GET['table']));
+        $fileldName = safe_replace($_GET['field']);
+        $fieldValue = safe_replace($_GET['value']);
+        $pk = safe_replace($_GET['pk']);
+        $pkField = \app\common\models\EActiveRecord::getPrikey($table);
+        if(empty($pkField)) $pkField = 'id';
+        if(!empty($pk)&&!empty($fileldName))
+        {
+            $result  =  Yii::$app->db->createCommand("UPDATE {{%$table}} SET $fileldName='$fieldValue' WHERE $pkField='$pk'")->execute();
+            if($result)
+            {
+                $msgdata = ['error' => 0,'msg' => '操作成功'];
+            }
+            else
+            {
+
+                $msgdata = ['error' => 1,'msg' => '操作失败'];
+            }
+        }
+        else
+        {
+
+            $msgdata = ['error' => 1,'msg' => '操作失败'];
+        }
+        echo_json($msgdata);
+    }
+
+    public function getWhere($query, $params=[], $isnull = [])
+    {
+        $where = [];
+        $tables = [];
+        $tablefrom = $query->getTablesUsedInFrom();
+        foreach ($tablefrom as $v){
+            $tables[] = str_replace(array('{{%','}}'),"",$v);
+        }
+        foreach ((array)$query->join as $v){
+            $tables[] = str_replace(array('{{%','}}'),"",$v[1]);
+        }
+
+        $yeartables = [
+            'f_car_condition'=>'year',
+            'f_cars_detail_data'=>'year',
+            'f_deta_illegal_using_car'=>'year',
+            'f_fluc_cost_hkm'=>'year',
+            'f_fluc_fuel_hkm'=>'year',
+            'f_fluc_illegal_using_car'=>'year',
+            'f_fluc_inefficient_car'=>'year',
+            'f_fuel_hkm'=>'year',
+            'f_mileage_attend'=>'year',
+            'f_one_car_cost'=>'year',
+            'f_one_car_one_table'=>'year_info',
+            'f_operating_cost_monitor'=>'year',
+            'f_rent_car_cost'=>'year',
+            'f_stats_cost_avg'=>'year',
+            'f_stats_cost_hkm'=>'year',
+            'f_stats_fuel_hkm'=>'year',
+            'f_stats_illegal_using_car'=>'year',
+            'f_stats_inefficient_car'=>'year',
+            'f_t_car_status'=>'year',
+            'f_t_car_status_fuel'=>'year',
+            'f_t_one_car_avg'=>'year',
+            'f_violating_order'=>'year',
+            'f_year_car_cost'=>'year',
+        ];
+
+        $citytables = [
+            'f_car_info'=>'city',
+            'f_cars_detail_data'=>'city',
+            'f_cost_abn_order'=>'city',
+            'f_fluc_cost_hkm'=>'city',
+            'f_fluc_fuel_hkm'=>'city',
+            'f_fluc_illegal_using_car'=>'city',
+            'f_fluc_inefficient_car'=>'city',
+            'f_stats_cost_avg'=>'city',
+            'f_stats_cost_hkm'=>'city',
+            'f_stats_fuel_hkm'=>'city',
+            'f_stats_illegal_using_car'=>'city',
+            'f_stats_inefficient_car'=>'city',
+            'f_t_car_status'=>'city',
+            'f_t_one_car_avg'=>'city',
+            'f_year_car_cost'=>'city',
+        ];
+        //序列化查询语句
+        $_where = [];
+        foreach ($tables as $v){
+            if($this->carCity && in_array($v,array_keys($citytables))){
+                $_where[$citytables[$v]] = $this->carCity;
+            }
+            if($this->carYears && in_array($v,array_keys($yeartables))){
+                $_where[$yeartables[$v]] = $this->carYears;
+            }
+        }
+        foreach ($_where as $k=>$v){
+            $where[] =  $k . (is_array($v) ? ( count($v)>1 ? " in ('".implode("','",$v)."')" : " = '".current($v)."'") : " = '".$v."'");
+        }
+
+
+
+        //日期选择
+        $yearField = 'year';
+        $monthField = 'month';
+        foreach ($tables as $v){
+            if($v=='f_one_car_one_table') {
+                $yearField = 'year_info';
+                $monthField = 'month_info';
+            }
+        }
+        if(!empty($params['start_date'])&&!empty($params['end_date']))
+        {
+            $startdateInfo = explode('-',$params['start_date']);
+            $start_year =   $startdateInfo[0];
+            $start_month = intval($startdateInfo[1]);
+            $enddateInfo = explode('-',$params['end_date']);
+            $end_year =    $enddateInfo[0];
+            $end_month = intval($enddateInfo[1]);
+            if(!empty($start_year)&&!empty($end_year))$where[] = " ($yearField>=$start_year and $yearField<=$end_year) ";
+            if(!empty($start_month)&&!empty($end_month))$where[] = " ($monthField>=$start_month and $monthField<=$end_month) ";
+        }
+        if(!empty($params['date'])) {
+            $dateInfo = explode('-', $params['date']);
+            $year = $dateInfo[0];
+            $month = intval($dateInfo[1]);
+            if(!empty($year))$where[] = " $yearField = $year ";
+            if(!empty($month))$where[] = " $monthField = $month ";
+        }
+
+        //地市选择
+        if(!empty($params['city'])||!empty($params['city_1'])||!empty($params['city_2'])||!empty($params['city_3']))
+        {
+            if($params['city_3'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_3']);
+            }
+            else if($params['city_2'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_2']);
+            }
+            else if($params['city_1'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_1']);
+            }
+            if(!empty($cityInfo[0]))$where[] = " city = '".$cityInfo[0]."' ";
+            if(!empty($cityInfo[1])){
+                $where[] = " dpt_sec = '".$cityInfo[1]."' ";
+            }elseif(in_array('dpt_sec',$isnull)){
+                $where[] = !empty($cityInfo[0]) ? " dpt_sec is not null " : " dpt_sec is null ";
+            }
+            if(!empty($cityInfo[2])){
+                $where[] = " grid = '".$cityInfo[2]."' ";
+            }elseif(in_array('grid',$isnull)){
+                $where[] = !empty($cityInfo[1]) ? " grid is not null " : " grid is null ";
+            }
+        }
+
+        if(!empty($params['card_num']))$where[] = " card_num = '".$params['card_num']."' ";
+
+        if(!empty($params['car_type'])){
+            $where[] = " car_type = '".$params['car_type']."' ";
+        }elseif(in_array('car_type',$isnull)){
+            $where[] = " car_type is null ";
+        }
+
+        if(!empty($params['using_tag'])){
+            $where[] = " using_tag = '".$params['using_tag']."' ";
+        }elseif(in_array('using_tag',$isnull)){
+            $where[] = " using_tag is null ";
+        }
+        if(!empty($params['self_rent'])){
+            $where[] = " self_rent = '".$params['self_rent']."' ";
+        }elseif(in_array('self_rent',$isnull)){
+            $where[] = " self_rent is null ";
+        }
+        if(!empty($params['car_src'])){
+            $where[] = " car_src = '".$params['car_src']."' ";
+        }elseif(in_array('car_src',$isnull)){
+            $where[] = " car_src is null ";
+        }
+        return $where;
+    }
+
+
+    /*
+     * 取得一车一表SQL语句或数据
+     */
+    public function getOneCarOneTable($params=[],$field = '*',$setYears=true,$ressql = true)
+    {
+        $params = $params ? $params : Yii::$app->request->get();
+
+        $tableschema = FOneCarOneTable::getTableSchema();
+        $columns = array_keys($tableschema->columns);
+        $query = FOneCarOneTable::find();
+        $where = [];
+
+        //限定年份数据
+        if($setYears && $this->carYears && $this->role_id>1 && in_array('year_info',$columns)){
+            $where[] =  'year_info' . (is_array($this->carYears) ? ( count($this->carYears)>1 ? " in ('".implode("','",$this->carYears)."')" : " = '".current($this->carYears)."'") : " = '".$this->carYears."'");
+        }
+        //没有设定年份,取当年
+        if(!empty($params['start_date'])&&!empty($params['end_date']))
+        {
+            $startdateInfo = explode('-',$params['start_date']);
+            $start_year =   $startdateInfo[0];
+            $start_month = intval($startdateInfo[1]);
+            $enddateInfo = explode('-',$params['end_date']);
+            $end_year =    $enddateInfo[0];
+            $end_month = intval($enddateInfo[1]);
+            if(!empty($start_year)&&!empty($end_year))$where[] = " (year_info>=$start_year and year_info<=$end_year) ";
+            if(!empty($start_month)&&!empty($end_month))$where[] = " (month_info>=$start_month and month_info<=$end_month) ";
+        }
+
+        if(!empty($params['date'])) {
+            $dateInfo = explode('-', $params['date']);
+            $year = $dateInfo[0];
+            $month = intval($dateInfo[1]);
+            if(!empty($year))$where[] = " year_info = $year ";
+            if(!empty($month))$where[] = " month_info = $month ";
+        }
+
+        foreach ($params as $k=>$v){
+            if(in_array($k,$columns) && trim($v)!==''&&$k!='city'){
+                if ($tableschema->columns[$k]->phpType=='string'){
+                    $where[] = $k . " = '".$v."'";
+                }else{
+                    $where[] = $k . " = ".$v;
+                }
+            }
+        }
+
+
+
+        if(!empty($where)){
+            $sql = join(" and ",$where);
+            $query->where($sql);
+        }
+        $query->select($field);
+        if($ressql){
+            return $query->createCommand()->getRawSql();
+        }else{
+            return $query->asArray()->all();
+        }
+
+    }
+
+    /*
+    * 取得车辆基础表SQL或数据
+    */
+    public function getCarInfo($params=[],$field = '*',$setCity=true,$ressql = true)
+    {
+        $params = $params ? $params : Yii::$app->request->get();
+        $tableschema = FCarInfo::getTableSchema();
+        $columns = array_keys($tableschema->columns);
+        $query = FCarInfo::find();
+        $where = [];
+        if($setCity && $this->carCity && $this->role_id>1 && in_array('city',$columns)){
+            $where[] =  'city' . (is_array($this->carCity) ? ( count($this->carCity)>1 ? " in ('".implode("','",$this->carCity)."')" : " = '".current($this->carCity)."'") : " = '".$this->carCity."'");
+        }
+        foreach ($params as $k=>$v){
+            if(in_array($k,$columns) && trim($v)!==''&&$k!='city'){
+                if($k=='card_num'){
+                    $where[] = $k . " LIKE '%".$v."%'";
+                }elseif ($tableschema->columns[$k]->phpType=='string'){
+                    $where[] = $k . " = '".$v."'";
+                }else{
+                    $where[] = $k . " = ".$v;
+                }
+            }
+        }
+        //地市选择
+        if(!empty($params['city'])||!empty($params['city_1'])||!empty($params['city_2'])||!empty($params['city_3']))
+        {
+            if($params['city_3'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_3']);
+            }
+            else if($params['city_2'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_2']);
+            }
+            else if($params['city_1'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_1']);
+            }
+            if(!empty($cityInfo[0]))$where[] = " city = '".$cityInfo[0]."' ";
+            if(!empty($cityInfo[1])) $where[] = " dpt_sec = '".$cityInfo[1]."' ";
+            if(!empty($cityInfo[2]))$where[] = " grid = '".$cityInfo[2]."' ";
+        }
+        //附加的地市条件
+        if(!empty($params['city_name_1'])||!empty($params['city_name_2'])||!empty($params['city_name_3']))
+        {
+            if(!empty($params['city_name_1']))$where[] = " city = '".$params['city_name_1']."' ";
+            if(!empty($params['city_name_2'])) $where[] = " dpt_sec = '".$params['city_name_2']."' ";
+            if(!empty($params['city_name_3']))$where[] = " grid = '".$params['city_name_3']."' ";
+        }
+
+        if(!empty($where)){
+            $sql = join(" and ",$where);
+            $query->where($sql);
+        }
+        $query->select($field);
+        if($ressql){
+            return $query->createCommand()->getRawSql();
+        }else{
+            return $query->asArray()->all();;
+        }
+
+    }
+    /*
+    * 拼接评价报表SQL及取得分页数据
+    */
+    public function getPingjiaData($table,$field='*',$params=[],$all=0)
+    {
+        $params = $params ? $params : Yii::$app->request->get();
+
+        if(!empty($params['city_1'])||!empty($params['city_2'])||!empty($params['city_3']))
+        {
+            if($params['city_3'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_3']);
+            }
+            else if($params['city_2'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_2']);
+            }
+            else if($params['city_1'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_1']);
+            }
+            $params['city'] = $cityInfo[0];
+            $params['dpt_sec'] = $cityInfo[1];
+            $params['grid'] = $cityInfo[2];
+        }
+        if(empty($params['city']))unset($params['city']);
+
+      
+        $groupby[] = 'ci.city';
+
+        if(!empty($params['city'])){
+            $groupby[] = 'ci.dpt_sec';
+            $field .= ',ci.dpt_sec';
+        }
+
+        if(!empty($params['dpt_sec'])){
+            $groupby[] = 'ci.grid';
+            $field .= ',ci.grid';
+        }
+
+        if(!empty($params['card_num'])){
+            $groupby[] = 'ci.card_num';
+            $field .= ',ci.card_num';
+        }
+        // && stripos($table,'card_num')!==false
+        if(!empty($params['grid'])){
+           // $groupby[] = 'ci.card_num';
+            //$field .= ',ci.card_num,ci.self_rent,ci.car_type,ci.using_tag';
+            $field .= ',ci.grid';
+        }
+
+        if(!empty($params['car_type'])){
+            $groupby[] = 'ci.car_type';
+            $field .= ',ci.car_type';
+        }
+
+        if(!empty($params['using_tag'])){
+            $groupby[] = 'ci.using_tag';
+            $field .= ',ci.using_tag';
+        }
+
+        if(!empty($params['self_rent'])){
+            $groupby[] = 'ci.self_rent';
+            $field .= ',ci.self_rent';
+        }
+      
+        if($all==0)
+        {
+
+            $groupby = join(",",$groupby);
+
+            $connection = Yii::$app->db;
+            //$count_sql = 'SELECT ci.city as city FROM '.$table. ' GROUP BY ' . $groupby;
+            //$count = count($connection->createCommand($count_sql)->queryAll());
+
+            $sql = 'SELECT '. $field .' FROM '.$table. ' GROUP BY ' . $groupby;
+             
+            
+        }
+        else
+        {
+            
+            
+            $connection = Yii::$app->db;
+            //$count_sql = 'SELECT ci.city as city FROM '.$table. ' GROUP BY ' . $groupby;
+            //$count = count($connection->createCommand($count_sql)->queryAll());
+
+            $sql = 'SELECT '. $field .' FROM '.$table;
+          
+            
+        }
+        //没有设定年份,取当年
+        if(!empty($params['start_date'])&&!empty($params['end_date']))
+        {
+            $startdateInfo = explode('-',$params['start_date']);
+            $start_year =   $startdateInfo[0];
+            $start_month = intval($startdateInfo[1]);
+            $enddateInfo = explode('-',$params['end_date']);
+            $end_year =    $enddateInfo[0];
+            $end_month = intval($enddateInfo[1]);
+            $year = !empty($end_year) ? $end_year : date('Y');
+        }
+        else
+        {
+            $year = !empty($params['year']) ? $params['year'] : date('Y');
+            $start_month = intval($params['start_month'])?intval($params['start_month']):1;
+            $end_month = intval($params['end_month'])?intval($params['end_month']):12;
+        }
+
+
+
+
+        $sql = str_replace(['年份','起始月份','终止月份'],[$year,$start_month,$end_month],$sql);
+
+        //排序
+        if(isset($params['sort']))
+        {
+            $sql .= ' ORDER BY ' .$params['sort'].' '.(isset($params['sortOrder']) && $params['sortOrder']=='asc'?'ASC':'DESC');
+        }
+
+        //分页
+        if(isset($params['limit'])){
+            $sql .= ' LIMIT ';
+            if(isset($params['offset'])){
+                $sql .= $params['offset']. ',';
+            }
+            $sql .= $params['limit'];
+        }
+
+        $data = $connection->createCommand($sql)->queryAll();
+        if(!empty($data[0]['city']))
+        {
+            $data = $this->arrayByArraySort($data,$this->cityOptions,'city');
+        }
+
+
+
+        return ["total"=>$count,"totalNotFiltered"=>$count,"rows"=>$data];
+
+    }
+
+    function arrayByArraySort($data,$sort,$column=null){
+        $temp = [];
+        if (!is_null($column)){
+            foreach ($data as $item){
+                $temp[$item[$column]][] = $item;
+            }
+        }else{
+            foreach ($data as $key => $item){
+                $temp[$key] = [$item];
+            }
+        }
+
+        $ret = [];
+        foreach ($sort as $sortum){
+            if (isset($temp[$sortum])){
+                $ret = array_merge($ret,$temp[$sortum]);
+            }
+        }
+        $ret = array_values($ret);
+        return $ret;
+
+    }
+
+    /*
+    * 取得车辆详情表SQL或数据
+    */
+    public function getCarsDetailData($params=[],$field = '*',$setYears=true,$ressql = true)
+    {
+        $params = $params ? $params : Yii::$app->request->get();
+        if(empty($params['city']))unset($params['city']);
+        $tableschema = FCarsDetailData::getTableSchema();
+        $columns = array_keys($tableschema->columns);
+        $query = FCarsDetailData::find();
+        $where = [];
+        if($setYears && $this->carYears && $this->role_id>1 && in_array('year',$columns)){
+            $where[] =  'year' . (is_array($this->carYears) ? ( count($this->carYears)>1 ? " in ('".implode("','",$this->carYears)."')" : " = '".current($this->carYears)."'") : " = '".$this->carYears."'");
+        }
+        foreach ($params as $k=>$v){
+            if(in_array($k,$columns) && trim($v)!==''){
+                if ($tableschema->columns[$k]->phpType=='string'){
+                    $where[] = $k . " = '".$v."'";
+                }else{
+                    $where[] = $k . " = ".$v;
+                }
+            }
+        }
+
+        //没有设定年份,取当年
+        if(!empty($params['start_date'])&&!empty($params['end_date']))
+        {
+            $startdateInfo = explode('-',$params['start_date']);
+            $start_year =   $startdateInfo[0];
+            $start_month = intval($startdateInfo[1]);
+            $enddateInfo = explode('-',$params['end_date']);
+            $end_year =    $enddateInfo[0];
+            $end_month = intval($enddateInfo[1]);
+            if(!empty($start_year)&&!empty($end_year))$where[] = " (year>=$start_year and year<=$end_year) ";
+            if(!empty($start_month)&&!empty($end_month))$where[] = " (month>=$start_month and month<=$end_month) ";
+        }
+
+        if(!empty($params['date'])) {
+            $dateInfo = explode('-', $params['date']);
+            $year = $dateInfo[0];
+            $month = intval($dateInfo[1]);
+            if(!empty($year))$where[] = " year = $year ";
+            if(!empty($month))$where[] = " month = $month ";
+        }
+
+        if(!empty($where)){
+            $sql = join(" and ",$where);
+            $query->where($sql);
+        }
+        $query->select($field);
+        if($ressql){
+            return $query->createCommand()->getRawSql();
+        }else{
+            return $query->asArray()->all();
+        }
+
+    }
+
+    /*
+    *取得地市条件
+    */
+    public function getCityWhere($params)
+    {
+        $where = [];
+        //地市选择
+        if(!empty($params['city'])||!empty($params['city_1'])||!empty($params['city_2'])||!empty($params['city_3']))
+        {
+            if($params['city_3'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_3']);
+            }
+            else if($params['city_2'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_2']);
+            }
+            else if($params['city_1'])
+            {
+                $cityInfo = Linkmenu::getMenuNameRs($params['city_1']);
+            }
+            //unset($params['city'],$params['city_1'],$params['city_2'],$params['city_3']);
+            if(!empty($cityInfo[0])){
+                $where['city'] = $cityInfo[0];
+            }
+            if(!empty($cityInfo[1])){
+                $where['dpt_sec'] = $cityInfo[1];
+            }
+            if(!empty($cityInfo[2])){
+                $where['grid'] = $cityInfo[2];
+            }
+        }
+
+        return $where;
+    }
+    /*
+    *pie图表设置
+    */
+    public function getChart1Option($option)
+    {
+        $def = [
+            'title' => [
+                'text' => '',
+                'textStyle' => [
+                    'fontSize' => 14,
+                ],
+                'subtext' => '',
+                'left' => 'left'
+            ],
+            'tooltip' => [
+                'trigger' => 'item',
+                'formatter' => '{a} <br/>{b} : {c} ({d}%)'
+            ],
+            'legend' => [
+                'left' => 'center',
+                'top' => 'bottom',
+                'data' => []
+            ],
+            'toolbox' => [
+                'show' => true,
+                'feature' => [
+                    'mark' => ['show' => true],
+                    'dataView' => ['show' => true, 'readOnly' => false],
+                    'restore' => ['show' => false],
+                    'saveAsImage' => ['show' => true]
+                ]
+            ],
+            'series' => [
+                [
+                    'name' => '',
+                    'type' => 'pie',
+                    'radius' => [20, 130],
+                    'center' => ['45%', '50%'],
+                    'roseType' => 'area',
+                    'itemStyle' => [
+                        'borderRadius' => 5
+                    ],
+                    'data' => [
+
+                    ]
+                ]
+            ]
+        ];
+
+        return array_replace_recursive($def,$option);
+    }
+
+    /*
+    *bar图表设置
+    */
+    public function getChart2Option($option)
+    {
+        $def = [
+            'title' => [
+                'text' => '',
+                'textStyle' => [
+                    'fontSize' => 14,
+                ],
+                'subtext' => '',
+                'left' => 'left'
+            ],
+            'tooltip' => [
+                'trigger' => 'axis',
+                'axisPointer' => [
+                    'type' => 'shadow'
+                ]
+            ],
+            'grid' => [
+                'left' => '3%',
+                'right' => '7%',
+                'bottom' => '3%',
+                'containLabel' => true,
+            ],
+            'toolbox' => [
+                'show' => true,
+                'feature' => [
+                    'dataZoom' => ['yAxisIndex' => 'none'],
+                    'dataView' => ['show' => true, 'readOnly' => false],
+                    'magicType' => ['type' => ['line', 'bar']],
+                    'restore' => ['show' => false],
+                    'saveAsImage' => ['show' => true]
+                ]
+            ],
+            'xAxis' => [
+                [
+                    'type' => 'category',
+                    'data' => [],
+                    'axisTick' => [
+                        'alignWithLabel' => true
+                    ],
+                    'axisLabel' => [
+                        'interval' => 0
+                    ]
+                ]
+            ],
+            'yAxis' => [
+                [
+                    'type' => 'value'
+                ]
+            ],
+            'series' => [
+                [
+                    'name' => '',
+                    'type' => 'bar',
+                    'barWidth' => '60%',
+                    'data' => [],
+                    'markLine' => [
+                        'data' => [
+                            ['type' => 'average', 'name' => '平均值']
+                        ]
+                    ]
+                ]
+            ]
+        ];
+
+        return array_replace_recursive($def,$option);
+    }
+
+
+}

+ 454 - 0
common/controllers/CController.php

@@ -0,0 +1,454 @@
+<?php
+namespace app\common\controllers;
+use app\modules\cms\models\CategoryPriv;
+use Yii;
+use yii\web\Controller;
+use yii\helpers\Url;
+use app\common\helpers\Cookie;
+
+/**
+ * 基类
+ */
+class CController extends Controller
+{
+    public $imgcodeUrl;
+    public $moduleName;
+    public $controllerName;
+    public $actionName;
+    public $adminHomeUrl;
+    public $waterMarkPos;//水印位置
+    public $mediaTimeTypes;//多媒体时长类型
+    public $transferPageTypes;//转换页数类型
+    public $loginWays;//登录方式
+    public $breadcrumbs;//面包屑
+    public function init()
+    {
+        parent::init();
+        error_reporting(0);
+        $this->adminHomeUrl = APP_URL."index.php";
+        $this->imgcodeUrl =  Url::to(['/site/imgcode','width'=>120,'height'=>40]);
+
+
+
+
+    }
+
+    public function behaviors()
+    {
+        $this->moduleName = Yii::$app->controller->module->id;
+        $this->controllerName = Yii::$app->controller->id;
+        $this->actionName = Yii::$app->controller->action->id;
+    }
+
+    public function render($view, $params = [])
+    {
+        $content = $this->getView()->render($view, $params, $this);
+        if (strpos(Yii::$app->urlManager->createAbsoluteUrl('/car'), '10.170.42')) {
+            return str_replace(['/assets/','action="/'],['/house-car/car/assets/','action="/house-car/car/'],$this->renderContent($content));
+        }
+        return $this->renderContent($content);
+    }
+
+    public function renderAjax($view, $params = [])
+    {
+        ob_start();
+
+        ob_implicit_flush(false);
+
+        $this->getView()->beginPage();
+        $this->getView()->head();
+        $this->getView()->beginBody();
+        echo $this->getView()->render($view, $params, $this);
+        $this->getView()->endBody();
+        $this->getView()->endPage(true);
+
+        $content = ob_get_clean();
+        if (strpos(Yii::$app->urlManager->createAbsoluteUrl('/car'), '10.170.42')) {
+            $content = str_replace(['/assets/','action="/'],['/house-car/car/assets/','action="/house-car/car/'],$content);
+        }
+        echo $content;
+        return ob_get_clean();
+    }
+
+    /**
+     * 返回后台身份状态信息
+     * @param  string $key
+     * @return array or string;
+     *
+     */
+    public  function getIdentityInfo($key='')
+    {
+        $cookieName = defined('IN_ADMIN')?'adminCookieName':'userCookieName';
+        $identityInfo = Cookie::getCookie(Yii::$app->params[$cookieName]);
+        if(empty($identityInfo)) $identityInfo = Yii::$app->session['adminInfo'];
+        $identityInfo = string2array(sys_auth($identityInfo,'DECODE'));
+        $dataStr = !empty($_GET['data'])?$_GET['data']:Cookie::getCookie('data_str');
+        if(empty($identityInfo) && $dataStr){
+            $identityInfo = $this->getIdentityInfoByToken($dataStr);
+        }
+        return $result = isset($key)&&isset($identityInfo[$key])?$identityInfo[$key]:$identityInfo;
+    }
+
+    //判断是否登录
+    public function hasLogined()
+    {
+        $cookieName = defined('IN_ADMIN')?'adminCookieName':'userCookieName';
+        $identityInfo = $this->getIdentityInfo(Yii::$app->params[$cookieName]);
+        if(!empty($identityInfo)&&is_array($identityInfo))
+        {
+            if(sys_auth($identityInfo['cookieHash'],'DECODE')!=$identityInfo['user_name'])
+            {
+                return false;
+            }
+            else
+            {
+                return true;
+            }
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    //Modal框中的提示信息
+    public function showAlertInModal($msg,$class='danger')
+    {
+        echo '<div class="alert alert-'.$class.'" >'.$msg.'</div>';
+    }
+
+
+   /**
+     * 页面提示信息
+     * @parame array $data array('message'=>$message,'arguments'=>$arguments,'url'=>$url,'title'=>$title,'time'=>$time,'target'=>$target)
+     * @param string  $message 错误信息
+     * @parame string $url     页面跳转路径
+     * @parame int $time 页面延迟跳转时间
+     * @parame string $target 目标窗口
+     */
+    public function showMessage($data,$exit=0)
+    {
+        if(is_array($data)) extract($data);
+        if(empty($time)) $time =0;//毫秒
+        if(empty($target)) $target = 'self';
+        if(empty($class))$class='info';//可选类别:danger,success,info,warning
+        //获取返回页面
+        if(empty($url))
+        {
+            $url = Yii::$app->request->referrer;
+            $tempUrl = explode("/",ltrim($url,SITE_PROTOCOL));
+            if(strpos($tempUrl[0],COOKIE_DOMAIN)===false)//其他网站入口,返回首页
+            {
+                if(defined('IN_WAP')&&IN_WAP==true)//如果是手机端
+                {
+                    $url = WAP_URL;
+                }
+                else
+                {
+                    $url = WEB_URL;
+                }
+            }
+        }
+        if(empty($title))
+            $title = Yii::t('admin','system alert');
+        if(!isset($message))
+            $message = '';
+        if($time>0)
+        {
+            echo Yii::$app->view->renderFile('@app/views/alert/info.php', array('message'=>$message,'url'=>$url,'title'=>$title,'time'=>$time,'target'=>$target,'class'=>$class));
+        }
+        else
+        {
+            echo "<script>";
+            echo "window.location.href='".$url."'";
+            echo "</script>";
+        }
+        if($exit)exit();
+    }
+
+    //生成含入口脚本的URL地址
+    public function createRealUrl($params)
+    {
+        if(!empty($_GET['data']) && is_array($params)){
+           $params['data'] = $_GET['data'];
+        }
+        $url =  urldecode(Yii::$app->urlManager->createAbsoluteUrl($params));
+        if (strpos($url, '10.170.42')) {
+            $url = str_replace(['http:','/car/','/ajax/'],['https:','/house-car/car/car/','/house-car/car/ajax/'],$url);
+        }
+        //$url = str_replace(['/car/'],['/house-car/car/car/'],$url);
+        return  $url;
+    }
+
+    //获取URL中传递的ID值(可以自定义参数名)
+    protected function getKeyId($keyField='id')
+    {
+        if(isset($_GET[$keyField]))
+        {
+            if(is_numeric($_GET[$keyField]))return intval($_GET[$keyField]);
+            else return safe_replace($_GET[$keyField]);
+        }
+        else
+        {
+            throw new \Exception($keyField.' is required');
+        }
+
+    }
+
+    //格式化树结构数据
+    public function serializeTreeData($resultList,$keyId,$parentKeyId,$nameKey='name',$langFile='resource')
+    {
+        $datas = array();
+        $results = array();
+        $i=0;
+        if(!empty($resultList))
+        {
+            foreach($resultList as $o)
+            {
+                $results[$i][$keyId] = $o->$keyId;
+                $results[$i]['parent_id'] = $o->$parentKeyId;
+                $results[$i]['name'] = Yii::t($langFile,$o->$nameKey);
+                $i++;
+            }
+        }
+        if (is_array($results)) {
+            foreach($results as $r) {
+                $datas[$r[$keyId]] = array('id'=>$r[$keyId], 'parent_id'=>$r['parent_id'], 'name'=>$r['name']);
+            }
+        }
+        return $datas;
+    }
+
+    //写配置文件
+    public static function setConfig($config, $filename="params") {
+        if(defined('SITE_MODE'))
+        {
+            $configfile = BASE_PATH.'config'.DIRECTORY_SEPARATOR.SITE_MODE.DIRECTORY_SEPARATOR.$filename.'.php';
+        }
+        else
+        {
+            $configfile = BASE_PATH.'config'.DIRECTORY_SEPARATOR.$filename.'.php';
+        }
+
+        if(!is_writable($configfile)) exit('Please chmod '.$configfile.' to 0777 !');
+        $pattern = $replacement = array();
+        foreach($config as $k=>$v) {
+            //if(in_array($k,array('OSS_ACCESS_ID','OSS_ACCESS_KEY','OSS_ENDPOINT','OSS_BUCKET','OPEN_ALIOSS'))) {
+            $v = trim($v);
+            $configs[$k] = $v;
+            $pattern[$k] = "/'".$k."'\s*=>\s*([']?)[^']*([']?)(\s*),/is";
+            $replacement[$k] = "'".$k."' => \${1}".$v."\${2}\${3},";
+            //}
+        }
+        $str = file_get_contents($configfile);
+        $str = preg_replace($pattern, $replacement, $str);
+        return Yii::$app->params['lockEx'] ? file_put_contents($configfile, $str, LOCK_EX) : file_put_contents($configfile, $str);
+    }
+
+    //写单个配置文件
+    public static function writeConfigFile($config, $filename="params") {
+        if(defined('SITE_MODE'))
+        {
+            $configfile = BASE_PATH.'config'.DIRECTORY_SEPARATOR.SITE_MODE.DIRECTORY_SEPARATOR.$filename.'.php';
+        }
+        else
+        {
+            $configfile = BASE_PATH.'config'.DIRECTORY_SEPARATOR.$filename.'.php';
+        }
+
+        if(!is_writable($configfile)) exit('Please chmod '.$configfile.' to 0777 !');
+        $configStr  =  "<?php".PHP_EOL;
+        $configStr .= "return array(".PHP_EOL;
+        $configStr .= "\t'params'=>array(".PHP_EOL;
+        $configStr .= "\t\t'$filename'=>array(".PHP_EOL;
+        if(is_array($config))foreach($config as $k=>$v)
+        {
+            $configStr .= "\t\t\t'$k'=>'$v',".PHP_EOL;
+        }
+        $configStr .= "\t\t),".PHP_EOL;
+        $configStr .= "\t),".PHP_EOL;
+        $configStr .= ");".PHP_EOL;
+        $configStr .= "?>";
+        return Yii::$app->params['lockEx'] ? file_put_contents($configfile, $configStr, LOCK_EX) : file_put_contents($configfile, $configStr);
+    }
+
+
+
+    //判断栏目权限
+    public static function hasCategoryPirv($obj)
+    {
+
+        if($obj->is_admin&&$obj->role_id==1)
+        {
+            return true;
+        }
+        else
+        {
+            $priv_obj = CategoryPriv::find()->where("cat_id=".$obj->cat_id." and role_id=".$obj->role_id." and is_admin=".$obj->is_admin." and action='".$obj->action."'")->one();
+            if(!empty($priv_obj))
+            {
+                return true;
+            }
+            else
+            {
+
+                return false;
+            }
+        }
+    }
+
+    //美化目录树显示
+    function beautifulTree($arr, $preview=0,$l = '-|')
+    {
+        if(Yii::$app->controller->module->transferconfig['previewpack']==1)$preview=1;
+        $attConfigInfo = \app\modules\admin\models\Config::find()->where("name='attachment'")->one();
+        $attConfig = string2array($attConfigInfo->value);
+        $fileTypeList = explode("|",$attConfig['file_type']);
+        static $l = '';
+        static $str = '<ul class="file-tree">';
+        //遍历刚才得到的目录树
+        foreach($arr as $key=>$val) {
+            //如果是个数组,也就代表它是个目录,那么就在它的子文件中加入-|来表示是下一级吧
+            if(is_array($arr[$key])) {
+                $valInfo = explode('/',strval($key));
+                $str.="<li data-jstree='{\"opened\":true,\"icon\":\"iconfont icon-wenjianjia1\"}'>&nbsp;".$valInfo[count($valInfo)-1]."<ul>";
+                $this->beautifulTree($arr[$key], $preview, $l);
+                $str.= "</ul>";
+            }else {
+                $valInfo = explode('/',strval($val));
+                $ext = in_array(fileext($val),$fileTypeList)?fileext($val):'file';
+                if($preview>=1)
+                {
+                    $str.="<li data-jstree='{\"opened\":true,\"icon\":\"iconfont icon-".$ext."\"}' data-md5='".md5($val)."' class='previewpackfile".$preview."' >&nbsp;".$l.$valInfo[count($valInfo)-1]."<span style='margin-left:15px;'>--点击预览</span></li>";
+                }
+                else
+                {
+                    $str.="<li data-jstree='{\"opened\":true,\"icon\":\"iconfont icon-".$ext."\"}'>&nbsp;".$l.$valInfo[count($valInfo)-1]."</li>";
+                }
+            }
+        }
+        $l = '';
+        return $str;
+    }
+
+    //压缩包文件数量
+    function packFileNum($arr)
+    {
+        static $num = 0;
+        //遍历刚才得到的目录树
+        if(is_array($arr))foreach($arr as $key=>$val) {
+            //如果是个数组,也就代表它是个目录,那么就在它的子文件中加入-|来表示是下一级吧
+            if(is_array($arr[$key])) {
+                $this->packFileNum($arr[$key]);
+            }else {
+
+                $num++;
+            }
+        }
+        return $num;
+    }
+
+    //头像
+    public function makeAvatar($imagePath,$width,$height)
+    {
+        $hash = $imagePath?md5($imagePath):'noavatar';
+        $img = \app\modules\admin\models\Attachment::find()->where("hash='".$hash."'")->limit(1)->one();
+        if(!$img&&is_net_file($imagePath))
+        {
+            return  $imagePath;
+        }
+        else
+        {
+            return APP_URL.'avt/'.$width.'/'.$height.'/'.$hash.'.jpg';
+        }
+
+    }
+
+    //缩略图
+    public function makeThumb($imagePath,$width,$height)
+    {
+        if(Yii::$app->params['oss']['OPEN_OSS']&&Yii::$app->params['oss']['OSS_THUMB'])
+        {
+            $fileUrl =  getFileUrl($imagePath);
+            if(Yii::$app->params['oss']['OSS_TYPE']=='tencent')
+            {
+                return $fileUrl.'?imageMogr2/thumbnail/'.$width.'x'.$height;
+            }
+            if(Yii::$app->params['oss']['OSS_TYPE']=='ali')
+            {
+                return $fileUrl.'?x-oss-process=image/resize,m_fill,h_'.$height.',w_'.$width;
+            }
+            if(Yii::$app->params['oss']['OSS_TYPE']=='baidu')
+            {
+                return $fileUrl.'?x-bce-process=image/resize,m_fill,w_'.$width.',h_'.$height;
+            }
+            else
+            {
+                return $fileUrl;
+            }
+        }
+        else
+        {
+            $hash = $imagePath?md5($imagePath):'noimage';
+            return APP_URL.'p/'.$width.'/'.$height.'/'.$hash.'.jpg';
+        }
+
+    }
+
+    //当前用户是否有权限访问和操作所请求的资源
+    public function checkRights($user_id,$model,$fild_name='user_id')
+    {
+        if ($model->$fild_name != $user_id){
+            if (Yii::$app->request->isAjax) {
+                $msgdata = ['error' => 1,'msg' => '没有操作权限'];
+                echo_json($msgdata);
+            }
+            else
+            {
+                throw new \yii\web\ForbiddenHttpException('你只能操作你自己创作的数据');
+            }
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+
+    //解密价值平台字串
+    public function getIdentityInfoByToken($str){
+        if ($str == null) {
+            return false;
+        }
+        //Cookie::setCookie('data_str',$str);
+        $str = str_replace("\\\\n", "", $str);
+        $str = str_replace("/add/", "+", $str);
+        // 解密
+        $decrypted = json_decode(openssl_decrypt(base64_decode($str),"AES-128-ECB", '2na$$PdV9AW8b#CS',OPENSSL_RAW_DATA),true);
+        //var_dump($decrypted);
+        if(!empty($decrypted) && is_array($decrypted) && isset($decrypted['LOGIN_ID']) && isset($decrypted['APP_ID']) && isset($decrypted['TIME_STAMP']) && isset($decrypted['REQUEST_URL'])){
+            //if(time()-5*60 > strtotime($decrypted['TIME_STAMP']) || time() + 5*60 < strtotime($decrypted['TIME_STAMP'])) return 'token';
+            $identityInfo = array();
+            $identityInfo['admin_id']=1;
+            $identityInfo['user_name']=$decrypted['LOGIN_ID'];
+            $identityInfo['role_id']=1;
+            $identityInfo['real_name']='管理员';
+            $identityInfo['role_name']='超级管理员';
+            $identityInfo['cookieHash'] = sys_auth($decrypted['LOGIN_ID']);
+            $identityInfo['login_type'] = 'token';
+            $info = sys_auth(array2string($identityInfo));
+
+            Yii::$app->session['adminInfo']=$info;
+
+            Cookie::setCookie(Yii::$app->params['adminCookieName'],$info);//使用COOKIE记录用户身份信息
+            //为锁屏功能设置的一个开关变量
+            Cookie::setCookie('lockscreen',0);
+
+            return $identityInfo;
+        }
+        return 'token';
+
+    }
+
+
+}

+ 678 - 0
common/controllers/FController.php

@@ -0,0 +1,678 @@
+<?php
+namespace app\common\controllers;
+use yii\helpers\Url;
+use app\common\components\SiteUrl;
+use app\common\helpers\Identify;
+use app\modules\ad\models\AdData;
+use app\modules\shopping\models\ShoppingStore;
+use app\modules\ucenter\models\UserFavorite;
+use app\common\components\CacheId;
+use app\models\SearchRecord;
+use app\common\components\MultiSearchUrl;
+use app\models\ContentModel;
+use app\models\ContentModelField;
+use yii\data\Pagination;
+use Yii;
+
+/**
+ * 前台基类
+ */
+class FController extends CController
+{
+
+    public $homeUrl;//首页地址
+    public $userInfo;
+    public $navList;//头部导航
+    public $footerLinks;//底部链接
+    public $wapMenuList;//手机端菜单
+    public $wapNavList;//手机端导航
+    public $filterConfig;//多条件筛选初始配置
+    public $keywords;//Meta keywords
+    public $description;//Meta keywords
+    public $searchtitle;//Meta searchtitle;
+    public function init()
+    {
+        parent::init();
+        $this->homeUrl = Url::to(['/web/default/index'],true);
+        $this->navList = $this->getNavData(2);//默认取PC内页导航数据
+        $this->footerLinks = $this->getNavData(4);
+        $this->wapNavList = $this->getNavData(6);
+        $this->userInfo = Identify::getUserInfo();
+        $this->initFilterConfig();
+    }
+
+    public function behaviors()
+    {
+
+        parent::behaviors();
+        return [
+
+            [
+                'class' => 'app\common\filters\FrontEndTokenFilter',
+            ],
+        ];
+    }
+
+
+
+
+    //获取导航/链接数据
+    public  function getNavData($type)
+    {
+        $allNavList =  json_decode(Yii::$app->cache->get(CacheId::navCacheId()),true);
+        $navList = $allNavList[$type];
+        $navData = [];
+        if(is_array($navList))foreach($navList as $nav)
+        {
+            if($nav['parent_id']>0)continue;
+            if($nav['is_dropdown']&&$nav['dropdown_level']>0)
+            {
+                if($nav['content_model_id'])
+                {
+                    $modelList =  json_decode(Yii::$app->cache->get(CacheId::modelListCacheId()),true);
+                    $functionName = $modelList[$nav['content_model_id']]['table_name'].'List';
+                    //SiteUrl::$functionName(8);
+                    $categoryList = json_decode(Yii::$app->cache->get(CacheId::categoryItemsCacheId($nav['content_model_id'])),true);
+                    $childs = [];
+                    if(is_array($categoryList))foreach($categoryList as $category)
+                    {
+                        if(empty($category['parent_id']))
+                        {
+                            //二级菜单
+                            $secChilds = [];
+                            if(is_array($categoryList))foreach($categoryList as $secCategory)
+                            {
+                                if($secCategory['parent_id']==$category['cat_id'])
+                                {
+                                    //三级菜单
+                                    $thirdChilds = [];
+                                    if(is_array($categoryList))foreach($categoryList as $thirdCategory)
+                                    {
+                                        if($thirdCategory['parent_id']==$secCategory['cat_id'])
+                                        {
+                                            $thirdChilds[] = array('title'=>$thirdCategory['cat_name'],'url'=>SiteUrl::$functionName($thirdCategory['cat_id']),'blank'=>$nav['blank']);
+                                        }
+                                    }
+
+                                    $secChilds[] = array('title'=>$secCategory['cat_name'],'url'=>SiteUrl::$functionName($secCategory['cat_id']),'blank'=>$nav['blank'],'childs'=>$thirdChilds);
+
+                                }
+                            }
+                            $childs[] =  array('title'=>$category['cat_name'],'url'=>SiteUrl::$functionName($category['cat_id']),'blank'=>$nav['blank'],'childs'=>$secChilds);
+
+                        }
+                    }
+                    $navData[] = array('title'=>$nav['title'],'url'=>$nav['url'],'blank'=>$nav['blank'],'width'=>$nav['width'],'is_dropdown'=>$nav['is_dropdown'],'dropdown_level'=>$nav['dropdown_level'],'iconfont'=>$nav['iconfont'],'childs'=>$childs);
+                }
+                else
+                {
+                    $childs = [];
+                    if(is_array($navList))foreach($navList as $childNav)
+                    {
+                        if($childNav['parent_id']==$nav['id'])
+                        {
+                            $secChilds = [];
+                            if(is_array($navList))foreach($navList as $secNav)
+                            {
+                                if($secNav['parent_id']==$childNav['id'])
+                                {
+                                    //三级菜单
+                                    $thirdChilds = [];
+                                    if(is_array($navList))foreach($navList as $thirdNav)
+                                    {
+                                        if($thirdNav['parent_id']==$secNav['id'])
+                                        {
+                                            $thirdChilds[] = array('title'=>$thirdNav['title'],'url'=>$thirdNav['url'],'blank'=>$thirdNav['blank'],'is_new'=>$thirdNav['is_new'],'is_hot'=>$thirdNav['is_hot'],'iconfont'=>$thirdNav['iconfont']);
+                                        }
+                                    }
+                                    $secChilds[] = array('title'=>$secNav['title'],'url'=>$secNav['url'],'blank'=>$secNav['blank'],'is_new'=>$secNav['is_new'],'is_hot'=>$secNav['is_hot'],'iconfont'=>$secNav['iconfont'],'childs'=>$thirdChilds);
+                                }
+                            }
+                            $childs[] = array('title'=>$childNav['title'],'url'=>$childNav['url'],'blank'=>$childNav['blank'],'is_new'=>$childNav['is_new'],'is_hot'=>$childNav['is_hot'],'iconfont'=>$childNav['iconfont'],'childs'=>$secChilds);
+                        }
+                    }
+                    $navData[] = array('title'=>$nav['title'],'url'=>$nav['url'],'blank'=>$nav['blank'],'width'=>$nav['width'],
+'is_dropdown'=>$nav['is_dropdown'],'dropdown_level'=>$nav['dropdown_level'],'iconfont'=>$nav['iconfont'],'childs'=>$childs);
+                }
+            }
+            else
+            {
+
+                $childs = [];
+                if(is_array($navList))foreach($navList as $childNav)
+                {
+                    if($childNav['parent_id']==$nav['id'])
+                    {
+                        $secChilds = [];
+                        if(is_array($navList))foreach($navList as $secNav)
+                        {
+                            if($secNav['parent_id']==$childNav['id'])
+                            {
+                                //三级菜单
+                                $thirdChilds = [];
+                                if(is_array($navList))foreach($navList as $thirdNav)
+                                {
+                                    if($thirdNav['parent_id']==$secNav['id'])
+                                    {
+                                        $thirdChilds[] = array('title'=>$thirdNav['title'],'url'=>$thirdNav['url'],'blank'=>$thirdNav['blank'],'is_new'=>$thirdNav['is_new'],'is_hot'=>$thirdNav['is_hot'],'iconfont'=>$thirdNav['iconfont']);
+                                    }
+                                }
+                                $secChilds[] = array('title'=>$secNav['title'],'url'=>$secNav['url'],'blank'=>$secNav['blank'],'is_new'=>$secNav['is_new'],'is_hot'=>$secNav['is_hot'],'iconfont'=>$secNav['iconfont'],'childs'=>$thirdChilds);
+                            }
+                        }
+
+                        $childs[] = array('title'=>$childNav['title'],'url'=>$childNav['url'],'blank'=>$childNav['blank'],'is_new'=>$childNav['is_new'],'is_hot'=>$childNav['is_hot'],'iconfont'=>$childNav['iconfont'],'childs'=>$secChilds);
+                    }
+                }
+
+                $navData[] = array('title'=>$nav['title'],'url'=>$nav['url'],'blank'=>$nav['blank'],'is_dropdown'=>$nav['is_dropdown'],'dropdown_level'=>$nav['dropdown_level'],'iconfont'=>$nav['iconfont'],'childs'=>$childs);
+            }
+        }
+        return $navData;
+    }
+
+    //单条记录字段值修改
+    public function actionSetfield()
+    {
+        $table = strtolower(safe_replace($_GET['table']));
+        $fileldName = safe_replace($_GET['field']);
+        $fieldValue = safe_replace($_GET['value']);
+        $pk = safe_replace($_GET['pk']);
+        $pkField = \app\common\models\EActiveRecord::getPrikey($table);
+        if(!empty($pk)&&!empty($fileldName))
+        {
+            if(empty($this->userInfo))
+            {
+                $msgdata = ['error' => 1,'msg' => '操作失败'];
+            }
+            else
+            {
+                $result  =  Yii::$app->db->createCommand("UPDATE {{%$table}} SET $fileldName='$fieldValue' WHERE $pkField='$pk' and user_id=".$this->userInfo['user_id'])->execute();
+                if($result)
+                {
+                    $msgdata = ['error' => 0,'msg' => '操作成功'];
+                }
+                else
+                {
+
+                    $msgdata = ['error' => 1,'msg' => '操作失败'];
+                }
+            }
+
+        }
+        else
+        {
+
+            $msgdata = ['error' => 1,'msg' => '操作失败'];
+        }
+        echo_json($msgdata);
+    }
+
+    //获取广告数据
+    public function getAdData($space_id)
+    {
+        $dataList = AdData::find()->where("space_id='".$space_id."' and status=1 and end_time>".TIMESTAMP)->orderBy(['list_order'=>SORT_ASC])->all();
+        return $dataList;
+    }
+
+    //判断当前用户是否已关注该记录
+    public function checkFavor($table_name,$data_id)
+    {
+        if($this->hasLogined())
+        {
+            $user_id = Identify::getUserInfo(null,'user_id');
+            $exist = UserFavorite::find()->where("user_id=$user_id and table_name='".$table_name."' and data_id='".$data_id."'")->exists();
+            if($exist)
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        else
+        {
+            return false;
+        }
+
+    }
+
+    //返回个人主页链接
+    function getUpage($user_id,$open_home=0)
+    {
+        if(defined('IN_WAP')&&IN_WAP==TRUE)
+        {
+            $str = 'href="javascript:;"';
+        }
+        else
+        {
+            if($open_home)
+            {
+                $str = 'href="'.\app\common\components\SiteUrl::uHome($user_id).'" target="_blank"';
+            }
+            else
+            {
+                $str = 'href="javascript:;"';
+            }
+        }
+
+        return $str;
+    }
+
+    //返回前台创作者名称信息
+    function getOwnername($user_id,$nick_name='')
+    {
+        if(empty($user_id))return '游客';
+        $store = ShoppingStore::find()->where("user_id=$user_id")->one();
+        if($store)
+        {
+            return $store->store_name;
+        }
+        else
+        {
+            if(!empty($nick_name))
+            {
+                return $nick_name;
+            }
+            else
+            {
+                $user = \app\modules\ucenter\models\User::findOne($user_id);
+                return $user->nick_name;
+            }
+
+        }
+    }
+
+    //返回前台创作者名称信息
+    function getOwneravatar($user_id,$avatar='')
+    {
+        if(empty($user_id))return;
+        $store = ShoppingStore::find()->where("user_id=$user_id")->one();
+        if($store)
+        {
+            return $store->logo;
+        }
+        else
+        {
+            if(!empty($avatar))
+            {
+                return $avatar;
+            }
+            else
+            {
+                $user = \app\modules\ucenter\models\User::findOne($user_id);
+                return $user->avatar;
+            }
+
+        }
+    }
+
+    //返回前台主页简介
+    function getOwnerdes($user_id,$des='')
+    {
+        if(empty($user_id))return '';
+        $store = ShoppingStore::find()->where("user_id=$user_id")->one();
+        if($store)
+        {
+            return $store->desc;
+        }
+        else
+        {
+            if(!empty($des))
+            {
+                return $des;
+            }
+            else
+            {
+                $user = \app\modules\ucenter\models\User::findOne($user_id);
+                return $user->signature;
+            }
+
+        }
+    }
+
+    //返回前台主页关键词
+    function getOwnerkeywords($user_id,$keywords='')
+    {
+        if(empty($user_id))return '';
+        $store = ShoppingStore::find()->where("user_id=$user_id")->one();
+        if($store)
+        {
+            return $store->keywords;
+        }
+        else
+        {
+            return $keywords;
+
+        }
+    }
+    //初始化列表多条件筛选配置
+    public function initFilterConfig()
+    {
+        //文档筛选条件
+        $this->filterConfig['doc'] = array(
+           'fieldConfig' => array(
+                'c'=>array('type'=>'cat_ids','flag'=>'like','field'=>'cat_ids'),
+                'xa'=>array('type'=>'equal','flag'=>'=','field'=>'ext_type_1'),
+                'xb'=>array('type'=>'equal','flag'=>'=','field'=>'ext_type_2'),
+                'xc'=>array('type'=>'equal','flag'=>'=','field'=>'ext_type_3'),
+                'xd'=>array('type'=>'equal','flag'=>'=','field'=>'ext_type_4'),
+                'xe'=>array('type'=>'equal','flag'=>'=','field'=>'ext_type_5'),
+                'sp'=>array('type'=>'boollist','flag'=>'=','field'=>array('is_new','is_hot','is_original','is_recommend')),
+                'vp'=>array('type'=>'boollist','flag'=>'=','field'=>array('is_vip','vip_free','is_free')),
+            ),
+            'sortConfig' => array(
+                '1'=>array('value'=>1, 'order'=>'create_time desc','title'=>'最新上传','tips'=>'点击按上传时间排序'),
+                '2'=>array('value'=>2, 'order'=>'downs desc','title'=>'热门下载','tips'=>'点击按下载量排序'),
+                '3'=>array('value'=>3, 'order'=>'views desc','title'=>'浏览优先','tips'=>'点击按浏览量排序'),
+                '4'=>array('value'=>4, 'order'=>'favors desc','title'=>'收藏优先','tips'=>'点击按收藏量排序'),
+            ),
+            'sortConfigWap' => array(
+                '1'=>array('value'=>1, 'order'=>'create_time desc','title'=>'综合','tips'=>'点击按上传时间排序'),
+                '2'=>array('value'=>2, 'order'=>'downs desc','title'=>'下载量','tips'=>'点击按下载量排序'),
+                '3'=>array('value'=>3, 'order'=>'views desc','title'=>'浏览量','tips'=>'点击按浏览量排序'),
+            ),
+            'xConfig' => array('1'=>'xa','2'=>'xb','3'=>'xc','4'=>'xd','5'=>'xe'),
+            'spConfig' => array('1'=>'最新','2'=>'最热','3'=>'原创','4'=>'推荐'),
+            'vpConfig' => array('1'=>'VIP专享','2'=>'VIP免费','3'=>'免费')
+        );
+
+        //资讯筛选条件
+        $this->filterConfig['news'] = array(
+            'fieldConfig' => array(
+                'c'=>array('type'=>'cat_ids','flag'=>'like','field'=>'cat_ids'),
+                'sp'=>array('type'=>'boollist','flag'=>'=','field'=>array('is_new','is_hot','is_recommend')),
+            ),
+            'sortConfig' => array(
+                '1'=>array('value'=>1, 'order'=>'create_time desc','title'=>'最新发布','tips'=>'点击按发布时间排序'),
+                '2'=>array('value'=>2, 'order'=>'digs desc','title'=>'点赞优先','tips'=>'点击按点赞量排序'),
+                '3'=>array('value'=>3, 'order'=>'views desc','title'=>'浏览优先','tips'=>'点击按浏览量排序'),
+                '4'=>array('value'=>4, 'order'=>'favors desc','title'=>'收藏优先','tips'=>'点击按收藏量排序'),
+            ),
+            'spConfig' => array('1'=>'最新','2'=>'最热','3'=>'推荐'),
+        );
+    }
+
+
+    //搜索逻辑处理
+    public function doSearch($kw,$model_id,$higherconfig=null)
+    {
+        if(!empty($higherconfig))$mapp = true;
+        require(BASE_PATH.'common'.DIRECTORY_SEPARATOR.'components'.DIRECTORY_SEPARATOR.'sphinxapi.php');
+        $higherconfig = $higherconfig?$higherconfig:Yii::$app->controller->module->higherconfig;
+
+        //每页显示数量
+        $pageSize = 10;
+        //记录搜索热点
+        $kwModel = SearchRecord::find()->where("keyword='".$kw."' and content_model_id=$model_id")->one();
+        if(!empty($kwModel))
+        {
+            $kwModel->times++;
+            $kwModel->save();
+        }
+        else
+        {
+            $kwModel = new SearchRecord();
+            $kwModel->content_model_id = $model_id;
+            $kwModel->keyword = $kw;
+            $kwModel->times = 1;
+            $kwModel->create_time = TIMESTAMP;
+            $kwModel->save();
+        }
+        //获取排序配置
+        $searchModelList = getSysconfigValue('search_models_flag');
+        $contentFilterConfig = $this->filterConfig[$searchModelList[$model_id]];
+        //筛选条件解析
+        $multiSearch = MultiSearchUrl::getSelfInstance(array('fieldConfig'=> $contentFilterConfig['fieldConfig'],'sortConfig'=>$contentFilterConfig['sortConfig']));
+        $searchConditions = $multiSearch->getSearchConditions();
+        //序列化多维度筛选
+        $sqlInfo  = $multiSearch->sqllizeConditions();
+        $st = $multiSearch->getConditionValueByType($searchConditions,'st');
+        //没有排序条件,默认按最新上传时间
+        if(empty($sqlInfo['order']))$sqlInfo['order']="order by create_time desc";
+        $page = Yii::$app->request->get('page',1);
+        if($higherconfig['open_sphinx'])
+        {
+            $cl = new \SphinxClient ();
+            $q = $kw;
+            $host = "localhost";
+            $port = 9312;
+            //此处变量名称与内容模型主表名一一对应
+            $index = $higherconfig[$searchModelList[$model_id].'_index'];
+            $cl->SetServer ( $host, $port );
+            $connect = $cl->_Connect();
+            if(!$connect)
+            {
+                $this->showMessage(array('class'=>'danger','message'=>'sphinx连接失败'),1);
+            }
+            $cl->SetConnectTimeout ( 1 );
+            $cl->SetArrayResult ( true );
+            $cl->SetMatchMode(SPH_MATCH_ALL);
+            $cl->SetLimits(($page-1)*$pageSize,$pageSize);
+            $cl->SetFieldWeights(array('title'=>10,'tags'=>5,'keywords'=>5,'description'=>3));
+            if(!empty($st))
+            {
+                $cl->SetSortMode(SPH_SORT_EXTENDED, str_replace("order by ","",$sqlInfo['order']));
+            }
+            else
+            {
+                $cl->SetSortMode(SPH_SORT_EXTENDED, "@weight DESC,@id DESC");//按照相关度排序
+            }
+            $res = $cl->Query ( $q, $index );
+            $count = $res['total_found'];
+            $resultList = [];
+            //定义关键字标注内容
+            $opts = array('before_match'=>'<span style="color:red">','after_match'=>'</span>');
+            if(is_array($res['matches']))foreach($res['matches'] as $k=>$match)
+            {
+                // "mysql" 我的索引名   “你好”要标红的关键字;
+                $go = $cl->BuildExcerpts(array($match['attrs']['title']),$index,$kw,$opts);
+                $res['matches'][$k]['attrs']['title'] = $go[0];
+                $resultList[$k] =  $res['matches'][$k]['attrs'];
+                $resultList[$k]['id'] = $match['id'];
+                $resultList[$k]['description'] = str_replace($kw,"<span style='color:red;'>$kw</span>",$resultList[$k]['description']);
+            }
+
+            $pages = new Pagination([
+                'totalCount' => $count,
+                'pageSize'   => $pageSize,
+                'defaultPageSize' => $pageSize, //添加默认
+            ]);
+        }
+        else
+        {
+            $contentModel = ContentModel::findOne($model_id);
+            $contentModelFieldList = ContentModelField::find()->where("model_id=$model_id")->all();
+            if($contentModel->table_name=='doc')
+            {
+                $tableName = Yii::$app->db->tablePrefix.$contentModel->table_name.'_real';
+
+            }
+            else
+            {
+                $tableName = Yii::$app->db->tablePrefix.$contentModel->table_name;
+            }
+            //增加标记判断
+            if(is_array($contentModelFieldList))foreach($contentModelFieldList as $contentModelField)
+            {
+                if(in_array($contentModelField->field,['is_delete','is_del','disabled']))
+                {
+                    $sqlother[] = " and ".$contentModelField->field.'=0';
+                }
+            }
+
+            if(!empty($sqlother))$sqlother = join(" ",$sqlother);
+
+            $query = new \yii\db\Query();
+            $query->from($tableName);
+            $sql = "(title like '%".$kw."%' or keywords like '%".$kw."%' or description like '%".$kw."%') and status=1 ".$sqlother;
+            $query->where($sql);
+            $query->orderBy(str_replace('order by ','',$sqlInfo['order']));
+            $countQuery = clone $query;
+            $count = $countQuery->count();
+            $pages = new Pagination([
+                'totalCount' => $count,
+                'pageSize'   => $pageSize,
+                'defaultPageSize' => $pageSize, //添加默认
+            ]);
+            //获取当前页内容
+            $resultList =  $query->offset($pages->offset)->limit($pages->limit)->all();
+            if(is_array($resultList))foreach($resultList as $k=>$result)
+            {
+                $resultList[$k]['title'] = str_replace($kw,"<span style='color:red;'>$kw</span>",$resultList[$k]['title']);
+                $resultList[$k]['description'] = str_replace($kw,"<span style='color:red;'>$kw</span>",$resultList[$k]['description']);
+            }
+        }
+
+        if(!$mapp)
+        {
+            $badwords = getSearchBadWords();
+            $hournow = get_date(TIMESTAMP,'H');
+            $filter = true;
+            if(Yii::$app->controller->module->badwordconfig['hours'])
+            {
+                $hours = explode(",",Yii::$app->controller->module->badwordconfig['hours']);
+                if(!in_array($hournow,$hours))
+                {
+                    $filter = false;
+                }
+
+            }
+            if($filter)
+            {
+                //设定过滤条件(爬虫过滤)
+                if(isSpider()&&Yii::$app->controller->module->badwordconfig['open_spider'])
+                {
+                    if(is_array($badwords))foreach($badwords as $badword)
+                    {
+                        if(strpos($kw,$badword)!==false)
+                        {
+                            return ['resultList'=>[],'searchConditions'=>$searchConditions,'st'=>[],'count'=>0,'pages'=>[],'pageCount'=>0,'contentFilterConfig'=>[],'currentPage'=>0,'pageSize'=>0];
+                        }
+                    }
+                }
+
+                //设定过滤条件(手机站)
+                if(!isSpider()&&defined('IN_WAP')&&IN_WAP==TRUE&&Yii::$app->controller->module->badwordconfig['open_wap'])
+                {
+                    if(is_array($badwords))foreach($badwords as $badword)
+                    {
+                        if(strpos($kw,$badword)!==false)
+                        {
+                            return ['resultList'=>[],'searchConditions'=>$searchConditions,'st'=>[],'count'=>0,'pages'=>[],'pageCount'=>0,'contentFilterConfig'=>[],'currentPage'=>0,'pageSize'=>0];
+                        }
+                    }
+                }
+
+                //设定过滤条件(PC站)
+                if(!isSpider()&&defined('REQUEST_FROM')&&REQUEST_FROM==1&&Yii::$app->controller->module->badwordconfig['open_pc'])
+                {
+                    if(is_array($badwords))foreach($badwords as $badword)
+                    {
+                        if(strpos($kw,$badword)!==false)
+                        {
+                            return ['resultList'=>[],'searchConditions'=>$searchConditions,'st'=>[],'count'=>0,'pages'=>[],'pageCount'=>0,'contentFilterConfig'=>[],'currentPage'=>0,'pageSize'=>0];
+                        }
+                    }
+                }
+            }
+        }
+
+        return ['resultList'=>$resultList,'searchConditions'=>$searchConditions,'st'=>$st,'count'=>$count,'pages'=>$pages,'pageCount'=>ceil($count/$pageSize),'contentFilterConfig'=>$contentFilterConfig,'currentPage'=>$page,'pageSize'=>$pageSize];
+    }
+
+    //列表页Sphinx查询
+    public function doList($query,$sql,$sqlInfo,$table,$pageSize,$higherconfig=null)
+    {
+        require(BASE_PATH.'common'.DIRECTORY_SEPARATOR.'components'.DIRECTORY_SEPARATOR.'sphinxapi.php');
+        $page = Yii::$app->request->get('page',1);
+        $higherconfig = $higherconfig?$higherconfig:Yii::$app->controller->module->higherconfig;
+        if($higherconfig['open_sphinx'])
+        {
+            $contentModel = ContentModel::find()->where("table_name='".$table."'")->one();
+            $cl = new \SphinxClient ();
+            $host = "localhost";
+            $port = 9312;
+            //此处变量名称与内容模型主表名一一对应
+            $searchModelList = getSysconfigValue('search_models_flag');
+            $index = $higherconfig[$searchModelList[$contentModel->model_id].'_index'];
+            $cl->SetServer ( $host, $port );
+            $connect = $cl->_Connect();
+            if(!$connect)
+            {
+                $this->showMessage(array('class'=>'danger','message'=>'sphinx连接失败'),1);
+            }
+
+            $cl->SetConnectTimeout ( 1 );
+            $cl->SetArrayResult ( true );
+            $cl->SetMatchMode(SPH_MATCH_EXTENDED2);
+            $cl->SetLimits(($page-1)*$pageSize,$pageSize);
+            if(empty($sqlInfo['order']))$sqlInfo['order']="order by create_time desc";
+            $cl->SetSortMode(SPH_SORT_EXTENDED, str_replace("order by ","",$sqlInfo['order']));
+            $fieldList = ContentModelField::find()->where("model_id=".$contentModel->model_id)->all();
+            if(is_array($fieldList))foreach($fieldList as $field)
+            {
+                $sql = str_replace($field->field,'@'.$field->field,$sql);
+
+            }
+
+            $sql = str_replace('and','&',$sql);
+            $sql = str_replace('or','|',$sql);
+            $sql = str_replace('%','',$sql);
+            $sql = str_replace('like','',$sql);
+            $res = $cl -> query($sql,$index);
+            $count = $res['total_found'];
+           /* echo $sql;
+
+            echo "Query failed: " . $cl->GetLastError() . ".\n";
+            echo json_encode($res);*/
+
+            $resultList = [];
+            //定义关键字标注内容
+            if(is_array($res['matches']))foreach($res['matches'] as $k=>$match)
+            {
+                $resultList[$k] =  $res['matches'][$k]['attrs'];
+                $resultList[$k]['id'] = $match['id'];
+            }
+
+            $pages = new Pagination([
+                'totalCount' => $count,
+                'pageSize'   => $pageSize,
+                'defaultPageSize' => $pageSize, //添加默认
+            ]);
+            $return = [
+                'count'=>$count,
+                'pages'=>$pages,
+                'pageSize'=>$pageSize,
+                'resultList'=>$resultList,
+            ];
+        }
+        else
+        {
+            $query->where($sql);
+            //没有排序条件,默认按最新上传时间
+            if(empty($sqlInfo['order']))$sqlInfo['order']="order by create_time desc";
+            $query->orderBy(str_replace('order by ','',$sqlInfo['order']));
+            //分页
+            $countQuery = clone $query;
+            $pages = new Pagination([
+                'totalCount' => $countQuery->count(),
+                'pageSize'   => $pageSize,
+                'defaultPageSize' => $pageSize //添加默认
+            ]);
+            $resultList =  $query->offset($pages->offset)->limit($pages->limit)->all();
+            $return = [
+                'count'=>$countQuery->count(),
+                'pages'=>$pages,
+                'pageSize'=>$pageSize,
+                'resultList'=>$resultList,
+            ];
+        }
+
+        return $return;
+    }
+
+
+
+}

+ 47 - 0
common/controllers/UController.php

@@ -0,0 +1,47 @@
+<?php
+namespace app\common\controllers;
+use app\common\components\SiteUrl;
+use Yii;
+
+/**
+ * 用户中心基类
+ */
+class UController extends FController
+{
+
+    public $layout = 'uc';
+    public $tableConfig;//列表页配置
+    public $tableTitle;//列表页表头
+    public $topLeftTableMenu;
+    public $topRightTableMenu;
+    public $operTableMenu;
+    public $assetsUrl;
+    public function behaviors()
+    {
+        parent::behaviors();
+        return [
+            [
+                'class' => 'app\common\filters\FrontEndAuthFilter',
+                'except' => ['login','register','forgetpwd','vip']
+            ],
+            [
+                'class' => 'app\common\filters\FrontEndLoginedFilter',
+                'only' => ['login','register']
+            ],
+            [
+                'class' => 'app\common\filters\FrontEndTokenFilter',
+                'except' => ['login','register','forgetpwd']
+            ],
+        ];
+    }
+
+    public function init()
+    {
+        parent::init();
+        $this->navList = $this->getNavData(3);
+        $this->breadcrumbs[] =  ['label' => '用户中心','url' =>SiteUrl::ucenter()];
+        $asset = \app\assets\PcAsset::register(Yii::$app->getView());
+        $this->assetsUrl = $asset->baseUrl;
+    }
+
+}

+ 112 - 0
common/data/model.sql

@@ -0,0 +1,112 @@
+CREATE TABLE `$basic_table` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `cat_id` int(10) unsigned NOT NULL default '0',
+  `parent_cat_id` int(10) unsigned NOT NULL default '0',
+  `root_cat_id` int(10) unsigned NOT NULL default '0',
+  `type_id` int(10) unsigned NOT NULL default '0',
+  `title` char(255) NOT NULL default '',
+  `thumb` varchar(500) NOT NULL default '',
+  `keywords` varchar(500) NOT NULL default '',
+  `description` varchar(500) NOT NULL default '',
+  `is_link` tinyint(1) unsigned NOT NULL default '0',
+  `url` varchar(500) NOT NULL default '',
+  `status` tinyint(1) unsigned NOT NULL default '1',
+  `is_new` tinyint(1) unsigned NOT NULL default '1',
+  `is_hot` tinyint(1) unsigned NOT NULL default '1',
+  `is_recommend` tinyint(1) unsigned NOT NULL default '1',
+  `sys_add` tinyint(1) unsigned NOT NULL default '0',
+  `is_position` tinyint(1) unsigned NOT NULL default '0',
+  `md5` char(32) NOT NULL default '',
+  `theme` char(50) NOT NULL default '',
+  `cat_ids` char(255) NOT NULL default '',
+  `user_name` char(50) NOT NULL,
+  `user_id` int(10)  NOT NULL default '0',
+  `views` int(10) unsigned NOT NULL default '0',
+  `favors` int(10) unsigned NOT NULL default '0',
+  `digs` int(10) unsigned NOT NULL default '0',
+  `list_order` int(10) unsigned NOT NULL default '0',
+  `create_time` bigint(20)  NOT NULL default '0',
+  `update_time` bigint(20)  NOT NULL default '0',
+  PRIMARY KEY  (`id`),
+  KEY `status` (`status`),
+  KEY `list_order` (`list_order`),
+  KEY `md5` (`md5`),
+  KEY `cat_id` (`cat_id`),
+  KEY `cat_ids` (`cat_ids`)
+) ENGINE=MyISAM;
+
+CREATE TABLE `$table_data` (
+  `id` int(10) unsigned NOT NULL,
+  `content` text NOT NULL,
+  `read_price` decimal(12,2) unsigned NOT NULL default '0',
+  `pay_type` tinyint(1) unsigned NOT NULL default '0',
+  `group_ids_view` varchar(500) NOT NULL default '',
+  `pagination_type` tinyint(1) DEFAULT NULL,                 
+  `maxchar_perpage` mediumint(6) DEFAULT NULL, 
+  `template` varchar(100) NOT NULL default '',
+  `allow_comment` tinyint(1) unsigned NOT NULL default '1',
+  `relation` varchar(1000) NOT NULL default '',
+  PRIMARY KEY  (`id`),
+  KEY `id` (`id`)
+) ENGINE=MyISAM;
+
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id,  'cat_id', '栏目', '', '', 1, 10, '/^[0-9]{1,10}$/', '请选择栏目', 'cat_id', 'array (\n  ''default_value'' => '''',\n)', '', '-99', '-99', 0, 1, 0, 1, 1, 1, 0, 0, 0, 1,  0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`,  `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'type_id', '类别', '', '', 1, 10, '', '', 'type_id', '', '', '', '', 0, 1, 0, 1, 1, 1, 0, 0, 0, 2, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`,  `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'title', '标题', '', 'input_title', 1, 255, '', '请输入标题', 'title', '', '', '', '', 0, 1, 0, 1, 1, 1, 1, 1, 0, 3, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position` , `is_omnipotent`,  `list_order`, `disabled`) VALUES($model_id, 'keywords', '关键词', '多个关键词“,”隔开', '', 0, 500, '', '', 'keywords', '', '', '-99', '-99', 0, 1, 0, 1, 1, 1, 1, 0, 0, 4, 0);
+
+
+INSERT INTO `$table_model_field` (`model_id`,  `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`,  `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'description', '摘要', '', '', 0, 500, '', '', 'textarea', 'array (\r\n  ''width'' => ''100'',\r\n  ''height'' => ''46'',\r\n  ''default_value'' => '''',\r\n  ''enable_html'' => ''0'',\r\n)', '', '', '', 0, 1, 0, 1, 0, 1, 1, 1,  0, 5, 0);
+
+
+INSERT INTO `$table_model_field` (`model_id`,  `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'content', '内容', '', '', 0, 999999, '', '内容不能为空', 'editor', 'array (\n  ''tool_bar'' => ''basic'',\n ''height'' => ''300'',\n)', '', '', '', 0, 0, 0, 1, 0, 1, 1, 0,  0, 6, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'thumb', '封面图', '', '', 0, 500, '', '', 'image', 'array (\n  ''front_form_type'' => ''5'',\n ''back_form_type'' => ''5'',\n)', '', '', '', 0, 1, 0, 0, 0, 1, 0, 1,  0, 7, 0);
+
+INSERT INTO `$table_model_field` (`model_id`,  `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'relation', '相关文章', '', '', 0, 1000, '', '', 'omnipotent', 'array (\n  "form_text" => "<input type=''hidden'' name=''info[relation]'' id=''relation'' value=''{FIELD_VALUE}'' style=''50'' >\r\n<ul class=''list-dot'' id=''relation_text''></ul>\r\n<div>\r\n<input type=''button'' value=''添加相关'' onclick=omnipotent(''select_id'',''?r=ajax/publicrelationlist&model_id={MODEL_ID}'',''添加相关文章'',1) class=''btn'' style=''''>\r\n<span class=''edit_content''>\r\n<input class=''btn'' value=''显示已有'' onclick=''show_relation({MODEL_ID},{ID})'' type=''button'' style=''''>\r\n</span>\r\n</div>",\n  ''field_type'' => ''varchar'',\n ''min_number'' => ''1'',\n)', '', '', '', 0, 0, 0, 0, 0, 0, 1, 0,  0, 8, 0);
+
+INSERT INTO `$table_model_field` (`model_id`,  `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'pages', '分页方式', '', '', 0, 1, '', '', 'pages', '', '', '-99', '-99', 0, 0, 0, 1, 0, 0, 0, 0,  0, 9, 0);
+
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'is_position', '推荐位', '', '', 0, 1, '', '', 'pos_id', '', '', '', '', 0, 1, 0, 1, 0, 0, 0, 0,  0, 10, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id,'group_ids_view', '阅读权限', '', '', 0, 500, '', '', 'group_id', '', '', '', '', 0, 0, 0, 1, 0, 0, 0, 0,  0, 11, 0);
+
+INSERT INTO `$table_model_field` (`model_id`,  `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'template', '内容页模板', '', '', 0, 100, '', '', 'template','', '', '-99', '-99', 0, 0, 0, 0, 0, 0, 0, 0, 0, 13,  0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id,'read_price', '阅读收费', '', '', 0, 15, '', '', 'read_price','', '', '-99', '-99', 0, 0, 0, 0, 0, 0, 0, 0,  0, 14,0);
+
+INSERT INTO `$table_model_field` (`model_id`,  `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id,'pay_type', '购买方式', '', '', 0, 1, '', '', 'box', 'array (\n  "options"  =>  "现金|1\r\n金币|2\r\n积分|3" ,\n   "box_type" => "radio",\n  "field_type" => "tinyint",\n  "min_number" => "1",\n  "width" => "88",\n  "size" => "1",\n  "default_value"  =>  "1" ,\n   "output_type"  =>  "0" ,\n)', '', '', '', 0, 0, 0, 0, 0, 0, 0, 0,  0, 15, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id,'allow_comment', '允许评论', '', '', 0, 1, '', '', 'box', 'array (\n  "options"  =>  "允许评论|1\r\n不允许评论|0" ,\n   "box_type" => "radio",\n  "field_type" => "tinyint",\n  "min_number" => "1",\n  "width" => "88",\n  "size" => "1",\n  "default_value"  =>  "1" ,\n   "output_type"  =>  "0" ,\n)', '', '', '', 0, 0, 0, 0, 0, 0, 0, 0,  0, 16, 0);
+
+INSERT INTO `$table_model_field` (`model_id`,  `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'is_link', '转向链接', '', '', 0, 1, '', '', 'is_link', '', '', '', '', 0, 1, 0, 0, 0, 1, 0, 0, 0, 17, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'url', 'URL', '', '', 0, 500, '', '', 'text', '', '', '', '', 1, 1, 0, 1, 0, 0, 0, 0, 0, 12, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id,'user_name', '发布人', '', '', 0, 50, '', '', 'text', '', '', '', '', 1, 1, 0, 1, 0, 0, 0, 0, 0,  91, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'create_time', '发布时间', '', '', 0, 20, '', '', 'datetime', 'array (\n  ''save_format'' => ''int'',\n ''show_format'' => ''Y-m-d H:i:s'',\r\n ''read_only'' => ''0'',\n)', '', '', '', 0, 1, 0, 0, 0, 0, 0, 1,  0, 92, 0);
+
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'update_time', '更新时间', '', '', 0, 20, '', '', 'datetime',  'array (\n  ''save_format'' => ''int'',\n ''show_format'' => ''Y-m-d H:i:s'',\r\n ''read_only'' => ''0'',\n)', '', '', '', 1, 1, 0, 1, 0, 0, 0, 0, 0, 93, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'status', '状态', '', '', 0, 2, '', '', 'box', 'array (\n "options" =>"发布|1\r\n草稿|0",\n "box_type" =>"radio",\n "field_type" => "int",\n "output_type" =>"1",\n)', '', '', '', 0, 1, 0, 1, 0, 0, 0, 0, 0,  94, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'is_new', '最新', '', '', 0, 1, '', '', 'box', 'array (\n "options" =>"是|1\r\n否|0",\n "box_type" =>"radio",\n "field_type" => "int",\n "output_type" =>"1",\n)', '', '', '', 0, 1, 0, 1, 0, 0, 0, 0, 0,  95, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'is_hot', '热门', '', '', 0, 1, '', '', 'box', 'array (\n "options" =>"是|1\r\n否|0",\n "box_type" =>"radio",\n "field_type" => "int",\n "output_type" =>"1",\n)', '', '', '', 0, 1, 0, 1, 0, 0, 0, 0, 0,  96, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'is_recommend', '推荐', '', '', 0, 1, '', '', 'box', 'array (\n "options" =>"是|1\r\n否|0",\n "box_type" =>"radio",\n "field_type" => "int",\n "output_type" =>"1",\n)', '', '', '', 0, 1, 0, 1, 0, 0, 0, 0, 0,  97, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'views', '浏览次数', '', '', 0, 10, '', '', 'number', '', '', '', '', 0, 1, 0, 1, 0, 0, 0, 0,  0, 98, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'favors', '收藏次数', '', '', 0, 10, '', '', 'number', '', '', '', '', 0, 1, 0, 1, 0, 0, 0, 0,  0, 99, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'digs', '点赞次数', '', '', 0, 10, '', '', 'number', '', '', '', '', 0, 1, 0, 1, 0, 0, 0, 0,  0, 100, 0);
+
+INSERT INTO `$table_model_field` (`model_id`, `field`, `name`, `tips`, `css`, `min_length`, `max_length`, `pattern`, `error_tips`, `form_type`, `setting`, `form_attribute`, `unset_group_ids`, `unset_role_ids`, `is_core`, `is_system`, `is_unique`, `is_base`, `is_search`, `is_add`, `is_fullsearch`, `is_position`, `is_omnipotent`, `list_order`, `disabled`) VALUES($model_id, 'list_order', '排序', '', '', 0, 10, '', '', 'number', '', '', '', '', 0, 1, 0, 1, 0, 0, 0, 0,  0, 200, 0);

+ 36 - 0
common/filters/BackEndAuthFilter.php

@@ -0,0 +1,36 @@
+<?php
+namespace app\common\filters;
+use Yii;
+use yii\base\ActionFilter;
+class BackEndAuthFilter extends ActionFilter
+{
+    public function beforeAction($action)
+    {
+        //未登录或COOKIE认证失败
+        $identityInfo = Yii::$app->controller->getIdentityInfo();
+
+        if($identityInfo=='token'){
+            Yii::$app->controller->showMessage(array('class'=>'warning','message'=>Yii::t('admin','please login backend system'),'url'=>'','time'=>300000));
+            return false;
+        }
+
+        if(!empty($identityInfo)&&is_array($identityInfo))
+        {
+
+            if(sys_auth($identityInfo['cookieHash'],'DECODE')!=$identityInfo['user_name'])
+            {
+                Yii::$app->controller->showMessage(array('class'=>'warning','message'=>Yii::t('admin','please login backend system'),'url'=>Yii::$app->controller->createRealUrl('admin/default/login'),'time'=>3000));
+                return false;
+            }
+        }
+        else
+        {
+            Yii::$app->controller->showMessage(array('class'=>'warning','message'=>Yii::t('admin','please login backend system'),'url'=>Yii::$app->controller->createRealUrl('admin/default/login'),'time'=>3000));
+            return false;
+
+        }
+        return true;
+    }
+
+
+}

+ 50 - 0
common/filters/BackEndResourceFilter.php

@@ -0,0 +1,50 @@
+<?php
+namespace app\common\filters;
+use Yii;
+use yii\base\ActionFilter;
+use app\modules\admin\models\Resource;
+class BackEndResourceFilter extends ActionFilter
+{
+
+    public function beforeAction($action)
+    {
+
+        $uniqueid = $action->controller->action->uniqueid;
+        if($uniqueid=='admin/default/index')return true;//每个人都有打开首页的权限
+        //未登录或COOKIE认证失败
+        $identityInfo = Yii::$app->controller->getIdentityInfo();
+        $role_id = $identityInfo['role_id'];
+        $module =  Yii::$app->controller->moduleName;
+        $controller = Yii::$app->controller->controllerName;
+        $actionName = Yii::$app->controller->actionName;
+        $resource = Resource::find()->where('module = :module and controller=:controller and action=:action', [':module' => $module,':controller' => $controller,':action' => $actionName])->one();
+        if($role_id==1)
+        {
+            return true;
+        }
+        else
+        {
+
+            $resultList = Resource::findBySql('SELECT hash FROM {{%resource}} where hash in(select hash from {{%role_resource}} where role_id='.$role_id.')')->orderBy(['role_resource_id' => SORT_ASC])->asArray()->all();
+            foreach($resultList as $k=>$v)
+            {
+                $resourceHashList[] = $v['hash'];
+            }
+            if(in_array($resource->hash,$resourceHashList))
+            {
+
+                return true;
+            }
+            else
+            {
+                Yii::$app->controller->showMessage(array('class'=>'danger','message'=>Yii::t('admin','you do not have rights to this resource'),'url'=>Yii::$app->controller->createRealUrl('admin/default/logout'),'time'=>2000));
+                return  false;
+            }
+        }
+
+
+
+    }
+
+
+}

+ 41 - 0
common/filters/FrontEndAuthFilter.php

@@ -0,0 +1,41 @@
+<?php
+namespace app\common\filters;
+use Yii;
+use yii\base\ActionFilter;
+class FrontEndAuthFilter extends ActionFilter
+{
+    public function beforeAction($action)
+    {
+
+        //未登录或COOKIE认证失败
+        $identityInfo = Yii::$app->controller->getIdentityInfo();
+        if(defined('IN_WAP')&&IN_WAP==TRUE)
+        {
+            $loginUrl = \app\common\components\SiteUrl::loginhome();
+        }
+        else
+        {
+            $loginUrl = \app\common\components\SiteUrl::login();
+        }
+
+        if(!empty($identityInfo)&&is_array($identityInfo))
+        {
+
+            if(sys_auth($identityInfo['cookieHash'],'DECODE')!=$identityInfo['user_name'])
+            {
+                Yii::$app->controller->showMessage(array('class'=>'warning','message'=>'您还没有登录,请先登录!','url'=>$loginUrl,'time'=>0));
+                return false;
+            }
+        }
+        else
+        {
+            Yii::$app->controller->showMessage(array('class'=>'warning','message'=>'您还没有登录,请先登录!','url'=>$loginUrl,'time'=>0));
+            return false;
+
+        }
+        return true;
+
+    }
+
+
+}

+ 22 - 0
common/filters/FrontEndLoginedFilter.php

@@ -0,0 +1,22 @@
+<?php
+namespace app\common\filters;
+use Yii;
+use yii\base\ActionFilter;
+class FrontEndLoginedFilter extends ActionFilter
+{
+    public function beforeAction($action)
+    {
+        $identityInfo = Yii::$app->controller->getIdentityInfo();
+        if(!empty($identityInfo)&&is_array($identityInfo))
+        {
+            if(sys_auth($identityInfo['cookieHash'],'DECODE')==$identityInfo['user_name'])
+            {
+                Yii::$app->controller->showMessage(array('class'=>'info','message'=>'您已经登录,不用重新登录!','url'=>\app\common\components\SiteUrl::home(),'time'=>3000));
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+}

+ 50 - 0
common/filters/FrontEndTokenFilter.php

@@ -0,0 +1,50 @@
+<?php
+namespace app\common\filters;
+use app\common\helpers\Identify;
+use Yii;
+use yii\base\ActionFilter;
+//刷新token
+class FrontEndTokenFilter extends ActionFilter
+{
+
+    public function beforeAction($action)
+    {
+
+        if(!Identify::hasLogined())return true;
+        $token = \app\common\helpers\Cookie::getCookie(Yii::$app->params['access_token_name']);
+        if(!empty($token))
+        {
+            $tokenModel = \app\modules\ucenter\models\UserToken::find()->where('token = :token and request_from=:request_from', [':token' => $token,':request_from' => REQUEST_FROM])->orderBy(['create_time'=>SORT_DESC])->one();
+            if($tokenModel)
+            {
+                $user = \app\modules\ucenter\models\User::find()->where("user_id=".$tokenModel->user_id)->one();
+            }
+
+        }
+        else
+        {
+
+            $user = \app\modules\ucenter\models\User::find()->where("user_id=".Identify::getUserInfo(null,'user_id'))->one();
+        }
+        if($user&&$user->refreshAccessToken($user,REQUEST_FROM))
+        {
+            $newTokenModel = \app\modules\ucenter\models\User::getToken($user->user_id,REQUEST_FROM);
+            if($newTokenModel->token!=$token)
+            {
+                \app\common\helpers\Cookie::setCookie(Yii::$app->params['access_token_name'],$newTokenModel->token);
+            }
+            return true;
+        }
+        else
+        {
+            //如果刷新失败,说明是多端登录,清除COOKIE
+            Identify::logout();
+            \app\common\helpers\Cookie::deleteCookie(Yii::$app->params['access_token_name']);
+            header("Location:".get_url());
+            return false;
+        }
+
+    }
+
+
+}

+ 1514 - 0
common/functions/cus.php

@@ -0,0 +1,1514 @@
+<?php
+
+//搜索参数编码转换
+function search_data($str) {
+    if (CHARSET=='utf-8') return $str;
+    if (CHARSET=='gbk') return iconv("gb2312","utf-8",$str);
+}
+
+
+//ajax请求时候的编码转换
+function ajax_data($str) {
+    if (CHARSET=='utf-8') return $str;
+    if (CHARSET=='gbk') return iconv("utf-8","gb2312",$str);
+}
+
+
+//检查模型是否存在,不存在抛出404错误
+function check_record_exists($model)
+{
+    if(empty($model))
+    {
+        if (Yii::$app->request->isAjax) {
+            $msgdata = ['error' => 1,'msg' => Yii::t('admin','the record does not exist')];
+            echo_json($msgdata);
+        }
+        else
+        {
+            throw new \Exception(Yii::t('admin','the record does not exist'),404);
+        }
+    }
+    else
+    {
+        return true;
+    }
+
+}
+
+//判断文档是否被删除
+function check_record_delete($model)
+{
+    if($model->is_delete)
+    {
+        if (Yii::$app->request->isAjax) {
+            $msgdata = ['error' => 1,'msg' => Yii::t('admin','the record does not exist')];
+            echo_json($msgdata);
+        }
+        else
+        {
+            throw new \Exception(Yii::t('admin','the record does not exist'),404);
+        }
+    }
+    else
+    {
+        return true;
+    }
+
+}
+
+//判断文档是否包含敏感词
+function check_record_badwords($model)
+{
+    //过滤时段设置
+    $filter = true;
+    $hournow = get_date(TIMESTAMP,'H');
+    if(Yii::$app->controller->module->badwordconfig['hours'])
+    {
+        $hours = explode(",",Yii::$app->controller->module->badwordconfig['hours']);
+        if(!in_array($hournow,$hours))
+        {
+            $filter = false;
+        }
+
+    }
+
+    if($filter==true)
+    {
+        $badwords = getRecordBadWords();
+        //设定过滤条件(爬虫过滤)
+        if(isSpider()&&Yii::$app->controller->module->badwordconfig['open_spider'])
+        {
+            if(is_array($badwords))foreach($badwords as $badword)
+            {
+                if(strpos($model->title,$badword)!==false||strpos($model->description,$badword)!==false)
+                {
+                    if (Yii::$app->request->isAjax) {
+                        $msgdata = ['error' => 1,'msg' => Yii::t('admin','the record does not exist')];
+                        echo_json($msgdata);
+                    }
+                    else
+                    {
+                        throw new \Exception(Yii::t('admin','the record does not exist'),404);
+                    }
+                }
+            }
+        }
+
+        //设定过滤条件(手机站)
+        if(!isSpider()&&defined('IN_WAP')&&IN_WAP==TRUE&&Yii::$app->controller->module->badwordconfig['open_wap'])
+        {
+            if(is_array($badwords))foreach($badwords as $badword)
+            {
+                if(strpos($model->title,$badword)!==false||strpos($model->description,$badword)!==false)
+                {
+                    if (Yii::$app->request->isAjax) {
+                        $msgdata = ['error' => 1,'msg' => Yii::t('admin','the record does not exist')];
+                        echo_json($msgdata);
+                    }
+                    else
+                    {
+                        throw new \Exception(Yii::t('admin','the record does not exist'),404);
+                    }
+                }
+            }
+        }
+
+        //设定过滤条件(PC站)
+        if(!isSpider()&&defined('REQUEST_FROM')&&REQUEST_FROM==1&&Yii::$app->controller->module->badwordconfig['open_pc'])
+        {
+            if(is_array($badwords))foreach($badwords as $badword)
+            {
+                if(strpos($model->title,$badword)!==false||strpos($model->description,$badword)!==false)
+                {
+                    if (Yii::$app->request->isAjax) {
+                        $msgdata = ['error' => 1,'msg' => Yii::t('admin','the record does not exist')];
+                        echo_json($msgdata);
+                    }
+                    else
+                    {
+                        throw new \Exception(Yii::t('admin','the record does not exist'),404);
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+    else
+    {
+        return true;
+    }
+
+}
+
+//列表过滤敏感词
+function check_doclist_badwords()
+{
+
+    $badwords1 = getBadWords(1);
+    if(!empty($badwords1))
+    {
+        $units[] = " is_badcom=0 ";
+    }
+
+
+    if(!\app\common\helpers\Identify::hasLogined())
+    {
+        $badwords2 = getBadWords(2);
+        if(!empty($badwords2))
+        {
+            $units[] = " is_badlogin=0 ";
+        }
+    }
+
+    if(!\app\common\helpers\Identify::hasLogined()||(\app\common\helpers\Identify::hasLogined()&&!\app\common\helpers\Identify::getUserInfo(NULL,'vip_info')))
+    {
+        $badwords3 = getBadWords(3);
+        if(!empty($badwords3))
+        {
+            $units[] = " is_badvip=0 ";
+        }
+    }
+
+    if(!empty($units))
+    {
+        $sql =  ' and '.join(' and ',$units);
+    }
+    else
+    {
+        $sql = '';
+    }
+
+
+    //过滤时段设置
+    $filter = true;
+    $hournow = get_date(TIMESTAMP,'H');
+    if(Yii::$app->controller->module->badwordconfig['hours'])
+    {
+        $hours = explode(",",Yii::$app->controller->module->badwordconfig['hours']);
+        if(!in_array($hournow,$hours))
+        {
+            $filter = false;
+        }
+
+    }
+
+
+    if($filter==true)
+    {
+
+        //设定过滤条件(爬虫过滤)
+        if(isSpider()&&Yii::$app->controller->module->badwordconfig['open_spider'])
+        {
+            return $sql;
+        }
+
+        //设定过滤条件(手机站)
+        if(!isSpider()&&defined('IN_WAP')&&IN_WAP==TRUE&&Yii::$app->controller->module->badwordconfig['open_wap'])
+        {
+            return $sql;
+        }
+
+        //设定过滤条件(PC站)
+        if(!isSpider()&&defined('REQUEST_FROM')&&REQUEST_FROM==1&&Yii::$app->controller->module->badwordconfig['open_pc'])
+        {
+            return $sql;
+        }
+
+        return '';
+    }
+    else
+    {
+        return '';
+    }
+
+}
+
+//获取OSS访问绝对URL;
+function getOssUrl()
+{
+    if(Yii::$app->params['oss']['OSS_DOMAIN'])
+    {
+        return SITE_PROTOCOL.Yii::$app->params['oss']['OSS_DOMAIN'].'/';
+    }
+    else
+    {
+        return SITE_PROTOCOL.Yii::$app->params['oss']['OSS_BUCKET'].'.'.Yii::$app->params['oss']['OSS_ENDPOINT'].'/';
+    }
+
+}
+//获取OSS内网访问绝对URL;
+function getOssInterUrl()
+{
+    return SITE_PROTOCOL.Yii::$app->params['oss']['OSS_BUCKET'].'.'.Yii::$app->params['oss']['OSS_INTERNAL_ENDPOINT'].'/';
+}
+/*
+ * $type 1:封面 2:头像
+ */
+function getThumb($filepath,$width,$height,$type=1)
+{
+    $hash = md5($filepath);
+    $img = \app\modules\admin\models\Attachment::find()->where("hash='".$hash."'")->limit(1)->one();
+    if($type==1)
+    {
+        if(empty($img)) $hash = 'noimage';
+        $flag = 'p';
+    }
+    if($type==2)
+    {
+        if(empty($img)) $hash = 'noavatar';
+        $flag = 'avt';
+    }
+    return APP_URL.$flag.'/'.$width.'/'.$height.'/'.$hash.'.jpg';
+}
+
+
+//获取系统配置单个值
+function getSysconfigValue($name,$key=null)
+{
+    $sysconfig = \app\modules\admin\models\Sysconfig::find()->where("name='".$name."'")->one();
+    if($sysconfig->type==3)
+    {
+        return $sysconfig->value;
+    }
+    else
+    {
+        if($key===null)
+        {
+            return json_decode($sysconfig->value,true);
+        }
+        else
+        {
+            if($sysconfig->type==1)
+            {
+                $result = json_decode($sysconfig->value,true);
+                return $result[$key];
+            }
+            else
+            {
+                return $key;
+            }
+
+        }
+
+    }
+
+}
+
+//获取用户模型下的默认用户组
+function getDefaultUserGroup($contentModelId)
+{
+
+    $userGroup = \app\modules\ucenter\models\UserGroup::find()->where("content_model_id='".$contentModelId."' and is_default=1")->orderBy(['group_id'=>SORT_ASC])->one();
+    return $userGroup->group_id;
+}
+
+//获取用户模型下的默认用户等级
+function getDefaultUserGroupLevel($contentModelId)
+{
+
+    $userGroup = \app\modules\ucenter\models\UserGroup::find()->where("content_model_id='".$contentModelId."' and is_default=1")->orderBy(['group_id'=>SORT_ASC])->one();
+    if($userGroup->group_id)
+    {
+        $userGroupLevel = \app\modules\ucenter\models\UserGroupLevel::find()->where("user_group_id='".$userGroup->group_id."' and is_default=1")->orderBy(['id'=>SORT_ASC])->one();
+        return $userGroupLevel->id;
+    }
+}
+
+
+/**合并搜索参数*
+ * $params 表单传递参数
+ * $initParams 初始化参数
+ * $otherParams 其他参数
+ */
+function mergeParams($query,$params,$initParams=[],$otherParams=[])
+{
+    $params = count($params)>0?array_merge($initParams,$params):$initParams;
+    if (count($params) > 0) {
+        $i=0;
+        foreach ($params as $key => $value) {
+            $value = trim($value);
+            if ($value != null) {
+                $flag = is_numeric($value)?'=':'like';
+                if($i==0){
+                    $query = $query->where(array($flag, $key, $value));
+                }else{
+                    $query = $query->andWhere(array($flag, $key, $value));
+                }
+                $i++;
+            }
+        }
+    }
+    if(count($otherParams)>0)
+    {
+        $k=0;
+        foreach($otherParams as $v)
+        {
+            if(count($initParams)==0&&count($params)==0&&$k==0)
+            {
+                $query = $query->where($v);
+            }
+            else
+            {
+                $query = $query->andWhere($v);
+            }
+            $k++;
+        }
+    }
+    return $query;
+}
+
+function getLastInsertId()
+{
+    return Yii::$app->db->getLastInsertID();
+}
+
+//CMS权限检测
+function check_rights($id, $ids = '', $s = ',') {
+    if(!$ids) return false;
+    $ids = explode($s, $ids);
+    return is_array($id) ? array_intersect($id, $ids) : in_array($id, $ids);
+}
+
+//获取用户模型附表名称
+function userDetailTable($content_model_id)
+{
+    $contentModel = \app\models\ContentModel::findOne($content_model_id);
+    $tablename = Yii::$app->db->tablePrefix.$contentModel->table_name;
+    return $tablename;
+}
+
+//通过分享码获取父级用户
+function getReferIdsByShareNo($share_no)
+{
+    $sharelogModel = \app\modules\ucenter\models\ShareLog::find()->where("share_no='".$share_no."'")->one();
+    $referer_id = intval($sharelogModel->agent_id);
+    $parentUser =  \app\modules\ucenter\models\User::findOne($sharelogModel->agent_id);
+    if(!empty($parentUser->referer_ids))
+    {
+        $referer_ids[] = $parentUser->user_id;
+        $referer_tempids = explode(",",trim($parentUser->referer_ids,","));
+        $referer_ids = array_merge($referer_ids,$referer_tempids);
+
+    }
+    else
+    {
+        $referer_ids[] = $parentUser->user_id;
+    }
+    return ['referer_id'=>$referer_id,'referer_ids'=>",".join(",",$referer_ids).","];
+}
+
+/**
+ * @todo 敏感词过滤,返回结果
+ * @param array $list 定义敏感词一维数组
+ * @param string $string 要过滤的内容
+ * @return string $log 处理结果
+ */
+function sensitive($string){
+    $badwordList = Yii::$app->db->createCommand("select * from {{%bad_word}}")->queryAll();
+    if($badwordList)foreach($badwordList as $badword)
+    {
+        if($badword['type']==99) { $list1[] = $badword['bad_word'];$list1_all[] = $badword;}//全局替换
+        if($badword['type']==4) $list2[] = $badword['bad_word'];//禁止搜索
+        if($badword['type']==88) $list3[] = $badword['bad_word'];//禁止发布
+    }
+    $count1 = 0; //违规替换词的个数
+    $stringAfter = $string; //替换后的内容
+    if(!empty($list1))
+    {
+        $sensitiveWord1 = ''; //违规词
+        $pattern = "/".implode("|",$list1)."/i"; //定义正则表达式
+        if(preg_match_all($pattern, $string, $matches)){ //匹配到了结果
+            $patternList = $matches[0]; //匹配到的数组
+            $count1 = count($patternList);
+            $sensitiveWord1 = implode(',', $patternList); //敏感词数组转字符串
+            $replaceWords = [];
+            if($patternList)foreach($patternList as $sesword)
+            {
+                if($list1_all)foreach($list1_all as $badword)
+                {
+                    if($badword['bad_word']==$sesword)
+                    {
+                        $replaceWords[] = $badword['replace_word']?$badword['replace_word']:'*';
+                        continue;
+                    }
+
+                }
+            }
+            if(!empty($replaceWords)&&count($patternList)==count($replaceWords))
+            {
+                $replaceArray = array_combine($patternList,$replaceWords); //把匹配到的数组进行合并,替换使用
+                //$replaceArray = array_combine($patternList,array_fill(0,count($patternList),'*')); //把匹配到的数组进行合并,替换使用
+                $stringAfter = strtr($string, $replaceArray); //结果替换
+            }
+
+        }
+    }
+
+    $count2 = 0; //违规禁止搜索词的个数
+    if(!empty($list2))
+    {
+        $sensitiveWord2 = '';
+        $pattern2 = "/".implode("|",$list2)."/i";
+        if(preg_match_all($pattern2, $string, $matches)){
+            $patternList2 = $matches[0];
+            $count2 = count($patternList2);
+            $sensitiveWord2 = implode(',', $patternList2);
+        }
+    }
+
+    $count3 = 0; //违规禁止发布词的个数
+    if(!empty($list3))
+    {
+        $sensitiveWord3 = '';
+        $pattern3 = "/".implode("|",$list3)."/i";
+        if(preg_match_all($pattern3, $string, $matches)){
+            $patternList3 = $matches[0];
+            $count3 = count($patternList3);
+            $sensitiveWord3 = implode(',', $patternList3);
+        }
+    }
+
+    if($count1==0&&$count2==0&&$count3==0)
+    {
+        $result = [];
+    }
+    else
+    {
+        $result['after'] = $stringAfter;
+        if($count1) {
+            $result['log1'] = "全局替换敏感词:[ {$sensitiveWord1} ]";
+        }
+        else
+        {
+            $result['log1'] = '';
+        }
+        if($count2) {
+            $result['log2'] = "禁止搜索敏感词:[ {$sensitiveWord2} ]";
+        }
+        else
+        {
+            $result['log2'] = '';
+        }
+        if($count3) {
+            $result['log3'] = "禁止发布敏感词:[ {$sensitiveWord3} ]";
+        }
+        else
+        {
+            $result['log3'] = '';
+        }
+    }
+    return $result;
+}
+
+//通过数据库表名获得对应的模型名称
+function getModelName($table)
+{
+    $modelName = str_replace('_', ' ', $table);
+    $modelName  = ucwords($modelName);
+    $modelName = str_replace(' ', '', $modelName);
+    return $modelName;
+}
+
+//本地化存储文件到临时目录
+function locateFile($file,$folder='temp')
+{
+    $result = parse_url($file);
+    $result['path'] = str_replace('/upload/','',$result['path']);
+    $relativeFile = ltrim(str_replace('/',DIRECTORY_SEPARATOR,$result['path']),DIRECTORY_SEPARATOR);
+    $targetFile = UPLOAD_PATH.$folder.DIRECTORY_SEPARATOR.$relativeFile;
+    dir_create(dirname($targetFile));
+    if(Yii::$app->params['oss']['OPEN_OSS']==1)
+    {
+        if(!file_exists($targetFile))
+        {
+            if(Yii::$app->params['oss']['OPEN_INTERNAL'])
+            {
+                file_put_contents($targetFile,file_get_contents(str_replace(Yii::$app->params['oss']['OSS_ENDPOINT'],Yii::$app->params['oss']['OSS_INTERNAL_ENDPOINT'],$file)));
+            }
+            else
+            {
+                file_put_contents($targetFile,file_get_contents($file));
+            }
+        }
+    }
+    else
+    {
+        if(!file_exists($targetFile))
+        {
+            file_put_contents($targetFile,file_get_contents($file));
+        }
+    }
+    return $targetFile;
+}
+
+//合辑下载时候归档所有文档
+function locateColFile($col,$docList)
+{
+    $targetPath = UPLOAD_PATH.'download'.DIRECTORY_SEPARATOR.md5($col['id']).DIRECTORY_SEPARATOR;
+    dir_create($targetPath);
+    if(is_array($docList))foreach($docList as $doc)
+    {
+        $file = getFileUrl($doc['file']);
+        $targetFile = $targetPath.$doc['title'].'.'.$doc['ext'];
+        if(Yii::$app->params['oss']['OPEN_OSS']==1)
+        {
+            if(!file_exists($targetFile))
+            {
+                if(Yii::$app->params['oss']['OPEN_INTERNAL'])
+                {
+                    file_put_contents($targetFile,file_get_contents(str_replace(Yii::$app->params['oss']['OSS_ENDPOINT'],Yii::$app->params['oss']['OSS_INTERNAL_ENDPOINT'],$file)));
+                }
+                else
+                {
+                    file_put_contents($targetFile,file_get_contents($file));
+                }
+            }
+        }
+        else
+        {
+            if(!file_exists($targetFile))
+            {
+                file_put_contents($targetFile,file_get_contents($file));
+            }
+        }
+    }
+    $zipFile = dirname($targetPath).DIRECTORY_SEPARATOR.md5($col['id']).'.zip';
+    if(!file_exists($zipFile))
+    {
+        new \app\common\components\Dozip($targetPath,$zipFile);
+    }
+    return $zipFile;
+}
+
+//大文件生成下载说明
+function initBigfileTorent($bigfile,$doc,$docConfig)
+{
+    $savePath = dirname(str_replace(UPLOAD_PATH,'',$bigfile)).DIRECTORY_SEPARATOR;
+    $bigfileUrl = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$savePath).basename($bigfile);
+    $torenFile = UPLOAD_PATH.$savePath.$doc['title'].'【下载说明】.txt';
+    $torenContents = "【下载地址】".$bigfileUrl.",该地址有效期仅".$docConfig['bigfilesize_time']."小时,请尽快下载!";
+    file_put_contents($torenFile,$torenContents);
+    $torenUrl = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$savePath).basename($torenFile);
+    return $torenUrl;
+}
+
+//生成网盘资源种子文件
+function initPanfile($doc,$docConfig,$folder='download')
+{
+    $savePath = $folder.DIRECTORY_SEPARATOR.get_date(TIMESTAMP,'Ymd').DIRECTORY_SEPARATOR;
+    $targetPath = UPLOAD_PATH.$savePath;
+    dir_create($targetPath);
+    $torenFile = $targetPath.$doc['title'].'【提取说明】.txt';
+    $contents = "【提取地址】".$doc['pan_url']."\r\n";
+    if($doc['pan_pwd']) $contents .= "【提取密码】".$doc['pan_pwd']."\r\n";
+    $contents .= "该地址有效期仅".$docConfig['bigfilesize_time']."小时,请尽快下载!";
+    file_put_contents($torenFile,$contents);
+    $torenUrl = UPLOAD_URL.str_replace(DIRECTORY_SEPARATOR,'/',$savePath).basename($torenFile);
+    return $torenUrl;
+}
+
+
+
+//自动根据文档标题和摘要返回标签(通用)
+function initTags($model)
+{
+    $tags = [];
+    $tagResultList = \app\models\Tag::find()->where("disabled=0")->all();
+    if(is_array($tagResultList))foreach($tagResultList as $tagResult)
+    {
+        if(strpos($model->title,$tagResult->tag)!==false) $tags[] = $tagResult->tag;
+        if(strpos($model->description,$tagResult->tag)!==false) $tags[] = $tagResult->tag;
+    }
+    if(!empty($tags))
+    {
+        return join(",",array_unique($tags));
+    }
+    else
+    {
+        return '';
+    }
+}
+
+
+//更新标签
+function refreshTag($tags,$table_name,$data_id,$user_id)
+{
+    //清空当前记录关联标签
+    \app\models\TagData::deleteAll("table_name='".$table_name."' and data_id=".$data_id);
+    $tags = str_replace(",",",",$tags);
+    $tagList = explode(",",$tags);
+    if(is_array($tagList))foreach($tagList as $tag)
+    {
+        //更新标签库
+        $tagModel = \app\models\Tag::find()->where("tag='".$tag."'")->one();
+        if(empty($tagModel))
+        {
+            $tagModel = new \app\models\Tag();
+            $tagModel->tag = $tag;
+            $pinyin = new \app\common\components\PinYin();
+            $tagModel->pinyin = $pinyin->encode($tagModel->tag);
+            $tagModel->create_time = TIMESTAMP;
+            $tagModel->user_id = $user_id;
+            $tagModel->save();
+        }
+        //记录关联标签
+        $tagDataModel = \app\models\TagData::find()->where("tag_id='".$tagModel->id."' and table_name='".$table_name."' and data_id=".$data_id)->one();
+        if(empty($tagDataModel))
+        {
+            $tagDataModel = new \app\models\TagData();
+            $tagDataModel->tag_id = $tagModel->id;
+            $tagDataModel->table_name = $table_name;
+            $tagDataModel->data_id = $data_id;
+            $tagDataModel->user_id = $user_id;
+            $tagDataModel->create_time = TIMESTAMP;
+            $tagDataModel->save();
+        }
+        //更新标签被引用数量
+        $quote_num = \app\models\TagData::find()->where("tag_id='".$tagModel->id."'")->count();
+        $tagModel->quote_num = $quote_num;
+        $tagModel->save();
+    }
+
+}
+
+//获取周期数据
+function getTimeList($stamp=0)
+{
+    //昨天
+    $predayStart = get_date(mktime(0,0,0,date('m'),date('d')-1,date('Y')),'Y-m-d H:i:s');
+    $predayEnd = get_date(mktime(0,0,0,date('m'),date('d'),date('Y'))-1,'Y-m-d H:i:s');
+
+    //今天
+    $dayStart = get_date(mktime(0,0,0,date('m'),date('d'),date('Y')),'Y-m-d H:i:s');
+    $dayEnd = get_date(mktime(0,0,0,date('m'),date('d')+1,date('Y'))-1,'Y-m-d H:i:s');
+
+    //上周
+    $preweekStart = get_date(str_to_time('last week monday'),'Y-m-d 00:00:00');
+    $preweekEnd = get_date( str_to_time('last week sunday'),'Y-m-d 23:59:59');
+    //$preweekStart = get_date(mktime(0, 0 , 0,date("m"),date("d")-date("w")+1-7,date("Y")),"Y-m-d H:i:s");
+    //$preweekEnd = get_date(mktime(23,59,59,date("m"),date("d")-date("w")+7-7,date("Y")),"Y-m-d H:i:s");
+
+    //本周
+    $weekStart = get_date(str_to_time('this week monday'),'Y-m-d 00:00:00');
+    $weekEnd = get_date( str_to_time('this week sunday'),'Y-m-d 23:59:59');
+    //$weekStart = get_date(mktime(0, 0 , 0,date("m"),date("d")-date("w")+1,date("Y")),"Y-m-d H:i:s");
+    //$weekEnd = get_date(mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y")),"Y-m-d H:i:s");
+
+    //上月
+    $premonthStart = get_date(mktime(0, 0 , 0,date("m")-1,1,date("Y")),"Y-m-d H:i:s");
+    $premonthEnd =  get_date(mktime(23,59,59,date("m") ,0,date("Y")),"Y-m-d H:i:s");
+
+    //本月
+    $monthStart =  get_date(mktime(0, 0 , 0,date("m"),1,date("Y")),"Y-m-d H:i:s");
+    $monthEnd =  get_date(mktime(23,59,59,date("m"),date("t"),date("Y")),"Y-m-d H:i:s");
+
+    //上季度
+    $season = ceil((date('n'))/3)-1;//上季度是第几季度
+    $presesStart =  get_date(mktime(0, 0, 0,$season*3-3+1,1,date('Y')),'Y-m-d H:i:s');
+    $presesEnd =  get_date(mktime(23,59,59,$season*3,date('t',mktime(0, 0 , 0,$season*3,1,date("Y"))),date('Y')),'Y-m-d H:i:s');
+
+    //本季度
+    $season = ceil((date('n'))/3);//当月是第几季度
+    $sesStart =  get_date( mktime(0, 0, 0,$season*3-3+1,1,date('Y')),'Y-m-d H:i:s');
+    $sesEnd =  get_date( mktime(23,59,59,$season*3,date('t',mktime(0, 0 , 0,$season*3,1,date("Y"))),date('Y')),'Y-m-d H:i:s');
+
+    //去年
+    $preyearStart =  get_date(mktime(0,0,0,1,1,date("Y",time())-1),"Y-m-d H:i:s");
+    $preyearEnd =  get_date(mktime(23,59,59,12,31,date("Y",time())-1),"Y-m-d H:i:s");
+
+    //今年
+    $yearStart =  get_date(mktime(0,0,0,1,1,date("Y",time())),"Y-m-d H:i:s");
+    $yearEnd =  get_date(mktime(23,59,59,12,31,date("Y",time())),"Y-m-d H:i:s");
+
+    $stampList = array(
+        'predayStart'=>str_to_time($predayStart),
+        'predayEnd'=>str_to_time($predayEnd),
+        'dayStart'=>str_to_time($dayStart),
+        'dayEnd'=>str_to_time($dayEnd),
+        'preweekStart'=>str_to_time($preweekStart),
+        'preweekEnd'=>str_to_time($preweekEnd),
+        'weekStart'=>str_to_time($weekStart),
+        'weekEnd'=>str_to_time($weekEnd),
+        'premonthStart'=>str_to_time($premonthStart),
+        'premonthEnd'=>str_to_time($premonthEnd),
+        'monthStart'=>str_to_time($monthStart),
+        'monthEnd'=>str_to_time($monthEnd),
+        'presesStart'=>str_to_time($presesStart),
+        'presesEnd'=>str_to_time($presesEnd),
+        'sesStart'=>str_to_time($sesStart),
+        'sesEnd'=>str_to_time($sesEnd),
+        'preyearStart'=>str_to_time($preyearStart),
+        'preyearEnd'=>str_to_time($preyearEnd),
+        'yearStart'=>str_to_time($yearStart),
+        'yearEnd'=>str_to_time($yearEnd),
+    );
+    $list = array(
+        'predayStart'=>($predayStart),
+        'predayEnd'=>($predayEnd),
+        'dayStart'=>($dayStart),
+        'dayEnd'=>($dayEnd),
+        'preweekStart'=>($preweekStart),
+        'preweekEnd'=>($preweekEnd),
+        'weekStart'=>($weekStart),
+        'weekEnd'=>($weekEnd),
+        'premonthStart'=>($premonthStart),
+        'premonthEnd'=>($premonthEnd),
+        'monthStart'=>($monthStart),
+        'monthEnd'=>($monthEnd),
+        'presesStart'=>($presesStart),
+        'presesEnd'=>($presesEnd),
+        'sesStart'=>($sesStart),
+        'sesEnd'=>($sesEnd),
+        'preyearStart'=>($preyearStart),
+        'preyearEnd'=>($preyearEnd),
+        'yearStart'=>($yearStart),
+        'yearEnd'=>($yearEnd),
+    );
+
+
+
+    return $stamp==1?$stampList:$list;
+}
+
+/**
+ * 获取指定月的前N个月数据
+ * @param $number 前number个月
+ * @param $time 指定的月份2021-05
+ * @return array 结果数据 ["2021-01", "2021-02", "2021-03"]
+ */
+function  getLastAllMonthByNumber($number, $time) {
+    $months = [$time];
+    for ($i = 1; $i < $number; $i++) {
+        $beforeMonth = get_date(strtotime( $time. '-01' . " -{$i} months"),"Y-m");
+        array_unshift($months, $beforeMonth);
+    }
+    return array_reverse($months);
+}
+
+//获取当月所有日期
+function get_days( $date ,$rtype = '1')
+{
+    $tem = explode('-' , $date);    //切割日期 得到年份和月份
+    $year = $tem['0'];
+    $month = $tem['1'];
+    if( in_array($month , array( 1,3 , 5 , 7 , 8 , '01' , '03' ,'05' , '07' ,'08' , 10 , 12)))
+    {
+        // $text = $year.'年的'.$month.'月有31天';
+        $text = '31';
+    }
+    elseif( $month == 2 )
+    {
+        if ( $year%400 == 0 || ($year%4 == 0 && $year%100 !== 0) )    //判断是否是闰年
+        {
+            // $text = $year.'年的'.$month.'月有29天';
+            $text = '29';
+        }
+        else{
+            // $text = $year.'年的'.$month.'月有28天';
+            $text = '28';
+        }
+    }
+    else{
+        // $text = $year.'年的'.$month.'月有30天';
+        $text = '30';
+    }
+    if ($rtype == '2') {
+        for ($i = 1; $i <= $text ; $i ++ ) {
+            $r[] = $year."-".$month."-".$i;
+        }
+    } else {
+        $r = $text;
+    }
+    return $r;
+}
+
+/**
+ * @param int $num 要转换的阿拉伯数字
+ * @return string 转换成的字符串
+ */
+function docnumConvert($num)
+{
+    if($num<=1000000)
+    {
+        return '共<b>'.$num.'</b>份';
+    }
+    if ($num >= 100000000) {
+        $num = '共<b>'.round($num / 100000000, 1).'</b><i class="total">亿</i>份</span>';
+    } else if ($num >= 10000000) {
+        $num = '共<b>'.round($num / 10000000, 1).'</b><i class="total">千万</i>份</span>';
+    }else if ($num >= 100000) {
+        $num = '共<b>'.round($num / 10000, 1).'</b><i class="total">万</i>份</span>';
+    }
+    return $num;
+}
+
+
+//美化时长显示
+function secondTime($seconds=0){
+    $duration = '';
+    $seconds  = (int) $seconds;
+    if ($seconds <= 0) {
+        return $duration.'0秒';
+    }
+    list($day, $hour, $minute, $second) = explode(' ', gmstrftime('%j %H %M %S', $seconds));
+    $day -= 1;
+    if ($day > 0) {
+        $duration .= (int) $day.'天';
+    }
+    if ($hour > 0) {
+        $duration .= (int) $hour.'小时';
+    }
+    if ($minute > 0) {
+        $duration .= (int) $minute.'分钟';
+    }
+    if ($second > 0) {
+        $duration .= (int) $second.'秒';
+    }
+    return $duration;
+}
+
+//生成下载码
+function getDowncode($id)
+{
+
+    $code = rand(100000,999999);
+    $exist =   \app\modules\doc\models\DocDowncode::find()->where("downcode='".$code."' and doc_id=".$id)->one();
+    if(!$exist)
+    {
+        return $code;
+    }
+    else
+    {
+        return getDowncode($id);
+    }
+
+}
+
+function getMimes()
+{
+    $mimes = array(
+        'hqx'    =>    'application/mac-binhex40',
+        'cpt'    =>    'application/mac-compactpro',
+        'csv'    =>    array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'),
+        'bin'    =>    'application/macbinary',
+        'dms'    =>    'application/octet-stream',
+        'lha'    =>    'application/octet-stream',
+        'lzh'    =>    'application/octet-stream',
+        'exe'    =>    array('application/octet-stream', 'application/x-msdownload'),
+        'class'    =>    'application/octet-stream',
+        'psd'    =>    'application/x-photoshop',
+        'so'    =>    'application/octet-stream',
+        'sea'    =>    'application/octet-stream',
+        'dll'    =>    'application/octet-stream',
+        'oda'    =>    'application/oda',
+        'pdf'    =>    array('application/pdf', 'application/x-download'),
+        'ai'    =>    'application/postscript',
+        'eps'    =>    'application/postscript',
+        'ps'    =>    'application/postscript',
+        'smi'    =>    'application/smil',
+        'smil'    =>    'application/smil',
+        'mif'    =>    'application/vnd.mif',
+        'xls'    =>    array('application/excel', 'application/vnd.ms-excel', 'application/msexcel'),
+        'ppt'    =>    array('application/powerpoint', 'application/vnd.ms-powerpoint'),
+        'wbxml'    =>    'application/wbxml',
+        'wmlc'    =>    'application/wmlc',
+        'dcr'    =>    'application/x-director',
+        'dir'    =>    'application/x-director',
+        'dxr'    =>    'application/x-director',
+        'dvi'    =>    'application/x-dvi',
+        'gtar'    =>    'application/x-gtar',
+        'gz'    =>    'application/x-gzip',
+        'php'    =>    'application/x-httpd-php',
+        'php4'    =>    'application/x-httpd-php',
+        'php3'    =>    'application/x-httpd-php',
+        'phtml'    =>    'application/x-httpd-php',
+        'phps'    =>    'application/x-httpd-php-source',
+        'js'    =>    'application/x-javascript',
+        'swf'    =>    'application/x-shockwave-flash',
+        'sit'    =>    'application/x-stuffit',
+        'tar'    =>    'application/x-tar',
+        'tgz'    =>    array('application/x-tar', 'application/x-gzip-compressed'),
+        'xhtml'    =>  'application/xhtml+xml',
+        'xht'    =>    'application/xhtml+xml',
+        'zip'    =>   array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),
+        'mid'    =>    'audio/midi',
+        'midi'    =>    'audio/midi',
+        'mpga'    =>    'audio/mpeg',
+        'mp2'    =>    'audio/mpeg',
+        'mp3'    =>    array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
+        'aif'    =>    'audio/x-aiff',
+        'aiff'    =>    'audio/x-aiff',
+        'aifc'    =>    'audio/x-aiff',
+        'ram'    =>    'audio/x-pn-realaudio',
+        'rm'    =>    'audio/x-pn-realaudio',
+        'rpm'    =>    'audio/x-pn-realaudio-plugin',
+        'ra'    =>    'audio/x-realaudio',
+        'rv'    =>    'video/vnd.rn-realvideo',
+        'wav'    =>    'audio/x-wav',
+        'bmp'    =>    'image/bmp',
+        'gif'    =>    'image/gif',
+        'jpeg'    =>    array('image/jpeg', 'image/pjpeg'),
+        'jpg'    =>    array('image/jpeg', 'image/pjpeg'),
+        'jpe'    =>    array('image/jpeg', 'image/pjpeg'),
+        'png'    =>    array('image/png',  'image/x-png'),
+        'tiff'    =>    'image/tiff',
+        'tif'    =>    'image/tiff',
+        'css'    =>    'text/css',
+        'html'    =>    'text/html',
+        'htm'    =>    'text/html',
+        'shtml'    =>    'text/html',
+        'txt'    =>    'text/plain',
+        'text'    =>    'text/plain',
+        'log'    =>    array('text/plain', 'text/x-log'),
+        'rtx'    =>    'text/richtext',
+        'rtf'    =>    'text/rtf',
+        'xml'    =>    'text/xml',
+        'xsl'    =>    'text/xml',
+        'mpeg'    =>    'video/mpeg',
+        'mpg'    =>    'video/mpeg',
+        'mp4'    =>    'video/mp4',
+        'mpe'    =>    'video/mpeg',
+        'qt'    =>    'video/quicktime',
+        'mov'    =>    'video/quicktime',
+        'avi'    =>    'video/x-msvideo',
+        'movie'    =>    'video/x-sgi-movie',
+        'doc'    =>     'application/msword',
+        'docx'    =>    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+        'xlsx'    =>    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+        'word'    =>    array('application/msword', 'application/octet-stream'),
+        'xl'    =>    'application/excel',
+        'eml'    =>    'message/rfc822',
+        'json' => array('application/json', 'text/json')
+    );
+    return $mimes;
+}
+
+//获取数据库连接中的数据库名称
+function getDsnAttribute($name, $dsn)
+{
+    if (preg_match('/' . $name . '=([^;]*)/', $dsn, $match)) {
+        return $match[1];
+    } else {
+        return null;
+    }
+}
+
+//根据表名(不含前缀名)获取主键名
+function getPrikeyByTableName($table_name)
+{
+    $db = Yii::$app->getDb();
+    $dbName = getDsnAttribute('dbname', $db->dsn);
+    $sqlbuf ="SELECT cu.Column_Name FROM  INFORMATION_SCHEMA.`KEY_COLUMN_USAGE` cu
+WHERE CONSTRAINT_NAME = 'PRIMARY' AND cu.Table_Name = '".Yii::$app->db->tablePrefix.$table_name."' AND CONSTRAINT_SCHEMA='".$dbName."';";
+    $result = Yii::$app->db->createCommand($sqlbuf)->queryOne();
+    return  $result['Column_Name'];
+}
+
+//返回不同内容的详情页链接
+function getContentLink($result)
+{
+    if($result['table_name']=='doc_real')
+    {
+        $url = $result['doc_type']==2?\app\common\components\SiteUrl::colDetail($result['data_id']):\app\common\components\SiteUrl::docDetail($result['data_id']);
+
+    }
+    return $url;
+}
+
+//返回文档详情页链接
+function getDocLink($result)
+{
+    $url = $result['doc_type']==2?\app\common\components\SiteUrl::colDetail($result['id']):\app\common\components\SiteUrl::docDetail($result['id']);
+    return $url;
+}
+
+//生成分享分享单号
+function getShareNo()
+{
+
+    $share_no = getProUniOrderNo();
+    $exist = \app\modules\ucenter\models\ShareLog::find()->where("share_no='".$share_no."'")->one();
+    if(!$exist)
+    {
+        return $share_no;
+    }
+    else
+    {
+        return getShareNo();
+    }
+}
+
+//返回用户提现账户
+function getWithdrawBank($userInfo,$k=0)
+{
+    $bankTypes = [];
+    if($userInfo['alipay_name']&&$userInfo['alipay_account'])
+    {
+        $bankTypes[1] = array('title'=>'支付宝','real_name'=>$userInfo['alipay_name'],'account'=>$userInfo['alipay_account'],'desc'=>'支付宝【'.$userInfo['alipay_name'].':'.$userInfo['alipay_account'].'】');
+    }
+    if($userInfo['bank_real_name']&&$userInfo['bank_name']&&$userInfo['bank_no'])
+    {
+        $bankTypes[2] = array('title'=>$userInfo['bank_name'],'real_name'=>$userInfo['bank_real_name'],'account'=>$userInfo['bank_no'],'desc'=>$userInfo['bank_name'].'【'.$userInfo['bank_real_name'].':'.$userInfo['bank_no'].'】');
+    }
+    return $k==0?$bankTypes:$bankTypes[$k];
+}
+
+//生成海报
+function createPoster($config=array(),$filename=""){
+    //如果要看报什么错,可以先注释调这个header
+    if(empty($filename)) header("content-type: image/png");
+    $imageDefault = array(
+        'left'=>0,
+        'top'=>0,
+        'right'=>0,
+        'bottom'=>0,
+        'width'=>100,
+        'height'=>100,
+        'opacity'=>100
+    );
+    $textDefault = array(
+        'text'=>'',
+        'left'=>0,
+        'top'=>0,
+        'fontSize'=>32,       //字号
+        'fontColor'=>'255,255,255', //字体颜色
+        'angle'=>0,
+    );
+    $background = $config['background'];//海报最底层得背景
+    //背景方法
+    $backgroundInfo = getimagesize($background);
+    $backgroundFun = 'imagecreatefrom'.image_type_to_extension($backgroundInfo[2], false);
+    $background = $backgroundFun($background);
+    $backgroundWidth = imagesx($background);  //背景宽度
+    $backgroundHeight = imagesy($background);  //背景高度
+    $imageRes = imageCreatetruecolor($backgroundWidth,$backgroundHeight);
+    $bg = imagecolorallocatealpha($imageRes, 255, 255, 255, 127);
+    imagefill($imageRes, 0, 0, $bg);
+    imagecopyresampled($imageRes,$background,0,0,0,0,imagesx($background),imagesy($background),imagesx($background),imagesy($background));
+    //处理了图片
+    if(!empty($config['image'])){
+        foreach ($config['image'] as $key => $val) {
+            $val = array_merge($imageDefault,$val);
+            $info = getimagesize($val['url']);
+            $function = 'imagecreatefrom'.image_type_to_extension($info[2], false);
+            if($val['stream']){   //如果传的是字符串图像流
+                $info = getimagesizefromstring($val['url']);
+                $function = 'imagecreatefromstring';
+            }
+            $res = $function($val['url']);
+            $resWidth = $info[0];
+            $resHeight = $info[1];
+            //建立画板 ,缩放图片至指定尺寸
+            $canvas=imagecreatetruecolor($val['width'], $val['height']);
+            //imagefill($canvas, 0, 0, $color);
+            //关键函数,参数(目标资源,源,目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h)
+            imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'],$resWidth,$resHeight);
+            $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left'];
+            $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']) - $val['height']:$val['top'];
+            //放置图像
+            imagecopymerge($imageRes,$canvas, $val['left'],$val['top'],$val['right'],$val['bottom'],$val['width'],$val['height'],$val['opacity']);//左,上,右,下,宽度,高度,透明度
+        }
+    }
+
+    //处理头像
+    if(!empty($config['avatar'])){
+        foreach ($config['avatar'] as $key => $val) {
+            if(empty($val))continue;
+            $val = array_merge($imageDefault,$val);
+            list($res,$resWidth,$resHeight) = toCircleImg($val['url']);
+            $res = getNewImgSize($res,$val['width'],$val['height'],$resWidth);
+            //关键函数,参数(目标资源,源,目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h)
+            $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left'];
+            $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']) - $val['height']:$val['top'];
+            imageantialias($imageRes, true);
+            imagecopy($imageRes, $res, $val['left'], $val['top'],$val['right'],$val['bottom'], $val['width'],  $val['height']);
+        }
+    }
+
+    //处理缩略图
+    if(!empty($config['thumb'])){
+        foreach ($config['thumb'] as $key => $val) {
+            $info = getimagesize($val['url']);
+            $function = 'imagecreatefrom'.image_type_to_extension($info[2], false);
+            if($val['stream']){   //如果传的是字符串图像流
+                $info = getimagesizefromstring($val['url']);
+                $function = 'imagecreatefromstring';
+            }
+            $res = $function($val['url']);
+            $info = getimagesize($val['url']);
+            $resWidth = $info[0];
+            $resHeight = $info[1];
+            $canvas=imagecreatetruecolor($val['width'], $val['height']);
+            //imagefill($canvas, 0, 0, $color);
+            //关键函数,参数(目标资源,源,目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h)
+            imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'],$resWidth,$resHeight);
+
+            imagecopy($imageRes, $canvas, $val['left'], $val['top'],$val['right'],$val['bottom'], $val['width'], $val['height']);
+
+        }
+    }
+    //处理文字
+    if(!empty($config['text'])){
+        foreach ($config['text'] as $key => $val) {
+            if(empty($val))continue;
+            $val = array_merge($textDefault,$val);
+            list($R,$G,$B) = explode(',', $val['fontColor']);
+            $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
+            $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left'];
+            $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']):$val['top'];
+            imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,$val['fontPath'],$val['text']);
+        }
+    }
+    if(!empty($config['text1'])){
+        foreach ($config['text1'] as $key => $val) {
+            if(empty($val))continue;
+            $val = array_merge($textDefault,$val);
+            list($R,$G,$B) = explode(',', $val['fontColor']);
+            $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
+            $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left'];
+            $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']):$val['top'];
+            imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,$val['fontPath'],$val['text']);
+        }
+    }
+    if(!empty($config['nickname'])){
+        foreach ($config['nickname'] as $key => $val) {
+            if(empty($val))continue;
+            $val = array_merge($textDefault,$val);
+            list($R,$G,$B) = explode(',', $val['fontColor']);
+            $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
+            $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left'];
+            $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']):$val['top'];
+            imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,$val['fontPath'],$val['text']);
+        }
+    }
+    imagesavealpha($imageRes , true);
+    //生成图片
+    if(!empty($filename)){
+        $res = imagepng ($imageRes,$filename); //保存到本地
+        imagedestroy($imageRes);
+        if(!$res) return false;
+        return $filename;
+    }else{
+        imagepng ($imageRes);     //在浏览器上显示
+        imagedestroy($imageRes);
+    }
+}
+
+/*
+* 转换为圆形
+*/
+function toCircleImg($imgpath)
+{
+    $wh  = getimagesize($imgpath);//pathinfo()不准
+    $src_img = null;
+    switch ($wh[2]) {
+        case 1:
+            //gif
+            $src_img = imagecreatefromgif($imgpath);
+            break;
+        case 2:
+            //jpg
+            $src_img = imagecreatefromjpeg($imgpath);
+            break;
+        case 3:
+            //png
+            $src_img = imagecreatefrompng($imgpath);
+            break;
+    }
+    $w   = $wh[0];
+    $h   = $wh[1];
+    $w   = min($w, $h);
+    $h   = $w;
+    $img = imagecreatetruecolor($w, $h);
+    imageantialias($img, true);
+    //这一句一定要有
+    imagesavealpha($img, true);
+    //拾取一个完全透明的颜色,最后一个参数127为全透明
+    $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
+    imagefill($img, 0, 0, $bg);
+
+    //拾取一个完全透明的颜色,最后一个参数127为全透明
+    /*$bg=imagecolorallocate($img,255,255,255);
+    imagecolortransparent($img,$bg);
+    imagefill($img, 0, 0, $bg);*/
+    $r   = $w / 2; //圆半径
+    $y_x = $r; //圆心X坐标
+    $y_y = $r; //圆心Y坐标
+    for ($x = 0; $x < $w; $x++) {
+        for ($y = 0; $y < $h; $y++) {
+            $rgbColor = imagecolorat($src_img, $x, $y);
+            if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
+                imagesetpixel($img, $x, $y, $rgbColor);
+            }
+        }
+    }
+    return [$img,$w,$h];
+}
+
+/*
+ * 根据指定尺寸裁剪目标图片,这里统一转成132*132的
+ * 注意第一个参数,为了简便,直接传递的是图片资源,如果是绝对地址图片路径,可以加以改造
+ */
+function getNewImgSize($imgpath,$new_width,$new_height,$w)
+{
+    $image_p = imagecreatetruecolor($new_width, $new_height);//新画布
+    $bg = imagecolorallocatealpha($image_p, 255, 255, 255, 127);
+    imagefill($image_p, 0, 0, $bg);
+    imagecopyresampled($image_p, $imgpath, 0, 0, 0, 0, $new_width, $new_height, $w, $w);
+    return $image_p;
+}
+
+
+//生成分享单
+function createShareNo($table_name,$data_id,$agent_id)
+{
+    $shareLog = \app\modules\ucenter\models\ShareLog::find()->where("table_name='".$table_name."' and data_id=$data_id and agent_id=$agent_id")->one();
+    if(empty($shareLog))
+    {
+        $shareLog = new \app\modules\ucenter\models\ShareLog();
+        $shareLog->table_name = $table_name;
+        $shareLog->data_id = $data_id;
+        $shareLog->agent_id = $agent_id;
+        $shareLog->share_no = getShareNo();
+        $shareLog->create_time = TIMESTAMP;
+        $shareLog->status = 1;
+        $shareLog->save();
+    }
+    return $shareLog;
+}
+
+//获取搜索敏感词
+function getSearchBadWords()
+{
+    $badwords = [];
+    $resultList = \app\models\BadWord::find()->where("type=4")->all();
+    if(is_array($resultList))foreach($resultList as $result)
+    {
+        $badwords[] = $result->bad_word;
+    }
+    if(!\app\common\helpers\Identify::hasLogined())
+    {
+        $resultList = \app\models\BadWord::find()->where("type=5")->all();
+        if(is_array($resultList))foreach($resultList as $result)
+        {
+            $badwords[] = $result->bad_word;
+        }
+    }
+    if(!\app\common\helpers\Identify::hasLogined()||(\app\common\helpers\Identify::hasLogined()&&!\app\common\helpers\Identify::getUserInfo(NULL,'vip_info')))
+    {
+        $resultList = \app\models\BadWord::find()->where("type=6")->all();
+        if(is_array($resultList))foreach($resultList as $result)
+        {
+            $badwords[] = $result->bad_word;
+        }
+    }
+    $badwords = array_unique($badwords);
+    return $badwords;
+
+}
+
+//获取详情页显示敏感词
+function getRecordBadWords()
+{
+    $badwords = [];
+    $resultList = \app\models\BadWord::find()->where("type=1")->all();
+    if(is_array($resultList))foreach($resultList as $result)
+    {
+        $badwords[] = $result->bad_word;
+    }
+    if(!\app\common\helpers\Identify::hasLogined())
+    {
+        $resultList = \app\models\BadWord::find()->where("type=2")->all();
+        if(is_array($resultList))foreach($resultList as $result)
+        {
+            $badwords[] = $result->bad_word;
+        }
+    }
+    if(!\app\common\helpers\Identify::hasLogined()||(\app\common\helpers\Identify::hasLogined()&&!\app\common\helpers\Identify::getUserInfo(NULL,'vip_info')))
+    {
+        $resultList = \app\models\BadWord::find()->where("type=3")->all();
+        if(is_array($resultList))foreach($resultList as $result)
+        {
+            $badwords[] = $result->bad_word;
+        }
+    }
+    $badwords = array_unique($badwords);
+    return $badwords;
+
+}
+
+//获取敏感词 type:类型
+function getBadWords($type)
+{
+    $badwords = [];
+    $resultList = \app\models\BadWord::find()->where("type=$type")->all();
+    if(is_array($resultList))foreach($resultList as $result)
+    {
+        $badwords[] = $result->bad_word;
+    }
+    $badwords = array_unique($badwords);
+    return $badwords;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//给文本添加锚链接(TAG集合)
+function anchorLinks($str)
+{
+    $arr = array();
+    $keyLinks = \app\models\Tag::find()->all();
+    foreach($keyLinks as $keylink)
+    {
+        $arr[] = array(
+            'id'   => $keylink->key_link_id,
+            'name' => $keylink->word,
+            'url'  => $keylink->url,
+        );
+    }
+    $newArr = array();
+    foreach ($arr as $k=>$v) {
+        $arr[$k]['length'] = abslength($v['name']);
+    }
+    $newArr = array_sort($arr);
+    $array = array($str);
+    foreach ($newArr as $vo) {
+        $res = preg_replace('/' . $vo['name'] . '/', '|||' . $vo['id'] . '|||', $array[0], 1);
+        if($res !== null){
+            $array[0] = $res;
+        }
+    }
+    foreach ($newArr as $vo) {
+        $array[0] = str_replace('|||' . $vo['id'] . '|||', '<a href="'.$vo['url'].'" target="_blank" title="'.$vo['name'].'">' . $vo['name'] . '</a>', $array[0]);
+    }
+
+    return $array[0];
+}
+
+
+
+
+
+//上传文件到远程服务器
+function remoteUpload($url,$file,$name='file')
+{
+    //$file = UPLOAD_PATH.str_replace("/",DIRECTORY_SEPARATOR,$fileRealPath))
+    $ch = curl_init();
+    //post数据,使用@符号,curl就会认为是有文件上传
+    $curlPost = array($name=> new \CURLFile($file));
+    curl_setopt($ch, CURLOPT_URL, $url);
+    curl_setopt($ch, CURLOPT_HEADER, 0);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+    curl_setopt($ch, CURLOPT_POST, 1); //POST提交
+    curl_setopt($ch, CURLOPT_POSTFIELDS,$curlPost);
+    $data =curl_exec($ch);
+    curl_close($ch);
+    return json_decode($data,true);
+}
+
+//发送短信通知
+function sendMobileMsg($action,$array)
+{
+    extract($array);
+    require_once BASE_PATH.'vendor/alimsg/AliMsg.php';
+    $tplResult = \app\modules\admin\models\MobileMsgTpl::find()->asArray()->all();
+    if(is_array($tplResult))foreach($tplResult as $tpl)
+    {
+        $tplList[$tpl['key']] = $tpl;
+    }
+    $configInfo = \app\models\Config::find()->where("name='msg'")->limit(1)->one();
+    $config = string2array($configInfo->value);
+    $config['tpl'] = $tplList[$action]['code'];
+    $argsInfos =  explode('\r\n',$tplList[$action]['args']);
+    $args = [];
+    if(is_array($argsInfos))foreach($argsInfos as $argInfo)
+    {
+        if(empty($argInfo))continue;
+        $tmp = explode("|",$argInfo);
+        $args[$tmp[0]] = eval("return $tmp[1];");
+    }
+    $msgtitle = $tplList[$action]['name'];
+    $msgcontent = $tplList[$action]['tpl'];
+    foreach($args as $k=>$v)
+    {
+        $msgcontent = str_replace('${'.$k.'}',$v,$msgcontent);
+    }
+    Yii::$app->db->createCommand("insert into {{%mobile_msg}} set mobile='".$mobile."',title='".$msgtitle."',content='".$msgcontent."',remarks='".$msgcontent."',sent_time=".TIMESTAMP.",real_sent_time=".TIMESTAMP."")->query();
+    $alimsg = \AliMsg::getInitCls($config);
+    if($mobile)
+    {
+        return $alimsg::sendMsg($mobile,$action,$args);
+    }
+}
+
+
+
+
+
+
+//剩余时间
+function left_time_str($sale_time,$full=0){
+    $left_time = $sale_time - TIMESTAMP;
+    if($left_time <= 0){
+        return '';
+    }
+    $str = '';
+    $day = floor($left_time/86400);
+    $hour = floor(($left_time - $day * 86400)/3600);
+    $min = floor((($left_time - $day * 86400) - $hour * 3600)/60);
+    if($full)
+    {
+        if ($day > 0) $str .= $day . '天';
+        if ($hour > 0) $str .= $hour . '小时';
+        if ($min > 0) $str .= $min . '分钟';
+        return $str;
+    }
+    else
+    {
+        if ($day > 0) return $day . '天';
+        if ($hour > 0) return $hour . '小时';
+        if ($min > 0) return $min . '分钟';
+    }
+
+}
+
+//文档类型封面
+function docTypeThumb($assetsUrl,$ext)
+{
+    $agent = check_mobile()?'wap':'web';
+    if(!empty(Yii::$app->params['style']))
+    {
+        $sourcePath = Yii::$app->params['themePath'].Yii::$app->params['theme'].'/'.$agent.'/assets/'.Yii::$app->params['style'];
+
+    }
+    else
+    {
+        $sourcePath = Yii::$app->params['themePath'].Yii::$app->params['theme'].'/'.$agent.'/assets';
+    }
+    if(file_exists($sourcePath.'/images/icon/'.$ext.'.png'))
+    {
+        return  $assetsUrl.'/images/icon/'.$ext.'.png';
+    }
+    else
+    {
+        return  $assetsUrl.'/images/icon/null.png';
+    }
+
+}
+
+?>

+ 182 - 0
common/functions/dir.php

@@ -0,0 +1,182 @@
+<?php 
+/*  
+ * dirFunc.php  
+ * 目录操作函数库    
+ * 更新: Jacky.Chen 2013/10/20 16:32  
+ *  
+ */
+
+/*
+ * 转化 \ 为 /
+ * @param	string	$path	路径
+ * @return	string	路径
+ * 
+ */
+function dir_path($path) {
+	$path = str_replace('\\', '/', $path);
+	if(substr($path, -1) != '/') $path = $path.'/';
+	return $path;
+}
+/**
+* 创建目录
+* 
+* @param	string	$path	路径
+* @param	string	$mode	属性
+* @return	string	如果已经存在则返回true,否则为flase
+*/
+function dir_create($path, $mode = 0777) {
+	
+	if(is_dir($path)) return TRUE;
+	
+	$path = dir_path($path);
+	$temp = explode('/', $path);
+	$cur_dir = '';
+	$max = count($temp) - 1;
+	for($i=0; $i<$max; $i++) {
+		$cur_dir .= $temp[$i].'/';
+		if (@is_dir($cur_dir)) continue;
+		@mkdir($cur_dir, 0777,true);
+		@chmod($cur_dir, 0777);
+	}
+	return is_dir($path);
+}
+/*
+ * 拷贝目录及下面所有文件
+ * @param	string	$fromdir	原路径
+ * @param	string	$todir		目标路径
+ * @return	string	如果目标路径不存在则返回false,否则为true
+*/
+function dir_copy($fromdir, $todir) {
+	$fromdir = dir_path($fromdir);
+	$todir = dir_path($todir);
+	if (!is_dir($fromdir)) return FALSE;
+	if (!is_dir($todir)) dir_create($todir);
+	$list = glob($fromdir.'*');
+	if (!empty($list)) {
+		foreach($list as $v) {
+			$path = $todir.basename($v);
+			if(is_dir($v)) {
+				dir_copy($v, $path);
+			} else {
+				copy($v, $path);
+				@chmod($path, 0777);
+			}
+		}
+	}
+    return TRUE;
+}
+/**
+* 转换目录下面的所有文件编码格式
+* 
+* @param	string	$in_charset		原字符集
+* @param	string	$out_charset	目标字符集
+* @param	string	$dir			目录地址
+* @param	string	$fileexts		转换的文件格式
+* @return	string	如果原字符集和目标字符集相同则返回false,否则为true
+*/
+function dir_iconv($in_charset, $out_charset, $dir, $fileexts = 'php|html|htm|shtml|shtm|js|txt|xml') {
+	if($in_charset == $out_charset) return false;
+	$list = dir_list($dir);
+	foreach($list as $v) {
+		if (pathinfo($v, PATHINFO_EXTENSION) == $fileexts && is_file($v)){
+			file_put_contents($v, iconv($in_charset, $out_charset, file_get_contents($v)));
+		}
+	}
+	return true;
+}
+/**
+* 列出目录下所有文件
+* 
+* @param	string	$path		路径
+* @param	string	$exts		扩展名
+* @param	array	$list		增加的文件列表
+* @return	array	所有满足条件的文件
+*/
+function dir_list($path, $exts = '', $list= array()) {
+	$path = dir_path($path);
+	$files = glob($path.'*');
+	foreach($files as $v) {
+		if (!$exts || pathinfo($v, PATHINFO_EXTENSION) == $exts) {
+			$list[] = $v;
+			if (is_dir($v)) {
+				$list = dir_list($v, $exts, $list);
+			}
+		}
+	}
+	return $list;
+}
+/**
+* 设置目录下面的所有文件的访问和修改时间
+* 
+* @param	string	$path		路径
+* @param	int		$mtime		修改时间
+* @param	int		$atime		访问时间
+* @return	array	不是目录时返回false,否则返回 true
+*/
+function dir_touch($path, $mtime = TIMESTAMP, $atime = TIMESTAMP) {
+	if (!is_dir($path)) return false;
+	$path = dir_path($path);
+	if (!is_dir($path)) touch($path, $mtime, $atime);
+	$files = glob($path.'*');
+	foreach($files as $v) {
+		is_dir($v) ? dir_touch($v, $mtime, $atime) : touch($v, $mtime, $atime);
+	}
+	return true;
+}
+/**
+* 目录列表
+* 
+* @param	string	$dir		路径
+* @param	int		$parentid	父id
+* @param	array	$dirs		传入的目录
+* @return	array	返回目录列表
+*/
+function dir_tree($dir, $parentid = 0, $dirs = array()) {
+	global $id;
+	if ($parentid == 0) $id = 0;
+	$list = glob($dir.'*');
+	foreach($list as $v) {
+		if (is_dir($v)) {
+            $id++;
+			$dirs[$id] = array('id'=>$id,'parentid'=>$parentid, 'name'=>basename($v), 'dir'=>$v.'/');
+			$dirs = dir_tree($v.'/', $id, $dirs);
+		}
+	}
+	return $dirs;
+}
+
+function dir_child($dir) {
+    $dirArray[]=NULL;
+    if (false != ($handle = opendir ( $dir ))) {
+        $i=0;
+        while ( false !== ($file = readdir ( $handle )) ) {
+            //去掉"“.”、“..”以及带“.xxx”后缀的文件
+            if ($file != "." && $file != "..") {
+                $dirArray[$i]=$file;
+                $i++;
+            }
+        }
+        //关闭句柄
+        closedir ( $handle );
+    }
+    return $dirArray;
+}
+
+
+/**
+* 删除目录及目录下面的所有文件
+* 
+* @param	string	$dir		路径
+* @return	bool	如果成功则返回 TRUE,失败则返回 FALSE
+*/
+function dir_delete($dir) {
+	$dir = dir_path($dir);
+	if (!is_dir($dir)) return FALSE;
+	$list = glob($dir.'*');
+	foreach($list as $v) {
+		is_dir($v) ? dir_delete($v) : @unlink($v);
+	}
+    return @rmdir($dir);
+}
+
+?>

+ 1697 - 0
common/functions/global.php

@@ -0,0 +1,1697 @@
+<?php
+/*  
+ * global.php   
+ * 公共函数库    
+ * 更新: Jacky.Chen 2013/10/20 15:45  
+ */
+
+/*
+ * 返回经addslashes处理过的字符串或数组
+ * @param $string 需要处理的字符串或数组
+ * @return mixed
+ */
+function new_add_slashes($string)
+{
+	if(!is_array($string))return addslashes($string);
+	foreach($string as $key=>$val)
+	{
+		$string[$key] = new_add_slashes($val);
+	}
+	return $string;
+}
+
+/*
+ * 返回经stripslashes处理过的字符串或数组
+ * @param $string 需要处理的字符串或数组
+ * @return mixed
+ */
+function new_stripslashes($string) {
+	if(!is_array($string)) return stripslashes($string);
+	foreach($string as $key => $val) $string[$key] = new_stripslashes($val);
+	return $string;
+}
+
+/*
+ * 返回经htmlspecialchars处理过的字符串或数组
+ * @param $obj 需要处理的字符串或数组
+ * @return mixed
+ */
+function new_htmlspecialchars($string) {
+	if(!is_array($string)) return htmlspecialchars($string);
+	foreach($string as $key => $val) $string[$key] = new_htmlspecialchars($val);
+	return $string;
+}
+
+//filterkeys 指定了排除在外的键值
+function safe_replace_array($array,$filterKeys=array())
+{
+    foreach($array as $k=>$v)
+    {
+        if(!in_array($k,$filterKeys)) $array[$k] = safe_replace($v);
+    }
+    return $array;
+}
+
+/*
+* 安全过滤函数
+* @parame $string
+* @return string
+*/
+function safe_replace($string)
+{
+	$string = str_replace('%20','',$string);
+	$string = str_replace('%27','',$string);
+	$string = str_replace('%2527','',$string);
+	$string = str_replace('*','',$string);
+	$string = str_replace('"','&quot;',$string);
+	$string = str_replace("'",'',$string);
+	$string = str_replace('"','',$string);
+	$string = str_replace(';','',$string);
+	$string = str_replace('>','&gt;',$string);
+	$string = str_replace('<','&lt;',$string);
+	$string = str_replace('{','',$string);
+	$string = str_replace('}','',$string);
+	$string = str_replace('\\','',$string);
+	return $string;
+}
+
+/**
+ * xss过滤函数
+ *
+ * @param $string
+ * @return string
+ */
+function remove_xss($string) {
+	$string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $string);
+
+	$parm1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
+
+	$parm2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
+
+	$parm = array_merge($parm1, $parm2);
+
+	for ($i = 0; $i < sizeof($parm); $i++) {
+		$pattern = '/';
+		for ($j = 0; $j < strlen($parm[$i]); $j++) {
+			if ($j > 0) {
+				$pattern .= '(';
+				$pattern .= '(&#[x|X]0([9][a][b]);?)?';
+				$pattern .= '|(&#0([9][10][13]);?)?';
+				$pattern .= ')?';
+			}
+			$pattern .= $parm[$i][$j];
+		}
+		$pattern .= '/i';
+		$string = preg_replace($pattern, '', $string);
+	}
+	return $string;
+}
+
+/**
+ * 转义 javascript 代码标记
+ *
+ * @param $str
+ * @return mixed
+ */
+function trim_script($str) {
+	if(is_array($str)){
+		foreach ($str as $key => $val){
+			$str[$key] = trim_script($val);
+		}
+	}else{
+		$str = preg_replace ( '/\<([\/]?)script([^\>]*?)\>/si', '&lt;\\1script\\2&gt;', $str );
+		$str = preg_replace ( '/\<([\/]?)iframe([^\>]*?)\>/si', '&lt;\\1iframe\\2&gt;', $str );
+		$str = preg_replace ( '/\<([\/]?)frame([^\>]*?)\>/si', '&lt;\\1frame\\2&gt;', $str );
+		$str = str_replace ( 'javascript:', 'javascript:', $str );
+	}
+	return $str;
+}
+
+
+/*
+ * 过滤ASCII码从0-28的控制字符
+ * @return String
+ */
+function trim_unsafe_control_chars($str) {
+	$rule = '/[' . chr ( 1 ) . '-' . chr ( 8 ) . chr ( 11 ) . '-' . chr ( 12 ) . chr ( 14 ) . '-' . chr ( 31 ) . ']*/';
+	return str_replace ( chr ( 0 ), '', preg_replace ( $rule, '', $str ) );
+}
+
+/*
+ * 格式化文本域内容
+ *
+ * @param $string 文本域内容
+ * @return string
+ */
+function trim_textarea($string) {
+	$string = nl2br ( str_replace ( ' ', '&nbsp;', $string ) );
+	return $string;
+}
+
+/**
+ * 安全过滤表单输入
+ *
+ * @param $string
+ * @return string
+ */
+function safe_filter_input($string) {
+	if(!is_array($string)) {
+		$string = trim($string);
+		$string = stripslashes($string);
+		$string = htmlspecialchars($string);
+		return $string;
+	}
+	foreach($string as $key => $val) {
+		$val = trim($val);
+		$val = stripslashes($val);
+		$val = htmlspecialchars($val);
+		$string[$key] = $val;
+	}
+	return $string;
+}
+
+
+/*
+ * 将文本格式成适合js输出的字符串
+ * @param string $string 需要处理的字符串
+ * @param intval $isjs 是否执行字符串格式化,默认为执行
+ * @return string 处理后的字符串
+ */
+function format_js($string, $isjs = 1) {
+	$string = addslashes(str_replace(array("\r", "\n", "\t"), array('', '', ''), $string));
+	return $isjs ? 'document.write("'.$string.'");' : $string;
+}
+/*
+ * 获取当前页面完整URL地址
+ */
+function get_url() {
+	$sys_protocal = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://';
+	$php_self = $_SERVER['PHP_SELF'] ? safe_replace($_SERVER['PHP_SELF']) : safe_replace($_SERVER['SCRIPT_NAME']);
+	$path_info = isset($_SERVER['PATH_INFO']) ? safe_replace($_SERVER['PATH_INFO']) : '';
+	$relate_url = isset($_SERVER['REQUEST_URI']) ? safe_replace($_SERVER['REQUEST_URI']) : $php_self.(isset($_SERVER['QUERY_STRING']) ? '?'.safe_replace($_SERVER['QUERY_STRING']) : $path_info);
+	return $sys_protocal.(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '').$relate_url;
+}
+
+
+/**
+ * 字符串截取,支持中英文
+ * @param $str
+ * @param int $start
+ * @param $length
+ * @param string $charset
+ * @param bool $suffix
+ * @return false|string
+ * @author 肆月
+ */
+function str_cut($str, $start = 0, $length,  $dot = '...')
+{
+    $charset = CHARSET;
+    if (function_exists("mb_substr")) {
+        if ($dot) {
+            if (strlen($str) > $length)
+                return mb_substr($str, $start, $length, $charset) . $dot;
+            else
+                return mb_substr($str, $start, $length, $charset);
+        } else {
+            return mb_substr($str, $start, $length, $charset);
+        }
+    } elseif (function_exists('iconv_substr')) {
+        if ($dot) {
+            if (strlen($str) > $length)
+                return iconv_substr($str, $start, $length, $charset). $dot;
+            else
+                return iconv_substr($str, $start, $length, $charset);
+        } else {
+            return iconv_substr($str, $start, $length, $charset);
+        }
+    }
+}
+
+//隐藏用户名中间字符仅保留头尾
+function hide_user_name($user_name,  $repeatStr = '*', $encode = 'utf-8')
+{
+    if (empty($user_name)) {
+        return '***';
+    }
+    $length = mb_strlen($user_name, $encode);
+    $firstStr = mb_substr($user_name, 0, 1, $encode);
+    $lastStr = mb_substr($user_name, -1, 1, $encode);
+    if($length ==1){
+        return $user_name;
+    }
+    return $length == 2 ? $firstStr . str_repeat($repeatStr, $length - 1) : $firstStr . str_repeat($repeatStr, $length - 2) . $lastStr;
+}
+
+/*
+ * 获取请求ip
+ * @return ip地址(整数形式)
+ */
+function ip() {
+	if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
+		$ip = getenv('HTTP_CLIENT_IP');
+	} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
+		$ip = getenv('HTTP_X_FORWARDED_FOR');
+	} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
+		$ip = getenv('REMOTE_ADDR');
+	} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
+		$ip = $_SERVER['REMOTE_ADDR'];
+	}
+	return preg_match ( '/[\d\.]{7,23}/', $ip, $matches ) ? ip2long($matches [0]) : 0;
+}
+
+/*
+ * 程序执行时间
+ * @return	int	单位ms
+ * 
+ */
+function execute_time() {
+	$stime = explode ( ' ', SYS_START_TIME );
+	$etime = explode ( ' ', microtime () );
+	return number_format ( ($etime [1] + $etime [0] - $stime [1] - $stime [0]), 6 );
+}
+
+/*
+ * 产生随机字符串
+ * @param    int        $length  输出长度
+ * @param    string     $chars   可选的 ,默认为 0123456789
+ * @return   string     字符串
+ * 
+ */
+function random($length, $chars = '0123456789') {
+	$hash = '';
+	$max = strlen($chars) - 1;
+	for($i = 0; $i < $length; $i++) {
+		$hash .= $chars[mt_rand(0, $max)];
+	}
+	return $hash;
+}
+
+/*
+ * 将字符串转换为数组
+ * @param	string	$data	字符串
+ * @return	array	返回数组格式,如果,data为空,则返回空数组
+ * 
+ */
+function string2array($data) {
+    $array = array();
+	if($data == '') return array();
+	eval("\$array = $data;");
+	return $array;
+}
+/**
+* 将数组转换为字符串
+*
+* @param	array	$data		数组
+* @param	bool	$isformdata	如果为0,则不使用new_stripslashes处理,可选参数,默认为1
+* @return	string	返回字符串,如果,data为空,则返回空
+*/
+function array2string($data, $isformdata = 1) {
+	if($data == '') return '';
+	if($isformdata) $data = new_stripslashes($data);
+	return  var_export($data, TRUE);
+}
+
+/*
+ * 转换字节数为其他单位
+ * @param	string	$filesize	字节大小
+ * @return	string	返回大小
+ */
+function sizecount($filesize) {
+	if ($filesize >= 1073741824) {
+		$filesize = round($filesize / 1073741824 * 100) / 100 .'GB';
+	} elseif ($filesize >= 1048576) {
+		$filesize = round($filesize / 1048576 * 100) / 100 .'MB';
+	} elseif($filesize >= 1024) {
+		$filesize = round($filesize / 1024 * 100) / 100 . 'KB';
+	} else {
+		$filesize = $filesize.'Bytes';
+	}
+	return $filesize;
+}
+
+/**
+ * @param int $num 要转换的阿拉伯数字
+ * @return string 转换成的字符串
+ */
+function numconvert($num)
+{
+    if ($num >= 100000000) {
+        $num = round($num / 100000000, 1) . '亿+';
+    } else if ($num >= 10000000) {
+        $num = round($num / 10000000, 1) . '万+';
+    } else if ($num >= 10000) {
+        $num = round($num / 10000, 1) . '万+';
+    }
+    return $num;
+}
+
+function numconvert2($num)
+{
+	$num = '<span style="font-weight: bold;">'.round($num / 10000, 2) . '</span>万';
+	return $num;
+}
+
+
+/*
+ * 对用户密码进行加密,用于后台
+ * @parame $password
+ * @parame $encrypt //加密因子
+ * @return string
+ * 
+ */
+function password($password,$encrypt='')
+{
+	
+	$pwd = array();
+	$pwd['encrypt'] = $encrypt?$encrypt:random(6, $chars = '123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ');
+	$pwd['password'] = md5(md5($password).$pwd['encrypt']);
+	return $encrypt?$pwd['password']:$pwd;
+
+}
+
+
+/*
+ * 判断是否为非法输入
+ * @parame $string
+ * return boolean
+ * 
+ */
+function is_bad_word($string)
+{
+	$array = array('"','\\',' ','&','*','#','/','<','>','\r','\t','\n','#',"'");
+	foreach($array as $value)
+	{
+		if(strpos($string,$value)!==false)
+		{
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+}
+/*
+ * 对数据进行编码转换
+ * @param array/string $data       数组
+ * @param string $input     需要转换的编码
+ * @param string $output    转换后的编码
+ * 
+ */
+ function array_iconv($data,$input='gbk',$output='utf-8')
+ {
+ 	if(!is_array($data))
+	{
+		$data =  iconv($input,$output."//IGNORE",$data);
+	}
+	else
+	{
+		foreach($data as $key=>$value)
+		{
+			$data[$key]  = iconv($input,$output."//IGNORE",$value);
+		}
+	}
+ 	return $data;
+ }
+/**
+ * 字符串加密、解密函数
+ * @param	string	$txt		字符串
+ * @param	string	$operation	ENCODE为加密,DECODE为解密,可选参数,默认为ENCODE,
+ * @param	string	$key		密钥:数字、字母、下划线
+ * @param	string	$expiry		过期时间
+ * @return	string
+ * 
+ */
+function sys_auth($string, $operation = 'ENCODE', $key = '', $expiry = 0) {
+	$key_length = 4;
+	$key = md5($key != '' ? $key : AUTH_KEY);
+	$fixedkey = md5($key);
+	$egiskeys = md5(substr($fixedkey, 16, 16));
+	$runtokey = $key_length ? ($operation == 'ENCODE' ? substr(md5(microtime(true)), -$key_length) : substr($string, 0, $key_length)) : '';
+	$keys = md5(substr($runtokey, 0, 16) . substr($fixedkey, 0, 16) . substr($runtokey, 16) . substr($fixedkey, 16));
+	$string = $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length));
+
+	$i = 0; $result = '';
+	$string_length = strlen($string);
+	for ($i = 0; $i < $string_length; $i++){
+		$result .= chr(ord($string[$i]) ^ ord($keys[$i % 32]));
+	}
+	if($operation == 'ENCODE') {
+		return $runtokey . str_replace('=', '', base64_encode($result));
+	} else {
+		if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$egiskeys), 0, 16)) {
+			return substr($result, 26);
+		} else {
+			return '';
+		}
+	}
+}
+
+// 函数返回当前 Unix 时间戳和微秒数
+function getmicrotime() {
+	list($usec, $sec) = explode(" ",microtime());
+	return ((float)$usec + (float)$sec);
+}
+
+/*
+ * 取得文件扩展
+ * @param $filename 文件名
+ * @return 扩展名
+ * 
+ */
+function fileext($filename) {
+	return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));
+}
+/**
+ * 查询字符是否存在于某字符串
+ *
+ * @param $haystack 字符串
+ * @param $needle 要查找的字符
+ * @return bool
+ */
+function str_exists($haystack, $needle)
+{
+	return !(strpos($haystack, $needle) === FALSE);
+}
+
+//判断远程文件
+function check_remote_file_exists($url)
+{
+     $handle = @fopen($url, 'r');
+     if(!$handle){
+         return false;
+     }else{
+         return true;
+     }
+}
+
+function check_remote_file_exists1($url)
+{
+    $curl = curl_init();
+    curl_setopt($curl, CURLOPT_URL, $url);
+    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
+    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); //强制协议为1.0
+    curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); //强制使用IPV4协议解析域名
+    // 不取回数据
+    curl_setopt($curl, CURLOPT_NOBODY, true);
+    // 发送请求
+    $result = curl_exec($curl);
+    $found = false;
+    // 如果请求没有发送失败
+    if ($result !== false)
+    {
+        // 再检查http响应码是否为200
+        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+        if ($statusCode == 200)
+        {
+            $found = true;
+        }
+    }
+    curl_close($curl);
+    return $found;
+}
+
+
+//获取远程文件大小
+function remote_file_size($url)
+{
+    $curl = curl_init();
+    curl_setopt($curl, CURLOPT_URL, $url);
+    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
+    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); //强制协议为1.0
+    curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); //强制使用IPV4协议解析域名
+	// 不取回数据
+	curl_setopt($curl, CURLOPT_NOBODY, true);
+	// 发送请求
+	$result = curl_exec($curl);
+	$size = 0;
+	// 如果请求没有发送失败
+	if ($result !== false)
+	{
+		$size = curl_getinfo($curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
+	}
+	curl_close($curl);
+	return $size;
+}
+
+/*
+ * 判断是否为图片
+ * 
+ */
+function is_image($file) {
+	$ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');
+	$ext = fileext($file);
+	return in_array($ext,$ext_arr) ? $ext_arr :false;
+}
+
+/*
+ * 判断是否为视频
+ * 
+ */
+function is_video($file) {
+	$ext_arr = array('rm','mpg','avi','mpeg','wmv','flv','asf','rmvb');
+	$ext = fileext($file);
+	return in_array($ext,$ext_arr) ? $ext_arr :false;
+}
+
+
+//保存远程图片
+function save_remote_file($remote_url,$local_path)
+{
+	$file = https_request($remote_url);
+	file_put_contents($local_path,$file); 
+	return $local_path;
+}
+
+//根据路径判断是否网络文件
+function is_net_file($url)
+{
+	if(preg_match('/^https?.*$/',$url))//网络文件
+	{
+		return  true;
+	}
+	else
+	{
+		return false;
+	}
+}
+/*
+ * 检查id是否存在于数组中
+ * @param $id
+ * @param $ids
+ * @param $s
+ * 
+ */
+function check_in($id, $ids = '', $s = ',') {
+	if(!$ids) return false;
+	$ids = explode($s, $ids);
+	return is_array($id) ? array_intersect($id, $ids) : in_array($id, $ids);
+}
+
+//判断目录是否可写
+function dir_writeable($dir) {
+	$writeable = 0;
+	if(is_dir($dir)) {
+		if($fp = @fopen("$dir/chkdir.test", 'w')) {
+			@fclose($fp);
+			@unlink("$dir/chkdir.test");
+			$writeable = 1;
+		} else {
+			$writeable = 0;
+		}
+	}
+	return $writeable;
+}
+
+/**
+ * 图片水印:gif,jpeg,png
+ * @param $imgSrc
+ * @param $markImg:水印图
+ * @param $markPos:水印位置 0:随机位置,在1~9之间随机选取一个位置
+ 1:顶部居左 2:顶部居中 3:顶部居右 4:左边居中
+ 5:图片中心 6:右边居中 7:底部居左 8:底部居中 9:底部居右 10:铺满
+ */
+
+function set_img_water($imgSrc,$markImg,$markQty=100,$markPos=9){
+	if(intval($markQty)==0)$markQty=100;
+    if($markPos==10)
+    {
+        $im = imagecreatefromstring(file_get_contents($imgSrc));
+        //获取水印源
+        $watermark = imagecreatefromstring(file_get_contents($markImg));
+        //获取图、水印 宽高类型
+        list($bgWidth, $bgHight, $bgType) = getimagesize($imgSrc);
+        list($logoWidth, $logoHight, $logoType) = getimagesize($markImg);
+        //定义平铺数据
+        $x_length = $bgWidth - 10; //x轴总长度
+        $y_length = $bgHight - 10; //y轴总长度
+        //创建透明画布 伪白色
+        $opacity=30;
+        $w = imagesx($watermark);
+        $h = imagesy($watermark);
+        $bigw = $w*2;
+        $bigh = $h*2;
+        $cut = imagecreatetruecolor($bigw,$bigh);
+        $white = imagecolorallocatealpha($cut, 255,255,255,0);
+        imagefill( $cut, 0, 0, $white );
+        //整合水印
+        //imagecopy($cut, $watermark, 0, 0, 0, 0, $w, $h);
+        imagecopyresampled($cut,$watermark,0,0,0,0,$bigw,$bigh,$w,$h);
+        //设定目标画布
+        $dst_img = @imagecreatetruecolor($bgWidth, $bgHight);
+        //上色
+        $color = imagecolorallocate($dst_img, 255, 255, 255);
+        imagefill($dst_img, 0, 0, $color);
+        
+        
+        //循环平铺水印
+        for ($x = 0; $x < $x_length; $x++)
+        {
+            for ($y = 0; $y < $y_length; $y++) {
+                imagecopymerge($dst_img, $cut, $x, $y, 0, 0, $bigw, $bigh, $opacity);
+                $y += ($logoHight+200);
+            }
+            $x += ($logoWidth+200);
+        }
+        //header("Content-type:image/png");
+        imagecopy($dst_img, $im, 0, 0, 0, 0, $bgWidth, $bgHight);
+        //imagepng($dst_img,$imgSrc);
+		switch ($bgType)
+        {
+            case 1: imagegif($dst_img, $imgSrc); break;
+            case 2: imagejpeg($dst_img, $imgSrc);break;
+            case 3: imagepng($dst_img, $imgSrc); break;
+            default: break;
+        }
+        imagedestroy($im);
+		imagedestroy($dst_img);
+        imagedestroy($cut);
+        return true;
+    }
+    else
+    {
+        $srcInfo = @getimagesize($imgSrc);
+        $srcImg_w = $srcInfo[0];
+        $srcImg_h = $srcInfo[1];
+        $srcim = null; $markim = null;
+        switch ($srcInfo[2])
+        {
+            case 1:
+                $srcim =imagecreatefromgif($imgSrc);  break;
+            case 2:
+                $srcim =imagecreatefromjpeg($imgSrc); break;
+            case 3:
+                $srcim =imagecreatefrompng($imgSrc);  break;
+            default:
+                die('unsupport file type'); exit();
+        }
+        if(!file_exists($markImg) || empty($markImg)){return;}
+
+        $markImgInfo = @getimagesize($markImg);
+        $markImg_w = $markImgInfo[0];
+        $markImg_h = $markImgInfo[1];
+
+        if($srcImg_w < $markImg_w || $srcImg_h < $markImg_h){return false;}
+
+        switch ($markImgInfo[2])
+        {
+            case 1:
+                $markim =imagecreatefromgif($markImg);  break;
+            case 2:
+                $markim =imagecreatefromjpeg($markImg); break;
+            case 3:
+                $markim =imagecreatefrompng($markImg);  break;
+            default:
+                return false;//die('不支持的水印图片文件类型');exit();
+        }
+
+        $logow = $markImg_w;
+        $logoh = $markImg_h;
+
+        if($markPos == 0){$markPos = rand(1, 9);}
+
+        switch($markPos)
+        {
+            case 1: $x = +5; 					$y = +5;  					break;//顶部居左
+            case 2: $x = ($srcImg_w-$logow)/2;	$y = +5; 					break;//顶部居中
+            case 3: $x = $srcImg_w- $logow-5;	$y = +15; 					break;//顶部居右
+            case 4: $x = +5;					$y = ($srcImg_h-$logoh)/2; 	break;//左边居中
+            case 5: $x = ($srcImg_w-$logow)/2;	$y = ($srcImg_h-$logoh)/2;	break;//图片中心
+            case 6: $x = $srcImg_w-$logow-5;	$y = ($srcImg_h-$logoh)/2; 	break;//右边居中
+            case 7: $x = +5;					$y = $srcImg_h-$logoh-5;	break;//底部居左
+            case 8: $x = ($srcImg_w-$logow)/2;	$y = $srcImg_h-$logoh-5;	break;//底部居中
+            case 9: $x = $srcImg_w-$logow-5;	$y = $srcImg_h-$logoh-5;	break;//底部居右
+            default:
+                return false;//die('此位置不支持');exit;
+        }
+
+        $dst_img = @imagecreatetruecolor($srcImg_w, $srcImg_h);
+
+        //上色
+        $color = imagecolorallocate($dst_img, 255, 255, 255);
+        imagefill($dst_img, 0, 0, $color);
+
+        imagecopy($dst_img, $srcim, 0, 0, 0, 0, $srcImg_w, $srcImg_h);
+        imagecopy($dst_img, $markim, $x, $y, 0, 0, $logow, $logoh);
+        imagedestroy($markim);
+
+        switch ($srcInfo[2])
+        {
+            case 1: imagegif($dst_img, $imgSrc); break;
+            case 2: imagejpeg($dst_img, $imgSrc);break;
+            case 3: imagepng($dst_img, $imgSrc); break;
+            default: break;
+        }
+        imagedestroy($dst_img);
+        imagedestroy($srcim);
+        return true;
+    }
+}
+
+//获取一个唯一文件名
+function get_unique_file_name($path,$ext)
+{
+	$fileName = TIMESTAMP.random(6, '0123456789abcdefghijklmnopqrstuvwxyz').".".$ext;//文件重命名
+	if(!file_exists($path.$fileName))
+	{
+		return $fileName;
+	}
+	else 
+	{
+		return get_unique_file_name($path,$ext);
+	}
+}
+
+//转换数组为可适应SQL语句插入语法值集合
+function change_array_to_sql_string($array=array()){ //转换数组为可适应SQL语句插入语法值集合
+	$array=str_replace("'","\'",$array);
+	return "'".implode("','",$array)."'";
+}
+
+// 截取某部分字符
+function interception_of_string($string='',$start='',$end='')
+{
+  if($string==''){return '';}
+  if($start!='')
+  {
+   $pos = strpos($string,$start);
+   if($pos===false)
+   {
+    return '';
+   }
+   else
+   {
+    $pos += strlen($start);
+    $string = substr($string,$pos);
+   }
+  }
+ 
+  if($end!='')
+  {
+   $pos = strpos($string,$end);
+   if($pos)
+   {
+    $string = substr($string,0,$pos);
+   }
+  }
+ 
+  return $string;
+ }
+
+
+//Curl
+function https_request($url,$options = null,$data = null,$header = null){
+	$curl = curl_init();
+	curl_setopt($curl, CURLOPT_URL, $url);
+	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
+    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); //强制协议为1.0
+    curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); //强制使用IPV4协议解析域名
+	if (!empty($data)){
+		curl_setopt($curl, CURLOPT_POST, 1);
+		curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
+	}
+    (isset($options['header'])&&$options['header'])?curl_setopt($curl, CURLOPT_HEADER, 1): curl_setopt($curl, CURLOPT_HEADER, 0);//如果有响应头
+    if(!empty($header))//如果有请求头
+    {
+        $curl_header = array();
+        foreach($header as $key=>$value)
+        {
+            $curl_header[] = "$key:$value";
+        }
+        curl_setopt($curl,CURLOPT_HTTPHEADER, $curl_header);
+    }
+    if(isset($options['gzip'])&&$options['gzip']==1) curl_setopt($curl, CURLOPT_ENCODING, "gzip"); //如果页面开启了GZIP压缩
+	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+	curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0');
+    if(!empty($options['time_out']))
+    {
+        curl_setopt($curl, CURLOPT_TIMEOUT, $options['time_out']);
+    }
+    else
+    {
+        curl_setopt($curl, CURLOPT_TIMEOUT, 15);
+    }
+    curl_setopt ($curl, CURLOPT_REFERER, get_url());
+	$output = curl_exec($curl);
+	curl_close($curl);
+	return $output;
+}
+
+/**批量替换敏感词
+ * @param array $badwords 敏感词数组
+ * @param array $replacement 替换词数组
+ * @param string $str 待替换内容
+ * @return string 
+ */
+function multi_replace($badwords,$replacement,$str)
+{
+	$replaceList = array();
+	if(is_array($badwords))
+	{
+		foreach($badwords as $badword)
+		{
+			$length = mb_strlen($badword,CHARSET);
+			$temp='';
+			for($i=0;$i<$length;$i++)
+			{
+				$temp .= $replacement;
+			}
+			$replaceList[] = $temp;
+		}
+	}
+	return $str = str_replace($badwords,$replaceList,$str);
+}
+
+/**封装后的配置文件包含方法
+ */
+function require_config($file)
+{
+	if(defined('SITE_MODE'))
+	{
+		return require BASE_PATH.'config'.DIRECTORY_SEPARATOR.SITE_MODE.DIRECTORY_SEPARATOR.$file;
+	}
+	else 
+	{
+		return require BASE_PATH.'config'.DIRECTORY_SEPARATOR.$file;
+	}
+}
+
+//格式正则校验
+function pattern_check($type,$value)
+{
+	switch($type)
+	{
+		case 'url':
+			$pattern = '/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/';
+			break;
+		case 'email':
+			$pattern = '/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/';
+			break;
+		default:break;
+	}
+	if(!empty($pattern)&&preg_match($pattern,$value)){
+		return true;
+	}
+	else{
+		return false;
+	}
+}
+
+//请求安全检测
+function check_safe_request_params(){
+	$getfilter="'|<[^>]*?>|^\\+\/v(8|9)|\\b(and|or)\\b.+?(>|<|=|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
+	$postfilter="^\\+\/v(8|9)|\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|<\\s*img\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
+	$cookiefilter="\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
+	$referer=empty($_SERVER['HTTP_REFERER']) ? array() : array($_SERVER['HTTP_REFERER']);
+	foreach($_GET as $key=>$value){
+		if (!check_request_params_ok($key,$value,$getfilter)){exit;}
+	}
+	foreach($_POST as $key=>$value){
+		if (!check_request_params_ok($key,$value,$postfilter)){exit;}
+	}
+	foreach($_COOKIE as $key=>$value){
+		if (!check_request_params_ok($key,$value,$cookiefilter)){exit;}
+	}
+	foreach($referer as $key=>$value){
+		if (!check_request_params_ok($key,$value,$getfilter)){exit;}
+	}
+}
+
+//请求安全检测:子方法
+function check_request_params_ok($StrFiltKey,$StrFiltValue,$ArrFiltReq){
+	$StrFiltValue=arr_foreach($StrFiltValue);
+	if (preg_match('/'.$ArrFiltReq.'/is',$StrFiltValue)==1 || preg_match('/'.$ArrFiltReq.'/is',$StrFiltKey)==1){return false;}
+	return true;
+}
+function arr_foreach($arr) {
+	static $str;
+	if (!is_array($arr)) {return $arr;}
+	foreach ($arr as $key => $val ) {
+		if (is_array($val)) {arr_foreach($val);} else {$str[] = $val;}
+	}
+	return implode($str);
+}
+//带超时时间设置的file_get_contents
+function new_file_get_contents($url,$timeout=null)
+{
+    if(isset($timeout))
+    {
+        $opts = array(
+            'http'=>array(
+                'method'=>"GET",
+                'timeout'=>$timeout,//单位秒
+            )
+        );
+        return file_get_contents( $url, false, stream_context_create($opts));
+    }
+    else
+    {
+        return file_get_contents($url);
+    }
+
+}
+
+//判断是否蜘蛛请求
+function checkrobot($useragent = '') {
+    static $kw_spiders = array('bot', 'crawl', 'spider' ,'slurp', 'sohu-search', 'lycos', 'robozilla','haosouspider','baidu','sogou','yisouspider','360spider','baiduspide','soso','yahoo','bingbot');
+    static $kw_browsers = array('msie', 'netscape', 'opera', 'konqueror', 'mozilla');
+    $useragent = strtolower(empty($useragent) ? $_SERVER['HTTP_USER_AGENT'] : $useragent);
+    if(strpos($useragent, 'http://') === false && strpos($useragent, 'https://') === false && dstrpos($useragent, $kw_browsers)) return false;
+    if(dstrpos($useragent, $kw_spiders)) return true;
+    return false;
+}
+
+function dstrpos($string, &$arr, $returnvalue = false) {
+    if(empty($string)) return false;
+    foreach((array)$arr as $v) {
+        if(strpos($string, $v) !== false) {
+            $return = $returnvalue ? $v : true;
+            return $return;
+        }
+    }
+    return false;
+}
+
+
+//压缩html
+function compress_html($str){
+    $str = trim($str);
+    $str = str_replace("\t","",$str);
+    $str = str_replace("\r\n","",$str);
+    $str = str_replace("\r","",$str);
+    $str = str_replace("\n","",$str);
+    $str=preg_replace("/>[ ]+/si",">",$str); //过滤>(">"号后面带空格)
+    $str=preg_replace("/[ ]+</si","<",$str); //过滤<("<"号前面带空格)
+    return trim($str);
+}
+
+//字符串过滤,只保留汉字数字英文标点符号
+function removeHtml($html,$filter=1)
+{
+    $html  = htmlspecialchars_decode($html);  //把一些预定义的 HTML 实体转换为字符
+    $html = strip_tags($html);               //函数剥去字符串中的 HTML、XML 以及 PHP 的标签,获取纯文本内容
+    $html = trim($html); //清除字符串两边的空格
+    $html = str_replace("&nbsp;","",$html);
+    $html = preg_replace("/\t/","",$html); //使用正则表达式替换内容,如:空格,换行,并将替换为空。
+    $html = preg_replace("/\r\n/","",$html);
+    $html = preg_replace("/\r/","",$html);
+    $html = preg_replace("/\n/","",$html);
+    $html = preg_replace("/ /","",$html);
+    $html = preg_replace("/ /","",$html); //匹配html中的空格
+    $html =  preg_replace('/($s*$)|(^s*^)/m', '',$html);
+    if($filter)
+    {
+        preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()]/u', $html, $result);
+        return implode('', $result[0]);
+    }
+    else
+    {
+        return $html;
+    }
+
+}
+
+//对转换过程中获取的内容做初始处理
+function beforeProcessHtml($html)
+{
+    preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9]/u', $html, $testResult);
+    if(empty($testResult[0]))
+    {
+        $html =  mb_convert_encoding($html,  'UTF-8', 'UTF-8');
+        preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()]/u', $html, $result);
+        return implode('', $result[0]);
+    }
+    else
+    {
+        return  $html;
+    }
+
+}
+
+//获取所有的cookie内容
+function get_all_cookie_str(){
+    $ckeStr='';
+    foreach ($_COOKIE as $ckeName=>$ckeVal){
+        if(!is_array($ckeVal)){
+            $ckeStr.= $ckeName.'='.$ckeVal.';';
+        }
+    }
+    $ckeStr = substr($ckeStr, 0,-1);//去除最后的 ;
+    return $ckeStr;
+}
+
+
+
+//PHP默认serialize有时会出错 http://us.php.net/manual/en/function.unserialize.php#71270
+function mb_unserialize($serial_str) {
+    $serial_str= preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
+    $serial_str= str_replace("\r", "", $serial_str);
+    return unserialize($serial_str);
+}
+
+//判断是否是移动端访问
+function check_mobile($debug = false) {
+    static $touchbrowser_list =array('iphone', 'android', 'phone', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',
+        'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',
+        'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',
+        'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',
+        'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',
+        'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',
+        'benq', 'haier', '^lct', '320x320', '240x320', '176x220');
+    static $mobilebrowser_list =array('windows phone');
+    static $wmlbrowser_list = array('cect', 'compal', 'ctl', 'lg', 'nec', 'tcl', 'alcatel', 'ericsson', 'bird', 'daxian', 'dbtel', 'eastcom',
+        'pantech', 'dopod', 'philips', 'haier', 'konka', 'kejian', 'lenovo', 'benq', 'mot', 'soutec', 'nokia', 'sagem', 'sgh',
+        'sed', 'capitel', 'panasonic', 'sonyericsson', 'sharp', 'amoi', 'panda', 'zte');
+
+    $pad_list = array('pad', 'gt-p1000');
+    $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
+    if(($v = dstrpos($useragent, $mobilebrowser_list, true))){
+        return '1'; //windows phone
+    }
+    if(($v = dstrpos($useragent, $touchbrowser_list, true))){
+        return '2';
+    }
+    if(($v = dstrpos($useragent, $wmlbrowser_list))) {
+        return '3'; //wml版
+    }
+    $brower = array('mozilla', 'chrome', 'safari', 'opera', 'm3gate', 'winwap', 'openwave', 'myop');
+    if(dstrpos($useragent, $brower)) return false;
+    return false;
+}
+
+//时间换算
+function info_last_time($time,$ac="Y年m月d日") {
+    $now=TIMESTAMP-$time;
+    $timestr = (substr_count($ac,'-')>0?'Y-m-d':'Y年m月d日');
+    if ($now>3456000)  return get_date($time,$timestr);
+    elseif ($now>345600)  return get_date($time,$ac);
+    elseif ($now>259200) return "三天前";
+    elseif ($now>172800) return "两天前";
+    elseif ($now>86400) return "一天前";
+    elseif ($now>72000) return "二十小时前";
+    elseif ($now>54000) return "十五小时前";
+    elseif ($now>43200) return "十二小时前";
+    elseif ($now>36000) return "十小时前";
+    elseif ($now>28800) return "八小时前";
+    elseif ($now>21600) return "六小时前";
+    elseif ($now>18000) return "五小时前";
+    elseif ($now>10800) return "三小时前";
+    elseif ($now>7200) return "两小时前";
+    elseif ($now>3600) return "一小时前";
+    elseif ($now>1800) return "半小时前";
+    elseif ($now>1200) return "二十分钟前";
+    elseif ($now>900) return "十五分钟前";
+    elseif ($now>600) return "十分钟前";
+    elseif ($now>300) return "五分钟前";
+    elseif ($now>180) return "三分钟前";
+    elseif ($now>120) return "两分钟前";
+    elseif ($now>=0) return "一分钟前";
+    elseif ($now<0) return "一秒钟前";
+    return get_date($time,$ac);
+}
+/**
+ * 格式化时间戳为日期字符串
+ * @global string $db_datefm
+ * @global string $db_timedf
+ * @global string $_datefm
+ * @global string $_timedf
+ * @param int $timestamp
+ * @param string $format
+ * @return string
+ */
+function get_date($timestamp, $format = null) {
+    if(empty($timestamp))return '';
+    $obj = new \DateTime("@$timestamp"); // 这里时间戳前要写一个@符号
+    $timezone = timezone_open(TIME_ZONE); // 设置时区
+    $obj->setTimezone($timezone);
+    $sDefaultFormat = $format ? $format : 'Y-m-d H:i';
+    return $obj->format($sDefaultFormat);
+}
+
+//日期转时间戳
+function str_to_time($str)
+{
+    $date = new \DateTime($str);
+    return  $date->format('U');
+}
+
+//301跳转
+function header_goto($str) {
+    Header("HTTP/1.1 301 Moved Permanently");
+    Header($str);exit;
+}
+
+
+/**
+ * 截断字符串
+ *
+ * @param string $content 内容
+ * @param int $length 截取字节数
+ * @param string $add 是否带省略号,Y|N
+ * @return string
+ */
+
+function substrs($content, $length, $add = 'Y') {
+	if (strlen($content) > $length) {
+		if (CHARSET != 'utf-8') {
+			$cutStr = '';
+			for ($i = 0; $i < $length - 1; $i++) {
+				$cutStr .= ord($content[$i]) > 127 ? $content[$i] . $content[++$i] : $content[$i];
+			}
+			$i < $length && ord($content[$i]) <= 127 && $cutStr .= $content[$i];
+			return $cutStr . ($add == 'Y' ? ' ..' : '');
+		}
+		return utf8_trim(substr($content, 0, $length)) . ($add == 'Y' ? ' ..' : '');
+	}
+	return $content;
+}
+
+/**
+ * utf8字符串整齐化
+ *
+ * @param string $str
+ * @return string
+ */
+function utf8_trim($str) {
+	$hex = '';
+	$len = strlen($str) - 1;
+	for ($i = $len; $i >= 0; $i -= 1) {
+		$ch = ord($str[$i]);
+		$hex .= " $ch";
+		if (($ch & 128) == 0 || ($ch & 192) == 192) {return substr($str, 0, $i);}
+	}
+	return $str . $hex;
+}
+
+
+function echo_json($arr){
+    ob_clean();
+    header('Content-type: application/json');
+    echo json_encode($arr);exit;
+}
+
+//生成唯一订单号
+function getUniOrderNo()
+{
+    $order_id = get_date(TIMESTAMP,'Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
+    $exists = \app\modules\shopping\models\ShoppingOrder::find()->where("order_sn='".$order_id."'")->exists();
+    if($exists)
+    {
+        return getUniOrderNo();
+    }
+    else
+    {
+        return $order_id;
+    }
+
+}
+//生成唯一券号
+function getUniCouponNo()
+{
+    $coupon_no = get_date(TIMESTAMP,'Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
+    $exists = \app\modules\ucenter\models\UserVipCoupon::find()->where("coupon_no='".$coupon_no."'")->exists();
+    if($exists)
+    {
+        return getUniCouponNo();
+    }
+    else
+    {
+        return $coupon_no;
+    }
+
+}
+//生成唯一订单号(毫秒级)
+function getProUniOrderNo()
+{
+    $order_id_main = get_date(TIMESTAMP,'YmdHis') . rand(10,99);
+    $order_id_len = strlen($order_id_main);
+    $order_id_sum = 0;
+    for($i=0; $i<$order_id_len; $i++){
+        $order_id_sum += (int)(substr($order_id_main,$i,1));
+    }
+    $order_id = $order_id_main . str_pad((100 - $order_id_sum % 100) % 100,2,'0',STR_PAD_LEFT);
+    return $order_id;
+}
+
+/**
+ *  二維数组排序
+ */
+function array_sort($arr,$sort)
+{
+   /* $sort = array(
+        'direction' => 'SORT_DESC', //排序顺序标志 SORT_DESC 降序;SORT_ASC 升序
+        'field'     => 'length',     //排序字段
+    );*/
+
+    $arrSort = array();
+    foreach($arr AS $uniqid => $row){
+        foreach($row AS $key=>$value){
+            $arrSort[$key][$uniqid] = $value;
+        }
+    }
+    if($sort['direction']){
+        array_multisort($arrSort[$sort['field']], constant($sort['direction']), $arr);
+    }
+    return $arr;
+}
+
+/**
+ * 可以统计中文字符串长度的函数
+ * @param $str 要计算长度的字符串
+ * @param $type 计算长度类型,0(默认)表示一个中文算一个字符,1表示一个中文算两个字符
+ */
+function abslength($str)
+{
+    if(empty($str)){
+        return 0;
+    }
+    if(function_exists('mb_strlen')){
+        return mb_strlen($str,'utf-8');
+    }
+    else {
+        preg_match_all("/./u", $str, $ar);
+        return count($ar[0]);
+    }
+}
+
+
+//过滤微信表情
+function filterEmoji($nickname)
+{
+    $nickname = preg_replace('/[\x{1F600}-\x{1F64F}]/u', '', $nickname);
+    $nickname = preg_replace('/[\x{1F300}-\x{1F5FF}]/u', '', $nickname);
+    $nickname = preg_replace('/[\x{1F680}-\x{1F6FF}]/u', '', $nickname);
+    $nickname = preg_replace('/[\x{2600}-\x{26FF}]/u', '', $nickname);
+    $nickname = preg_replace('/[\x{2700}-\x{27BF}]/u', '', $nickname);
+    $nickname = str_replace(array('"','\''), '', $nickname);
+    return $nickname;
+}
+
+//单条对象记录转数组
+function single_object_to_array($result,$needfield = array())
+{
+    $info = array();
+    if(is_object($result))
+    {
+        foreach($result as $key=>$value)
+        {
+            if(!empty($needfield)&&in_array($key,$needfield))
+            {
+                $info[$key] = $value;
+            }
+            if(empty($needfield))
+            {
+                $info[$key] = $value;
+            }
+        }
+        return $info;
+    }
+    else
+    {
+        return $result;
+    }
+
+}
+
+//获得文件绝对路径
+function getFileUrl($path,$internal=0)
+{
+    if(empty($path)) return;
+    if(strpos($path,'http')!==false)
+    {
+        $path = str_replace(array('https://','http://'),array(SITE_PROTOCOL,SITE_PROTOCOL),$path);
+    }
+    else
+    {
+        //如果开启了OSS
+        if(Yii::$app->params['oss']['OPEN_OSS'])
+        {
+            if($internal==1)
+            {
+                $path =  getOssInterUrl().$path;
+            }
+            else
+            {
+                $path =  getOssUrl().$path;
+            }
+        }
+        else
+        {
+            $path =  UPLOAD_URL.$path;
+        }
+
+    }
+    if(IN_WAP)
+    {
+        $path = str_replace(WEB_URL,WAP_URL,$path);
+    }
+    return $path;
+}
+
+
+//获得文件转换结果路径
+function getFileWorkPath($file)
+{
+    $result = parse_url($file);
+    $path= str_replace('/upload/','',$result['path']);
+    $ext = fileext($path);
+    $workpath = dirname($path).DIRECTORY_SEPARATOR.md5(basename($path,'.'.$ext)).DIRECTORY_SEPARATOR;
+    $workpath = ltrim(str_replace(DIRECTORY_SEPARATOR,'/',$workpath),'/');
+    return $workpath;
+}
+
+//获得文件相对路径
+function getFilePath($file)
+{
+    $result = parse_url($file);
+    $path= str_replace('/upload/','',$result['path']);
+    return $path;
+}
+
+function unserializeFileRealUrl($string,$first=true)
+{
+    $fileList = string2array($string);
+    $urls = '';
+    if($first)
+    {
+        if(isset($fileList['filepath']))
+        {
+            if(!empty($fileList['filepath']))
+            {
+                $urls = getFileUrl($fileList['filepath']);
+            }
+        }
+        else
+        {
+            if(!empty($fileList[0]['filepath']))
+            {
+                if(strpos($fileList[0]['fileurl'],'http')!==false)
+                {
+                    return $fileList[0]['fileurl'];
+                }
+                else
+                {
+                    $urls = getFileUrl($fileList[0]['filepath']);
+                }
+            }
+        }
+    }
+    else
+    {
+        $urls = array();
+        if(is_array($fileList))foreach($fileList as $file)
+        {
+            if(!empty($file['filepath']))$urls[] = getFileUrl($file['filepath']);
+        }
+    }
+    return $urls;
+}
+
+
+//判断是否是手机站
+function is_wap_site()
+{
+    if(IN_WAP==true)
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+//判断是IOS或安卓系统
+function get_device_type()
+{
+    //全部变成小写字母
+    $agent = strtolower($_SERVER['HTTP_USER_AGENT']);
+    $type ='other';
+    //分别进行判断
+    if(strpos($agent,'iphone') || strpos($agent,'ipad'))
+    {
+        $type ='ios';
+    }
+    if(strpos($agent,'android'))
+    {
+        $type ='android';
+    }
+    return $type;
+}
+
+//判断是否是微信访问
+function check_micromsg()
+{
+    $agent =  strtolower($_SERVER['HTTP_USER_AGENT']);
+    if (stripos($agent, 'MicroMessenger') !== false)
+    {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+//判断是否是百度小程序访问
+function check_baiduapp()
+{
+    $agent =  strtolower($_SERVER['HTTP_USER_AGENT']);
+    if (stripos($agent, 'baiduboxapp') !== false)
+    {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+//判断是否是微信小程序访问
+function check_wxapp()
+{
+    $agent =  strtolower($_SERVER['HTTP_USER_AGENT']);
+    if (stripos($agent, 'miniprogram') !== false)
+    {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/*
+ * 作用:用*号替代姓名除第一个字之外的字符
+ * 参数:
+ *
+ *
+ * 返回值:string
+ */
+function starReplace($name, $num = 0)
+{
+    if ($num && mb_strlen($name, 'UTF-8') > $num) {
+        return mb_substr($name, 0, 4) . '*';
+    }
+
+    if ($num && mb_strlen($name, 'UTF-8') <= $num) {
+        return $name;
+    }
+
+    $doubleSurname = [
+        '欧阳', '太史', '端木', '上官', '司马', '东方', '独孤', '南宫',
+        '万俟', '闻人', '夏侯', '诸葛', '尉迟', '公羊', '赫连', '澹台', '皇甫', '宗政', '濮阳',
+        '公冶', '太叔', '申屠', '公孙', '慕容', '仲孙', '钟离', '长孙', '宇文', '司徒', '鲜于',
+        '司空', '闾丘', '子车', '亓官', '司寇', '巫马', '公西', '颛孙', '壤驷', '公良', '漆雕', '乐正',
+        '宰父', '谷梁', '拓跋', '夹谷', '轩辕', '令狐', '段干', '百里', '呼延', '东郭', '南门', '羊舌',
+        '微生', '公户', '公玉', '公仪', '梁丘', '公仲', '公上', '公门', '公山', '公坚', '左丘', '公伯',
+        '西门', '公祖', '第五', '公乘', '贯丘', '公皙', '南荣', '东里', '东宫', '仲长', '子书', '子桑',
+        '即墨', '达奚', '褚师', '吴铭'
+    ];
+
+    $surname = mb_substr($name, 0, 2);
+    if (in_array($surname, $doubleSurname)) {
+        $name = mb_substr($name, 0, 2) . str_repeat('*', (mb_strlen($name, 'UTF-8') - 2));
+    } else {
+        $name = mb_substr($name, 0, 1) . str_repeat('*', (mb_strlen($name, 'UTF-8') - 1));
+    }
+
+
+    return $name;
+}
+
+//比如找回密码当中邮件验证码用到的
+function randString($length=32)
+{
+    return Yii::$app->getSecurity()->generateRandomString($length);
+}
+
+//生成密码
+function generatePwd($password)
+{
+
+    return Yii::$app->getSecurity()->generatePasswordHash($password);
+
+}
+
+//校验密码
+function validatePwd($password,$hash)
+{
+   return Yii::$app->getSecurity()->validatePassword($password, $hash);
+}
+
+//页面元素 name 转ID
+function nameToId($name)
+{
+    $name = str_replace('[','-',$name);
+    $name = str_replace(']','',$name);
+    return strtolower($name);
+}
+
+//抛出404
+function do404()
+{
+    throw new \Exception('页面未找到',404);
+}
+
+
+function isSpider() {
+    $agent= strtolower($_SERVER['HTTP_USER_AGENT']);
+    if (!empty($agent)) {
+        $spiderSite= array(
+            "TencentTraveler",
+            "Baiduspider+",
+            "BaiduGame",
+            "Googlebot",
+            "msnbot",
+            "Sosospider+",
+            "Sogou web spider",
+            "ia_archiver",
+            "Yahoo! Slurp",
+            "YoudaoBot",
+            "Yahoo Slurp",
+            "MSNBot",
+            "Java (Often spam bot)",
+            "BaiDuSpider",
+            "Voila",
+            "Yandex bot",
+            "BSpider",
+            "twiceler",
+            "Sogou Spider",
+            "Speedy Spider",
+            "Google AdSense",
+            "Heritrix",
+            "Python-urllib",
+            "Alexa (IA Archiver)",
+            "Ask",
+            "Exabot",
+            "Custo",
+            "OutfoxBot/YodaoBot",
+            "yacy",
+            "SurveyBot",
+            "legs",
+            "lwp-trivial",
+            "Nutch",
+            "StackRambler",
+            "The web archive (IA Archiver)",
+            "Perl tool",
+            "MJ12bot",
+            "Netcraft",
+            "MSIECrawler",
+            "WGet tools",
+            "larbin",
+            "Fish search",
+        );
+        foreach($spiderSite as $val) {
+            $str = strtolower($val);
+            if (strpos($agent, $str) !== false) {
+                return true;
+            }
+        }
+    } else {
+        return false;
+    }
+}
+
+
+
+
+
+
+
+
+
+/**
+ * @param array $_define   默认seo配置
+ * @param unknown_type $_values	对应 targets 的一组值
+ * @param unknown_type $_targets
+ * @return multitype:string
+ */
+function seoSettings($_define = array(), $_replaceconfig = array(),$_default = array()) {
+
+    if (!empty($_define)) {
+        $cTitle = $_define[$_replaceconfig['pre'].'meta_title'];
+        $cKeywords = $_define[$_replaceconfig['pre'].'meta_keywords'];
+        $cDescription = $_define[$_replaceconfig['pre'].'meta_description'];
+    }
+    $_values = $_replaceconfig['values'];
+    $_targets = $_replaceconfig['targets'];
+    /* 过滤参数 */
+    foreach ($_values as $key => $value) {
+        $_values[$key] = empty($value) ? '' : trim(strip_tags($value));
+    }
+
+    /*设置默认值*/
+    empty($cTitle) && $cTitle = $_default['meta_title'];
+    empty($cKeywords) && $cKeywords = $_default['meta_keywords'];
+    empty($cDescription) && $cDescription = $_default['meta_description'];
+
+    /* 参数处理 */
+    $webPageTitle = parseSeoTargets($cTitle, $_values, $_targets);
+    $metaDescription = parseSeoTargets($cDescription, $_values, $_targets);
+    $metaKeywords = trim(parseSeoTargets($cKeywords, $_values, $_targets),',');
+    $metaKeywords = str_replace(',',',',trim($metaKeywords,','));
+    //如果关键词为空,用标题替代
+    if(empty($metaKeywords))$metaKeywords = $webPageTitle;
+    return array($webPageTitle, $metaKeywords, $metaDescription);
+}
+
+/**
+ * @param string $content
+ * @param array $_replace
+ * @param array $_targets
+ * @return string
+ */
+function parseSeoTargets($content, $_values, $_targets) {
+    $content = str_replace($_targets, $_values, $content);
+    $content = trim(preg_replace(array('((\s*\,\s*)+)', '((\s*\|\s*)+)', '((\s*\t\s*)+)'), array(
+        ',', '|', '', ''), $content), ' -,|');
+    return $content;
+}
+
+//获取目录(含子目录)下所有文件
+function get_allfiles($path,&$files) {
+    if(is_dir($path)){
+        $dp = dir($path);
+        while ($file = $dp ->read()){
+            if($file !="." && $file !=".."){
+                get_allfiles($path."/".$file, $files);
+            }
+        }
+        $dp ->close();
+    }
+    if(is_file($path)){
+        $files[] = $path;
+    }
+}
+
+function get_filenamesbydir($dir){
+    $files = array();
+    get_allfiles($dir,$files);
+    return $files;
+}
+
+
+
+
+?>
+

+ 1631 - 0
common/functions/global1.php

@@ -0,0 +1,1631 @@
+<?php
+/*  
+ * global.php   
+ * 公共函数库    
+ * 更新: Jacky.Chen 2013/10/20 15:45  
+ */
+
+/*
+ * 返回经addslashes处理过的字符串或数组
+ * @param $string 需要处理的字符串或数组
+ * @return mixed
+ */
+function new_add_slashes($string)
+{
+	if(!is_array($string))return addslashes($string);
+	foreach($string as $key=>$val)
+	{
+		$string[$key] = new_add_slashes($val);
+	}
+	return $string;
+}
+
+/*
+ * 返回经stripslashes处理过的字符串或数组
+ * @param $string 需要处理的字符串或数组
+ * @return mixed
+ */
+function new_stripslashes($string) {
+	if(!is_array($string)) return stripslashes($string);
+	foreach($string as $key => $val) $string[$key] = new_stripslashes($val);
+	return $string;
+}
+
+/*
+ * 返回经htmlspecialchars处理过的字符串或数组
+ * @param $obj 需要处理的字符串或数组
+ * @return mixed
+ */
+function new_htmlspecialchars($string) {
+	if(!is_array($string)) return htmlspecialchars($string);
+	foreach($string as $key => $val) $string[$key] = new_htmlspecialchars($val);
+	return $string;
+}
+
+//filterkeys 指定了排除在外的键值
+function safe_replace_array($array,$filterKeys=array())
+{
+    foreach($array as $k=>$v)
+    {
+        if(!in_array($k,$filterKeys)) $array[$k] = safe_replace($v);
+    }
+    return $array;
+}
+
+/*
+* 安全过滤函数
+* @parame $string
+* @return string
+*/
+function safe_replace($string)
+{
+	$string = str_replace('%20','',$string);
+	$string = str_replace('%27','',$string);
+	$string = str_replace('%2527','',$string);
+	$string = str_replace('*','',$string);
+	$string = str_replace('"','&quot;',$string);
+	$string = str_replace("'",'',$string);
+	$string = str_replace('"','',$string);
+	$string = str_replace(';','',$string);
+	$string = str_replace('>','&gt;',$string);
+	$string = str_replace('<','&lt;',$string);
+	$string = str_replace('{','',$string);
+	$string = str_replace('}','',$string);
+	$string = str_replace('\\','',$string);
+	return $string;
+}
+
+/**
+ * xss过滤函数
+ *
+ * @param $string
+ * @return string
+ */
+function remove_xss($string) {
+	$string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $string);
+
+	$parm1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');
+
+	$parm2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');
+
+	$parm = array_merge($parm1, $parm2);
+
+	for ($i = 0; $i < sizeof($parm); $i++) {
+		$pattern = '/';
+		for ($j = 0; $j < strlen($parm[$i]); $j++) {
+			if ($j > 0) {
+				$pattern .= '(';
+				$pattern .= '(&#[x|X]0([9][a][b]);?)?';
+				$pattern .= '|(&#0([9][10][13]);?)?';
+				$pattern .= ')?';
+			}
+			$pattern .= $parm[$i][$j];
+		}
+		$pattern .= '/i';
+		$string = preg_replace($pattern, '', $string);
+	}
+	return $string;
+}
+
+/**
+ * 转义 javascript 代码标记
+ *
+ * @param $str
+ * @return mixed
+ */
+function trim_script($str) {
+	if(is_array($str)){
+		foreach ($str as $key => $val){
+			$str[$key] = trim_script($val);
+		}
+	}else{
+		$str = preg_replace ( '/\<([\/]?)script([^\>]*?)\>/si', '&lt;\\1script\\2&gt;', $str );
+		$str = preg_replace ( '/\<([\/]?)iframe([^\>]*?)\>/si', '&lt;\\1iframe\\2&gt;', $str );
+		$str = preg_replace ( '/\<([\/]?)frame([^\>]*?)\>/si', '&lt;\\1frame\\2&gt;', $str );
+		$str = str_replace ( 'javascript:', 'javascript:', $str );
+	}
+	return $str;
+}
+
+
+/*
+ * 过滤ASCII码从0-28的控制字符
+ * @return String
+ */
+function trim_unsafe_control_chars($str) {
+	$rule = '/[' . chr ( 1 ) . '-' . chr ( 8 ) . chr ( 11 ) . '-' . chr ( 12 ) . chr ( 14 ) . '-' . chr ( 31 ) . ']*/';
+	return str_replace ( chr ( 0 ), '', preg_replace ( $rule, '', $str ) );
+}
+
+/*
+ * 格式化文本域内容
+ *
+ * @param $string 文本域内容
+ * @return string
+ */
+function trim_textarea($string) {
+	$string = nl2br ( str_replace ( ' ', '&nbsp;', $string ) );
+	return $string;
+}
+
+/**
+ * 安全过滤表单输入
+ *
+ * @param $string
+ * @return string
+ */
+function safe_filter_input($string) {
+	if(!is_array($string)) {
+		$string = trim($string);
+		$string = stripslashes($string);
+		$string = htmlspecialchars($string);
+		return $string;
+	}
+	foreach($string as $key => $val) {
+		$val = trim($val);
+		$val = stripslashes($val);
+		$val = htmlspecialchars($val);
+		$string[$key] = $val;
+	}
+	return $string;
+}
+
+
+/*
+ * 将文本格式成适合js输出的字符串
+ * @param string $string 需要处理的字符串
+ * @param intval $isjs 是否执行字符串格式化,默认为执行
+ * @return string 处理后的字符串
+ */
+function format_js($string, $isjs = 1) {
+	$string = addslashes(str_replace(array("\r", "\n", "\t"), array('', '', ''), $string));
+	return $isjs ? 'document.write("'.$string.'");' : $string;
+}
+/*
+ * 获取当前页面完整URL地址
+ */
+function get_url() {
+	$sys_protocal = isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://';
+	$php_self = $_SERVER['PHP_SELF'] ? safe_replace($_SERVER['PHP_SELF']) : safe_replace($_SERVER['SCRIPT_NAME']);
+	$path_info = isset($_SERVER['PATH_INFO']) ? safe_replace($_SERVER['PATH_INFO']) : '';
+	$relate_url = isset($_SERVER['REQUEST_URI']) ? safe_replace($_SERVER['REQUEST_URI']) : $php_self.(isset($_SERVER['QUERY_STRING']) ? '?'.safe_replace($_SERVER['QUERY_STRING']) : $path_info);
+	return $sys_protocal.(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '').$relate_url;
+}
+
+
+/**
+ * 字符串截取,支持中英文
+ * @param $str
+ * @param int $start
+ * @param $length
+ * @param string $charset
+ * @param bool $suffix
+ * @return false|string
+ * @author 肆月
+ */
+function str_cut($str, $start = 0, $length,  $dot = '...')
+{
+    $charset = CHARSET;
+    if (function_exists("mb_substr")) {
+        if ($dot) {
+            if (strlen($str) > $length)
+                return mb_substr($str, $start, $length, $charset) . $dot;
+            else
+                return mb_substr($str, $start, $length, $charset);
+        } else {
+            return mb_substr($str, $start, $length, $charset);
+        }
+    } elseif (function_exists('iconv_substr')) {
+        if ($dot) {
+            if (strlen($str) > $length)
+                return iconv_substr($str, $start, $length, $charset). $dot;
+            else
+                return iconv_substr($str, $start, $length, $charset);
+        } else {
+            return iconv_substr($str, $start, $length, $charset);
+        }
+    }
+}
+
+//隐藏用户名中间字符仅保留头尾
+function hide_user_name($user_name,  $repeatStr = '*', $encode = 'utf-8')
+{
+    if (empty($user_name)) {
+        return '***';
+    }
+    $length = mb_strlen($user_name, $encode);
+    $firstStr = mb_substr($user_name, 0, 1, $encode);
+    $lastStr = mb_substr($user_name, -1, 1, $encode);
+    if($length ==1){
+        return $user_name;
+    }
+    return $length == 2 ? $firstStr . str_repeat($repeatStr, $length - 1) : $firstStr . str_repeat($repeatStr, $length - 2) . $lastStr;
+}
+
+/*
+ * 获取请求ip
+ * @return ip地址(整数形式)
+ */
+function ip() {
+	if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
+		$ip = getenv('HTTP_CLIENT_IP');
+	} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
+		$ip = getenv('HTTP_X_FORWARDED_FOR');
+	} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
+		$ip = getenv('REMOTE_ADDR');
+	} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
+		$ip = $_SERVER['REMOTE_ADDR'];
+	}
+	return preg_match ( '/[\d\.]{7,23}/', $ip, $matches ) ? ip2long($matches [0]) : 0;
+}
+
+/*
+ * 程序执行时间
+ * @return	int	单位ms
+ * 
+ */
+function execute_time() {
+	$stime = explode ( ' ', SYS_START_TIME );
+	$etime = explode ( ' ', microtime () );
+	return number_format ( ($etime [1] + $etime [0] - $stime [1] - $stime [0]), 6 );
+}
+
+/*
+ * 产生随机字符串
+ * @param    int        $length  输出长度
+ * @param    string     $chars   可选的 ,默认为 0123456789
+ * @return   string     字符串
+ * 
+ */
+function random($length, $chars = '0123456789') {
+	$hash = '';
+	$max = strlen($chars) - 1;
+	for($i = 0; $i < $length; $i++) {
+		$hash .= $chars[mt_rand(0, $max)];
+	}
+	return $hash;
+}
+
+/*
+ * 将字符串转换为数组
+ * @param	string	$data	字符串
+ * @return	array	返回数组格式,如果,data为空,则返回空数组
+ * 
+ */
+function string2array($data) {
+    $array = array();
+	if($data == '') return array();
+	eval("\$array = $data;");
+	return $array;
+}
+/**
+* 将数组转换为字符串
+*
+* @param	array	$data		数组
+* @param	bool	$isformdata	如果为0,则不使用new_stripslashes处理,可选参数,默认为1
+* @return	string	返回字符串,如果,data为空,则返回空
+*/
+function array2string($data, $isformdata = 1) {
+	if($data == '') return '';
+	if($isformdata) $data = new_stripslashes($data);
+	return  var_export($data, TRUE);
+}
+
+/*
+ * 转换字节数为其他单位
+ * @param	string	$filesize	字节大小
+ * @return	string	返回大小
+ */
+function sizecount($filesize) {
+	if ($filesize >= 1073741824) {
+		$filesize = round($filesize / 1073741824 * 100) / 100 .'GB';
+	} elseif ($filesize >= 1048576) {
+		$filesize = round($filesize / 1048576 * 100) / 100 .'MB';
+	} elseif($filesize >= 1024) {
+		$filesize = round($filesize / 1024 * 100) / 100 . 'KB';
+	} else {
+		$filesize = $filesize.'Bytes';
+	}
+	return $filesize;
+}
+
+/**
+ * @param int $num 要转换的阿拉伯数字
+ * @return string 转换成的字符串
+ */
+function numconvert($num)
+{
+    if ($num >= 100000000) {
+        $num = round($num / 100000000, 1) . '亿+';
+    } else if ($num >= 10000000) {
+        $num = round($num / 10000000, 1) . '万+';
+    } else if ($num >= 10000) {
+        $num = round($num / 10000, 1) . '万+';
+    }
+    return $num;
+}
+
+
+
+/*
+ * 对用户密码进行加密,用于后台
+ * @parame $password
+ * @parame $encrypt //加密因子
+ * @return string
+ * 
+ */
+function password($password,$encrypt='')
+{
+	
+	$pwd = array();
+	$pwd['encrypt'] = $encrypt?$encrypt:random(6, $chars = '123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ');
+	$pwd['password'] = md5(md5($password).$pwd['encrypt']);
+	return $encrypt?$pwd['password']:$pwd;
+
+}
+
+
+/*
+ * 判断是否为非法输入
+ * @parame $string
+ * return boolean
+ * 
+ */
+function is_bad_word($string)
+{
+	$array = array('"','\\',' ','&','*','#','/','<','>','\r','\t','\n','#',"'");
+	foreach($array as $value)
+	{
+		if(strpos($string,$value)!==false)
+		{
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+}
+/*
+ * 对数据进行编码转换
+ * @param array/string $data       数组
+ * @param string $input     需要转换的编码
+ * @param string $output    转换后的编码
+ * 
+ */
+ function array_iconv($data,$input='gbk',$output='utf-8')
+ {
+ 	if(!is_array($data))
+	{
+		$data =  iconv($input,$output."//IGNORE",$data);
+	}
+	else
+	{
+		foreach($data as $key=>$value)
+		{
+			$data[$key]  = iconv($input,$output."//IGNORE",$value);
+		}
+	}
+ 	return $data;
+ }
+/**
+ * 字符串加密、解密函数
+ * @param	string	$txt		字符串
+ * @param	string	$operation	ENCODE为加密,DECODE为解密,可选参数,默认为ENCODE,
+ * @param	string	$key		密钥:数字、字母、下划线
+ * @param	string	$expiry		过期时间
+ * @return	string
+ * 
+ */
+function sys_auth($string, $operation = 'ENCODE', $key = '', $expiry = 0) {
+	$key_length = 4;
+	$key = md5($key != '' ? $key : AUTH_KEY);
+	$fixedkey = md5($key);
+	$egiskeys = md5(substr($fixedkey, 16, 16));
+	$runtokey = $key_length ? ($operation == 'ENCODE' ? substr(md5(microtime(true)), -$key_length) : substr($string, 0, $key_length)) : '';
+	$keys = md5(substr($runtokey, 0, 16) . substr($fixedkey, 0, 16) . substr($runtokey, 16) . substr($fixedkey, 16));
+	$string = $operation == 'ENCODE' ? sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$egiskeys), 0, 16) . $string : base64_decode(substr($string, $key_length));
+
+	$i = 0; $result = '';
+	$string_length = strlen($string);
+	for ($i = 0; $i < $string_length; $i++){
+		$result .= chr(ord($string{$i}) ^ ord($keys{$i % 32}));
+	}
+	if($operation == 'ENCODE') {
+		return $runtokey . str_replace('=', '', base64_encode($result));
+	} else {
+		if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$egiskeys), 0, 16)) {
+			return substr($result, 26);
+		} else {
+			return '';
+		}
+	}
+}
+
+// 函数返回当前 Unix 时间戳和微秒数
+function getmicrotime() {
+	list($usec, $sec) = explode(" ",microtime());
+	return ((float)$usec + (float)$sec);
+}
+
+/*
+ * 取得文件扩展
+ * @param $filename 文件名
+ * @return 扩展名
+ * 
+ */
+function fileext($filename) {
+	return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));
+}
+/**
+ * 查询字符是否存在于某字符串
+ *
+ * @param $haystack 字符串
+ * @param $needle 要查找的字符
+ * @return bool
+ */
+function str_exists($haystack, $needle)
+{
+	return !(strpos($haystack, $needle) === FALSE);
+}
+
+//判断远程文件
+function check_remote_file_exists($url)
+{
+     $handle = @fopen($url, 'r');
+     if(!$handle){
+         return false;
+     }else{
+         return true;
+     }
+}
+
+function check_remote_file_exists1($url)
+{
+    $curl = curl_init();
+    curl_setopt($curl, CURLOPT_URL, $url);
+    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
+    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); //强制协议为1.0
+    curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); //强制使用IPV4协议解析域名
+    // 不取回数据
+    curl_setopt($curl, CURLOPT_NOBODY, true);
+    // 发送请求
+    $result = curl_exec($curl);
+    $found = false;
+    // 如果请求没有发送失败
+    if ($result !== false)
+    {
+        // 再检查http响应码是否为200
+        $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+        if ($statusCode == 200)
+        {
+            $found = true;
+        }
+    }
+    curl_close($curl);
+    return $found;
+}
+
+
+//获取远程文件大小
+function remote_file_size($url)
+{
+    $curl = curl_init();
+    curl_setopt($curl, CURLOPT_URL, $url);
+    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
+    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); //强制协议为1.0
+    curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); //强制使用IPV4协议解析域名
+	// 不取回数据
+	curl_setopt($curl, CURLOPT_NOBODY, true);
+	// 发送请求
+	$result = curl_exec($curl);
+	$size = 0;
+	// 如果请求没有发送失败
+	if ($result !== false)
+	{
+		$size = curl_getinfo($curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
+	}
+	curl_close($curl);
+	return $size;
+}
+
+/*
+ * 判断是否为图片
+ * 
+ */
+function is_image($file) {
+	$ext_arr = array('jpg','gif','png','bmp','jpeg','tiff');
+	$ext = fileext($file);
+	return in_array($ext,$ext_arr) ? $ext_arr :false;
+}
+
+/*
+ * 判断是否为视频
+ * 
+ */
+function is_video($file) {
+	$ext_arr = array('rm','mpg','avi','mpeg','wmv','flv','asf','rmvb');
+	$ext = fileext($file);
+	return in_array($ext,$ext_arr) ? $ext_arr :false;
+}
+
+
+//保存远程图片
+function save_remote_file($remote_url,$local_path)
+{
+	$file = https_request($remote_url);
+	file_put_contents($local_path,$file); 
+	return $local_path;
+}
+
+//根据路径判断是否网络文件
+function is_net_file($url)
+{
+	if(preg_match('/^https?.*$/',$url))//网络文件
+	{
+		return  true;
+	}
+	else
+	{
+		return false;
+	}
+}
+/*
+ * 检查id是否存在于数组中
+ * @param $id
+ * @param $ids
+ * @param $s
+ * 
+ */
+function check_in($id, $ids = '', $s = ',') {
+	if(!$ids) return false;
+	$ids = explode($s, $ids);
+	return is_array($id) ? array_intersect($id, $ids) : in_array($id, $ids);
+}
+
+//判断目录是否可写
+function dir_writeable($dir) {
+	$writeable = 0;
+	if(is_dir($dir)) {
+		if($fp = @fopen("$dir/chkdir.test", 'w')) {
+			@fclose($fp);
+			@unlink("$dir/chkdir.test");
+			$writeable = 1;
+		} else {
+			$writeable = 0;
+		}
+	}
+	return $writeable;
+}
+
+/**
+ * 图片水印:gif,jpeg,png
+ * @param $imgSrc
+ * @param $markImg:水印图
+ * @param $markPos:水印位置 0:随机位置,在1~9之间随机选取一个位置
+ 1:顶部居左 2:顶部居中 3:顶部居右 4:左边居中
+ 5:图片中心 6:右边居中 7:底部居左 8:底部居中 9:底部居右
+ */
+
+function set_img_water($imgSrc,$markImg,$markQty=100,$markPos=9){
+	if(intval($markQty)==0)$markQty=100;
+	$srcInfo = @getimagesize($imgSrc);
+	$srcImg_w = $srcInfo[0];
+	$srcImg_h = $srcInfo[1];
+	$srcim = null; $markim = null;
+	switch ($srcInfo[2])
+	{
+		case 1:
+			$srcim =imagecreatefromgif($imgSrc);  break;
+		case 2:
+			$srcim =imagecreatefromjpeg($imgSrc); break;
+		case 3:
+			$srcim =imagecreatefrompng($imgSrc);  break;
+		default:
+			die('unsupport file type'); exit();
+	}
+	if(!file_exists($markImg) || empty($markImg)){return;}
+	
+	$markImgInfo = @getimagesize($markImg);
+	$markImg_w = $markImgInfo[0];
+	$markImg_h = $markImgInfo[1];
+	
+	if($srcImg_w < $markImg_w || $srcImg_h < $markImg_h){return false;}
+	
+	switch ($markImgInfo[2])
+	{
+		case 1:
+			$markim =imagecreatefromgif($markImg);  break;
+		case 2:
+			$markim =imagecreatefromjpeg($markImg); break;
+		case 3:
+			$markim =imagecreatefrompng($markImg);  break;
+		default:
+			return false;//die('不支持的水印图片文件类型');exit();
+	}
+	
+	$logow = $markImg_w;
+	$logoh = $markImg_h;
+	 
+	if($markPos == 0){$markPos = rand(1, 9);}
+	
+	switch($markPos)
+	{
+		case 1: $x = +5; 					$y = +5;  					break;//顶部居左
+		case 2: $x = ($srcImg_w-$logow)/2;	$y = +5; 					break;//顶部居中
+		case 3: $x = $srcImg_w- $logow-5;	$y = +15; 					break;//顶部居右
+		case 4: $x = +5;					$y = ($srcImg_h-$logoh)/2; 	break;//左边居中
+		case 5: $x = ($srcImg_w-$logow)/2;	$y = ($srcImg_h-$logoh)/2;	break;//图片中心
+		case 6: $x = $srcImg_w-$logow-5;	$y = ($srcImg_h-$logoh)/2; 	break;//右边居中
+		case 7: $x = +5;					$y = $srcImg_h-$logoh-5;	break;//底部居左
+		case 8: $x = ($srcImg_w-$logow)/2;	$y = $srcImg_h-$logoh-5;	break;//底部居中
+		case 9: $x = $srcImg_w-$logow-5;	$y = $srcImg_h-$logoh-5;	break;//底部居右
+		default:
+			return false;//die('此位置不支持');exit;
+	}
+	
+	$dst_img = @imagecreatetruecolor($srcImg_w, $srcImg_h);
+	imagecopy($dst_img, $srcim, 0, 0, 0, 0, $srcImg_w, $srcImg_h);
+	imagecopy($dst_img, $markim, $x, $y, 0, 0, $logow, $logoh);
+	imagedestroy($markim);
+	
+	switch ($srcInfo[2])
+	{
+		case 1: imagegif($dst_img, $imgSrc); break;
+		case 2: imagejpeg($dst_img, $imgSrc);break;
+		case 3: imagepng($dst_img, $imgSrc); break;
+		default: break;
+	}
+	imagedestroy($dst_img);
+	imagedestroy($srcim);
+	return true;
+}
+
+//获取一个唯一文件名
+function get_unique_file_name($path,$ext)
+{
+	$fileName = TIMESTAMP.random(6, '0123456789abcdefghijklmnopqrstuvwxyz').".".$ext;//文件重命名
+	if(!file_exists($path.$fileName))
+	{
+		return $fileName;
+	}
+	else 
+	{
+		return get_unique_file_name($path,$ext);
+	}
+}
+
+//转换数组为可适应SQL语句插入语法值集合
+function change_array_to_sql_string($array=array()){ //转换数组为可适应SQL语句插入语法值集合
+	$array=str_replace("'","\'",$array);
+	return "'".implode("','",$array)."'";
+}
+
+// 截取某部分字符
+function interception_of_string($string='',$start='',$end='')
+{
+  if($string==''){return '';}
+  if($start!='')
+  {
+   $pos = strpos($string,$start);
+   if($pos===false)
+   {
+    return '';
+   }
+   else
+   {
+    $pos += strlen($start);
+    $string = substr($string,$pos);
+   }
+  }
+ 
+  if($end!='')
+  {
+   $pos = strpos($string,$end);
+   if($pos)
+   {
+    $string = substr($string,0,$pos);
+   }
+  }
+ 
+  return $string;
+ }
+
+
+//Curl
+function https_request($url,$options = null,$data = null,$header = null){
+	$curl = curl_init();
+	curl_setopt($curl, CURLOPT_URL, $url);
+	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
+    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); //强制协议为1.0
+    curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); //强制使用IPV4协议解析域名
+	if (!empty($data)){
+		curl_setopt($curl, CURLOPT_POST, 1);
+		curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
+	}
+    (isset($options['header'])&&$options['header'])?curl_setopt($curl, CURLOPT_HEADER, 1): curl_setopt($curl, CURLOPT_HEADER, 0);//如果有响应头
+    if(!empty($header))//如果有请求头
+    {
+        $curl_header = array();
+        foreach($header as $key=>$value)
+        {
+            $curl_header[] = "$key:$value";
+        }
+        curl_setopt($curl,CURLOPT_HTTPHEADER, $curl_header);
+    }
+    if(isset($options['gzip'])&&$options['gzip']==1) curl_setopt($curl, CURLOPT_ENCODING, "gzip"); //如果页面开启了GZIP压缩
+	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+	curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0');
+    if(!empty($options['time_out']))
+    {
+        curl_setopt($curl, CURLOPT_TIMEOUT, $options['time_out']);
+    }
+    else
+    {
+        curl_setopt($curl, CURLOPT_TIMEOUT, 15);
+    }
+    curl_setopt ($curl, CURLOPT_REFERER, get_url());
+	$output = curl_exec($curl);
+	curl_close($curl);
+	return $output;
+}
+
+/**批量替换敏感词
+ * @param array $badwords 敏感词数组
+ * @param array $replacement 替换词数组
+ * @param string $str 待替换内容
+ * @return string 
+ */
+function multi_replace($badwords,$replacement,$str)
+{
+	$replaceList = array();
+	if(is_array($badwords))
+	{
+		foreach($badwords as $badword)
+		{
+			$length = mb_strlen($badword,CHARSET);
+			$temp='';
+			for($i=0;$i<$length;$i++)
+			{
+				$temp .= $replacement;
+			}
+			$replaceList[] = $temp;
+		}
+	}
+	return $str = str_replace($badwords,$replaceList,$str);
+}
+
+/**封装后的配置文件包含方法
+ */
+function require_config($file)
+{
+	if(defined('SITE_MODE'))
+	{
+		return require BASE_PATH.'config'.DIRECTORY_SEPARATOR.SITE_MODE.DIRECTORY_SEPARATOR.$file;
+	}
+	else 
+	{
+		return require BASE_PATH.'config'.DIRECTORY_SEPARATOR.$file;
+	}
+}
+
+//格式正则校验
+function pattern_check($type,$value)
+{
+	switch($type)
+	{
+		case 'url':
+			$pattern = '/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/';
+			break;
+		case 'email':
+			$pattern = '/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/';
+			break;
+		default:break;
+	}
+	if(!empty($pattern)&&preg_match($pattern,$value)){
+		return true;
+	}
+	else{
+		return false;
+	}
+}
+
+//请求安全检测
+function check_safe_request_params(){
+	$getfilter="'|<[^>]*?>|^\\+\/v(8|9)|\\b(and|or)\\b.+?(>|<|=|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
+	$postfilter="^\\+\/v(8|9)|\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|<\\s*img\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
+	$cookiefilter="\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
+	$referer=empty($_SERVER['HTTP_REFERER']) ? array() : array($_SERVER['HTTP_REFERER']);
+	foreach($_GET as $key=>$value){
+		if (!check_request_params_ok($key,$value,$getfilter)){exit;}
+	}
+	foreach($_POST as $key=>$value){
+		if (!check_request_params_ok($key,$value,$postfilter)){exit;}
+	}
+	foreach($_COOKIE as $key=>$value){
+		if (!check_request_params_ok($key,$value,$cookiefilter)){exit;}
+	}
+	foreach($referer as $key=>$value){
+		if (!check_request_params_ok($key,$value,$getfilter)){exit;}
+	}
+}
+
+//请求安全检测:子方法
+function check_request_params_ok($StrFiltKey,$StrFiltValue,$ArrFiltReq){
+	$StrFiltValue=arr_foreach($StrFiltValue);
+	if (preg_match('/'.$ArrFiltReq.'/is',$StrFiltValue)==1 || preg_match('/'.$ArrFiltReq.'/is',$StrFiltKey)==1){return false;}
+	return true;
+}
+function arr_foreach($arr) {
+	static $str;
+	if (!is_array($arr)) {return $arr;}
+	foreach ($arr as $key => $val ) {
+		if (is_array($val)) {arr_foreach($val);} else {$str[] = $val;}
+	}
+	return implode($str);
+}
+
+//带超时时间设置的file_get_contents
+function new_file_get_contents($url,$timeout=null)
+{
+    if(isset($timeout))
+    {
+        $opts = array(
+            'http'=>array(
+                'method'=>"GET",
+                'timeout'=>$timeout,//单位秒
+            )
+        );
+        return file_get_contents( $url, false, stream_context_create($opts));
+    }
+    else
+    {
+        return file_get_contents($url);
+    }
+
+}
+
+//判断是否蜘蛛请求
+function checkrobot($useragent = '') {
+    static $kw_spiders = array('bot', 'crawl', 'spider' ,'slurp', 'sohu-search', 'lycos', 'robozilla','haosouspider','baidu','sogou','yisouspider','360spider','baiduspide','soso','yahoo','bingbot');
+    static $kw_browsers = array('msie', 'netscape', 'opera', 'konqueror', 'mozilla');
+    $useragent = strtolower(empty($useragent) ? $_SERVER['HTTP_USER_AGENT'] : $useragent);
+    if(strpos($useragent, 'http://') === false && dstrpos($useragent, $kw_browsers)) return false;
+    if(dstrpos($useragent, $kw_spiders)) return true;
+    return false;
+}
+
+function dstrpos($string, &$arr, $returnvalue = false) {
+    if(empty($string)) return false;
+    foreach((array)$arr as $v) {
+        if(strpos($string, $v) !== false) {
+            $return = $returnvalue ? $v : true;
+            return $return;
+        }
+    }
+    return false;
+}
+
+
+//压缩html
+function compress_html($str){
+    $str = trim($str);
+    $str = str_replace("\t","",$str);
+    $str = str_replace("\r\n","",$str);
+    $str = str_replace("\r","",$str);
+    $str = str_replace("\n","",$str);
+    $str=preg_replace("/>[ ]+/si",">",$str); //过滤>(">"号后面带空格)
+    $str=preg_replace("/[ ]+</si","<",$str); //过滤<("<"号前面带空格)
+    return trim($str);
+}
+
+//字符串过滤,只保留汉字数字英文标点符号
+function removeHtml($html,$filter=1)
+{
+    $html  = htmlspecialchars_decode($html);  //把一些预定义的 HTML 实体转换为字符
+    $html = strip_tags($html);               //函数剥去字符串中的 HTML、XML 以及 PHP 的标签,获取纯文本内容
+    $html = trim($html); //清除字符串两边的空格
+    $html = str_replace("&nbsp;","",$html);
+    $html = preg_replace("/\t/","",$html); //使用正则表达式替换内容,如:空格,换行,并将替换为空。
+    $html = preg_replace("/\r\n/","",$html);
+    $html = preg_replace("/\r/","",$html);
+    $html = preg_replace("/\n/","",$html);
+    $html = preg_replace("/ /","",$html);
+    $html = preg_replace("/ /","",$html); //匹配html中的空格
+    $html =  preg_replace('/($s*$)|(^s*^)/m', '',$html);
+    if($filter)
+    {
+        preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()]/u', $html, $result);
+        return implode('', $result[0]);
+    }
+    else
+    {
+        return $html;
+    }
+
+}
+
+//对转换过程中获取的内容做初始处理
+function beforeProcessHtml($html)
+{
+    preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9]/u', $html, $testResult);
+    if(empty($testResult[0]))
+    {
+        $html =  mb_convert_encoding($html,  'UTF-8', 'UTF-8');
+        preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9。、!?:;﹑•"…‘’“”〝〞∕¦‖— 〈〉﹞﹝「」‹›〖〗】【»«』『〕〔》《﹐¸﹕︰﹔!¡?¿﹖﹌﹏﹋'´ˊˋ―﹫︳︴¯_ ̄﹢﹦﹤‐­˜﹟﹩﹠﹪﹡﹨﹍﹉﹎﹊ˇ︵︶︷︸︹︿﹀︺︽︾ˉ﹁﹂﹃﹄︻︼()]/u', $html, $result);
+        return implode('', $result[0]);
+    }
+    else
+    {
+        return  $html;
+    }
+
+}
+
+//获取所有的cookie内容
+function get_all_cookie_str(){
+    $ckeStr='';
+    foreach ($_COOKIE as $ckeName=>$ckeVal){
+        if(!is_array($ckeVal)){
+            $ckeStr.= $ckeName.'='.$ckeVal.';';
+        }
+    }
+    $ckeStr = substr($ckeStr, 0,-1);//去除最后的 ;
+    return $ckeStr;
+}
+
+
+
+//PHP默认serialize有时会出错 http://us.php.net/manual/en/function.unserialize.php#71270
+function mb_unserialize($serial_str) {
+    $serial_str= preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
+    $serial_str= str_replace("\r", "", $serial_str);
+    return unserialize($serial_str);
+}
+
+//判断是否是移动端访问
+function check_mobile($debug = false) {
+    static $touchbrowser_list =array('iphone', 'android', 'phone', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',
+        'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',
+        'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',
+        'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',
+        'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',
+        'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',
+        'benq', 'haier', '^lct', '320x320', '240x320', '176x220');
+    static $mobilebrowser_list =array('windows phone');
+    static $wmlbrowser_list = array('cect', 'compal', 'ctl', 'lg', 'nec', 'tcl', 'alcatel', 'ericsson', 'bird', 'daxian', 'dbtel', 'eastcom',
+        'pantech', 'dopod', 'philips', 'haier', 'konka', 'kejian', 'lenovo', 'benq', 'mot', 'soutec', 'nokia', 'sagem', 'sgh',
+        'sed', 'capitel', 'panasonic', 'sonyericsson', 'sharp', 'amoi', 'panda', 'zte');
+
+    $pad_list = array('pad', 'gt-p1000');
+    $useragent = strtolower($_SERVER['HTTP_USER_AGENT']);
+    if(($v = dstrpos($useragent, $mobilebrowser_list, true))){
+        return '1'; //windows phone
+    }
+    if(($v = dstrpos($useragent, $touchbrowser_list, true))){
+        return '2';
+    }
+    if(($v = dstrpos($useragent, $wmlbrowser_list))) {
+        return '3'; //wml版
+    }
+    $brower = array('mozilla', 'chrome', 'safari', 'opera', 'm3gate', 'winwap', 'openwave', 'myop');
+    if(dstrpos($useragent, $brower)) return false;
+    return false;
+}
+
+//时间换算
+function info_last_time($time,$ac="Y年m月d日") {
+    $now=TIMESTAMP-$time;
+    $timestr = (substr_count($ac,'-')>0?'Y-m-d':'Y年m月d日');
+    if ($now>3456000)  return get_date($time,$timestr);
+    elseif ($now>345600)  return get_date($time,$ac);
+    elseif ($now>259200) return "三天前";
+    elseif ($now>172800) return "两天前";
+    elseif ($now>86400) return "一天前";
+    elseif ($now>72000) return "二十小时前";
+    elseif ($now>54000) return "十五小时前";
+    elseif ($now>43200) return "十二小时前";
+    elseif ($now>36000) return "十小时前";
+    elseif ($now>28800) return "八小时前";
+    elseif ($now>21600) return "六小时前";
+    elseif ($now>18000) return "五小时前";
+    elseif ($now>10800) return "三小时前";
+    elseif ($now>7200) return "两小时前";
+    elseif ($now>3600) return "一小时前";
+    elseif ($now>1800) return "半小时前";
+    elseif ($now>1200) return "二十分钟前";
+    elseif ($now>900) return "十五分钟前";
+    elseif ($now>600) return "十分钟前";
+    elseif ($now>300) return "五分钟前";
+    elseif ($now>180) return "三分钟前";
+    elseif ($now>120) return "两分钟前";
+    elseif ($now>=0) return "一分钟前";
+    elseif ($now<0) return "一秒钟前";
+    return get_date($time,$ac);
+}
+/**
+ * 格式化时间戳为日期字符串
+ * @global string $db_datefm
+ * @global string $db_timedf
+ * @global string $_datefm
+ * @global string $_timedf
+ * @param int $timestamp
+ * @param string $format
+ * @return string
+ */
+function get_date($timestamp, $format = null) {
+    if(empty($timestamp))return '';
+    $obj = new \DateTime("@$timestamp"); // 这里时间戳前要写一个@符号
+    $timezone = timezone_open(TIME_ZONE); // 设置时区
+    $obj->setTimezone($timezone);
+    $sDefaultFormat = $format ? $format : 'Y-m-d H:i';
+    return $obj->format($sDefaultFormat);
+}
+
+//日期转时间戳
+function str_to_time($str)
+{
+    $date = new \DateTime($str);
+    return  $date->format('U');
+}
+
+//301跳转
+function header_goto($str) {
+    Header("HTTP/1.1 301 Moved Permanently");
+    Header($str);exit;
+}
+
+
+/**
+ * 截断字符串
+ *
+ * @param string $content 内容
+ * @param int $length 截取字节数
+ * @param string $add 是否带省略号,Y|N
+ * @return string
+ */
+
+function substrs($content, $length, $add = 'Y') {
+	if (strlen($content) > $length) {
+		if (CHARSET != 'utf-8') {
+			$cutStr = '';
+			for ($i = 0; $i < $length - 1; $i++) {
+				$cutStr .= ord($content[$i]) > 127 ? $content[$i] . $content[++$i] : $content[$i];
+			}
+			$i < $length && ord($content[$i]) <= 127 && $cutStr .= $content[$i];
+			return $cutStr . ($add == 'Y' ? ' ..' : '');
+		}
+		return utf8_trim(substr($content, 0, $length)) . ($add == 'Y' ? ' ..' : '');
+	}
+	return $content;
+}
+
+/**
+ * utf8字符串整齐化
+ *
+ * @param string $str
+ * @return string
+ */
+function utf8_trim($str) {
+	$hex = '';
+	$len = strlen($str) - 1;
+	for ($i = $len; $i >= 0; $i -= 1) {
+		$ch = ord($str[$i]);
+		$hex .= " $ch";
+		if (($ch & 128) == 0 || ($ch & 192) == 192) {return substr($str, 0, $i);}
+	}
+	return $str . $hex;
+}
+
+
+function echo_json($arr){
+    ob_clean();
+    header('Content-type: application/json');
+    echo json_encode($arr);exit;
+}
+
+//生成唯一订单号
+function getUniOrderNo()
+{
+    $order_id = get_date(TIMESTAMP,'Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
+    $exists = \app\modules\shopping\models\ShoppingOrder::find()->where("order_sn='".$order_id."'")->exists();
+    if($exists)
+    {
+        return getUniOrderNo();
+    }
+    else
+    {
+        return $order_id;
+    }
+
+}
+//生成唯一券号
+function getUniCouponNo()
+{
+    $coupon_no = get_date(TIMESTAMP,'Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
+    $exists = \app\modules\ucenter\models\UserVipCoupon::find()->where("coupon_no='".$coupon_no."'")->exists();
+    if($exists)
+    {
+        return getUniCouponNo();
+    }
+    else
+    {
+        return $coupon_no;
+    }
+
+}
+//生成唯一订单号(毫秒级)
+function getProUniOrderNo()
+{
+    $order_id_main = get_date(TIMESTAMP,'YmdHis') . rand(10,99);
+    $order_id_len = strlen($order_id_main);
+    $order_id_sum = 0;
+    for($i=0; $i<$order_id_len; $i++){
+        $order_id_sum += (int)(substr($order_id_main,$i,1));
+    }
+    $order_id = $order_id_main . str_pad((100 - $order_id_sum % 100) % 100,2,'0',STR_PAD_LEFT);
+    return $order_id;
+}
+
+/**
+ *  二維数组排序
+ */
+function array_sort($arr,$sort)
+{
+   /* $sort = array(
+        'direction' => 'SORT_DESC', //排序顺序标志 SORT_DESC 降序;SORT_ASC 升序
+        'field'     => 'length',     //排序字段
+    );*/
+
+    $arrSort = array();
+    foreach($arr AS $uniqid => $row){
+        foreach($row AS $key=>$value){
+            $arrSort[$key][$uniqid] = $value;
+        }
+    }
+    if($sort['direction']){
+        array_multisort($arrSort[$sort['field']], constant($sort['direction']), $arr);
+    }
+    return $arr;
+}
+
+/**
+ * 可以统计中文字符串长度的函数
+ * @param $str 要计算长度的字符串
+ * @param $type 计算长度类型,0(默认)表示一个中文算一个字符,1表示一个中文算两个字符
+ */
+function abslength($str)
+{
+    if(empty($str)){
+        return 0;
+    }
+    if(function_exists('mb_strlen')){
+        return mb_strlen($str,'utf-8');
+    }
+    else {
+        preg_match_all("/./u", $str, $ar);
+        return count($ar[0]);
+    }
+}
+
+
+//过滤微信表情
+function filterEmoji($nickname)
+{
+    $nickname = preg_replace('/[\x{1F600}-\x{1F64F}]/u', '', $nickname);
+    $nickname = preg_replace('/[\x{1F300}-\x{1F5FF}]/u', '', $nickname);
+    $nickname = preg_replace('/[\x{1F680}-\x{1F6FF}]/u', '', $nickname);
+    $nickname = preg_replace('/[\x{2600}-\x{26FF}]/u', '', $nickname);
+    $nickname = preg_replace('/[\x{2700}-\x{27BF}]/u', '', $nickname);
+    $nickname = str_replace(array('"','\''), '', $nickname);
+    return $nickname;
+}
+
+//单条对象记录转数组
+function single_object_to_array($result,$needfield = array())
+{
+    $info = array();
+    if(is_object($result))
+    {
+        foreach($result as $key=>$value)
+        {
+            if(!empty($needfield)&&in_array($key,$needfield))
+            {
+                $info[$key] = $value;
+            }
+            if(empty($needfield))
+            {
+                $info[$key] = $value;
+            }
+        }
+        return $info;
+    }
+    else
+    {
+        return $result;
+    }
+
+}
+
+//获得文件绝对路径
+function getFileUrl($path,$internal=0)
+{
+    if(empty($path)) return;
+    if(strpos($path,'http')!==false)
+    {
+        $path = str_replace(array('https://','http://'),array(SITE_PROTOCOL,SITE_PROTOCOL),$path);
+    }
+    else
+    {
+        //如果开启了OSS
+        if(Yii::$app->params['oss']['OPEN_OSS'])
+        {
+            if($internal==1)
+            {
+                $path =  getOssInterUrl().$path;
+            }
+            else
+            {
+                $path =  getOssUrl().$path;
+            }
+        }
+        else
+        {
+            $path =  UPLOAD_URL.$path;
+        }
+
+    }
+    if(IN_WAP)
+    {
+        $path = str_replace(WEB_URL,WAP_URL,$path);
+    }
+    return $path;
+}
+
+
+//获得文件转换结果路径
+function getFileWorkPath($file)
+{
+    $result = parse_url($file);
+    $path= str_replace('/upload/','',$result['path']);
+    $ext = fileext($path);
+    $workpath = dirname($path).DIRECTORY_SEPARATOR.md5(basename($path,'.'.$ext)).DIRECTORY_SEPARATOR;
+    $workpath = ltrim(str_replace(DIRECTORY_SEPARATOR,'/',$workpath),'/');
+    return $workpath;
+}
+
+//获得文件相对路径
+function getFilePath($file)
+{
+    $result = parse_url($file);
+    $path= str_replace('/upload/','',$result['path']);
+    return $path;
+}
+
+function unserializeFileRealUrl($string,$first=true)
+{
+    $fileList = string2array($string);
+    $urls = '';
+    if($first)
+    {
+        if(isset($fileList['filepath']))
+        {
+            if(!empty($fileList['filepath']))
+            {
+                $urls = getFileUrl($fileList['filepath']);
+            }
+        }
+        else
+        {
+            if(!empty($fileList[0]['filepath']))
+            {
+                if(strpos($fileList[0]['fileurl'],'http')!==false)
+                {
+                    return $fileList[0]['fileurl'];
+                }
+                else
+                {
+                    $urls = getFileUrl($fileList[0]['filepath']);
+                }
+            }
+        }
+    }
+    else
+    {
+        $urls = array();
+        if(is_array($fileList))foreach($fileList as $file)
+        {
+            if(!empty($file['filepath']))$urls[] = getFileUrl($file['filepath']);
+        }
+    }
+    return $urls;
+}
+
+
+//判断是否是手机站
+function is_wap_site()
+{
+    if(IN_WAP==true)
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
+//判断是IOS或安卓系统
+function get_device_type()
+{
+    //全部变成小写字母
+    $agent = strtolower($_SERVER['HTTP_USER_AGENT']);
+    $type ='other';
+    //分别进行判断
+    if(strpos($agent,'iphone') || strpos($agent,'ipad'))
+    {
+        $type ='ios';
+    }
+    if(strpos($agent,'android'))
+    {
+        $type ='android';
+    }
+    return $type;
+}
+
+//判断是否是微信访问
+function check_micromsg()
+{
+    $agent =  strtolower($_SERVER['HTTP_USER_AGENT']);
+    if (stripos($agent, 'MicroMessenger') !== false)
+    {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+//判断是否是百度小程序访问
+function check_baiduapp()
+{
+    $agent =  strtolower($_SERVER['HTTP_USER_AGENT']);
+    if (stripos($agent, 'baiduboxapp') !== false)
+    {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+//判断是否是微信小程序访问
+function check_wxapp()
+{
+    $agent =  strtolower($_SERVER['HTTP_USER_AGENT']);
+    if (stripos($agent, 'miniprogram') !== false)
+    {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/*
+ * 作用:用*号替代姓名除第一个字之外的字符
+ * 参数:
+ *
+ *
+ * 返回值:string
+ */
+function starReplace($name, $num = 0)
+{
+    if ($num && mb_strlen($name, 'UTF-8') > $num) {
+        return mb_substr($name, 0, 4) . '*';
+    }
+
+    if ($num && mb_strlen($name, 'UTF-8') <= $num) {
+        return $name;
+    }
+
+    $doubleSurname = [
+        '欧阳', '太史', '端木', '上官', '司马', '东方', '独孤', '南宫',
+        '万俟', '闻人', '夏侯', '诸葛', '尉迟', '公羊', '赫连', '澹台', '皇甫', '宗政', '濮阳',
+        '公冶', '太叔', '申屠', '公孙', '慕容', '仲孙', '钟离', '长孙', '宇文', '司徒', '鲜于',
+        '司空', '闾丘', '子车', '亓官', '司寇', '巫马', '公西', '颛孙', '壤驷', '公良', '漆雕', '乐正',
+        '宰父', '谷梁', '拓跋', '夹谷', '轩辕', '令狐', '段干', '百里', '呼延', '东郭', '南门', '羊舌',
+        '微生', '公户', '公玉', '公仪', '梁丘', '公仲', '公上', '公门', '公山', '公坚', '左丘', '公伯',
+        '西门', '公祖', '第五', '公乘', '贯丘', '公皙', '南荣', '东里', '东宫', '仲长', '子书', '子桑',
+        '即墨', '达奚', '褚师', '吴铭'
+    ];
+
+    $surname = mb_substr($name, 0, 2);
+    if (in_array($surname, $doubleSurname)) {
+        $name = mb_substr($name, 0, 2) . str_repeat('*', (mb_strlen($name, 'UTF-8') - 2));
+    } else {
+        $name = mb_substr($name, 0, 1) . str_repeat('*', (mb_strlen($name, 'UTF-8') - 1));
+    }
+
+
+    return $name;
+}
+
+//比如找回密码当中邮件验证码用到的
+function randString($length=32)
+{
+    return Yii::$app->getSecurity()->generateRandomString($length);
+}
+
+//生成密码
+function generatePwd($password)
+{
+
+    return Yii::$app->getSecurity()->generatePasswordHash($password);
+
+}
+
+//校验密码
+function validatePwd($password,$hash)
+{
+   return Yii::$app->getSecurity()->validatePassword($password, $hash);
+}
+
+//页面元素 name 转ID
+function nameToId($name)
+{
+    $name = str_replace('[','-',$name);
+    $name = str_replace(']','',$name);
+    return strtolower($name);
+}
+
+//抛出404
+function do404()
+{
+    throw new \Exception('页面未找到',404);
+}
+
+
+function isSpider() {
+    $agent= strtolower($_SERVER['HTTP_USER_AGENT']);
+    if (!empty($agent)) {
+        $spiderSite= array(
+            "TencentTraveler",
+            "Baiduspider+",
+            "BaiduGame",
+            "Googlebot",
+            "msnbot",
+            "Sosospider+",
+            "Sogou web spider",
+            "ia_archiver",
+            "Yahoo! Slurp",
+            "YoudaoBot",
+            "Yahoo Slurp",
+            "MSNBot",
+            "Java (Often spam bot)",
+            "BaiDuSpider",
+            "Voila",
+            "Yandex bot",
+            "BSpider",
+            "twiceler",
+            "Sogou Spider",
+            "Speedy Spider",
+            "Google AdSense",
+            "Heritrix",
+            "Python-urllib",
+            "Alexa (IA Archiver)",
+            "Ask",
+            "Exabot",
+            "Custo",
+            "OutfoxBot/YodaoBot",
+            "yacy",
+            "SurveyBot",
+            "legs",
+            "lwp-trivial",
+            "Nutch",
+            "StackRambler",
+            "The web archive (IA Archiver)",
+            "Perl tool",
+            "MJ12bot",
+            "Netcraft",
+            "MSIECrawler",
+            "WGet tools",
+            "larbin",
+            "Fish search",
+        );
+        foreach($spiderSite as $val) {
+            $str = strtolower($val);
+            if (strpos($agent, $str) !== false) {
+                return true;
+            }
+        }
+    } else {
+        return false;
+    }
+}
+
+
+
+
+
+
+
+
+
+/**
+ * @param array $_define   默认seo配置
+ * @param unknown_type $_values	对应 targets 的一组值
+ * @param unknown_type $_targets
+ * @return multitype:string
+ */
+function seoSettings($_define = array(), $_replaceconfig = array(),$_default = array()) {
+
+    if (!empty($_define)) {
+        $cTitle = $_define[$_replaceconfig['pre'].'meta_title'];
+        $cKeywords = $_define[$_replaceconfig['pre'].'meta_keywords'];
+        $cDescription = $_define[$_replaceconfig['pre'].'meta_description'];
+    }
+    $_values = $_replaceconfig['values'];
+    $_targets = $_replaceconfig['targets'];
+    /* 过滤参数 */
+    foreach ($_values as $key => $value) {
+        $_values[$key] = empty($value) ? '' : trim(strip_tags($value));
+    }
+
+    /*设置默认值*/
+    empty($cTitle) && $cTitle = $_default['meta_title'];
+    empty($cKeywords) && $cKeywords = $_default['meta_keywords'];
+    empty($cDescription) && $cDescription = $_default['meta_description'];
+
+    /* 参数处理 */
+    $webPageTitle = parseSeoTargets($cTitle, $_values, $_targets);
+    $metaDescription = parseSeoTargets($cDescription, $_values, $_targets);
+    $metaKeywords = trim(parseSeoTargets($cKeywords, $_values, $_targets),',');
+    $metaKeywords = str_replace(',',',',trim($metaKeywords,','));
+    //如果关键词为空,用标题替代
+    if(empty($metaKeywords))$metaKeywords = $webPageTitle;
+    return array($webPageTitle, $metaKeywords, $metaDescription);
+}
+
+/**
+ * @param string $content
+ * @param array $_replace
+ * @param array $_targets
+ * @return string
+ */
+function parseSeoTargets($content, $_values, $_targets) {
+    $content = str_replace($_targets, $_values, $content);
+    $content = trim(preg_replace(array('((\s*\,\s*)+)', '((\s*\|\s*)+)', '((\s*\t\s*)+)'), array(
+        ',', '|', '', ''), $content), ' -,|');
+    return $content;
+}
+
+//获取目录(含子目录)下所有文件
+function get_allfiles($path,&$files) {
+    if(is_dir($path)){
+        $dp = dir($path);
+        while ($file = $dp ->read()){
+            if($file !="." && $file !=".."){
+                get_allfiles($path."/".$file, $files);
+            }
+        }
+        $dp ->close();
+    }
+    if(is_file($path)){
+        $files[] = $path;
+    }
+}
+
+function get_filenamesbydir($dir){
+    $files = array();
+    get_allfiles($dir,$files);
+    return $files;
+}
+
+
+
+
+?>
+

+ 81 - 0
common/helpers/Capcha.php

@@ -0,0 +1,81 @@
+<?php
+namespace app\common\helpers;
+use Yii;
+/*  
+ * Capcha.php  
+ * 验证码生成
+ * 更新: Jacky.Chen 2019/06/20 15:45  
+ *  
+ */
+class Capcha{
+	private $charset = 'abcdefghkmnprstuvwxyzABCDEFGHKMNPRSTUVWXYZ23456789';//随机因子
+	private $code;//验证码
+	public  $codelen = 4;//验证码长度
+	public  $width = 100;//宽度
+	public  $height = 30;//高度
+	private $img;//图形资源句柄
+	private $font;//指定的字体
+	private $fontsize = 15;//指定字体大小
+	private $fontcolor;//指定字体颜色
+	//构造方法初始化
+	public function __construct() {
+        if(!file_exists(BASE_PATH.'/static/fonts/elephant.ttf'))
+            exit('The file:'.BASE_PATH.'/static/fonts/elephant.ttf'.' does not exist.');
+		$this->font = BASE_PATH.'/static/fonts/elephant.ttf';//注意字体路径要写对,否则显示不了图片
+	}
+	//生成随机码
+	private function createCode() {
+		$_len = strlen($this->charset)-1;
+		for ($i=0;$i<$this->codelen;$i++) {
+			$this->code .= $this->charset[mt_rand(0,$_len)];
+		}
+	}
+	//生成背景
+	private function createBg() {
+		$this->img = imagecreatetruecolor($this->width, $this->height);
+		$white = imagecolorallocate($this->img, 255,255,255);
+		imagefilledrectangle($this->img,0,$this->height,$this->width,0,$white);
+	}
+	//生成文字
+	private function createFont() {
+		$_x = $this->width / $this->codelen;
+		for ($i=0;$i<$this->codelen;$i++) {
+			$this->fontcolor = imagecolorallocate($this->img,mt_rand(0,156),mt_rand(0,156),mt_rand(0,156));
+			imagettftext($this->img,$this->fontsize,mt_rand(-30,30),$_x*$i+mt_rand(1,5),$this->height / 1.2,$this->fontcolor,$this->font,$this->code[$i]);
+		}
+	}
+	//生成线条、雪花
+	private function createLine() {
+		//线条
+		for ($i=0;$i<6;$i++) {
+			$color = imagecolorallocate($this->img,mt_rand(0,156),mt_rand(0,156),mt_rand(0,156));
+			imageline($this->img,mt_rand(0,$this->width),mt_rand(0,$this->height),mt_rand(0,$this->width),mt_rand(0,$this->height),$color);
+		}
+		//雪花
+		for ($i=0;$i<100;$i++) {
+			$color = imagecolorallocate($this->img,mt_rand(200,255),mt_rand(200,255),mt_rand(200,255));
+		imagestring($this->img,mt_rand(1,5),mt_rand(0,$this->width),mt_rand(0,$this->height),'*',$color);
+		}
+		
+	}
+	//输出
+	private function outPut() {
+		header('Content-type:image/png');
+		imagepng($this->img);
+		imagedestroy($this->img);
+	}
+	//对外生成
+	public function doimg() {
+		$this->createBg();
+		$this->createCode();
+		$this->createLine();
+		$this->createFont();
+		$this->outPut();
+	}
+	//获取验证码
+	public function getCode() {
+		return strtolower($this->code);
+	}
+}
+
+?>

+ 59 - 0
common/helpers/Cookie.php

@@ -0,0 +1,59 @@
+<?php
+namespace app\common\helpers;
+use Yii;
+class Cookie
+{
+	static function getInitCls()
+	{
+		static $initCls = NULL;
+		if(!isset($initCls)) $initCls = new Cookie();
+		return $initCls;
+	}
+
+	//设置cookie
+	public static function setCookie($name,$value,$expire=0)
+	{
+        ob_clean();
+        $cookies = Yii::$app->response->cookies;
+        $args = [
+            'name' => $name,
+            'value' => $value,
+        ];
+        if(!empty($expire))
+        {
+            $args['expire'] =  TIMESTAMP+$expire;
+        }
+        if(defined('COOKIE_DOMAIN')&&COOKIE_DOMAIN!='')
+        {
+            $args['domain'] =  COOKIE_DOMAIN;
+        }
+        $cookies->add(new \yii\web\Cookie($args));
+		return true;
+	}
+
+	//读取cookie值
+	public static function getCookie($name)
+	{
+        $cookies = Yii::$app->request->cookies;
+        return $cookies->getValue($name);
+	}
+
+	//销毁cookie
+	public static function deleteCookie($name)
+	{
+        if(defined('COOKIE_DOMAIN')&&COOKIE_DOMAIN!='')
+		{
+            $cookie =  new \yii\web\Cookie([
+                'name' => $name,
+                'domain' => COOKIE_DOMAIN,
+            ]);
+            Yii::$app->response->cookies->remove($cookie);
+		}
+		else
+		{
+            $cookies  = Yii::$app->response->cookies;
+            unset($cookies[$name]);
+		}
+
+	}
+}

+ 266 - 0
common/helpers/Identify.php

@@ -0,0 +1,266 @@
+<?php
+namespace app\common\helpers;
+use app\modules\ucenter\models\User;
+use app\modules\ucenter\models\UserGroup;
+use app\modules\ucenter\models\UserGroupLevel;
+use app\modules\ucenter\models\UserLoginLog;
+use app\modules\ucenter\models\Message;
+use app\modules\ucenter\models\MessageRead;
+use app\modules\ucenter\models\ShareLog;
+use app\common\components\Wallet;
+use app\models\ContentModel;
+use Yii;
+//前台用户COOKIE生成,更新,销毁身份认证类
+class Identify 
+{
+    //传入用户对象,生成用户身份状态cookie
+    public static function doLogin($user,$expire=0)
+    {
+        $identityInfo = array();
+        $identityInfo['user_id'] = $user->user_id;
+        $identityInfo['user_name'] = $user->user_name;
+        $identityInfo['cookieHash'] = sys_auth($user->user_name);
+        //上一次登录时间
+        if($user->last_login_time)
+        {
+            $lastLoginLog = UserLoginLog::find()->where("user_id=".$user->user_id."")->orderBy(['id' => SORT_DESC])->limit(1)->one();
+            $identityInfo['last_login_time'] = $lastLoginLog->login_time;
+        }
+        $identityInfo = sys_auth(array2string($identityInfo));
+        if(!empty($expire))
+        {
+            Cookie::getInitCls()->setCookie(Yii::$app->params['userCookieName'],$identityInfo,$expire);
+        }
+        else
+        {
+            Cookie::getInitCls()->setCookie(Yii::$app->params['userCookieName'],$identityInfo);
+        }
+        $user->last_login_time=TIMESTAMP;
+        $user->last_login_ip = MYIP;
+        $user->save();
+        //写登录日志
+        $loginLog = new UserLoginLog();
+        $loginLog->user_id = $user->user_id;
+        $loginLog->login_ip = MYIP;
+        $loginLog->login_time = TIMESTAMP;
+        $loginLog->request_from = REQUEST_FROM;
+        $loginLog->create_time = TIMESTAMP;
+        $loginLog->update_time = TIMESTAMP;
+        $loginLog->save();
+        //更新用户关联数据
+        \app\modules\ucenter\models\User::refreshData($user->user_id);
+        return true;
+    }
+
+    //获取用户信息
+    public static function getUserInfo($user_id=NULL,$key=NULL)
+    {
+        if(empty($user_id))
+        {
+            $identityInfo = Cookie::getInitCls()->getCookie(Yii::$app->params['userCookieName']);
+            if(empty($identityInfo))
+            {
+                return null;
+            }
+            else
+            {
+                $identityInfo = string2array(sys_auth($identityInfo,'DECODE'));
+                $user = User::findOne($identityInfo['user_id']);
+            }
+
+        }
+        else
+        {
+            $identityInfo = [];
+            $user = User::findOne($user_id);
+            if(empty($user))
+            {
+                return null;
+            }
+        }
+        $identityInfo['user_id'] = intval($user->user_id);
+        $identityInfo['user_name'] = $user->user_name;
+        $identityInfo['group_id'] = intval($user->group_id);
+        $identityInfo['user_group_level'] = intval($user->user_group_level);
+        $identityInfo['email']=$user->email;
+        $identityInfo['mobile']=$user->mobile;
+        $identityInfo['nick_name']=$user->nick_name;
+        $identityInfo['real_name']=$user->real_name;
+        $identityInfo['sex'] = $user->sex;
+        $identityInfo['birthday'] = $user->birthday;
+        $identityInfo['signature'] = $user->signature;
+        $identityInfo['qq'] = $user->qq;
+        $identityInfo['weixin'] = $user->weixin;
+        $identityInfo['region_id']=$user->region_id;
+        $identityInfo['address']=$user->address;
+        $identityInfo['money'] = $user->money;
+        $identityInfo['coin'] = $user->coin;
+        $identityInfo['point'] = $user->point;
+        $identityInfo['allpoint'] = $user->allpoint;
+        $identityInfo['amount_money_income'] = $user->amount_money_income;
+        $identityInfo['coin_income'] = $user->coin_income;
+        $identityInfo['amount_coin_income'] = $user->amount_coin_income;
+        $identityInfo['content_model_id'] = intval($user->content_model_id);
+        $identityInfo['avatar'] = $user->avatar;
+        $identityInfo['weixin_img'] = $user->weixin_img;
+        $identityInfo['vip_info'] = $user?$user->vipInfo():null;
+        $identityInfo['vip_settings'] =  $user?$user->vipSettings():null;
+        $identityInfo['org_vip_settings'] =  $user?$user->vipSettings('org_vip_settings'):null;
+        $identityInfo['vip_name'] =  $user?$user->vipName():null;
+        $identityInfo['org_vip_name'] =  $user?$user->vipName('org_vip_settings'):null;
+        $identityInfo['open_home'] = $user->open_home;
+        $identityInfo['open_upload'] = $user->open_upload;
+        $identityInfo['cart_num'] = 0;
+        $identityInfo['referer_id'] = $user->referer_id;
+        $identityInfo['referer_ids'] = $user->referer_ids;
+        $identityInfo['is_lock'] = $user->is_lock;
+        $identityInfo['is_delete'] = $user->is_delete;
+        if($user)
+        {
+            //附表信息
+            $tablename = userDetailTable($user->content_model_id);
+            $userDetail = Yii::$app->db->createCommand("select * from $tablename where user_id=".$user->user_id)->queryOne();
+            $identityInfo = array_merge($identityInfo,$userDetail);
+            //用户组
+            $identityInfo['group_name'] = $user->group?$user->group->group_name:'';
+            $identityInfo['group_level_name'] = $user->grouplevel?$user->grouplevel->name:'';
+            //获取用户等级基础权限
+            $identityInfo['group_rights'] = string2array($user->grouplevel->settings);
+            //获取未读消息数量
+            $readIds = [];
+            $readedMsgList =  MessageRead::find()->where("user_id=".$user->user_id)->all();
+            if(is_array($readedMsgList))foreach($readedMsgList as $readMsg)
+            {
+                $readIds[] = $readMsg->m_id;
+            }
+            $sysCount = Message::find()->where("message_type=1")->count();
+            $sysCount = $sysCount-count($readIds);
+            $commonCount = Message::find()->where("to_user=".$user->user_id." and have_read=0 and to_delete=0")->count();
+            $identityInfo['msgcount'] = ($sysCount+$commonCount)>0?($sysCount+$commonCount):0;
+            //获取关联机构信息
+            $store = Yii::$app->db->createCommand("select * from {{%shopping_store}} where user_id=".$user->user_id)->queryOne();
+            if($store)
+            {
+                $identityInfo['store'] = $store;
+                $identityInfo['store_id'] = $store['store_id'];
+            }
+            //认证信息
+            $certList = getSysconfigValue('user_cert_type');
+            if(is_array($certList))foreach($certList as $k=>$name)
+            {
+                $identityInfo['cert_'.$k.'_name'] = $identityInfo['cert_'.$k]==1?$name:'';
+            }
+        }
+        return  !is_null($key)?$identityInfo[$key]:$identityInfo;
+    }
+
+
+
+    //判断用户是否登录,并验证信息是否合法
+    public static function hasLogined()
+    {
+        $userInfo = self::getUserInfo();
+        if(!empty($userInfo)&&sys_auth($userInfo['cookieHash'],'DECODE') == $userInfo['user_name'])
+        {
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    //注销用户登录信息
+    public static function logout()
+    {
+        Cookie::getInitCls()->deleteCookie(Yii::$app->params['userCookieName']);
+        return true;
+    }
+
+    public static function test()
+    {
+        print_r(Yii::$app->controller->module->pointconfig);
+        exit;
+    }
+
+    //创建新用户
+    public static function createUser($userOpenAuth,$contentModelId)
+    {
+        //系统默认值
+        $baseconfigResult = \app\modules\admin\models\Config::find()->where("name='baseconfig'")->one();
+        $baseconfig = string2array($baseconfigResult->value);
+        $pointconfigResult = \app\modules\admin\models\Config::find()->where("name='point'")->one();
+        $pointconfig = string2array($pointconfigResult->value);
+
+        if(empty($baseconfig['username_pre']))exit('请设置用户名前缀');
+        $default_user_group = getDefaultUserGroup($contentModelId);
+        if(empty($default_user_group))exit('请设置默认用户组');
+        $default_user_group_level = getDefaultUserGroupLevel($contentModelId);
+        if(empty($default_user_group_level))exit('请设置默认用户等级');
+
+        //写用户
+        $userInfo = string2array(base64_decode($userOpenAuth->user_info));
+        $max_user = User::find()->orderBy(['user_id'=>SORT_DESC])->one();
+        $user = new User();
+        $user->request_from = (strpos($userOpenAuth->scene_id,'pc_')!==false||strpos($userOpenAuth->scene_id,'mplogin_')!==false)?1:REQUEST_FROM;
+        $user->user_id = $max_user->user_id+1;
+        $user->user_name = $baseconfig['username_pre'].str_pad($max_user->user_id+1,10,'0',STR_PAD_LEFT);
+        $user->nick_name = $userInfo['nick_name']?$userInfo['nick_name']:Yii::$app->params['defaultNickName'];
+        $user->avatar = $userInfo['avatar']?$userInfo['avatar']:'';
+        $user->mobile = $userInfo['mobile']?$userInfo['mobile']:'';
+        $user->sex = intval($userInfo['sex']);
+        //用于分销的参数
+        $share_no = \app\common\helpers\Cookie::getCookie(Yii::$app->params['shareArgName']);
+        if(!empty($share_no))
+        {
+            $shareResult = getReferIdsByShareNo($share_no);
+            $user->referer_id = $shareResult['referer_id'];
+            $user->referer_ids = $shareResult['referer_ids'];
+        }
+        else
+        {
+            $user->referer_id = 0;
+        }
+        $user->register_time = TIMESTAMP;
+        $user->user_group_level = $default_user_group_level;//默认用户等级
+        $user->group_id = $default_user_group;//默认用户组
+        $user->content_model_id = $contentModelId;
+        if($user->save())
+        {
+            //邀请注册积分奖励
+            if($pointconfig['invite_register_prize']>0&&$user->referer_id>0)
+            {
+                Wallet::pointChange($user->referer_id,$pointconfig['invite_register_prize'],'邀请注册',1,'point');
+            }
+            $tableName = userDetailTable($contentModelId);
+            $sql = "insert into $tableName set user_id=".$user->user_id."";
+            Yii::$app->db->createCommand($sql)->execute();
+            //百度竞价跟踪
+            $bd_vid =  \app\common\helpers\Cookie::getCookie('bd_vid');
+            if(!empty($bd_vid))
+            {
+                $higherconfigResult = \app\modules\admin\models\Config::find()->where("name='higherconfig'")->one();
+                $higherconfig = string2array($higherconfigResult->value);
+                $token = $higherconfig['reg_cpc_token'];
+                if(!empty($token))
+                {
+                    $cv = array(
+                        'logidUrl' => APP_URL.'?bd_vid='.$bd_vid, // 您的落地页url
+                        'newType' => 49 // 转化类型请按实际情况填写
+                    );
+                    $conversionTypes = array($cv);
+                    $baiducpc = new \app\common\components\BaiduCpc();
+                    $baiducpc->sendConvertData($token, $conversionTypes);
+                }
+
+            }
+            return $user;
+        }
+        else
+        {
+            return false;
+        }
+
+    }
+
+}

+ 88 - 0
common/helpers/Session.php

@@ -0,0 +1,88 @@
+<?php
+namespace app\common\helpers;
+use Yii;
+/*  
+ * Session.php  
+ * Session 操作
+ * 更新: Jacky.Chen 2019/06/20 15:45  
+ *  
+ */
+class Session
+{
+	static function getInitCls()
+	{
+		static $initCls = NULL;
+		if(!isset($initCls)) $initCls = new Session();
+		return $initCls;
+	}
+
+	//设置
+	public static function set($name,$value)
+	{
+
+        $session = Yii::$app->session;
+        if ($session->isActive)$session->open();
+        if(strpos($name,'.')!==false)
+        {
+            self::setArray($name,$value);
+        }
+        else{
+            $session->set($name, $value);
+        }
+		return true;
+	}
+	//读取
+	public static function get($name)
+	{
+        $session = Yii::$app->session;
+        if ($session->isActive)$session->open();
+        if(strpos($name,'.')!==false)
+        {
+            return self::getArray($name);
+        }
+        else
+        {
+            return $session->get($name);
+        }
+
+	}
+    //设置数组中的值,用法  setArray('user.name','jack')
+    public static function setArray($name,$value)
+    {
+
+        $session = Yii::$app->session;
+        if ($session->isActive)$session->open();
+        $names = explode('.',$name);
+        $rs = $session->get($names[0]);
+        $rs[$names[1]] = $value;
+        self::set($names[0],$rs);
+        return true;
+
+    }
+    //读取
+    public static function getArray($name)
+    {
+        $session = Yii::$app->session;
+        if ($session->isActive)$session->open();
+        $names = explode('.',$name);
+        return $session[$names[0]][$names[1]];
+    }
+	//删除
+	public static function remove($name)
+	{
+        $session = Yii::$app->session;
+        if ($session->isActive)$session->open();
+        $session->remove($name);
+        return true;
+	}
+    //销毁
+    public static function destory()
+    {
+        $session = Yii::$app->session;
+        if ($session->isActive)$session->open();
+        $session->destroy();
+        return true;
+    }
+
+
+}

+ 304 - 0
common/models/EActiveRecord.php

@@ -0,0 +1,304 @@
+<?php
+//model 的重写基类
+
+namespace app\common\models;
+use app\models\Linkmenu;
+use app\models\ContentModel;
+use app\modules\admin\models\Sysconfig;
+use app\modules\admin\models\Role;
+use app\modules\ucenter\models\UserGroup;
+use app\modules\ad\models\AdInd;
+use app\modules\ad\models\AdSpace;
+use Yii;
+use yii\db\ActiveRecord;
+
+class EActiveRecord extends ActiveRecord
+{
+
+    public static function shortTableName()
+    {
+        $table_name = self::tableName();
+        return str_replace(array('{{%','}}'),"",$table_name);
+    }
+
+    /**
+     * 获取模型验证的第一个错误
+     */
+    public function returnFirstError()
+    {
+        $errors = $this->getErrors();
+        if(!empty($errors)){
+            $firstError = array_splice($errors, 0,1);
+            $attribute = key($firstError);
+            return $this->getFirstError($attribute);
+        }
+        return null;
+    }
+
+    //获取最后插入ID
+    public static  function getLastInsertId()
+    {
+        return Yii::$app->db->getLastInsertID();
+    }
+
+    /**
+     * @返回主键.
+     */
+
+    public static function modelPrimaryKey()
+    {
+        $pkInfo = parent::primaryKey();
+        return $pkInfo[0];
+    }
+
+    //禁用状态
+    public static function disableOptions($k=null)
+    {
+        $options = array('1'=>'禁用','0'=>'启用');
+        if(is_numeric($k))return $options[$k];
+        return $options;
+    }
+
+    //是否选择
+    public static function boolOptions($k=null)
+    {
+        $options = array('1'=>'是','0'=>'否');
+        if(is_numeric($k))return $options[$k];
+        return $options;
+    }
+
+    //返回某个表(传入表名不含前缀)的主键
+    public static function getPrikey($table=null)
+    {
+        if($table==null)$table = self::shortTableName();
+        //查询表的主键
+        $dsnInfo = explode(";",Yii::$app->db->dsn);
+        $dbInfo = explode("=",$dsnInfo['1']);
+        //$sql = "SELECT k.column_name,k.table_name FROM information_schema.table_constraints t JOIN information_schema.key_column_usage k USING ( constraint_name, table_schema, table_name ) WHERE t.constraint_type = 'PRIMARY KEY' AND k.table_name = '".Yii::$app->db->tablePrefix.$table."' AND t.table_schema = '$dbInfo[1]'";
+        $sql = "SELECT column_name FROM information_schema.key_column_usage WHERE table_name='".Yii::$app->db->tablePrefix.$table."' AND constraint_name LIKE '%_pkey'";
+        $result = Yii::$app->db->createCommand($sql)->queryOne();
+        return  $result['column_name'];
+    }
+
+    //返回属性名称
+    public static function getAttributeName($field)
+    {
+        if($field=='operate')
+        {
+            return Yii::t('attr',$field);
+        }
+        else
+        {
+            $table_name = self::shortTableName();
+            return Yii::t('attr',$table_name.'.'.$field);
+        }
+    }
+
+    //后台角色
+    public static function roleOptions($k=0)
+    {
+        $resultList = Role::find()->where("disabled=0")->all();
+        foreach($resultList as $result)
+        {
+            $options[$result->role_id] = $result->role_name;
+        }
+        if($k>0)return $options[$k];
+        return $options;
+    }
+
+    //联动菜单
+    public static function linkmenuOptions($k=0)
+    {
+        $resultList = Linkmenu::find()->where("key_id=0")->all();
+        foreach($resultList as $result)
+        {
+            $options[$result->menu_id] = $result->name;
+        }
+        if($k>0)return $options[$k];
+        return $options;
+    }
+
+    //系统参数选项
+    public static function sysconfigOptions($name,$k=null)
+    {
+        $sysconfig = Sysconfig::find()->where("name='$name'")->one();
+        $resultList = json_decode($sysconfig->value,true);
+        if($sysconfig->type==1)
+        {
+            if(is_array($resultList))foreach($resultList as $id=>$name)
+            {
+                $options[$id] = $name;
+            }
+            if(!is_null($k))return $options[$k];
+        }
+        else
+        {
+            if(is_array($resultList))foreach($resultList as $name)
+            {
+                $options[] = $name;
+            }
+            if($k!='') return $k;
+
+        }
+        return $options;
+    }
+
+    //是否选择(字段管理页面)
+    public static function fieldBoolOptions($k=null)
+    {
+        $options = array('0'=>'否','1'=>'是');
+        if(is_numeric($k))return $options[$k];
+        return $options;
+    }
+
+
+    //返回广告行业选项
+    public  function indOptions($k=NULL)
+    {
+        $resultList = AdInd::find()->where("disabled=0")->orderBy(['list_order'=>SORT_ASC])->all();
+        if(is_array($resultList))foreach($resultList as $result)
+        {
+            $options[$result->ind_id] = $result->name;
+        }
+        if($k>0)return $options[$k];
+        return $options;
+    }
+
+    //返回广告位选项
+    public  function adspaceOptions($k=NULL)
+    {
+        $resultList = AdSpace::find()->where("disabled=0")->orderBy(['list_order'=>SORT_ASC])->all();
+        if(is_array($resultList))foreach($resultList as $result)
+        {
+            $options[$result->space_id] = $result->name."(".$result->space_no.")";
+        }
+        if($k>0)return $options[$k];
+        return $options;
+    }
+
+    //返回用户组选项
+    public static function userGroupOptions($k=NULL)
+    {
+        $resultList = UserGroup::find()->where("disabled=0")->orderBy(['list_order'=>SORT_ASC])->all();
+        if(is_array($resultList))foreach($resultList as $result)
+        {
+            $options[$result->group_id] = $result->group_name;
+        }
+        if($k>0)return $options[$k];
+        return $options;
+    }
+
+    //返回VIP类型选择
+    public static function viptypeOptions($k=null,$cat=null)
+    {
+        if($cat==null)
+        {
+            $vipTypeList = \app\modules\ucenter\models\UserVipType::find()->where("status=1")->orderBy(['vip_cat'=>SORT_ASC,'list_order'=>SORT_ASC])->all();
+        }
+        else
+        {
+            $vipTypeList = \app\modules\ucenter\models\UserVipType::find()->where("vip_cat='".$cat."' and status=1")->orderBy(['list_order'=>SORT_ASC])->all();
+        }
+
+        if(is_array($vipTypeList))foreach($vipTypeList as $vipType)
+        {
+            $options[$vipType->id] = $vipType->title;
+        }
+        if($k>0)return $options[$k];
+        return $options;
+    }
+
+    //返回用户等级选项
+    public static function userGroupLevelOptions($group_id,$k=NULL)
+    {
+        $levelList = \app\modules\ucenter\models\UserGroupLevel::find()->where("user_group_id=".$group_id."")->orderBy(['id'=>SORT_ASC])->all();
+        $options = [];
+        if(is_array($levelList))foreach($levelList as $levelInfo)
+        {
+            $options[$levelInfo['id']] = $levelInfo['name'];
+        }
+        if($k>0)return $options[$k];
+        return $options;
+    }
+
+    //返回用户模型选项
+    public static function userModelOptions($k=NULL)
+    {
+        $resultList = ContentModel::find()->where("type=2 and disabled=0")->all();
+        if(is_array($resultList))foreach($resultList as $result)
+        {
+            $options[$result->model_id] = $result->name;
+        }
+        if($k>0)return $options[$k];
+        return $options;
+    }
+
+    //返回当前模型ID
+    public static function getContentModelId()
+    {
+        $table_name = self::shortTableName();
+        $contentModel = ContentModel::find()->where("table_name='".$table_name."'")->one();
+        return $contentModel->model_id;
+    }
+
+
+    //返回标签链接
+    public static function getTagLinksByModel($tags,$model_id)
+    {
+        if(empty($tags))return[];
+        $tags = explode(",",$tags);
+        if(is_array($tags))foreach($tags as $tag)
+        {
+            $tagModel = \app\models\Tag::find()->where("tag='".$tag."'")->one();
+            if(!empty($tagModel))
+            {
+                $links[] = ['title'=>$tagModel->tag,'link'=>\app\common\components\SiteUrl::tagLink($tagModel->pinyin,$model_id)];
+            }
+        }
+        return $links;
+    }
+
+    //返回内容首个标签
+    public static function getFirstTag($tags)
+    {
+        $tags = explode(",",$tags);
+        return $tags[0]?$tags[0]:'无';
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    //文本型选项
+    public static function boxOptions($str,$k=null)
+    {
+        $typeList = explode("\n",$str);
+        if(!empty($typeList))foreach($typeList as $_k) {
+            $v = explode("|",$_k);
+            if(!empty($v[0])){
+                $options[trim($v[1])] = $v[0];
+            }
+        }
+        if($k>0)return $options[$k];
+        return $options;
+    }
+
+    //售后步骤
+    public static function refundStepOptions($type,$k=null)
+    {
+        $type==1?$options = array('1'=>'申请退货退款','2'=>'卖家处理','3'=>'买家寄回商品','4'=>'买家收货','5'=>'退款完毕'):$options = array('1'=>'申请退款','2'=>'卖家处理','3'=>'退款完毕');
+        if(is_numeric($k))return $options[$k];
+        return $options;
+    }
+
+}

+ 25 - 0
common/models/EModel.php

@@ -0,0 +1,25 @@
+<?php
+//model 的重写基类
+
+namespace app\common\models;
+use Yii;
+use yii\base\Model;
+
+class EModel extends Model
+{
+
+    /**
+     * 获取模型验证的第一个错误
+     */
+    public function returnFirstError()
+    {
+        $errors = $this->getErrors();
+        if(!empty($errors)){
+            $firstError = array_splice($errors, 0,1);
+            $attribute = key($firstError);
+            return $this->getFirstError($attribute);
+        }
+        return null;
+    }
+
+}

+ 86 - 0
common/modules/EModule.php

@@ -0,0 +1,86 @@
+<?php
+namespace app\common\modules;
+use app\common\components\CacheId;
+use app\modules\admin\models\Config;
+use app\modules\ad\models\AdData;
+use Yii;
+/**
+ * admin module definition class
+ */
+class EModule extends \yii\base\Module
+{
+    public $attconfig;
+    public $ossconfig;
+    public $baseconfig;
+    public $wapconfig;
+    public $imageconfig;
+    public $csrconfig;
+    public $higherconfig;
+    public $payconfig;
+    public $coinconfig;
+    public $pointconfig;
+    public $baiduconfig;
+    public $openauthconfig;
+    public $smsconfig;
+    public $mailerconfig;
+    public $ueditorconfig;
+    public $docconfig;
+    public $mpconfig;
+    public $wxappconfig;
+    public $bdappconfig;
+    public $transferconfig;
+    public $withdrawconfig;
+    public $commissionconfig;
+    public $posterconfig;
+    public $shoppingconfig;
+    public $cmsconfig;
+    public $badwordconfig;
+    public $floatAd;
+    public $allCategorys;
+    public function init()
+    {
+        parent::init();
+        if(checkrobot()==false)//排除爬虫
+        {
+            //控制PC和WAP切换
+            if(defined('IN_WAP')&&IN_WAP==TRUE)
+            {
+                $url  = get_url();
+                if(strpos($url,WEB_URL)!==false){
+
+                    $url = str_replace(WEB_URL,WAP_URL,$url);
+                    Header("HTTP/1.1 301 Moved Permanently");
+                    Header("Location: ".$url);
+                }
+            }
+            if(!check_mobile())
+            {
+                $url  = get_url();
+                if(strpos($url,WAP_URL)!==false){
+                    $url = str_replace(WAP_URL,WEB_URL,$url);
+                    Header("HTTP/1.1 301 Moved Permanently");
+                    Header("Location: ".$url);
+                }
+            }
+        }
+
+        //加入全局配置
+        /*$configResultList = Config::find()->all();
+        if(is_array($configResultList))foreach($configResultList as $configResult)
+        {
+            $configName = str_replace('config','',$configResult->name);
+            $configName = str_replace('attachment','att',$configName).'config';
+            $this->$configName = string2array($configResult->value);
+        }*/
+        /*if(empty($this->cmsconfig['news_breadname']))$this->cmsconfig['news_breadname'] = '资讯';
+        if(empty($this->cmsconfig['news_contentname']))$this->cmsconfig['news_contentname'] = '资讯';
+        if(empty($this->docconfig['breadname']))$this->docconfig['breadname'] = '文档';
+        if(empty($this->docconfig['docname']))$this->docconfig['docname'] = '文档';
+        if(empty($this->docconfig['colname']))$this->docconfig['colname'] = '合辑';
+        $this->floatAd = AdData::find()->where("space_id=(select space_id from {{%ad_space}} where space_no='b9') and status=1 and start_time<=".TIMESTAMP." and end_time>=".TIMESTAMP)->one();
+        $this->allCategorys = json_decode(Yii::$app->cache->get(CacheId::categoryCacheId()),true);*/
+
+    }
+
+
+}

+ 21 - 0
common/widget/CommentWidget.php

@@ -0,0 +1,21 @@
+<?php
+namespace app\common\widget;
+use yii\base\Widget;
+use Yii;
+
+class CommentWidget extends Widget
+{
+
+	public function init()
+	{
+
+	}
+
+	public function run()
+	{
+
+        return $this->render('comment',[]);
+	}
+	
+
+}

+ 17 - 0
common/widget/FieldWidget.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace app\common\widget;
+use yii\base\Widget;
+use Yii;
+class FieldWidget extends Widget
+{
+    public $table_name;//表名
+    public $field;//字段名称
+    public $field_type;//字段类型
+    public $is_system;//是否主表字段
+    public $old_field;//原字段名
+    public $max_length;
+
+
+
+}

+ 268 - 0
common/widget/LinkcatWidget.php

@@ -0,0 +1,268 @@
+<?php
+
+namespace app\common\widget;
+use yii\base\Widget;
+use app\assets\CoreAsset;
+use app\assets\PluginsAsset;
+use app\modules\cms\models\Category;
+use yii\helpers\Html;
+use Yii;
+class LinkcatWidget extends Widget
+{
+	public $model;
+    public $level;
+    public $content_model_id;
+    public $name;
+    public $value;
+    public $id;
+    public $blockClass='';
+    public $unitClass = '';
+    public $selectClass = '';
+    public $emptyTxts = [];
+    public $dataUrl = '';
+    public $selectedIds=[0,0,0,0];
+    public $style;
+    public $blockStyle;
+    public $unitStyle;
+    public $space;
+    public $is_open;
+    public $select_default;
+    public $required;
+	public function init()
+	{
+
+		if(empty($this->name))
+		{
+			echo '缺少NAME';
+			exit;
+		}
+
+        if(empty($this->level))
+        {
+            echo '请设置层级';
+            exit;
+        }
+
+        if(empty($this->content_model_id))
+        {
+            echo '请设置内容模型';
+            exit;
+        }
+        $this->dataUrl = Yii::$app->controller->createRealUrl('ajax/nextlinkcat');
+        if($this->value)$this->selectedIds = Category::getParentCatIdRs($this->value);
+
+	}
+	public function run()
+	{
+        $this->registerClientScript();
+        if(!empty($this->model))
+        {
+            $modelName = strtolower(basename(str_replace("\\",DIRECTORY_SEPARATOR,get_class($this->model))));
+            if(empty($this->id)) $this->id = $modelName.'-'.$this->name;
+            echo Html::activeTextInput($this->model, $this->name, ['value'=>$this->value,'id'=>$this->id,'style'=>'display:none','class'=>$this->required.' layui-input', 'lay-verify'=>$this->required, 'data-level'=>$this->level,'data-verifyid'=>$this->id."_".$this->level]);
+        }
+        else
+        {
+            if(empty($this->id)) $this->id = str_replace(array('[',']'),array('-',''),$this->name);
+            else  $this->id = str_replace(array('[',']'),array('-',''),$this->id);
+            echo "<input type='hidden' value='".$this->value."' id='".$this->id."' name='".$this->name."'  class='".$this->required."  layui-input' lay-verify='".$this->required."'  data-level='".$this->level."' data-verifyid='".$this->id."_".$this->level."'>";
+
+        }
+        echo "<div id='".$this->id."_block' class='".$this->blockClass."' style='".$this->blockStyle."' >";
+        for($i=1;$i<=$this->level;$i++)
+        {
+            echo "<div class='".$this->unitClass."' style='".$this->unitStyle."'>";
+            echo "<select lay-ignore class='".$this->id."_".$i." ".$this->selectClass."' id='".$this->id."_".$i."' name='".$this->id."_".$i."'  >";
+            echo "<option value=''>".$this->emptyTxts[$i-1]."</option>";
+            echo "</select>";
+            echo "</div>";
+        }
+        echo "</div>";
+        $js = <<<JS
+       //setInterval(function(){console.log($('#{$this->id}').val())},2000)
+        $('#{$this->id}_block').cascadingDropdown({
+    selectBoxes: [
+        {
+            selector: '.{$this->id}_1',
+            source: function(request, response) {
+                var content_model_id = {$this->content_model_id};
+                var data_url = '{$this->dataUrl}';
+                $.getJSON(data_url, {content_model_id:content_model_id}, function(result) {
+                    var data = result.data;
+                    var selectOnlyOption = data.length >= 1;
+                    response($.map(data, function(item, index) {
+                        return {
+                            label: item.cat_name,
+                            value: item.cat_id,
+                            selected: item.cat_id=='{$this->selectedIds[0]}'
+                        };
+                    }));
+
+                });
+            },
+          onChange: function(event, value, requiredValues, requirementsMet){
+                var targetId="{$this->id}_{$this->level}";
+                var realId = "{$this->id}";
+                var eventTargetId = $(event.target).attr('id');
+                if(value!='')
+                {
+                   $('#'+realId).val(value)
+
+                }
+                else
+                {
+                    $('#'+realId).val('')
+                }
+
+            }
+        },
+        {
+            selector: '.{$this->id}_2',
+            requires: ['.{$this->id}_1'],
+            source: function(request, response) {
+                var parent_id;
+
+                $.each(request, function(key, val) {
+                   parent_id = val;
+                });
+                var data_url = '{$this->dataUrl}';
+                $.getJSON(data_url, {parent_id:parent_id,content_model_id:{$this->content_model_id}}, function(result) {
+                    var data = result.data;
+                    var selectOnlyOption = data.length >= 1;
+                    response($.map(data, function(item, index) {
+                        return {
+                            label: item.cat_name,
+                            value: item.cat_id,
+                            selected: item.cat_id=='{$this->selectedIds[1]}'
+                        };
+                    }));
+                    if(data.length==0)
+                    {
+                        $('.{$this->id}_2').attr('disabled','disable');
+                        $('.{$this->id}_3').attr('disabled','disable');
+                        $('.{$this->id}_4').attr('disabled','disable');
+                       var realId = "{$this->id}";
+                       $('#'+realId).val($('.{$this->id}_1 option:selected').val());
+                    }
+                });
+            },
+             onChange: function(event, value, requiredValues, requirementsMet){
+                var targetId="{$this->id}_{$this->level}";
+                var realId = "{$this->id}";
+                var eventTargetId = $(event.target).attr('id');
+                if(value!='')
+                {
+                   $('#'+realId).val(value)
+                }
+                else
+                {
+                    $('#'+realId).val('')
+                }
+            }
+
+        },
+        {
+            selector: '.{$this->id}_3',
+            requires: ['.{$this->id}_1', '.{$this->id}_2'],
+            requireAll: true,
+            source: function(request, response) {
+                var parent_id;
+                $.each(request, function(key, val) {
+                   parent_id = val;
+                });
+                var data_url = '{$this->dataUrl}';
+                $.getJSON(data_url,  {parent_id:parent_id,content_model_id:{$this->content_model_id}}, function(result) {
+                    var data = result.data;
+                    response($.map(data, function(item, index) {
+                        return {
+                            label: item.cat_name,
+                            value: item.cat_id,
+                            selected: item.cat_id=='{$this->selectedIds[2]}'
+                        };
+                    }));
+                    if(data.length==0)
+                    {
+                       $('.{$this->id}_3').attr('disabled','disable');
+                       $('.{$this->id}_4').attr('disabled','disable');
+                       var realId = "{$this->id}";
+                       $('#'+realId).val($('.{$this->id}_2 option:selected').val());
+                    }
+                });
+
+            },
+            onChange: function(event, value, requiredValues, requirementsMet){
+                var targetId="{$this->id}_{$this->level}";
+                var realId = "{$this->id}";
+                var eventTargetId = $(event.target).attr('id');
+                if(value!='')
+                {
+                   $('#'+realId).val(value)
+                }
+                else
+                {
+                    $('#'+realId).val('')
+                }
+            }
+
+        },
+        {
+            selector: '.{$this->id}_4',
+            requires: ['.{$this->id}_1', '.{$this->id}_2', '.{$this->id}_3'],
+            requireAll: true,
+            source: function(request, response) {
+                var parent_id;
+                $.each(request, function(key, val) {
+                   parent_id = val;
+                });
+                var data_url = '{$this->dataUrl}';
+                $.getJSON(data_url,  {parent_id:parent_id,content_model_id:{$this->content_model_id}}, function(result) {
+                    var data = result.data;
+                    response($.map(data, function(item, index) {
+                        return {
+                            label: item.cat_name,
+                            value: item.cat_id,
+                            selected: item.cat_id=='{$this->selectedIds[3]}'
+                        };
+                    }));
+                    if(data.length==0)
+                    {
+                        $('.{$this->id}_4').attr('disabled','disable');
+                        var realId = "{$this->id}";
+                        $('#'+realId).val($('.{$this->id}_3 option:selected').val());
+                    }
+                });
+            },
+            onChange: function(event, value, requiredValues, requirementsMet){
+                var targetId="{$this->id}_{$this->level}";
+                var realId = "{$this->id}";
+                var eventTargetId = $(event.target).attr('id');
+                if(value!='')
+                {
+                   $('#'+realId).val(value)
+                }
+                else
+                {
+                    $('#'+realId).val('')
+                }
+            }
+        }
+    ]
+});
+
+
+JS;
+        $view = $this->getView();
+        $view->registerJs($js);
+
+	}
+	
+	protected  function registerClientScript()
+	{
+        $view = $this->getView();
+        $coreAsset = CoreAsset::register($view);
+        $coreAssetsUrl = $coreAsset->baseUrl;
+        $assetPlugin = PluginsAsset::register($view);
+        $pluginUrl = $assetPlugin->baseUrl;
+        return array('coreAssetsUrl'=>$coreAssetsUrl,'pluginUrl'=>$pluginUrl);
+	}
+}

+ 273 - 0
common/widget/LinkmenuWidget.php

@@ -0,0 +1,273 @@
+<?php
+/*
+ * 调用示例:  <?php echo  \app\common\widget\LinkmenuWidget::widget(['key_id'=>1,'name'=>'parent_id','level'=>3,'model'=>$model,'emptyTxts'=>['省份','城市','区县'],'value'=>1610,'selectClass'=>'form-select original ','blockClass'=>'mb-3 row','unitClass'=>'col-md-2']);?>
+ */
+namespace app\common\widget;
+use yii\base\Widget;
+use app\assets\CoreAsset;
+use app\assets\PluginsAsset;
+use yii\helpers\Html;
+use Yii;
+class LinkmenuWidget extends Widget
+{
+	public $model;
+    public $level;
+    public $key_id;
+    public $name;
+    public $value;
+    public $id;
+    public $blockClass='';
+    public $unitClass = '';
+    public $selectClass = '';
+    public $emptyTxts = [];
+    public $dataUrl = '';
+    public $selectedIds=[0,0,0,0];
+    public $style;
+    public $blockStyle;
+    public $unitStyle;
+    public $space;
+    public $is_open;
+    public $select_default;
+    public $required;
+	public function init()
+	{
+
+		if(empty($this->name))
+		{
+			echo '缺少NAME';
+			exit;
+		}
+
+        if(empty($this->level))
+        {
+            echo '请设置层级';
+            exit;
+        }
+
+        if(empty($this->key_id))
+        {
+            echo '请设置Key Id';
+            exit;
+        }
+        $this->dataUrl = Yii::$app->controller->createRealUrl('ajax/nextlinkmenu');
+        if($this->value)$this->selectedIds = \app\models\Linkmenu::getParentMenuIdRs($this->value);
+
+	}
+	public function run()
+	{
+        $this->registerClientScript();
+        if(!empty($this->model))
+        {
+            $modelName = strtolower(basename(str_replace("\\",DIRECTORY_SEPARATOR,get_class($this->model))));
+            if(empty($this->id)) $this->id = $modelName.'-'.$this->name;
+            echo Html::activeTextInput($this->model, $this->name, ['value'=>$this->value,'id'=>$this->id,'style'=>'display:none','class'=>$this->required.' layui-input', 'lay-verify'=>$this->required, 'data-level'=>$this->level,
+'data-verifyid'=>$this->id."_".$this->level]);
+        }
+        else
+        {
+
+            if(empty($this->id)) $this->id = str_replace(array('[',']'),array('-',''),$this->name);
+            else  $this->id = str_replace(array('[',']'),array('-',''),$this->id);
+            echo "<input type='hidden'  value='".$this->value."' id='".$this->id."' name='".$this->name."'  class='".$this->required." layui-input' lay-verify='".$this->required."' data-level='".$this->level."' data-verifyid='".$this->id."_".$this->level."'>";
+
+        }
+        echo "<div id='".$this->id."_block' class='".$this->blockClass."' style='".$this->blockStyle."' >";
+        for($i=1;$i<=$this->level;$i++)
+        {
+            echo "<div class='".$this->unitClass."' style='".$this->unitStyle."'>";
+            echo "<select lay-ignore class='".$this->id."_".$i." ".$this->selectClass."' id='".$this->id."_".$i."' name='".$this->id."_".$i."'  >";
+            echo "<option value=''>".$this->emptyTxts[$i-1]."</option>";
+            echo "</select>";
+            echo "</div>";
+        }
+        echo "</div>";
+        $js = <<<JS
+        $('#{$this->id}_block').cascadingDropdown({
+    selectBoxes: [
+        {
+            selector: '.{$this->id}_1',
+            source: function(request, response) {
+                var parent_id = {$this->key_id};
+                var data_url = '{$this->dataUrl}';
+                $.getJSON(data_url, {parent_id:parent_id}, function(result) {
+                    var data = result.data;
+                    var selectOnlyOption = data.length >= 1;
+                    response($.map(data, function(item, index) {
+                        return {
+                            label: item.name,
+                            value: item.menu_id,
+                            selected: item.menu_id=='{$this->selectedIds[0]}'
+                        };
+
+                    }));
+                });
+            },
+            onChange: function(event, value, requiredValues, requirementsMet){
+                var targetId="{$this->id}_{$this->level}";
+                var realId = "{$this->id}";
+                var eventTargetId = $(event.target).attr('id');
+                if(value=='')
+                {
+                   $('#'+realId).val('');
+                }
+                else
+                {
+                    if(targetId==eventTargetId&&value!='')
+                    {
+                        $('#'+realId).val(value)
+                    }
+                }
+            }
+        },
+        {
+            selector: '.{$this->id}_2',
+            requires: ['.{$this->id}_1'],
+            source: function(request, response) {
+                var parent_id;
+                $.each(request, function(key, val) {
+                   parent_id = val;
+                });
+                var data_url = '{$this->dataUrl}';
+                $.getJSON(data_url, {parent_id:parent_id}, function(result) {
+                    var data = result.data;
+                    var selectOnlyOption = data.length < 1;
+                    response($.map(data, function(item, index) {
+                        return {
+                            label: item.name,
+                            value: item.menu_id,
+                            selected: item.menu_id=='{$this->selectedIds[1]}'
+                        };
+                    }));
+
+                });
+            },
+             onChange: function(event, value, requiredValues, requirementsMet){
+                var targetId="{$this->id}_{$this->level}";
+                var realId = "{$this->id}";
+                var eventTargetId = $(event.target).attr('id');
+                if(value=='')
+                {
+                    $('#'+realId).val('')
+                }
+                else
+                {
+                    if(targetId==eventTargetId&&value!='')
+                    {
+                       $('#'+realId).val(value)
+                    }
+                }
+
+
+            }
+
+        },
+        {
+            selector: '.{$this->id}_3',
+            requires: ['.{$this->id}_1', '.{$this->id}_2'],
+            requireAll: true,
+            source: function(request, response) {
+                var parent_id;
+                $.each(request, function(key, val) {
+                   parent_id = val;
+                });
+                var data_url = '{$this->dataUrl}';
+                $.getJSON(data_url,  {parent_id:parent_id}, function(result) {
+                    var data = result.data;
+                    response($.map(data, function(item, index) {
+                        return {
+                            label: item.name,
+                            value: item.menu_id,
+                            selected: item.menu_id=='{$this->selectedIds[2]}'
+                        };
+                    }));
+
+                });
+
+            },
+            onChange: function(event, value, requiredValues, requirementsMet){
+                var targetId="{$this->id}_{$this->level}";
+                var realId = "{$this->id}";
+                var eventTargetId = $(event.target).attr('id');
+                if(value=='')
+                {
+                    $('#'+realId).val('');
+                }
+                else
+                {
+                    if(targetId==eventTargetId&&value!='')
+                    {
+                       $('#'+realId).val(value)
+                    }
+                }
+
+            }
+
+        },
+        {
+            selector: '.{$this->id}_4',
+            requires: ['.{$this->id}_1', '.{$this->id}_2', '.{$this->id}_3'],
+            requireAll: true,
+            source: function(request, response) {
+                var parent_id;
+                $.each(request, function(key, val) {
+                   parent_id = val;
+                });
+                var data_url = '{$this->dataUrl}';
+                $.getJSON(data_url,  {parent_id:parent_id}, function(result) {
+                    var data = result.data;
+                    response($.map(data, function(item, index) {
+                        return {
+                            label: item.name,
+                            value: item.menu_id,
+                            selected: item.menu_id=='{$this->selectedIds[3]}'
+                        };
+                    }));
+
+                });
+            },
+            onChange: function(event, value, requiredValues, requirementsMet){
+                var targetId="{$this->id}_{$this->level}";
+                var realId = "{$this->id}";
+                var eventTargetId = $(event.target).attr('id');
+                if(value=='')
+                {
+                    $('#'+realId).val('');
+                }
+                else
+                {
+                    if(targetId==eventTargetId&&value!='')
+                    {
+                       $('#'+realId).val(value)
+                    }
+                }
+
+            }
+        }
+    ]
+});
+
+
+JS;
+
+        if (Yii::$app->request->isAjax) {
+            echo "<script>";
+            echo "{$js}";
+            echo "</script>";
+        }
+        else
+        {
+            $view = $this->getView();
+            $view->registerJs($js);
+        }
+	}
+	
+	protected  function registerClientScript()
+	{
+        $view = $this->getView();
+        $coreAsset = CoreAsset::register($view);
+        $coreAssetsUrl = $coreAsset->baseUrl;
+        $assetPlugin = PluginsAsset::register($view);
+        $pluginUrl = $assetPlugin->baseUrl;
+        return array('coreAssetsUrl'=>$coreAssetsUrl,'pluginUrl'=>$pluginUrl);
+	}
+}

+ 110 - 0
common/widget/PayWidget.php

@@ -0,0 +1,110 @@
+<?php
+
+namespace app\common\widget;
+use yii\base\Widget;
+use Yii;
+
+class PayWidget extends Widget
+{
+	public $request_from;
+    public $act;
+    public $payconfig;
+    public $alipay;
+    public $wxpay;
+    public $return_url;
+    public $docConfig;
+    public $selVipType;
+	public function init()
+	{
+        $this->request_from = REQUEST_FROM;
+        $this->payconfig = Yii::$app->controller->module->payconfig;
+        if($this->request_from==1)
+        {
+            if($this->payconfig['hpwx_pay'])
+            {
+                $this->wxpay = 'hpwx_pay';
+            }
+            if($this->payconfig['hpali_pay'])
+            {
+                $this->alipay = 'hpali_pay';
+            }
+            if(empty($this->wxpay)&&$this->payconfig['weixin_pay'])
+            {
+                $this->wxpay = 'weixin_pay';
+            }
+            if(empty($this->alipay)&&$this->payconfig['apd_pay'])
+            {
+                $this->alipay = 'apd_pay';
+            }
+        }
+        if($this->request_from==2)
+        {
+            if($this->payconfig['hpwx_pay'])
+            {
+                $this->wxpay = 'hpwx_pay';
+            }
+            if($this->payconfig['hpali_pay'])
+            {
+                $this->alipay = 'hpali_pay';
+            }
+            if(empty($this->wxpay)&&$this->payconfig['wxh5_pay'])
+            {
+                $this->wxpay = 'wxh5_pay';
+            }
+            if(empty($this->alipay)&&$this->payconfig['apw_pay'])
+            {
+                $this->alipay = 'apw_pay';
+            }
+        }
+        //百度小程序
+        if($this->request_from==3)
+        {
+            if($this->payconfig['hpwx_pay'])
+            {
+                $this->wxpay = 'hpwx_pay';
+            }
+            if($this->payconfig['hpali_pay'])
+            {
+                $this->alipay = 'hpali_pay';
+            }
+            if(empty($this->wxpay)&&$this->payconfig['wxh5_pay'])
+            {
+                $this->wxpay = 'wxh5_pay';
+            }
+            if(empty($this->alipay)&&$this->payconfig['apw_pay'])
+            {
+                $this->alipay = 'apw_pay';
+            }
+        }
+        //微信浏览器
+        if($this->request_from==5)
+        {
+            if($this->payconfig['hpwx_pay'])
+            {
+                $this->wxpay = 'hpwx_pay';
+            }
+
+            if($this->payconfig['hpali_pay'])
+            {
+                $this->alipay = 'hpali_pay';
+            }
+
+            if(empty($this->wxpay)&&$this->payconfig['weixin_pay'])
+            {
+                $this->wxpay = 'weixin_pay';
+            }
+            if(empty($this->alipay)&&$this->payconfig['apw_pay'])
+            {
+                //$this->alipay = 'apw_pay';
+            }
+        }
+	}
+
+	public function run()
+	{
+        $order_sn = getUniOrderNo();
+        return $this->render('pay',array('payconfig'=>$this->payconfig,'request_from'=>$this->request_from,'act'=>$this->act,'wxpay'=>$this->wxpay,'alipay'=>$this->alipay,'order_sn'=>$order_sn,'return_url'=>$this->return_url,'docConfig'=>$this->docConfig,'selVipType'=>$this->selVipType));
+	}
+	
+
+}

+ 33 - 0
common/widget/ShareWidget.php

@@ -0,0 +1,33 @@
+<?php
+namespace app\common\widget;
+use app\modules\doc\models\DocReal;
+use yii\base\Widget;
+use Yii;
+
+class ShareWidget extends Widget
+{
+
+	public function init()
+	{
+
+	}
+
+	public function run()
+	{
+        $view = defined('IN_WAP')&&IN_WAP==TRUE?'share/wap':'share/pc';
+        //文档详情页显示佣金
+        if(Yii::$app->controller->moduleName=='doc'&&isset($_GET['id']))
+        {
+            $id = intval($_GET['id']);
+            $doc = DocReal::findOne($id);
+            if(Yii::$app->controller->module->commissionconfig['on'])
+            {
+                $commission = (Yii::$app->controller->module->commissionconfig['doc_commission_level1_rate']/100)*$doc->coin_price.Yii::$app->controller->module->coinconfig['coin_name'];
+            }
+        }
+
+        return $this->render($view,['commission'=>$commission]);
+	}
+	
+
+}

+ 48 - 0
common/widget/SlideloadWidget.php

@@ -0,0 +1,48 @@
+<?php
+/**
+ * Author: Jack.Chen
+ * Create time: 20-5-30 下午1:38
+ * Description: 操作内容模型关联的字段操作
+ */
+namespace app\common\widget;
+
+use yii\base\Widget;
+use Yii;
+class SlideloadWidget extends Widget
+{
+
+    public $pageCount;//总页数
+    public $currentPage;//当前页
+    public $count;//记录总数
+    public $ajaxUrl;//数据读取接口
+    public $searchConditions;//搜索序列化条件
+    public $keyword;//搜索关键词
+    public $modelId;//内容模型
+    public $listContentId = 'content_list';//列表页内容容器Id
+    public $marginHeight=100;//距离底部高度临界值
+    public $loadBtnTitle='加载更多';
+    public function init()
+    {
+
+    }
+    public function run()
+    {
+        $view = defined('IN_WAP')&&IN_WAP==TRUE?'slideload/wap':'slideload/pc';
+        return $this->render($view,array(
+                'pageCount'=>$this->pageCount,
+                'currentPage'=>$this->currentPage,
+                'count'=>$this->count,
+                'ajaxUrl'=>$this->ajaxUrl,
+                'searchConditions'=>$this->searchConditions,
+                'keyword'=>$this->keyword,
+                'modelId'=>$this->modelId,
+                'listContentId'=>$this->listContentId,
+                'loadBtnTitle'=>$this->loadBtnTitle,
+                'marginHeight'=>$this->marginHeight
+            )
+        );
+
+    }
+
+
+}

+ 180 - 0
common/widget/UeditorWidget.php

@@ -0,0 +1,180 @@
+<?php
+namespace app\common\widget;
+use yii\base\Widget;
+use app\assets\CoreAsset;
+use app\assets\PluginsAsset;
+use Yii;
+//编辑器
+class UeditorWidget extends Widget
+{
+	public  $id;//容器ID
+	public  $name;//变量名
+	public  $toolBar='full';//全能型 full , 标准型 basic, 前台发布 publish, 简约:simple
+	public  $width='100%';
+	public  $height='200';
+	public  $defaultValue='';//初始值
+	public  $lang;//语言
+	public  $allowPageBreak=1; //允许使用分页符 1:允许 0:不允许
+	public  $saveRemoteImage=1; //保存远程图片,默认开启保存
+	public  $allowUploadAttachment=0;//允许上传附件 1:允许 0:不允许
+    public  $allowInsertCode=0;//允许插入源代码
+    public  $map;//是否开启百度地图
+    public  $theme = "gray";//皮肤
+	private $pageBreakTag;//分页符
+    private $imageUrl;//图片上传提交地址
+    private $imgPath;//图片修正地址
+    private $imageManagerUrl;//在线管理图片url
+    private $imageManagerPath;//图片修正地址
+    private $scrawlUrl;//涂鸦上传地址
+    private $scrawlPath;//图片修正地址
+    private $wordImageUrl;//word转存提交地址
+    private $wordImagePath;
+    private $fileUrl;//附件上传提交地址
+    private $filePath;
+    private $saveRemotImageUrl;//处理远程图片抓取的程序地址
+    private $saveRemotImagePath;//保存远程图片的路径
+    private $getMovieUrl; //视频数据获取程序处理地址
+	public function init()
+	{
+		//id 和 name
+		if(empty($this->id))
+		{
+			echo '缺少ID';
+			exit;
+		}
+		if(empty($this->name))$this->name = $this->id;
+		//语言设定
+        $this->lang = 'zh-cn';
+		//分页符号
+		$this->pageBreakTag=Yii::$app->params['ueditor']['pageBreakTag'];
+	}
+	public function run()
+	{
+
+        $assetsUrl = $this->registerClientScript();
+        echo "<script src='".$assetsUrl['pluginUrl']."/ueditor1_4_3/ueditor.all.min.js?v=12'></script>";
+        echo "<script src='".$assetsUrl['pluginUrl']."/ueditor1_4_3/lang/".$this->lang."/".$this->lang.".js'></script>";
+		echo "<script type='text/plain' id='".$this->id."' name='".$this->name."' style='width:100%' class='kiivoeditor'>".htmlspecialchars_decode($this->defaultValue)."</script>";
+		echo "<script type=\"text/javascript\">
+			 window.UEDITOR_HOME_URL = '".$assetsUrl['pluginUrl']."/ueditor1_4_3/';";
+         echo "var URL = window.UEDITOR_HOME_URL || getUEBasePath();";
+		 echo  "UE.getEditor('".$this->id."',{theme:'".$this->theme."',lang:'".$this->lang."',";
+		echo "UEDITOR_HOME_URL : URL,";
+        echo "listiconpath:'".$assetsUrl['pluginUrl']."/ueditor1_4_3/themes/".$this->theme."/ueditor-list/',";
+        echo "initialStyle:'ol.custom_cn li,ol.custom_cn1 li,ol.custom_cn2 li,ol.custom_num li,ol.custom_num1 li,ol.custom_num2 li{list-style:none;}',";
+        echo "serverUrl:URL + 'php/controller.php?base_path=".sys_auth(BASE_PATH)."&app_path=".sys_auth(APP_PATH)."&upload_path=".sys_auth(UPLOAD_PATH)."&auth_key=".AUTH_KEY."',";
+        //echo "serverUrl: 'https://www.zhitiku.cn/assets/39418df8/ueditor1_4_3/php/controller.php?base_path=".urlencode(BASE_PATH)."&app_path=".urlencode(APP_PATH)."&upload_path=".urlencode(UPLOAD_PATH)."',";
+        /*
+		echo "imageUrl:'".$this->imageUrl."',"; //图片上传提交地址
+		echo "imagePath:'".$this->imgPath."',";
+		echo "wordImageUrl:'".$this->wordImageUrl."',"; //work转存上传提交地址
+		echo "wordImagePath:'".$this->wordImagePath."',";
+		echo "imageManagerUrl:'".$this->imageManagerUrl."',"; //图片管理提交地址
+		echo "imageManagerPath:'".$this->imageManagerPath."',";
+      	echo "scrawlUrl:'".$this->scrawlUrl."',"; //涂鸦图片提交地址
+		echo "scrawlPath:'".$this->scrawlPath."',";
+		echo "fileUrl:'".$this->fileUrl."',"; //附件上传提交地址
+		echo "filePath:'".$this->filePath."',";
+		echo "catcherUrl:'".$this->saveRemotImageUrl."',"; //抓取远程图片地址
+		echo "catcherPath:'".$this->saveRemotImagePath."',";
+		echo "getMovieUrl:'".$this->getMovieUrl."',";
+        */
+
+		//宽度
+		if(!empty($this->width))echo "initialFrameWidth:'".$this->width."',";
+		//高度
+		if(!empty($this->height))echo "initialFrameHeight:'".$this->height."',";
+		//后台时支持源码查看
+        $strSource = defined('IN_ADMIN')?'"source",':'';
+		//判断是否支持附件上传和图片上传
+        $strAttachment = $this->allowUploadAttachment?'"simpleupload", "insertimage","attachment",':'';
+		//判断是否支持分页
+        $strPage = $this->allowPageBreak?'"pagebreak",':'';
+		//判断是否支持百度地图
+        $strMap = $this->map?'"map",':'';
+        //判断是否支持插入代码
+        $strInsertCode = $this->allowInsertCode?'"insertcode",':'';
+        if($this->toolBar=='publish')
+        {
+            $this->toolBar = '"fullscreen","undo","redo", "removeformat","|","bold","italic","underline","strikethrough","|","insertunorderedlist","insertorderedlist","justifyleft","justifycenter","justifyright","justifyjustify","|","customstyle","fontsize","fontfamily","forecolor","backcolor","|","unlink", "link","blockquote",'.$strInsertCode.'"inserttable","|",'.$strAttachment.'"pasteplain"';
+        }
+        else if($this->toolBar=='simple')
+        {
+            $this->toolBar = '"undo","redo", "removeformat","|","bold","italic","underline","strikethrough","|","insertunorderedlist","insertorderedlist","justifyleft","justifycenter","justifyright","justifyjustify","|","unlink", "link","blockquote","|","simpleupload"';
+        }
+        else if($this->toolBar=='mobile')
+        {
+            $this->toolBar = '"undo","redo", "removeformat","|","bold","italic","underline","strikethrough","|","insertunorderedlist","insertorderedlist","justifyleft","justifycenter","justifyright","justifyjustify","|","simpleupload"';
+        }
+		else if($this->toolBar=='basic')
+		{
+            $this->toolBar = '"fullscreen",'.$strSource.'"undo","redo", "removeformat","cleardoc","|","bold","italic","underline","strikethrough","|","insertunorderedlist","insertorderedlist","justifyleft","justifycenter","justifyright","justifyjustify","|","rowspacingtop", "rowspacingbottom", "lineheight", "|","indent","customstyle","fontsize","fontfamily","forecolor","backcolor","|","unlink", "link","blockquote",'.$strInsertCode.'"inserttable", "|", "horizontal",'.$strPage.$strAttachment.$strMap.'"pasteplain"';
+		}
+		else if($this->toolBar=='full')
+		{
+            $this->toolBar = ' "fullscreen", '.$strSource.', "|", "undo", "redo", "|",
+            "bold", "italic", "underline", "fontborder", "strikethrough", "superscript", "subscript", "removeformat", "formatmatch", "autotypeset", "blockquote", "pasteplain", "|", "forecolor", "backcolor", "insertorderedlist", "insertunorderedlist", "selectall", "cleardoc", "|",
+            "rowspacingtop", "rowspacingbottom", "lineheight", "|",
+            "customstyle", "paragraph", "fontfamily", "fontsize", "|",
+            "directionalityltr", "directionalityrtl", "indent", "|",
+            "justifyleft", "justifycenter", "justifyright", "justifyjustify", "|", "touppercase", "tolowercase", "|",
+            "link", "unlink", "anchor", "|", "imagenone", "imageleft", "imageright", "imagecenter", "|",
+            '.$strAttachment.' "emotion", "scrawl", "insertvideo", "music",  '.$strMap.' "insertframe", "insertcode", "webapp", '.$strPage.' "template", "background", "|",
+            "horizontal", "date", "time", "spechars", "snapscreen", "wordimage", "|",
+            "inserttable", "deletetable", "insertparagraphbeforetable", "insertrow", "deleterow", "insertcol", "deletecol", "mergecells", "mergeright", "mergedown", "splittocells", "splittorows", "splittocols", "charts", "|",
+            "print", "preview", "searchreplace", "drafts" ,"help"';
+		}
+
+		//判断是否保存远程图片
+		if(!$this->saveRemoteImage)
+		{
+			echo "catchRemoteImageEnable:false,";
+		}
+        else
+        {
+            echo "catchRemoteImageEnable:true,";
+        }
+        //禁止高度自适应
+        echo "autoHeightEnabled:false,";
+        echo "zIndex:9999,";
+		echo "toolbars:[[".$this->toolBar."]],";
+		echo "pageBreakTag:'".$this->pageBreakTag."',";
+        if(defined('IN_ADMIN'))
+        {
+            echo "
+				//focus时自动清空初始化时的内容
+				autoClearinitialContent:false,
+				//关字数统计
+				wordCount:true,
+				//关闭elementPath
+				elementPathEnabled:false
+				//更多其他参数,请参考editor_config.js中的配置项
+			});
+		</script>";
+        }
+        else
+        {
+            echo "
+				//focus时自动清空初始化时的内容
+				autoClearinitialContent:false,
+				//关闭字数统计
+				wordCount:false,
+				//关闭elementPath
+				elementPathEnabled:false
+				//更多其他参数,请参考editor_config.js中的配置项
+			});
+		</script>";
+        }
+
+	}
+	
+	protected  function registerClientScript()
+	{
+        $view = $this->getView();
+        $coreAsset = CoreAsset::register($view);
+        $coreAssetsUrl = $coreAsset->baseUrl;
+        $assetPlugin = PluginsAsset::register($view);
+        $pluginUrl = $assetPlugin->baseUrl;
+        return array('coreAssetsUrl'=>$coreAssetsUrl,'pluginUrl'=>$pluginUrl);
+	}
+}

+ 10 - 0
common/widget/fields/author/config.inc.php

@@ -0,0 +1,10 @@
+<?php
+$field_type				= 'varchar'; //字段数据库类型	
+$field_basic_table		= 1; //是否允许作为主表字段
+$field_allow_index		= 1; //是否允许建立索引
+$field_minlength		= 0; //字符长度默认最小值
+$field_maxlength		= '50'; //字符长度默认最大值
+$field_allow_search		= 1; //作为搜索条件
+$field_allow_fullsearch	= 0; //作为全站搜索信息
+$field_allow_isunique	= 1; //是否允许值唯一
+?>

+ 6 - 0
common/widget/fields/author/field_add_form.inc.php

@@ -0,0 +1,6 @@
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >默认值</label>
+    <div class="col-md-10">
+        <input type="text" name="setting[default_value]" value="" autocomplete="off" class="form-control" >
+    </div>
+</div>

+ 6 - 0
common/widget/fields/author/field_edit_form.inc.php

@@ -0,0 +1,6 @@
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >默认值</label>
+    <div class="col-md-10">
+        <input type="text" name="setting[default_value]" value="<?php echo $setting['default_value'];?>" autocomplete="off" class="form-control" >
+    </div>
+</div>

+ 16 - 0
common/widget/fields/author/form.inc.php

@@ -0,0 +1,16 @@
+    function author($field, $value, $fieldinfo) {
+        if($value=='') $value = !empty($fieldinfo['default_value'])?$fieldinfo['default_value']:'';
+        $require = $fieldinfo['min_length']  ? 'required' : '';
+        $pattern = $fieldinfo['pattern'] ?$fieldinfo['pattern']:'';
+        $errortips = $fieldinfo['error_tips'] ?$fieldinfo['error_tips']:'';
+        $form_attribute = $fieldinfo['form_attribute'] ?$fieldinfo['form_attribute']:'';
+        $css = $fieldinfo['css'] ?$fieldinfo['css']:'';
+        $string =  '<div class="mb-3 row '.$require.'">';
+        $string .= '<label class="col-md-2 col-form-label">'.$fieldinfo['name'].'</label>';
+        $string .= '<div class="col-md-10">';
+        $string .= '<input type="text" name="info['.$field.']" value="'.$value.'"  data-pattern = "'.$pattern.'" data-errtips = "'.$errortips.'" autocomplete="off" class="form-control '.$require.'" '.$form_attribute.'   style="'.$css.'">';
+        $string .= $fieldinfo['tips']?'<div class="text-muted  input-word-aux">提示:'.$fieldinfo['tips'].'</div>':'';
+        $string .= '</div>';
+        $string .= '</div>';
+        return $string;
+    }

+ 10 - 0
common/widget/fields/box/config.inc.php

@@ -0,0 +1,10 @@
+<?php
+$field_type				= 'tinyint'; //字段数据库类型
+$field_basic_table		= 1; //是否允许作为主表字段
+$field_allow_index		= 1; //是否允许建立索引
+$field_minlength		= 0; //字符长度默认最小值
+$field_maxlength		= ''; //字符长度默认最大值
+$field_allow_search		= 1; //作为搜索条件
+$field_allow_fullsearch	= 0; //作为全站搜索信息
+$field_allow_isunique	= 0; //是否允许值唯一
+?>

+ 112 - 0
common/widget/fields/box/field_add_form.inc.php

@@ -0,0 +1,112 @@
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >选项值(px)</label>
+    <div class="col-md-10">
+        <textarea name="setting[options]"  id="options" class="form-control" style="height:100px;">选项名称1|选项值1</textarea>
+        <div class="text-muted input-word-aux">提示:名称在前,值在后,"|"分割, 多个选项换行输入</div>
+    </div>
+</div>
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >选项类型</label>
+    <div class=" col-md-10">
+        <ul class="list-group">
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='radio' class='form-check-input' checked>
+                    <label class='form-check-label'>单选框</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='checkbox' class='form-check-input'>
+                    <label class='form-check-label'>复选框</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='select' class='form-check-input'>
+                    <label class='form-check-label'>下拉单选</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='multiple' class='form-check-input'>
+                    <label class='form-check-label'>下拉多选</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='switch' class='form-check-input'>
+                    <label class='form-check-label'>开关(适用于输出值为1,0的组合,且1在前面)</label>
+                </div>
+            </li>
+        </ul>
+    </div>
+</div>
+
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >字段类型</label>
+    <div class="col-md-10">
+        <select class="form-select " name="setting[field_type]" id="setting_field_type" data-dselect-clearable="true">
+            <option value="varchar">字符 VARCHAR</option>
+            <option value="tinyint">整数 TINYINT(3)</option>
+            <option value="smallint">整数 SMALLINT(5)</option>
+            <option value="mediumint">整数 MEDIUMINT(8)</option>
+            <option value="int">整数 INT(10)</option>
+        </select>
+    </div>
+</div>
+
+<div class="mb-3 row" id="min_number" style="display:none">
+    <label class="col-md-2 col-form-label" >整数类型</label>
+    <div class=" col-md-10">
+        <ul class="list-group">
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[min_number]' value='1' class='form-check-input'>
+                    <label class='form-check-label'>正整数</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[min_number]' value='-1' class='form-check-input'>
+                    <label class='form-check-label'>整数</label>
+                </div>
+            </li>
+        </ul>
+    </div>
+</div>
+
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >默认值</label>
+    <div class="col-md-10">
+        <input type="text" name="setting[default_value]" value="" autocomplete="off" class="form-control" >
+    </div>
+</div>
+<div class="mb-3 row" >
+    <label class="col-md-2 col-form-label" >输出方式</label>
+    <div class=" col-md-10">
+        <ul class="list-group">
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[output_type]' value='1' class='form-check-input' checked>
+                    <label class='form-check-label'>输出选项值</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[output_type]' value='0' class='form-check-input'>
+                    <label class='form-check-label'>输出选项名称</label>
+                </div>
+            </li>
+        </ul>
+    </div>
+</div>
+
+<div class="mb-3 row" >
+    <label class="col-md-2 col-form-label" >筛选字段</label>
+    <div class=" col-md-10">
+        <input  value="1"  id="switch-filter_type" type="checkbox" switch="success" class="row-switch" name="setting[filter_type]">
+        <label class="switch-check-label " for="switch-filter_type" data-on-label="是" data-off-label="否"></label>
+    </div>
+</div>
+

+ 112 - 0
common/widget/fields/box/field_edit_form.inc.php

@@ -0,0 +1,112 @@
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >选项值(px)</label>
+    <div class="col-md-10">
+        <textarea name="setting[options]"  id="options" class="form-control" style="height:100px;"><?php echo isset($setting['options'])?$setting['options']:'';?></textarea>
+        <div class="text-muted input-word-aux">提示:名称在前,值在后,"|"分割, 多个选项换行输入</div>
+    </div>
+</div>
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >选项类型</label>
+    <div class=" col-md-10">
+        <ul class="list-group">
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='radio' class='form-check-input'  <?php if(isset($setting['box_type'])&&$setting['box_type']=='radio') echo 'checked';?> >
+                    <label class='form-check-label'>单选框</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='checkbox' class='form-check-input'  <?php if(isset($setting['box_type'])&&$setting['box_type']=='checkbox') echo 'checked';?> >
+                    <label class='form-check-label'>复选框</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='select' class='form-check-input'  <?php if(isset($setting['box_type'])&&$setting['box_type']=='select') echo 'checked';?> >
+                    <label class='form-check-label'>下拉单选</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='multiple' class='form-check-input'  <?php if(isset($setting['box_type'])&&$setting['box_type']=='multiple') echo 'checked';?> >
+                    <label class='form-check-label'>下拉多选</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[box_type]' value='switch' class='form-check-input'  <?php if(isset($setting['box_type'])&&$setting['box_type']=='switch') echo 'checked';?> >
+                    <label class='form-check-label'>开关(适用于输出值为1,0的组合,且1在前面)</label>
+                </div>
+            </li>
+        </ul>
+    </div>
+</div>
+
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >字段类型</label>
+    <div class="col-md-10">
+        <select class="form-select " name="setting[field_type]" id="setting_field_type" onchange="if($(this).val()!='varchar'){$('#min_number').show();}else{$('#min_number').hide();}">
+            <option value="varchar" <?php if(isset($setting['field_type'])&&$setting['field_type']=='varchar') echo 'selected';?>>字符 VARCHAR</option>
+            <option value="tinyint" <?php if(isset($setting['field_type'])&&$setting['field_type']=='tinyint') echo 'selected';?>>整数 TINYINT(3)</option>
+            <option value="smallint" <?php if(isset($setting['field_type'])&&$setting['field_type']=='smallint') echo 'selected';?>>整数 SMALLINT(5)</option>
+            <option value="mediumint" <?php if(isset($setting['field_type'])&&$setting['field_type']=='mediumint') echo 'selected';?>>整数 MEDIUMINT(8)</option>
+            <option value="int" <?php if(isset($setting['field_type'])&&$setting['field_type']=='int') echo 'selected';?>>整数 INT(10)</option>
+        </select>
+    </div>
+</div>
+
+<div class="mb-3 row" id="min_number"  style="<?php if($setting['field_type']=='varchar'){?> display: none <?php }?>">
+    <label class="col-md-2 col-form-label" >整数类型</label>
+    <div class=" col-md-10">
+        <ul class="list-group">
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[min_number]' value='1' class='form-check-input' <?php if(isset($setting['min_number'])&&$setting['min_number']==1) echo 'checked';?>>
+                    <label class='form-check-label'>正整数</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[min_number]' value='-1' class='form-check-input' <?php if(isset($setting['min_number'])&&$setting['min_number']==-1) echo 'checked';?> >
+                    <label class='form-check-label'>整数</label>
+                </div>
+            </li>
+        </ul>
+    </div>
+</div>
+
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >默认值</label>
+    <div class="col-md-10">
+        <input type="text" name="setting[default_value]" value="<?php echo isset($setting['default_value'])?$setting['default_value']:'';?>" autocomplete="off" class="form-control" >
+    </div>
+</div>
+
+<div class="mb-3 row" >
+    <label class="col-md-2 col-form-label" >输出方式</label>
+    <div class=" col-md-10">
+        <ul class="list-group">
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[output_type]' value='1' class='form-check-input' <?php if(isset($setting['output_type'])&&$setting['output_type']) echo 'checked';?> >
+                    <label class='form-check-label'>输出选项值</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[output_type]' value='0' class='form-check-input'  <?php if(isset($setting['output_type'])&&!$setting['output_type']) echo 'checked';?>>
+                    <label class='form-check-label'>输出选项名称</label>
+                </div>
+            </li>
+        </ul>
+    </div>
+</div>
+<div class="mb-3 row" >
+    <label class="col-md-2 col-form-label" >筛选字段</label>
+    <div class=" col-md-10">
+        <input  value="1"  id="switch-filter_type" type="checkbox" switch="success" class="row-switch" name="setting[filter_type]" <?php if(isset($setting['filter_type'])&&$setting['filter_type']) echo 'checked';?> >
+        <label class="switch-check-label " for="switch-filter_type" data-on-label="是" data-off-label="否"></label>
+    </div>
+</div>
+

+ 53 - 0
common/widget/fields/box/form.inc.php

@@ -0,0 +1,53 @@
+    function box($field, $value, $fieldinfo) {
+        $string = '';
+        $require = $fieldinfo['min_length']  ? 'required required_box' : '';
+        $pattern = $fieldinfo['pattern'] ?$fieldinfo['pattern']:'';
+        $errortips = $fieldinfo['error_tips'] ?$fieldinfo['error_tips']:'';
+        if($value=='') $value = !empty($fieldinfo['default_value'])?$fieldinfo['default_value']:'';
+        $options = isset($fieldinfo['options'])?explode("\n",$fieldinfo['options']):array();
+        if(!empty($options))foreach($options as $_k) {
+            $v = explode("|",$_k);
+            if(!empty($v[0])){
+                $k = trim($v[1]);
+                $optionList[$k] = $v[0];
+            }
+        }
+        //去除空内容
+        $values = explode(',',$value);
+        $value = array();
+        if(!empty($values))foreach($values as $_k) {
+            if($_k != '') $value[] = $_k;
+        }
+        $value = implode(',',$value);
+        $string =  '<div class="mb-3 row '.$require.'" data-pattern = "'.$pattern.'" data-errtips = "'.$errortips.'" data-boxtype="'.$fieldinfo['box_type'].'" data-name="'.(in_array($fieldinfo['box_type'],['multiple','checkbox'])?"info[$field][]":"info[$field]").'">';
+        $string .= '<label class="col-md-2 col-form-label">'.$fieldinfo['name'].'</label>';
+
+        if(isset($optionList)&&isset($fieldinfo['box_type']))switch($fieldinfo['box_type']) {
+            case 'radio':
+                $string .= FormElements::radio($optionList,$value,"name='info[$field]' $fieldinfo[form_attribute] class='form-check-input' ",0);
+                $string .= $fieldinfo['tips']?'<div class="text-muted  input-word-aux offset-l-2">提示:'.$fieldinfo['tips'].'</div>':'';
+            break;
+            case 'checkbox':
+                $string .= FormElements::checkbox($optionList,$value,"name='info[$field][]' $fieldinfo[form_attribute]  class='form-check-input' ",0);
+                $string .= $fieldinfo['tips']?'<div class="text-muted  input-word-aux offset-l-2">提示:'.$fieldinfo['tips'].'</div>':'';
+            break;
+            case 'select':
+                $string .= '<div class="col-md-10">';
+                $string .= FormElements::select($optionList,$value,Yii::t('admin','please select'),"name='info[$field]' id='$field'  $fieldinfo[form_attribute] data-dselect-clearable='true' class='form-select $require'");
+                $string .= $fieldinfo['tips']?'<div class="text-muted  input-word-aux">提示:'.$fieldinfo['tips'].'</div>':'';
+                $string .= '</div>';
+            break;
+            case 'multiple':
+                $string .= '<div class="col-md-10">';
+                $string .= FormElements::select($optionList,$value,Yii::t('admin','please select'),"name='info[$field][]' id='$field'  multiple='multiple' data-dselect-clearable='true' class='form-select $require'");
+                $string .= $fieldinfo['tips']?'<div class="text-muted  input-word-aux">提示:'.$fieldinfo['tips'].'</div>':'';
+                $string .= '</div>';
+            break;
+            case 'switch':
+            $string .= FormElements::switchbox($optionList,$value,"name='info[$field]' $fieldinfo[form_attribute] class='form-check-input' ",$field);
+            $string .= $fieldinfo['tips']?'<div class="text-muted  input-word-aux offset-l-2">提示:'.$fieldinfo['tips'].'</div>':'';
+            break;
+        }
+        $string  .= '</div>';
+        return $string;
+    }

+ 10 - 0
common/widget/fields/cat_id/config.inc.php

@@ -0,0 +1,10 @@
+<?php
+$field_type				= 'int'; //字段数据库类型	
+$field_basic_table		= 1; //是否允许作为主表字段
+$field_allow_index		= 1; //是否允许建立索引
+$field_minlength		= 1; //字符长度默认最小值
+$field_maxlength		= '10'; //字符长度默认最大值
+$field_allow_search		= 0; //作为搜索条件
+$field_allow_fullsearch	= 0; //作为全站搜索信息
+$field_allow_isunique	= 0; //是否允许值唯一
+?>

+ 1 - 0
common/widget/fields/cat_id/field_add_form.inc.php

@@ -0,0 +1 @@
+ 

+ 0 - 0
common/widget/fields/cat_id/field_edit_form.inc.php


+ 13 - 0
common/widget/fields/cat_id/form.inc.php

@@ -0,0 +1,13 @@
+
+    function cat_id($field, $value, $fieldinfo) {
+        if(!$value) $value = $this->cat_id;
+        $publish_str = '';
+        $string =  '<div class="mb-3 row ">';
+        $string .= '<label class="col-md-2 col-form-label">'.$fieldinfo['name'].'</label>';
+        $string .= '<div class="col-md-10">';
+        $string .= '<input type="hidden" name="info['.$field.']" value="'.$value.'">';
+        $string .= '<div style="line-height: 35px;">'.$this->catTits.'</div>';
+        $string .= '</div>';
+        $string .= '</div>';
+        return $string;
+    }

+ 96 - 0
common/widget/fields/content_form.class.php

@@ -0,0 +1,96 @@
+<?php
+use app\common\components\CacheId;
+use app\common\components\FormElements;
+use app\common\widget\UeditorWidget;
+use app\common\widget\LinkmenuWidget;
+use app\modules\cms\models\PositionData;
+use app\modules\cms\models\Category;
+use app\modules\cms\models\CategoryConfig;
+use app\modules\admin\models\Sysconfig;
+use app\models\Linkmenu;
+use app\common\models\EActiveRecord;
+class content_form {
+	var $model_id;
+	var $fields;
+	var $id;
+    var $formValidator;
+    var $extTypeList;
+    var $url;
+    var $data;
+    function __construct($model_id,$cat_id = 0,$categorys = array()) {
+		$this->model_id = $model_id;
+		$this->cat_id = $cat_id;
+		$this->categorys = $categorys;
+        $this->catTits = Category::getTits($cat_id);
+        $arr_parent_ids = $this->categorys[$cat_id]['arr_parent_ids'];
+        if(!empty($arr_parent_ids))
+        {
+            $extResult = CategoryConfig::find()->where("cat_id=".$this->cat_id." or cat_id in(".trim($arr_parent_ids,',').")")->orderBy(['cat_id'=>SORT_ASC,'list_order'=>SORT_ASC])->limit(5)->asArray()->all();
+        }
+        else
+        {
+            $extResult = CategoryConfig::find()->where("cat_id=".$this->cat_id)->orderBy(['cat_id'=>SORT_ASC,'list_order'=>SORT_ASC])->limit(5)->asArray()->all();
+        }
+
+        if(is_array($extResult))foreach($extResult as $k=>$tmpResult)
+        {
+            $tmpResult['var_name']= 'ext_type_'.($k+1);
+            $this->extTypeList[$tmpResult['var_name']] = $tmpResult;
+        }
+		$this->fields =  json_decode(Yii::$app->cache->get(CacheId::modelFieldCacheId($model_id)),true);
+        foreach($this->fields as $k=>$field)
+        {
+            if(!empty($this->extTypeList))foreach($this->extTypeList as $extType)
+            {
+                if($k==$extType['var_name'])
+                {
+                    $this->fields[$k]['tips'] = $extType['name'];
+                    $this->fields[$k]['name'] = $extType['bak'];
+                }
+            }
+        }
+    }
+
+
+	function get($data = array()) {
+        $identityInfo = Yii::$app->controller->getIdentityInfo();
+        //获取用户组或角色
+        if(!defined('IN_ADMIN')) $group_id = $identityInfo['group_id'];
+        else $role_id = $identityInfo['role_id'];
+		$this->data = $data;
+		if(isset($data['id'])) $this->id = $data['id'];
+		$this->url = isset($data['url'])?$data['url']:'';//跳转链接
+		$info = array();
+		if(is_array($this->fields))foreach($this->fields as $field=>$v) {
+			if(defined('IN_ADMIN')) {
+				if($v['is_core'] || check_rights($role_id, $v['unset_role_ids'])) continue;
+			} else {
+				if($v['is_core'] || !$v['is_add'] || check_rights($group_id, $v['unset_group_ids'])) continue;
+			}
+			$func = $v['form_type'];
+			$value = isset($data[$field]) ? htmlspecialchars($data[$field], ENT_QUOTES) : '';
+			if($func=='pages' && isset($data['maxchar_perpage'])) {
+				$value = $data['pagination_type'].'|'.$data['maxchar_perpage'];
+			}
+			if(!method_exists($this, $func)) continue;
+            if($func!='box'&&$func!='author'&&$func!='cat_id'&&$func!='copy_from'&&$func!='datetime'&&$func!='downfiles'&&$func!='editor'&&$func!='ext_type'&&$func!='group_id'&&$func!='image'&&$func!='images'&&$func!='is_link'&&$func!='keywords'&&$func!='linkmenu'&&$func!='map'&&$func!='number'&&$func!='pages'&&$func!='pos_id'&&$func!='read_price'&&$func!='sysconfig'&&$func!='text'&&$func!='textarea'&&$func!='title'&&$func!='type_id')continue;
+			$form = $this->$func($field, $value, $v);
+            //star 1:必填
+			if($form !== false) {
+				if(defined('IN_ADMIN')) {
+					if($v['is_base']) {
+						$star = $v['min_length'] || $v['pattern'] ? 1 : 0;
+						$info['base'][$field] = array('name'=>$v['name'], 'tips'=>$v['tips'], 'form'=>$form, 'star'=>$star,'is_omnipotent'=>$v['is_omnipotent'],'form_type'=>$v['form_type'],'is_add_admin'=>$v['is_add_admin']);
+					} else {
+						$star = $v['min_length'] || $v['pattern'] ? 1 : 0;
+						$info['senior'][$field] = array('name'=>$v['name'], 'tips'=>$v['tips'], 'form'=>$form, 'star'=>$star,'is_omnipotent'=>$v['is_omnipotent'],'form_type'=>$v['form_type'],'is_add_admin'=>$v['is_add_admin']);
+					}
+				} else {
+					$star = $v['min_length'] || $v['pattern'] ? 1 : 0;
+					$info[$field] = array('name'=>$v['name'], 'tips'=>$v['tips'], 'form'=>$form, 'star'=>$star,'is_omnipotent'=>$v['is_omnipotent'],'form_type'=>$v['form_type'],'is_add'=>$v['is_add']);
+				}
+			}
+		}
+		return $info;
+	}
+}?>

+ 72 - 0
common/widget/fields/content_input.class.php

@@ -0,0 +1,72 @@
+<?php
+class content_input {
+	var $model_id;
+	var $fields;
+    var $model;
+	var $data;
+    var $site_config;
+    function __construct($model_id) {
+		$this->db_pre = Yii::$app->db->tablePrefix;
+		$this->model_id = $model_id;
+        $this->fields =  json_decode(Yii::$app->cache->get(CacheId::modelFieldCacheId($model_id)),true);
+        $this->model = json_decode(Yii::$app->cache->get(CacheId::modelFieldCacheId($model_id)),true);
+        $this->site_config = json_decode(Yii::$app->cache->get(CacheId::siteConfigCacheId()),true);
+    }
+
+	function get($data,$is_import = 0) {
+        $identityInfo = Yii::$app->controller->getIdentityInfo();
+        if(!defined('IN_ADMIN')) $group_id = $identityInfo['group_id'];//获取用户组
+        else $role_id = $identityInfo['role_id'];
+        $this->data = $data = trim_script($data);
+        $info = array();
+        foreach($data as $field=>$value)
+        {
+            if(!isset($this->fields[$field]) || check_in($role_id, $this->fields[$field]['unset_role_ids']) || check_in($group_id, $this->fields[$field]['unset_group_ids'])) continue;
+            $name = $this->fields[$field]['name'];
+            $min_length = $this->fields[$field]['min_length'];
+            $max_length = $this->fields[$field]['max_length'];
+            $pattern = $this->fields[$field]['pattern'];
+            $error_tips = $this->fields[$field]['error_tips'];
+            if(empty($error_tips)) $error_tips = $name.'不符合条件';
+            $length = empty($value) ? 0 : (is_string($value) ? strlen($value) : count($value));
+            if($min_length && $length < $min_length) {
+                if($is_import) {
+                    return false;
+                } else {
+                    Yii::$app->controller->showMessage(array('class'=>'info', 'message'=>$name.' 不能少于 '.$min_length.'个字符'));
+                }
+            }
+            if($max_length && $length > $max_length) {
+                if($is_import) {
+                    $value = str_cut($value,0,$max_length,'');
+                } else {
+                    Yii::$app->controller->showMessage(array('class'=>'info', 'message'=>$name.' 不能多于 '.$max_length.'个字符'));
+                }
+            } elseif($max_length) {
+                $value = str_cut($value,0,$max_length,'');
+            }
+            if($pattern && $length && !preg_match($pattern, $value) && !$is_import) Yii::$app->controller->showMessage(array('class'=>'info', 'message'=>$error_tips));
+            $this->table_name = $this->fields[$field]['is_system'] ? $this->db_pre.$this->model['table_name'] : $this->db_pre.$this->model['table_name'].'_data';
+            if($this->fields[$field]['is_unique'])
+            {
+                //这里要补充判断唯一方法
+                $exists = (new \yii\db\Query())
+                    ->from($this->table_name)
+                    ->where([$field => $value])
+                    ->count();
+                if($exists)Yii::$app->controller->showMessage(array('class'=>'info', 'message'=>$name.' 不能重复'));
+            }
+            $func = $this->fields[$field]['form_type'];
+            if(method_exists($this, $func)) $value = $this->$func($field, $value);
+            if($this->fields[$field]['is_system']) {
+                $info['system'][$field] = $value;
+            } else {
+                $info['model'][$field] = $value;
+            }
+            //颜色选择为隐藏域 在这里进行取值
+            $info['system']['style'] = $_POST['style_color'] ? strip_tags($_POST['style_color']) : '';
+            if($_POST['style_font_weight']) $info['system']['style'] = $info['system']['style'].';'.strip_tags($_POST['style_font_weight']);
+        }
+        return $info;
+	}
+}?>

+ 25 - 0
common/widget/fields/content_output.class.php

@@ -0,0 +1,25 @@
+<?php
+class content_output {
+	var $fields;
+	var $data;
+
+	function __construct($model_id,$cat_id = 0,$categorys = array()) {
+		$this->model_id = $model_id;
+		$this->cat_id = $cat_id;
+		$this->categorys = $categorys;
+        $this->fields =  json_decode(Yii::$app->cache->get(CacheId::modelFieldCacheId($model_id)),true);
+    }
+	function get($data) {
+		$this->data = $data;
+		$this->id = $data['id'];
+		$info = array();
+		foreach($this->fields as $field=>$v) {
+			if(!isset($data[$field])) continue;
+			$func = $v['form_type'];
+			$value = $data[$field];
+			$result = method_exists($this, $func) ? $this->$func($field, $data[$field]) : $data[$field];
+			if($result !== false) $info[$field] = $result;
+		}
+		return $info;
+	}
+}?>

+ 21 - 0
common/widget/fields/content_update.class.php

@@ -0,0 +1,21 @@
+<?php
+class content_update {
+	var $model_id;
+	var $fields;
+	var $data;
+
+    function __construct($model_id,$id) {
+		$this->model_id = $model_id;
+        $this->fields =  json_decode(Yii::$app->cache->get(CacheId::modelFieldCacheId($model_id)),true);
+		$this->id = $id;
+    }
+	function update($data) {
+		$info = array();
+		$this->data = $data;
+		foreach($data as $field=>$value) {
+			if(!isset($this->fields[$field])) continue;
+			$func = $this->fields[$field]['form_type'];
+			$info[$field] = method_exists($this, $func) ? $this->$func($field, $value) : $value;
+		}
+	}
+}?>

+ 10 - 0
common/widget/fields/copy_from/config.inc.php

@@ -0,0 +1,10 @@
+<?php
+$field_type				= 'varchar'; //字段数据库类型	
+$field_basic_table		= 1; //是否允许作为主表字段
+$field_allow_index		= 0; //是否允许建立索引
+$field_minlength		= 0; //字符长度默认最小值
+$field_maxlength		= '100'; //字符长度默认最大值
+$field_allow_search		= 0; //作为搜索条件
+$field_allow_fullsearch	= 0; //作为全站搜索信息
+$field_allow_isunique	= 0; //是否允许值唯一
+?>

+ 6 - 0
common/widget/fields/copy_from/field_add_form.inc.php

@@ -0,0 +1,6 @@
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >默认值</label>
+    <div class="col-md-10">
+        <input type="text" name="setting[default_value]" value="" autocomplete="off" class="form-control" >
+    </div>
+</div>

+ 6 - 0
common/widget/fields/copy_from/field_edit_form.inc.php

@@ -0,0 +1,6 @@
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >默认值</label>
+    <div class="col-md-10">
+        <input type="text" name="setting[default_value]" value="<?php echo $setting['default_value'];?>" autocomplete="off" class="form-control" >
+    </div>
+</div>

+ 19 - 0
common/widget/fields/copy_from/form.inc.php

@@ -0,0 +1,19 @@
+    function copy_from($field, $value, $fieldinfo) {
+        $require = $fieldinfo['min_length']  ? 'required' : '';
+        $pattern = $fieldinfo['pattern'] ?$fieldinfo['pattern']:'';
+        $errortips = $fieldinfo['error_tips'] ?$fieldinfo['error_tips']:'';
+        $copy_from_array = json_decode(Yii::$app->cache->get(CacheId::copyFromCacheId()),true);
+        if(!empty($copy_from_array)) {
+            foreach($copy_from_array as $_k=>$_v) {
+                $copy_from_datas[$_k] = $_v['name'];
+            }
+        }
+        $string  =  '<div class="mb-3 row '.$require.'">';
+        $string .= '<label class="col-md-2 col-form-label">'.$fieldinfo['name'].'</label>';
+        $string .= '<div class="col-md-10">';
+        $string .= FormElements::select($copy_from_datas,$value,Yii::t('admin','please select'),"name='info[$field]' id='$field'  $fieldinfo[form_attribute] data-pattern = '$pattern' data-errtips = '$errortips' data-dselect-clearable='true' class='form-select $require'");
+        $string .= $fieldinfo['tips']?'<div class="text-muted  input-word-aux">提示:'.$fieldinfo['tips'].'</div>':'';
+        $string .= '</div>';
+        $string  .= '</div>';
+        return $string;
+    }

+ 10 - 0
common/widget/fields/datetime/config.inc.php

@@ -0,0 +1,10 @@
+<?php
+$field_type				= 'datetime'; //字段数据库类型	
+$field_basic_table		= 1; //是否允许作为主表字段
+$field_allow_index		= 1; //是否允许建立索引
+$field_minlength		= '0'; //字符长度默认最小值
+$field_maxlength		= '0'; //字符长度默认最大值
+$field_allow_search		= 1; //作为搜索条件
+$field_allow_fullsearch	= 0; //作为全站搜索信息
+$field_allow_isunique	= 0; //是否允许值唯一
+?>

+ 84 - 0
common/widget/fields/datetime/field_add_form.inc.php

@@ -0,0 +1,84 @@
+
+<div class="mb-3 row" >
+    <label class="col-md-2 col-form-label" >存储格式</label>
+    <div class=" col-md-10">
+        <ul class="list-group">
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[save_format]' value='date' class='form-check-input' >
+                    <label class='form-check-label'>日期(<?php echo date('Y-m-d');?>)</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[save_format]' value='datetime' class='form-check-input'>
+                    <label class='form-check-label'>日期+24小时制时间(<?php echo date('Y-m-d H:i:s');?>)</label>
+                </div>
+            </li>
+            <li class='list-group-item'>
+                <div class='form-check'>
+                    <input type='radio' name='setting[save_format]' value='int' class='form-check-input' checked>
+                    <label class='form-check-label'>整数时间戳</label>
+                </div>
+            </li>
+        </ul>
+    </div>
+</div>
+
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >显示格式</label>
+    <div class="col-md-10">
+        <select class="form-select " name="setting[show_format]" >
+            <option value="Y-m-d H:i:s">24小时制:<?php echo date('Y-m-d H:i:s');?></option>
+            <option value="Y-m-d H:i"><?php echo date('Y-m-d H:i');?></option>
+            <option value="Y-m-d"><?php echo date('Y-m-d');?></option>
+            <option value="m-d"><?php echo date('m-d');?></option>
+        </select>
+    </div>
+</div>
+
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label" >动态限制</label>
+    <div class="col-md-10">
+        <select class="form-select " name="setting[dynamic]" >
+            <option value="">请选择</option>
+            <option value="1">今天以前的日期(包括今天)</option>
+            <option value="2">今天以后的日期(不包括今天)</option>
+            <option value="3">本月的日期1号至本月最后一天</option>
+        </select>
+    </div>
+</div>
+<div class="mb-3 row">
+    <label class="col-md-2 col-form-label">静态限制</label>
+    <div class="row col-md-10">
+        <div class="col-sm-auto ">
+            <label class="visually-hidden" >请输入</label>
+            <input type="date"  class="form-control" name="setting[min_date]" placeholder="起始日期" autocomplete="off">
+        </div>
+        <div class="col-sm-auto">
+            <label class="visually-hidden" >终止日期</label>
+            <input type="date"  class="form-control" name="setting[max_date]" placeholder="终止日期" autocomplete="off">
+        </div>
+        <div class="text-muted input-word-aux"></div>
+    </div>
+</div>
+
+<div class="mb-3 row" style="display: none">
+    <label class="col-md-2 col-form-label" >控件Id</label>
+    <div class="col-md-10">
+        <input type="text" name="setting[input_id]" value="" autocomplete="off" class="form-control" >
+    </div>
+</div>
+<div class="mb-3 row" style="display: none">
+    <label class="col-md-2 col-form-label" >控件Name</label>
+    <div class="col-md-10">
+        <input type="text" name="setting[input_name]" value="" autocomplete="off" class="form-control" >
+    </div>
+</div>
+<div class="mb-3 row" >
+    <label class="col-md-2 col-form-label" >输入框只读</label>
+    <div class=" col-md-10">
+        <input  value="1"  id="switch-read_only" type="checkbox" switch="success" class="row-switch" name="setting[read_only]">
+        <label class="switch-check-label " for="switch-read_only" data-on-label="是" data-off-label="否"></label>
+    </div>
+</div>

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません