Browse Source

游戏 sdk准备部署

wcc 3 years ago
commit
35371102d5
100 changed files with 29835 additions and 0 deletions
  1. 72 0
      .gitignore
  2. 3 0
      README.md
  3. 33 0
      admin/admin/controller/DialogController.php
  4. 138 0
      admin/admin/controller/HookController.php
  5. 91 0
      admin/admin/controller/IndexController.php
  6. 207 0
      admin/admin/controller/LinkController.php
  7. 172 0
      admin/admin/controller/MailerController.php
  8. 186 0
      admin/admin/controller/MainController.php
  9. 733 0
      admin/admin/controller/MenuController.php
  10. 179 0
      admin/admin/controller/NavController.php
  11. 306 0
      admin/admin/controller/NavMenuController.php
  12. 462 0
      admin/admin/controller/PluginController.php
  13. 152 0
      admin/admin/controller/PublicController.php
  14. 430 0
      admin/admin/controller/RbacController.php
  15. 126 0
      admin/admin/controller/RecycleBinController.php
  16. 292 0
      admin/admin/controller/RouteController.php
  17. 324 0
      admin/admin/controller/SettingController.php
  18. 83 0
      admin/admin/controller/StorageController.php
  19. 836 0
      admin/admin/controller/ThemeController.php
  20. 371 0
      admin/admin/controller/UserController.php
  21. 83 0
      admin/admin/controller/account/AccountController.php
  22. 279 0
      admin/admin/controller/account/GoodsController.php
  23. 72 0
      admin/admin/controller/account/OrderController.php
  24. 64 0
      admin/admin/controller/account/WapController.php
  25. 125 0
      admin/admin/controller/activity/IntegralActivityController.php
  26. 254 0
      admin/admin/controller/agent/AgentController.php
  27. 178 0
      admin/admin/controller/agent/AgentGameController.php
  28. 108 0
      admin/admin/controller/agent/BaseController.php
  29. 112 0
      admin/admin/controller/agent/GameController.php
  30. 54 0
      admin/admin/controller/agent/NoticeController.php
  31. 58 0
      admin/admin/controller/agent/SeoController.php
  32. 60 0
      admin/admin/controller/agent/SlideController.php
  33. 74 0
      admin/admin/controller/app/BaseController.php
  34. 386 0
      admin/admin/controller/app/GameAppController.php
  35. 235 0
      admin/admin/controller/app/GameRebateController.php
  36. 180 0
      admin/admin/controller/app/MessageController.php
  37. 76 0
      admin/admin/controller/app/RebateController.php
  38. 206 0
      admin/admin/controller/app/SpcController.php
  39. 336 0
      admin/admin/controller/app/VersionController.php
  40. 59 0
      admin/admin/controller/article/ActivityController.php
  41. 59 0
      admin/admin/controller/article/NewsController.php
  42. 59 0
      admin/admin/controller/article/NoticeController.php
  43. 59 0
      admin/admin/controller/article/WalkthroughController.php
  44. 330 0
      admin/admin/controller/conf/PaywayController.php
  45. 542 0
      admin/admin/controller/data/DataController.php
  46. 665 0
      admin/admin/controller/data/DayController.php
  47. 170 0
      admin/admin/controller/data/LtvController.php
  48. 590 0
      admin/admin/controller/data/RankController.php
  49. 321 0
      admin/admin/controller/data/RemainController.php
  50. 2121 0
      admin/admin/controller/distribution/AbsController.php
  51. 305 0
      admin/admin/controller/distribution/BaseController.php
  52. 357 0
      admin/admin/controller/distribution/LandingPageController.php
  53. 188 0
      admin/admin/controller/distribution/PackageController.php
  54. 460 0
      admin/admin/controller/distribution/PlanController.php
  55. 249 0
      admin/admin/controller/distribution/PlatformController.php
  56. 132 0
      admin/admin/controller/distribution/PromotionWhitelistController.php
  57. 50 0
      admin/admin/controller/feedback/FeedbackController.php
  58. 516 0
      admin/admin/controller/financial/AgentController.php
  59. 129 0
      admin/admin/controller/financial/AgentCpaLogController.php
  60. 521 0
      admin/admin/controller/financial/GamemoneyController.php
  61. 488 0
      admin/admin/controller/financial/OrderController.php
  62. 1015 0
      admin/admin/controller/financial/PtbController.php
  63. 206 0
      admin/admin/controller/game/AndroidGameController.php
  64. 145 0
      admin/admin/controller/game/ChannelController.php
  65. 170 0
      admin/admin/controller/game/CpController.php
  66. 399 0
      admin/admin/controller/game/CpsGameController.php
  67. 233 0
      admin/admin/controller/game/GameCategoryController.php
  68. 1354 0
      admin/admin/controller/game/GameController.php
  69. 424 0
      admin/admin/controller/game/H5gameController.php
  70. 222 0
      admin/admin/controller/game/HelpController.php
  71. 265 0
      admin/admin/controller/game/IosGameController.php
  72. 147 0
      admin/admin/controller/game/PaySwitchController.php
  73. 271 0
      admin/admin/controller/game/QqController.php
  74. 132 0
      admin/admin/controller/game/ServerController.php
  75. 235 0
      admin/admin/controller/gift/GiftController.php
  76. 189 0
      admin/admin/controller/identify/HolidaySetController.php
  77. 203 0
      admin/admin/controller/identify/IdentifyConfController.php
  78. 331 0
      admin/admin/controller/identify/IdentifyGameController.php
  79. 155 0
      admin/admin/controller/identify/IdentifyMemController.php
  80. 156 0
      admin/admin/controller/identify/IdentifyPlatformLogController.php
  81. 427 0
      admin/admin/controller/lottery/LotteryController.php
  82. 120 0
      admin/admin/controller/member/BanController.php
  83. 55 0
      admin/admin/controller/member/MemGameController.php
  84. 746 0
      admin/admin/controller/member/MemberController.php
  85. 155 0
      admin/admin/controller/member/RoleController.php
  86. 141 0
      admin/admin/controller/member/VipController.php
  87. 302 0
      admin/admin/controller/mp/agent/AgBaseController.php
  88. 119 0
      admin/admin/controller/mp/agent/AgentController.php
  89. 102 0
      admin/admin/controller/mp/agent/GameController.php
  90. 70 0
      admin/admin/controller/mp/agent/H5AgentGameController.php
  91. 70 0
      admin/admin/controller/mp/agent/MpAgentGameController.php
  92. 861 0
      admin/admin/controller/mp/data/DataController.php
  93. 191 0
      admin/admin/controller/mp/data/RankController.php
  94. 230 0
      admin/admin/controller/mp/fill/SubMemRankController.php
  95. 642 0
      admin/admin/controller/mp/financial/FinancialController.php
  96. 1195 0
      admin/admin/controller/mp/game/GameController.php
  97. 589 0
      admin/admin/controller/mp/game/HomeTagController.php
  98. 147 0
      admin/admin/controller/mp/game/PaySwitchController.php
  99. 849 0
      admin/admin/controller/mp/hunter/HunterController.php
  100. 66 0
      admin/admin/controller/mp/member/MemRiskController.php

+ 72 - 0
.gitignore

@@ -0,0 +1,72 @@
+# ---> PhpStorm
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/dictionaries
+
+# Sensitive or high-churn files:
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.xml
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+
+# Gradle:
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# CMake
+cmake-build-debug/
+
+# Mongo Explorer plugin:
+.idea/**/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Ruby plugin and RubyMine
+/.rakeTasks
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+### PhpStorm Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+.idea/sonarlint
+
+
+.idea
+*.iml
+out
+gen
+/public/static/web/images/
+/public/static/web/pc/images/

+ 3 - 0
README.md

@@ -0,0 +1,3 @@
+# game-sdk
+
+游戏SDK

+ 33 - 0
admin/admin/controller/DialogController.php

@@ -0,0 +1,33 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <zxxjjforever@163.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+
+class DialogController extends AdminBaseController
+{
+    public function _initialize()
+    {
+
+    }
+
+    public function map()
+    {
+        $location = $this->request->param('location');
+        $location = explode(',', $location);
+        $lng      = empty($location[0]) ? 116.424966 : $location[0];
+        $lat      = empty($location[1]) ? 39.907851 : $location[1];
+
+        $this->assign(['lng' => $lng, 'lat' => $lat]);
+        return $this->fetch();
+    }
+
+}

+ 138 - 0
admin/admin/controller/HookController.php

@@ -0,0 +1,138 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <zxxjjforever@163.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use admin\admin\model\HookModel;
+use admin\admin\model\PluginModel;
+use admin\admin\model\HookPluginModel;
+use think\Db;
+
+/**
+ * Class HookController 钩子管理控制器
+ * @package app\admin\controller
+ */
+class HookController extends AdminBaseController
+{
+    /**
+     * 钩子管理
+     * @adminMenu(
+     *     'name'   => '钩子管理',
+     *     'parent' => 'admin/Plugin/default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '钩子管理',
+     *     'param'  => ''
+     * )
+     */
+    public function index()
+    {
+        $hookModel = new HookModel();
+        $hooks     = $hookModel->select();
+        $this->assign('hooks', $hooks);
+        return $this->fetch();
+    }
+
+    /**
+     * 钩子插件管理
+     * @adminMenu(
+     *     'name'   => '钩子插件管理',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '钩子插件管理',
+     *     'param'  => ''
+     * )
+     */
+    public function plugins()
+    {
+        $hook        = $this->request->param('hook');
+        $pluginModel = new PluginModel();
+        $plugins     = $pluginModel->field('a.*,b.hook,b.plugin,b.list_order,b.status as hook_plugin_status,b.id as hook_plugin_id')->alias('a')->join('__HOOK_PLUGIN__ b', 'a.name = b.plugin')->where('b.hook', $hook)->select();
+        $this->assign('plugins', $plugins);
+        return $this->fetch();
+    }
+
+    /**
+     * 钩子插件排序
+     * @adminMenu(
+     *     'name'   => '钩子插件排序',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '钩子插件排序',
+     *     'param'  => ''
+     * )
+     */
+    public function pluginListOrder()
+    {
+        $hookPluginModel = new HookPluginModel();
+        parent::listOrders($hookPluginModel);
+
+        $this->adminSuccess("排序更新成功!");
+    }
+
+    /**
+     * 同步钩子
+     * @adminMenu(
+     *     'name'   => '同步钩子',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '同步钩子',
+     *     'param'  => ''
+     * )
+     */
+    public function sync()
+    {
+
+        $apps = cmf_scan_dir(APP_PATH . '*', GLOB_ONLYDIR);
+
+        foreach ($apps as $app) {
+            $hookConfigFile = APP_PATH . $app . '/hooks.php';
+            if (file_exists($hookConfigFile)) {
+                $hooksInFile = include $hookConfigFile;
+
+                foreach ($hooksInFile as $hookName => $hook) {
+
+                    $hook['type'] = empty($hook['type']) ? 2 : $hook['type'];
+
+                    if (!in_array($hook['type'], [2, 3, 4])) {
+                        $hook['type'] = 2;
+                    }
+
+                    $findHook = Db::name('hook')->where(['hook' => $hookName])->count();
+
+                    $hook['app'] = $app;
+
+                    if ($findHook > 0) {
+                        Db::name('hook')->where(['hook' => $hookName])->strict(false)->field(true)->update($hook);
+                    } else {
+                        $hook['hook'] = $hookName;
+                        Db::name('hook')->insert($hook);
+                    }
+                }
+            }
+        }
+
+        return $this->fetch();
+    }
+
+
+}

+ 91 - 0
admin/admin/controller/IndexController.php

@@ -0,0 +1,91 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\agent\AgentCache;
+use huo\controller\member\MemCache;
+use huo\controller\pay\SdkOrderCache;
+use huo\model\member\MemoauthModel;
+use huo\model\menu\AdminMenuModel;
+use huolib\constant\AgentConst;
+use huolib\constant\MpConfConst;
+use huomp\model\weixin\MpConfModel;
+use huoMpAd\MpOpenMktNew;
+use huoMpAd\MpReportData;
+use think\Db;
+
+class IndexController extends AdminBaseController {
+    public function _initialize() {
+        $adminSettings = cmf_get_option('admin_settings');
+        if (empty($adminSettings['admin_password']) || $this->request->path() == $adminSettings['admin_password']) {
+            $adminId = cmf_get_current_admin_id();
+            if (empty($adminId)) {
+                session("__LOGIN_BY_CMF_ADMIN_PW__", 1);//设置后台登录加密码
+            }
+        }
+        parent::_initialize();
+    }
+
+    /**
+     * 后台首页
+     */
+    public function index() {
+        $adminMenuModel = new AdminMenuModel();
+        $menus = $adminMenuModel->menuTree();
+        $this->assign("menus", $menus);
+        $admin = Db::name("user")->where('id', cmf_get_current_admin_id())->find();
+        $this->assign('admin', $admin);
+
+        return $this->fetch();
+    }
+
+    public function test() {
+
+
+
+        $order_id = 'g1618156261834410003';
+        //(new MpReportData())->payReport($order_id);
+//        $_order_info = (new SdkOrderCache())->getInfoByOrderId($order_id);
+//        (new MpReportData())->createRoleReport($_order_info['mg_mem_id'], '206','103831');
+//        echo 1111;exit;
+
+        $_order_info = (new SdkOrderCache())->getInfoByOrderId($order_id);
+        $_mem_info = (new MemCache())->getInfoById($_order_info['mem_id']);
+        $_agent_info = (new AgentCache())->getInfoByAgentId($_mem_info['agent_id']);
+        if (!empty($_agent_info)
+            && in_array($_agent_info['role_id'], [AgentConst::AGENT_ROLE_MP_ACCOUNT, AgentConst::AGENT_ROLE_MP_AD])
+        ) {
+            $_mp_conf_model = new MpConfModel();
+            $_mp_conf_info = $_mp_conf_model->getDataByAppId($_order_info['app_id'], MpConfConst::MP_CONF_TYPE_6);
+            if (empty($_mp_conf_info)) {
+                echo 222222;exit;
+            }
+            $_conf_id = $_mp_conf_info['id'];
+            $_openid = (new MemoauthModel())->getOpenIdByMpMemId($_conf_id, $_order_info['mem_id']);
+            $_action_data = [];
+            $_action_data['url'] = 'http://www.qq.com';
+            $_action_data['action_time'] = $_order_info['pay_time'];
+            $_action_data['action_type'] = 'PURCHASE';
+            $_action_data['openid'] = $_openid;
+            $_action_data['action_param_value'] = $_order_info['amount'];
+            $_mp_open_mkt = new MpOpenMktNew();
+            //$_mp_open_mkt->dataReport($_mp_conf_info, $_mem_info['agent_id'], $_action_data);
+            $a = $_mp_open_mkt->getDataSourceInfo($_mp_conf_info, $_mem_info['agent_id']);
+            dump($a);
+            $b = $_mp_open_mkt->getDataSourceReport(
+                $_mp_conf_info, $_mem_info['agent_id'], '2021-04-11', '2021-04-11'
+            );
+            dump($b);
+            exit;
+        }
+    }
+}

+ 207 - 0
admin/admin/controller/LinkController.php

@@ -0,0 +1,207 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use admin\admin\model\LinkModel;
+
+class LinkController extends AdminBaseController
+{
+    protected $targets = ["_blank" => "新标签页打开", "_self" => "本窗口打开"];
+
+    /**
+     * 友情链接管理
+     * @adminMenu(
+     *     'name'   => '友情链接',
+     *     'parent' => 'admin/Setting/default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 50,
+     *     'icon'   => '',
+     *     'remark' => '友情链接管理',
+     *     'param'  => ''
+     * )
+     */
+    public function index()
+    {
+        $linkModel = new LinkModel();
+        $links     = $linkModel->select();
+        $this->assign('links', $links);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加友情链接
+     * @adminMenu(
+     *     'name'   => '添加友情链接',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '添加友情链接',
+     *     'param'  => ''
+     * )
+     */
+    public function add()
+    {
+        $this->assign('targets', $this->targets);
+        return $this->fetch();
+    }
+
+    /**
+     * 添加友情链接提交保存
+     * @adminMenu(
+     *     'name'   => '添加友情链接提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '添加友情链接提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function addPost()
+    {
+        $data      = $this->request->param();
+        $linkModel = new LinkModel();
+        $result    = $linkModel->validate(true)->allowField(true)->save($data);
+        if ($result === false) {
+            $this->adminError($linkModel->getError());
+        }
+
+        $this->adminSuccess("添加成功!", url("link/index"));
+    }
+
+    /**
+     * 编辑友情链接
+     * @adminMenu(
+     *     'name'   => '编辑友情链接',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '编辑友情链接',
+     *     'param'  => ''
+     * )
+     */
+    public function edit()
+    {
+        $id        = $this->request->param('id', 0, 'intval');
+        $linkModel = LinkModel::get($id);
+        $this->assign('targets', $this->targets);
+        $this->assign('link', $linkModel);
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑友情链接提交保存
+     * @adminMenu(
+     *     'name'   => '编辑友情链接提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '编辑友情链接提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function editPost()
+    {
+        $data      = $this->request->param();
+        $linkModel = new LinkModel();
+        $result    = $linkModel->validate(true)->allowField(true)->isUpdate(true)->save($data);
+        if ($result === false) {
+            $this->adminError($linkModel->getError());
+        }
+
+        $this->adminSuccess("保存成功!", url("link/index"));
+    }
+
+    /**
+     * 删除友情链接
+     * @adminMenu(
+     *     'name'   => '删除友情链接',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '删除友情链接',
+     *     'param'  => ''
+     * )
+     */
+    public function delete()
+    {
+        $id = $this->request->param('id', 0, 'intval');
+        LinkModel::destroy($id);
+
+        $this->adminSuccess("删除成功!", url("link/index"));
+    }
+
+    /**
+     * 友情链接排序
+     * @adminMenu(
+     *     'name'   => '友情链接排序',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '友情链接排序',
+     *     'param'  => ''
+     * )
+     */
+    public function listOrder()
+    {
+        $linkModel = new  LinkModel();
+        parent::listOrders($linkModel);
+        $this->adminSuccess("排序更新成功!");
+    }
+
+    /**
+     * 友情链接显示隐藏
+     * @adminMenu(
+     *     'name'   => '友情链接显示隐藏',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '友情链接显示隐藏',
+     *     'param'  => ''
+     * )
+     */
+    public function toggle()
+    {
+        $data      = $this->request->param();
+        $linkModel = new LinkModel();
+
+        if (isset($data['ids']) && !empty($data["display"])) {
+            $ids = $this->request->param('ids/a');
+            $linkModel->where(['id' => ['in', $ids]])->update(['status' => 1]);
+            $this->adminSuccess("更新成功!");
+        }
+
+        if (isset($data['ids']) && !empty($data["hide"])) {
+            $ids = $this->request->param('ids/a');
+            $linkModel->where(['id' => ['in', $ids]])->update(['status' => 0]);
+            $this->adminSuccess("更新成功!");
+        }
+
+
+    }
+
+}

+ 172 - 0
admin/admin/controller/MailerController.php

@@ -0,0 +1,172 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use think\Validate;
+
+class MailerController extends AdminBaseController
+{
+
+    /**
+     * 邮箱配置
+     * @adminMenu(
+     *     'name'   => '邮箱配置',
+     *     'parent' => 'admin/Setting/default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 10,
+     *     'icon'   => '',
+     *     'remark' => '邮箱配置',
+     *     'param'  => ''
+     * )
+     */
+    public function index()
+    {
+        $emailSetting = cmf_get_option('smtp_setting');
+        $this->assign($emailSetting);
+        return $this->fetch();
+    }
+
+    /**
+     * 邮箱配置
+     * @adminMenu(
+     *     'name'   => '邮箱配置提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '邮箱配置提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function indexPost()
+    {
+        $post = array_map('trim', $this->request->param());
+
+        if (in_array('', $post) && !empty($post['smtpsecure'])) {
+            $this->adminError("不能留空!");
+        }
+
+        cmf_set_option('smtp_setting', $post);
+
+        $this->adminSuccess("保存成功!");
+    }
+
+    /**
+     * 邮件模板
+     * @adminMenu(
+     *     'name'   => '邮件模板',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '邮件模板',
+     *     'param'  => ''
+     * )
+     */
+    public function template()
+    {
+        $allowedTemplateKeys = ['verification_code'];
+        $templateKey         = $this->request->param('template_key');
+
+        if (empty($templateKey) || !in_array($templateKey, $allowedTemplateKeys)) {
+            $this->adminError('非法请求!');
+        }
+
+        $template = cmf_get_option('email_template_' . $templateKey);
+        $this->assign($template);
+        return $this->fetch('template_verification_code');
+    }
+
+    /**
+     * 邮件模板提交
+     * @adminMenu(
+     *     'name'   => '邮件模板提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '邮件模板提交',
+     *     'param'  => ''
+     * )
+     */
+    public function templatePost()
+    {
+        $allowedTemplateKeys = ['verification_code'];
+        $templateKey         = $this->request->param('template_key');
+
+        if (empty($templateKey) || !in_array($templateKey, $allowedTemplateKeys)) {
+            $this->adminError('非法请求!');
+        }
+
+        $data = $this->request->param();
+
+        unset($data['template_key']);
+
+        cmf_set_option('email_template_' . $templateKey, $data);
+
+        $this->adminSuccess("保存成功!");
+    }
+
+    /**
+     * 邮件发送测试
+     * @adminMenu(
+     *     'name'   => '邮件发送测试',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '邮件发送测试',
+     *     'param'  => ''
+     * )
+     */
+    public function test()
+    {
+        if ($this->request->isPost()) {
+
+            $validate = new Validate([
+                'to'      => 'require|email',
+                'subject' => 'require',
+                'content' => 'require',
+            ]);
+            $validate->message([
+                'to.require'      => '收件箱不能为空!',
+                'to.email'        => '收件箱格式不正确!',
+                'subject.require' => '标题不能为空!',
+                'content.require' => '内容不能为空!',
+            ]);
+
+            $data = $this->request->param();
+            if (!$validate->check($data)) {
+                $this->adminError($validate->getError());
+            }
+
+            $result = cmf_send_email($data['to'], $data['subject'], $data['content']);
+            if ($result && empty($result['error'])) {
+                $this->adminSuccess('发送成功!');
+            } else {
+                $this->adminError('发送失败:' . $result['message']);
+            }
+
+        } else {
+            return $this->fetch();
+        }
+
+    }
+
+
+}
+

+ 186 - 0
admin/admin/controller/MainController.php

@@ -0,0 +1,186 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use huo\logic\agent\AgentLogic;
+use huo\logic\data\DayDataLogic;
+use huo\logic\data\RankDataLogic;
+use huo\logic\data\StatisticsLogic;
+use huo\model\game\GameextModel;
+use huo\model\game\GameModel;
+use huo\model\member\MemberExtModel;
+use huo\model\member\MemberModel;
+use huo\model\menu\AdminMenuModel;
+use huo\model\order\OrderModel;
+use huo\model\user\AgentExtModel;
+use huo\model\user\UserModel;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use huolib\constant\MemConst;
+use huolib\tool\Time;
+use huoLtv\logic\DayLogic;
+use think\Lang;
+
+class MainController extends AdminBaseController {
+    protected $map = [];
+
+    public function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_index'.EXT);
+        parent::_initialize();
+        if (AgentConst::ROLE_TYPE_PC == $this->role_type
+            || AgentConst::ROLE_TYPE_AGENT == $this->role_type) {
+            /* 查找拥有的渠道ID */
+            $_agent_ids = (new AgentLogic())->getAgentIds($this->admin_id);
+            $this->map['agent_id'] = ['in', $_agent_ids];
+        }
+    }
+
+    /**
+     * @return mixed
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function index() {
+        $_agent_type = [AgentConst::ROLE_TYPE_AGENT, AgentConst::ROLE_TYPE_GROUP];
+        if (!empty($this->origin_agent_id) || in_array($this->role_type, $_agent_type)) {
+            $this->redirect(url('admin/mp.data.data/index'));
+        }
+        $this->getGameData();
+        $this->getChannelData();
+        $this->getMemberData();
+        $this->getActiveData();
+        $this->getOrderData();
+        list($_start_time, $_end_time) = Time::lastThirty();
+        $_map = $this->map;
+        $_map['start_time'] = date('Y-m-d', $_start_time);
+        $_map['end_time'] = date('Y-m-d', $_end_time);
+        $this->getStatisticsData();
+//        $_day_logic = (new DayDataLogic());
+//        $_user_add = $_day_logic->getFieldList('reg_cnt', $_map, '1,30');
+//        $_user_paid = $_day_logic->getFieldList('sum_money', $_map, '1,30');
+//        $this->assign('user_add_key', json_encode(array_keys($_user_add)));
+//        $this->assign('user_add_value', json_encode(array_values($_user_add)));
+//        $this->assign('user_paid_key', json_encode(array_keys($_user_paid)));
+//        $this->assign('user_paid_value', json_encode(array_values($_user_paid)));
+        $this->assign('game_rank', (new GameextModel())->getChargeRank());
+        $_channel_rank = (new RankDataLogic())->agent([], '6');
+        $_channel_rank = $_channel_rank->toArray();
+        $this->assign('channel_rank', $_channel_rank['data']);
+        $this->assign('user_rank', (new MemberExtModel())->getChargeRank());
+        $_menu_model = new AdminMenuModel();
+        $_game_menu = ['app' => 'admin', 'controller' => 'data.rank', 'action' => 'game'];
+        $_member_menu = ['app' => 'admin', 'controller' => 'data.rank', 'action' => 'member'];
+        $_agent_menu = ['app' => 'admin', 'controller' => 'data.rank', 'action' => 'agent'];
+        $_menu['game'] = $_menu_model->getMenuIdPpUrl($_game_menu);
+        $_menu['agent'] = $_menu_model->getMenuIdPpUrl($_agent_menu);
+        $_menu['member'] = $_menu_model->getMenuIdPpUrl($_member_menu);
+        $this->assign('menu', $_menu);
+
+        return $this->fetch();
+    }
+    public function getStatisticsData() {
+        list($_start_time, $_end_time) = Time::lastThirty();
+        $_start_time = $_start_time + CommonConst::CONST_DAY_SECONDS;
+        $_map = $this->map;
+        $_map['start_time'] = date('Y-m-d', $_start_time);
+        $_map['end_time'] = date('Y-m-d', $_end_time);
+        //$_datas = (new DayLogic())->getAdminList($_map, '1,30', '+date');
+        $_datas = (new DayDataLogic())->getAdminList($_map, '1,30', '+date');
+        $_statistics_data = $_datas['list'];
+        $_user_add = [];
+        $_user_paid = [];
+        $_date_arr = [];
+        $_user_add_date_arr = [];
+        $_user_paid_date_arr = [];
+        foreach ($_statistics_data as $_k => $_v) {
+            $_date = substr($_v['date'], 8);
+            $_user_add_date_arr[] = $_v['date'];
+            $_user_paid_date_arr[] = $_v['date'];
+            $_user_add[$_v['date']] = $_v['reg_cnt'];
+            $_user_paid[$_v['date']] = $_v['sum_money'];
+            $_date_arr[] = $_date;
+        }
+        $_today_data = (new StatisticsLogic())->getTodayData($_map);
+        $_today_date = date('Y-m-d');
+        $_date_arr[] = substr($_today_date, 8);
+        $_user_add_date_arr[] = $_today_date;
+        $_user_paid_date_arr[] = $_today_date;
+        $_user_add[$_today_date] = $_today_data['reg_cnt'];
+        $_user_paid[$_today_date] = $_today_data['sum_money'];
+        $this->assign('user_add_date_arr', json_encode($_user_add_date_arr));
+        $this->assign('user_add_key', json_encode($_date_arr));
+        $this->assign('user_add_value', json_encode(array_values($_user_add)));
+        $this->assign('user_paid_date_arr', json_encode($_user_paid_date_arr));
+        $this->assign('user_paid_key', json_encode($_date_arr));
+        $this->assign('user_paid_value', json_encode(array_values($_user_paid)));
+    }
+    /**
+     * 获取游戏数据
+     */
+    public function getGameData() {
+        $_model = new GameModel();
+        $_game['total'] = format_ten_thousand($_model->total());
+        $_game['yesterday'] = format_ten_thousand($_model->yesterdayCount());
+        $_game['today'] = format_ten_thousand($_model->todayCount());
+        $this->assign('game', $_game);
+    }
+
+    /**
+     * 获取渠道数据
+     */
+    public function getChannelData() {
+        $_model = new UserModel();
+        $_channel['total'] = format_ten_thousand($_model->agentTotal());
+        $_channel['yesterday'] = format_ten_thousand($_model->agentYesterdayCount());
+        $_channel['today'] = format_ten_thousand($_model->agentTodayCount());
+        $this->assign('channel', $_channel);
+    }
+
+    /**
+     * 获取玩家数据
+     */
+    public function getMemberData() {
+        $_model = new MemberModel();
+        $_map = $this->map;
+//        $_map['status'] = MemConst::STATUS_NORMAL;
+        $_member['total'] = format_ten_thousand($_model->total($_map));
+        $_member['yesterday'] = format_ten_thousand($_model->yesterdayCount($_map));
+        $_member['today'] = format_ten_thousand($_model->todayCount($_map));
+        $this->assign('mem', $_member);
+    }
+
+    /**
+     * 获取活跃数据
+     */
+    public function getActiveData() {
+        //获取总活跃  今日活跃  昨天活跃   last_login_time
+        $_model = new MemberModel();
+        $_active['total'] = format_ten_thousand($_model->totalActive($this->map));
+        $_active['yesterday'] = format_ten_thousand($_model->yesterdayActive($this->map));
+        $_active['today'] = format_ten_thousand($_model->todayActive($this->map));
+        $this->assign('active', $_active);
+    }
+
+    /**
+     * 获取订单流水数据
+     */
+    public function getOrderData() {
+        $_model = new OrderModel();
+        $_order['total'] = format_ten_thousand($_model->totalMoney($this->map));
+        $_order['yesterday'] = format_ten_thousand($_model->yesterdayMoney($this->map));
+        $_order['today'] = format_ten_thousand($_model->todayMoney($this->map));
+        $this->assign('order', $_order);
+    }
+}

+ 733 - 0
admin/admin/controller/MenuController.php

@@ -0,0 +1,733 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use huo\model\menu\AdminMenuModel;
+use cmf\controller\AdminBaseController;
+use think\Db;
+use tree\Tree;
+
+class MenuController extends AdminBaseController {
+    /**
+     * 后台菜单管理
+     * @adminMenu(
+     *     'name'   => '后台菜单',
+     *     'parent' => 'admin/Setting/default',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '后台菜单管理',
+     *     'param'  => ''
+     * )
+     */
+    public function index() {
+        // session('admin_menu_index', 'Menu/index');
+        $result = Db::name('AdminMenu')->order(["list_order" => "DESC"])->select()->toArray();
+        $tree = new Tree();
+        $tree->icon = ['&nbsp;&nbsp;&nbsp;│ ', '&nbsp;&nbsp;&nbsp;├─ ', '&nbsp;&nbsp;&nbsp;└─ '];
+        $tree->nbsp = '&nbsp;&nbsp;&nbsp;';
+        $newMenus = [];
+        foreach ($result as $m) {
+            $newMenus[$m['id']] = $m;
+        }
+        foreach ($result as $key => $value) {
+            $result[$key]['parent_id_node'] = ($value['parent_id']) ? ' class="child-of-node-'.$value['parent_id'].'"'
+                : '';
+            $result[$key]['style'] = empty($value['parent_id']) ? '' : 'display:none;';
+            $result[$key]['str_manage'] = '<a href="'.url(
+                    "Menu/add", ["parent_id" => $value['id'], "menu_id" => $this->request->param("menu_id")]
+                )
+                                          .'">'.lang('ADD_SUB_MENU').'</a>  <a href="'.url(
+                                              "Menu/edit", ["id" => $value['id'], "menu_id" => $this->request->param(
+                                                             "menu_id"
+                                                         )]
+                                          )
+                                          .'">'.lang('EDIT').'</a>  <a class="js-ajax-delete" href="'.url(
+                                              "Menu/delete", ["id" => $value['id'], "menu_id" => $this->request->param(
+                                                               "menu_id"
+                                                           )]
+                                          ).'">'.lang('DELETE').'</a> ';
+            $result[$key]['status'] = $value['status'] ? lang('DISPLAY') : lang('HIDDEN');
+            if (APP_DEBUG) {
+                $result[$key]['app'] = $value['app']."/".$value['controller']."/".$value['action'];
+            }
+        }
+        $tree->init($result);
+        $str
+            = "<tr id='node-\$id' \$parent_id_node style='\$style'>
+                        <td style='padding-left:20px;'><input name='list_orders[\$id]' type='text' size='3' value='\$list_order' class='input input-order'></td>
+                        <td>\$id</td>
+                        <td class='text-left' >\$spacer\$name</td>
+                        <td>\$app</td>
+                        <td>\$status</td>
+                        <td>\$str_manage</td>
+                    </tr>";
+        $category = $tree->getTree(0, $str);
+        $this->assign("category", $category);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 后台所有菜单列表
+     * @adminMenu(
+     *     'name'   => '所有菜单',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '后台所有菜单列表',
+     *     'param'  => ''
+     * )
+     */
+    public function lists() {
+        session('admin_menu_index', 'Menu/lists');
+        $result = Db::name('AdminMenu')->order(["app" => "ASC", "controller" => "ASC", "action" => "ASC"])->select();
+        $this->assign("menus", $result);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 后台菜单添加
+     * @adminMenu(
+     *     'name'   => '后台菜单添加',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '后台菜单添加',
+     *     'param'  => ''
+     * )
+     */
+    public function add() {
+        $tree = new Tree();
+        $parentId = $this->request->param("parent_id", 0, 'intval');
+        $result = Db::name('AdminMenu')->order(["list_order" => "DESC"])->select();
+        $array = [];
+        foreach ($result as $r) {
+            $r['selected'] = $r['id'] == $parentId ? 'selected' : '';
+            $array[] = $r;
+        }
+        $str = "<option value='\$id' \$selected>\$spacer \$name</option>";
+        $tree->init($array);
+        $selectCategory = $tree->getTree(0, $str);
+        $this->assign("select_category", $selectCategory);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 后台菜单添加提交保存
+     * @adminMenu(
+     *     'name'   => '后台菜单添加提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '后台菜单添加提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function addPost() {
+        if ($this->request->isPost()) {
+            $result = $this->validate($this->request->param(), 'AdminMenu');
+            if ($result !== true) {
+                $this->adminError($result);
+            } else {
+                $data = $this->request->param();
+                Db::name('AdminMenu')->strict(false)->field(true)->insert($data);
+                $app = $this->request->param("app");
+                $controller = $this->request->param("controller");
+                $action = $this->request->param("action");
+                $param = $this->request->param("param");
+                $authRuleName = "$app/$controller/$action";
+                $menuName = $this->request->param("name");
+                $findAuthRuleCount = Db::name('auth_rule')->where(
+                    [
+                        'app'  => $app,
+                        'name' => $authRuleName,
+                        'type' => 'admin_url'
+                    ]
+                )->count();
+                if (empty($findAuthRuleCount)) {
+                    Db::name('AuthRule')->insert(
+                        [
+                            "name"  => $authRuleName,
+                            "app"   => $app,
+                            "type"  => "admin_url", //type 1-admin rule;2-user rule
+                            "title" => $menuName,
+                            'param' => $param,
+                        ]
+                    );
+                }
+                $sessionAdminMenuIndex = session('admin_menu_index');
+                $to = empty($sessionAdminMenuIndex) ? "Menu/index" : $sessionAdminMenuIndex;
+                $this->exportmenulang();
+                $this->adminSuccess("添加成功!", url($to));
+            }
+        }
+    }
+
+    /**
+     * 后台菜单编辑
+     * @adminMenu(
+     *     'name'   => '后台菜单编辑',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '后台菜单编辑',
+     *     'param'  => ''
+     * )
+     */
+    public function edit() {
+        $tree = new Tree();
+        $id = $this->request->param("id", 0, 'intval');
+        $rs = Db::name('AdminMenu')->where(["id" => $id])->find();
+        $result = Db::name('AdminMenu')->order(["list_order" => "DESC"])->select();
+        $array = [];
+        foreach ($result as $r) {
+            $r['selected'] = $r['id'] == $rs['parent_id'] ? 'selected' : '';
+            $array[] = $r;
+        }
+        $str = "<option value='\$id' \$selected>\$spacer \$name</option>";
+        $tree->init($array);
+        $selectCategory = $tree->getTree(0, $str);
+        $this->assign("data", $rs);
+        $this->assign("select_category", $selectCategory);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 后台菜单编辑提交保存
+     * @adminMenu(
+     *     'name'   => '后台菜单编辑提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '后台菜单编辑提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $id = $this->request->param('id', 0, 'intval');
+            $oldMenu = Db::name('AdminMenu')->where(['id' => $id])->find();
+            $result = $this->validate($this->request->param(), 'AdminMenu.edit');
+            if ($result !== true) {
+                $this->adminError($result);
+            } else {
+                Db::name('AdminMenu')->strict(false)->field(true)->update($this->request->param());
+                $app = $this->request->param("app");
+                $controller = $this->request->param("controller");
+                $action = $this->request->param("action");
+                $param = $this->request->param("param");
+                $authRuleName = "$app/$controller/$action";
+                $menuName = $this->request->param("name");
+                $findAuthRuleCount = Db::name('auth_rule')->where(
+                    [
+                        'app'  => $app,
+                        'name' => $authRuleName,
+                        'type' => 'admin_url'
+                    ]
+                )->count();
+                if (empty($findAuthRuleCount)) {
+                    $oldApp = $oldMenu['app'];
+                    $oldController = $oldMenu['controller'];
+                    $oldAction = $oldMenu['action'];
+                    $oldName = "$oldApp/$oldController/$oldAction";
+                    $findOldRuleId = Db::name('AuthRule')->where(["name" => $oldName])->value('id');
+                    if (empty($findOldRuleId)) {
+                        Db::name('AuthRule')->insert(
+                            [
+                                "name"  => $authRuleName,
+                                "app"   => $app,
+                                "type"  => "admin_url",
+                                "title" => $menuName,
+                                "param" => $param
+                            ]
+                        );//type 1-admin rule;2-user rule
+                    } else {
+                        Db::name('AuthRule')->where(['id' => $findOldRuleId])->update(
+                            [
+                                "name"  => $authRuleName,
+                                "app"   => $app,
+                                "type"  => "admin_url",
+                                "title" => $menuName,
+                                "param" => $param]
+                        );//type 1-admin rule;2-user rule
+                    }
+                } else {
+                    Db::name('AuthRule')->where(
+                        [
+                            'app'  => $app,
+                            'name' => $authRuleName,
+                            'type' => 'admin_url'
+                        ]
+                    )->update(["title" => $menuName, 'param' => $param]);//type 1-admin rule;2-user rule
+                }
+                $this->exportmenulang();
+                $this->adminSuccess("保存成功!");
+            }
+        }
+    }
+
+    /**
+     * 后台菜单删除
+     * @adminMenu(
+     *     'name'   => '后台菜单删除',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '后台菜单删除',
+     *     'param'  => ''
+     * )
+     */
+    public function delete() {
+        $id = $this->request->param("id", 0, 'intval');
+        $count = Db::name('AdminMenu')->where(["parent_id" => $id])->count();
+        if ($count > 0) {
+            $this->adminError("该菜单下还有子菜单,无法删除!");
+        }
+        if (Db::name('AdminMenu')->delete($id) !== false) {
+            $this->adminSuccess("删除菜单成功!");
+        } else {
+            $this->adminError("删除失败!");
+        }
+    }
+
+    /**
+     * 后台菜单排序
+     * @adminMenu(
+     *     'name'   => '后台菜单排序',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '后台菜单排序',
+     *     'param'  => ''
+     * )
+     */
+    public function listOrder() {
+        $adminMenuModel = new AdminMenuModel();
+        parent::listOrders($adminMenuModel);
+        $this->adminSuccess("排序更新成功!");
+    }
+
+    /**
+     * 导入新后台菜单
+     * @adminMenu(
+     *     'name'   => '导入新后台菜单',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '导入新后台菜单',
+     *     'param'  => ''
+     * )
+     */
+    public function getActions() {
+        Annotations::$config['cache'] = false;
+        $annotationManager = Annotations::getManager();
+        $annotationManager->registry['adminMenu'] = 'app\admin\annotation\AdminMenuAnnotation';
+        $annotationManager->registry['adminMenuRoot'] = 'app\admin\annotation\AdminMenuRootAnnotation';
+        $newMenus = [];
+        $apps = cmf_scan_dir(APP_PATH.'*', GLOB_ONLYDIR);
+        $app = $this->request->param('app', '');
+        if (empty($app)) {
+            $app = $apps[0];
+        }
+        if (!in_array($app, $apps)) {
+            $this->adminError('应用'.$app.'不存在!');
+        }
+        if ($app == 'admin') {
+            $filePatten = APP_PATH.$app.'/controller/*Controller.php';
+        } else {
+            $filePatten = APP_PATH.$app.'/controller/Admin*Controller.php';
+        }
+        $controllers = cmf_scan_dir($filePatten);
+        if (!empty($controllers)) {
+            foreach ($controllers as $controller) {
+                $controller = preg_replace('/\.php$/', '', $controller);
+                $controllerName = preg_replace('/\Controller$/', '', $controller);
+                $controllerClass = "app\\$app\\controller\\$controller";
+                $menuAnnotations = Annotations::ofClass($controllerClass, '@adminMenuRoot');
+                if (!empty($menuAnnotations)) {
+                    foreach ($menuAnnotations as $menuAnnotation) {
+                        $name = $menuAnnotation->name;
+                        $icon = $menuAnnotation->icon;
+                        $type = 0;//1:有界面可访问菜单,2:无界面可访问菜单,0:只作为菜单
+                        $action = $menuAnnotation->action;
+                        $status = empty($menuAnnotation->display) ? 0 : 1;
+                        $listOrder = floatval($menuAnnotation->order);
+                        $param = $menuAnnotation->param;
+                        $remark = $menuAnnotation->remark;
+                        if (empty($menuAnnotation->parent)) {
+                            $parentId = 0;
+                        } else {
+                            $parent = explode('/', $menuAnnotation->parent);
+                            $countParent = count($parent);
+                            if ($countParent > 3) {
+                                throw new \Exception($controllerClass.':'.$action.'  @adminMenuRoot parent格式不正确!');
+                            }
+                            $parentApp = $app;
+                            $parentController = $controllerName;
+                            $parentAction = '';
+                            switch ($countParent) {
+                                case 1:
+                                    $parentAction = $parent[0];
+                                    break;
+                                case 2:
+                                    $parentController = $parent[0];
+                                    $parentAction = $parent[1];
+                                    break;
+                                case 3:
+                                    $parentApp = $parent[0];
+                                    $parentController = $parent[1];
+                                    $parentAction = $parent[2];
+                                    break;
+                            }
+                            $findParentAdminMenu = Db::name('admin_menu')->where(
+                                [
+                                    'app'        => $parentApp,
+                                    'controller' => $parentController,
+                                    'action'     => $parentAction
+                                ]
+                            )->find();
+                            if (empty($findParentAdminMenu)) {
+                                $parentId = Db::name('admin_menu')->insertGetId(
+                                    [
+                                        'app'        => $parentApp,
+                                        'controller' => $parentController,
+                                        'action'     => $parentAction,
+                                        'name'       => '--new--'
+                                    ]
+                                );
+                            } else {
+                                $parentId = $findParentAdminMenu['id'];
+                            }
+                        }
+                        $findAdminMenu = Db::name('admin_menu')->where(
+                            [
+                                'app'        => $app,
+                                'controller' => $controllerName,
+                                'action'     => $action
+                            ]
+                        )->find();
+                        if (empty($findAdminMenu)) {
+                            Db::name('admin_menu')->insert(
+                                [
+                                    'parent_id'  => $parentId,
+                                    'type'       => $type,
+                                    'status'     => $status,
+                                    'list_order' => $listOrder,
+                                    'app'        => $app,
+                                    'controller' => $controllerName,
+                                    'action'     => $action,
+                                    'param'      => $param,
+                                    'name'       => $name,
+                                    'icon'       => $icon,
+                                    'remark'     => $remark
+                                ]
+                            );
+                            $menuName = $name;
+                            array_push($newMenus, "$app/$controllerName/$action 已导入");
+                        } else {
+                            if ($findAdminMenu['name'] == '--new--') {
+                                Db::name('admin_menu')->where(
+                                    [
+                                        'app'        => $app,
+                                        'controller' => $controllerName,
+                                        'action'     => $action
+                                    ]
+                                )->update(
+                                    [
+                                        'parent_id'  => $parentId,
+                                        'type'       => $type,
+                                        'status'     => $status,
+                                        'list_order' => $listOrder,
+                                        'param'      => $param,
+                                        'name'       => $name,
+                                        'icon'       => $icon,
+                                        'remark'     => $remark
+                                    ]
+                                );
+                                $menuName = $name;
+                            } else {
+                                // 只关注菜单层级关系,是否有视图
+                                Db::name('admin_menu')->where(
+                                    [
+                                        'app'        => $app,
+                                        'controller' => $controllerName,
+                                        'action'     => $action
+                                    ]
+                                )->update(
+                                    [
+                                        'parent_id' => $parentId,
+                                        'type'      => $type,
+                                    ]
+                                );
+                                $menuName = $findAdminMenu['name'];
+                            }
+                            array_push($newMenus, "$app/$controllerName/$action 层级关系已更新");
+                        }
+                        $authRuleName = "{$app}/{$controllerName}/{$action}";
+                        $findAuthRuleCount = Db::name('auth_rule')->where(
+                            [
+                                'app'  => $app,
+                                'name' => $authRuleName,
+                                'type' => 'admin_url'
+                            ]
+                        )->count();
+                        if ($findAuthRuleCount == 0) {
+                            Db::name('auth_rule')->insert(
+                                [
+                                    'app'   => $app,
+                                    'name'  => $authRuleName,
+                                    'type'  => 'admin_url',
+                                    'param' => $param,
+                                    'title' => $menuName
+                                ]
+                            );
+                        } else {
+                            Db::name('auth_rule')->where(
+                                [
+                                    'app'  => $app,
+                                    'name' => $authRuleName,
+                                    'type' => 'admin_url',
+                                ]
+                            )->update(
+                                [
+                                    'param' => $param,
+                                    'title' => $menuName
+                                ]
+                            );
+                        }
+                    }
+                }
+                $reflect = new \ReflectionClass($controllerClass);
+                $methods = $reflect->getMethods(\ReflectionMethod::IS_PUBLIC);
+                if (!empty($methods)) {
+                    foreach ($methods as $method) {
+                        if ($method->class == $controllerClass && strpos($method->name, '_') !== 0) {
+                            $menuAnnotations = Annotations::ofMethod($controllerClass, $method->name, '@adminMenu');
+                            if (!empty($menuAnnotations)) {
+                                $menuAnnotation = $menuAnnotations[0];
+                                $name = $menuAnnotation->name;
+                                $icon = $menuAnnotation->icon;
+                                $type = $menuAnnotation->hasView ? 1 : 2;//1:有界面可访问菜单,2:无界面可访问菜单,0:只作为菜单
+                                $action = $method->name;
+                                $status = empty($menuAnnotation->display) ? 0 : 1;
+                                $listOrder = floatval($menuAnnotation->order);
+                                $param = $menuAnnotation->param;
+                                $remark = $menuAnnotation->remark;
+                                if (empty($menuAnnotation->parent)) {
+                                    $parentId = 0;
+                                } else {
+                                    $parent = explode('/', $menuAnnotation->parent);
+                                    $countParent = count($parent);
+                                    if ($countParent > 3) {
+                                        throw new \Exception($controllerClass.':'.$action.'  @menuRoot parent格式不正确!');
+                                    }
+                                    $parentApp = $app;
+                                    $parentController = $controllerName;
+                                    $parentAction = '';
+                                    switch ($countParent) {
+                                        case 1:
+                                            $parentAction = $parent[0];
+                                            break;
+                                        case 2:
+                                            $parentController = $parent[0];
+                                            $parentAction = $parent[1];
+                                            break;
+                                        case 3:
+                                            $parentApp = $parent[0];
+                                            $parentController = $parent[1];
+                                            $parentAction = $parent[2];
+                                            break;
+                                    }
+                                    $findParentAdminMenu = Db::name('admin_menu')->where(
+                                        [
+                                            'app'        => $parentApp,
+                                            'controller' => $parentController,
+                                            'action'     => $parentAction
+                                        ]
+                                    )->find();
+                                    if (empty($findParentAdminMenu)) {
+                                        $parentId = Db::name('admin_menu')->insertGetId(
+                                            [
+                                                'app'        => $parentApp,
+                                                'controller' => $parentController,
+                                                'action'     => $parentAction,
+                                                'name'       => '--new--'
+                                            ]
+                                        );
+                                    } else {
+                                        $parentId = $findParentAdminMenu['id'];
+                                    }
+                                }
+                                $findAdminMenu = Db::name('admin_menu')->where(
+                                    [
+                                        'app'        => $app,
+                                        'controller' => $controllerName,
+                                        'action'     => $action
+                                    ]
+                                )->find();
+                                if (empty($findAdminMenu)) {
+                                    Db::name('admin_menu')->insert(
+                                        [
+                                            'parent_id'  => $parentId,
+                                            'type'       => $type,
+                                            'status'     => $status,
+                                            'list_order' => $listOrder,
+                                            'app'        => $app,
+                                            'controller' => $controllerName,
+                                            'action'     => $action,
+                                            'param'      => $param,
+                                            'name'       => $name,
+                                            'icon'       => $icon,
+                                            'remark'     => $remark
+                                        ]
+                                    );
+                                    $menuName = $name;
+                                    array_push($newMenus, "$app/$controllerName/$action 已导入");
+                                } else {
+                                    if ($findAdminMenu['name'] == '--new--') {
+                                        Db::name('admin_menu')->where(
+                                            [
+                                                'app'        => $app,
+                                                'controller' => $controllerName,
+                                                'action'     => $action
+                                            ]
+                                        )->update(
+                                            [
+                                                'parent_id'  => $parentId,
+                                                'type'       => $type,
+                                                'status'     => $status,
+                                                'list_order' => $listOrder,
+                                                'param'      => $param,
+                                                'name'       => $name,
+                                                'icon'       => $icon,
+                                                'remark'     => $remark
+                                            ]
+                                        );
+                                        $menuName = $name;
+                                    } else {
+                                        // 只关注菜单层级关系,是否有视图
+                                        Db::name('admin_menu')->where(
+                                            [
+                                                'app'        => $app,
+                                                'controller' => $controllerName,
+                                                'action'     => $action
+                                            ]
+                                        )->update(
+                                            [
+                                                'parent_id' => $parentId,
+                                                'type'      => $type,
+                                            ]
+                                        );
+                                        $menuName = $findAdminMenu['name'];
+                                    }
+                                    array_push($newMenus, "$app/$controllerName/$action 已更新");
+                                }
+                                $authRuleName = "{$app}/{$controllerName}/{$action}";
+                                $findAuthRuleCount = Db::name('auth_rule')->where(
+                                    [
+                                        'app'  => $app,
+                                        'name' => $authRuleName,
+                                        'type' => 'admin_url'
+                                    ]
+                                )->count();
+                                if ($findAuthRuleCount == 0) {
+                                    Db::name('auth_rule')->insert(
+                                        [
+                                            'app'   => $app,
+                                            'name'  => $authRuleName,
+                                            'type'  => 'admin_url',
+                                            'param' => $param,
+                                            'title' => $menuName
+                                        ]
+                                    );
+                                } else {
+                                    Db::name('auth_rule')->where(
+                                        [
+                                            'app'  => $app,
+                                            'name' => $authRuleName,
+                                            'type' => 'admin_url',
+                                        ]
+                                    )->update(
+                                        [
+                                            'param' => $param,
+                                            'title' => $menuName
+                                        ]
+                                    );
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        $index = array_search($app, $apps);
+        $nextIndex = $index + 1;
+        $nextIndex = $nextIndex >= count($apps) ? 0 : $nextIndex;
+        if ($nextIndex) {
+            $this->assign("next_app", $apps[$nextIndex]);
+        }
+        $this->assign("app", $app);
+        $this->assign("new_menus", $newMenus);
+
+        return $this->fetch();
+    }
+
+    public function exportmenulang() {
+        $this->_exportAppMenuDefaultLang('zh-cn', 'name');
+        $this->_exportAppMenuDefaultLang('en-us', 'en_name');
+    }
+
+    /**
+     *  导出后台菜单语言包
+     *
+     * @param string $lang
+     * @param string $menu_name
+     */
+    private function _exportAppMenuDefaultLang($lang = 'zh-cn', $menu_name) {
+        $menus = Db::name('AdminMenu')->order(["id" => "ASC"])->select();
+//        $langDir = config('DEFAULT_LANG');
+        $adminMenuLang = CMF_ROOT."data/lang/".$lang."/admin_menu.php";
+        if (!empty($adminMenuLang) && !file_exists_case($adminMenuLang)) {
+            mkdir(dirname($adminMenuLang), 0777, true);
+        }
+        $lang = [];
+        foreach ($menus as $menu) {
+            $lang_key = strtoupper($menu['app'].'_'.$menu['controller'].'_'.$menu['action']);
+            $lang[$lang_key] = $menu[$menu_name];
+        }
+        $langStr = var_export($lang, true);
+        $langStr = preg_replace("/\s+\d+\s=>\s(\n|\r)/", "\n", $langStr);
+        if (!empty($adminMenuLang)) {
+            file_put_contents($adminMenuLang, "<?php\nreturn $langStr;");
+        }
+    }
+}

+ 179 - 0
admin/admin/controller/NavController.php

@@ -0,0 +1,179 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: kane <chengjin005@163.com> 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use admin\admin\model\NavModel;
+use think\Db;
+
+/**
+ * Class NavController 导航类别管理控制器
+ * @package app\admin\controller
+ */
+class NavController extends AdminBaseController
+{
+    /**
+     * 导航管理
+     * @adminMenu(
+     *     'name'   => '导航管理',
+     *     'parent' => 'admin/Setting/default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 30,
+     *     'icon'   => '',
+     *     'remark' => '导航管理',
+     *     'param'  => ''
+     * )
+     */
+    public function index()
+    {
+        $navModel = new NavModel();
+
+        $navs = $navModel->select();
+        $this->assign('navs', $navs);
+
+        return $this->fetch();
+
+    }
+
+    /**
+     * 添加导航
+     * @adminMenu(
+     *     'name'   => '添加导航',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '添加导航',
+     *     'param'  => ''
+     * )
+     */
+    public function add()
+    {
+        return $this->fetch();
+    }
+
+    /**
+     * 添加导航提交保存
+     * @adminMenu(
+     *     'name'   => '添加导航提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '添加导航提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function addPost()
+    {
+
+        $navModel = new NavModel();
+        $arrData  = $this->request->post();
+
+        if (empty($arrData["is_main"])) {
+            $arrData["is_main"] = 0;
+        } else {
+            $navModel->where("is_main", 1)->update(["is_main" => 0]);
+        }
+
+        $navModel->allowField(true)->insert($arrData);
+        $this->adminSuccess(lang("EDIT_SUCCESS"), url("nav/index"));
+
+    }
+
+    /**
+     * 编辑导航
+     * @adminMenu(
+     *     'name'   => '编辑导航',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '编辑导航',
+     *     'param'  => ''
+     * )
+     */
+    public function edit()
+    {
+        $navModel = new NavModel();
+        $intId    = $this->request->param("id", 0, 'intval');
+
+        $objNavCat = $navModel->where(["id" => $intId])->find();
+        $arrNavCat = $objNavCat ? $objNavCat->toArray() : [];
+
+        $this->assign($arrNavCat);
+        return $this->fetch();
+    }
+
+
+    /**
+     * 编辑导航提交保存
+     * @adminMenu(
+     *     'name'   => '编辑导航提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '编辑导航提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function editPost()
+    {
+
+        $navModel = new NavModel();
+        $arrData  = $this->request->post();
+
+        if (empty($arrData["is_main"])) {
+            $arrData["is_main"] = 0;
+        } else {
+            $navModel->where("is_main", 1)->update(["is_main" => 0]);
+        }
+
+        $navModel->allowField(true)->where(["id" => $arrData["id"]])->update($arrData);
+        $this->adminSuccess(lang("EDIT_SUCCESS"), url("nav/index"));
+
+    }
+
+    /**
+     * 删除导航
+     * @adminMenu(
+     *     'name'   => '删除导航',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '删除导航',
+     *     'param'  => ''
+     * )
+     */
+    public function delete()
+    {
+        $navModel = new NavModel();
+        $intId    = $this->request->param("id", 0, "intval");
+
+        if (empty($intId)) {
+            $this->adminError(lang("NO_ID"));
+        }
+
+        $navModel->where(["id" => $intId])->delete();
+        $this->adminSuccess(lang("DELETE_SUCCESS"), url("nav/index"));
+
+    }
+
+
+}

+ 306 - 0
admin/admin/controller/NavMenuController.php

@@ -0,0 +1,306 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: kane <chengjin005@163.com> 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use admin\admin\model\NavMenuModel;
+use cmf\controller\AdminBaseController;
+use tree\Tree;
+
+/**
+ * Class NavMenuController 前台菜单管理控制器
+ * @package app\admin\controller
+ */
+class NavMenuController extends AdminBaseController
+{
+    /**
+     * 导航菜单
+     * @adminMenu(
+     *     'name'   => '导航菜单',
+     *     'parent' => 'admin/Nav/index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '导航菜单',
+     *     'param'  => ''
+     * )
+     */
+    public function index()
+    {
+        $intNavId     = $this->request->param("nav_id");
+        $navMenuModel = new NavMenuModel();
+
+        if (empty($intNavId)) {
+            $this->adminError("请指定导航!");
+        }
+
+        $objResult = $navMenuModel->where("nav_id", $intNavId)->order(["list_order" => "DESC"])->select();
+        $arrResult = $objResult ? $objResult->toArray() : [];
+
+        $tree       = new Tree();
+        $tree->icon = ['&nbsp;&nbsp;&nbsp;│ ', '&nbsp;&nbsp;&nbsp;├─ ', '&nbsp;&nbsp;&nbsp;└─ '];
+        $tree->nbsp = '&nbsp;&nbsp;&nbsp;';
+
+        $array = [];
+        foreach ($arrResult as $r) {
+            $r['str_manage'] = '<a href="' . url("NavMenu/add", ["parent_id" => $r['id'], "nav_id" => $r['nav_id']]) . '">添加子菜单</a>  <a href="'
+                . url("NavMenu/edit", ["id" => $r['id'], "parent_id" => $r['parent_id'], "nav_id" => $r['nav_id']]) . '">编辑</a>  <a class="js-ajax-delete" href="' . url("NavMenu/delete", ["id" => $r['id'], 'nav_id' => $r['nav_id']]) . '">删除</a> ';
+            $r['status']     = $r['status'] ? "显示" : "隐藏";
+            $array[]         = $r;
+        }
+
+        $tree->init($array);
+        $str = "<tr>
+            <td><input name='list_orders[\$id]' type='text' size='3' value='\$list_order' class='input input-order'></td>
+            <td>\$id</td>
+            <td >\$spacer\$name</td>
+            <td>\$status</td>
+            <td>\$str_manage</td>
+        </tr>";
+
+        $categories = $tree->getTree(0, $str);
+
+        $this->assign("categories", $categories);
+        $this->assign('nav_id', $intNavId);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加导航菜单
+     * @adminMenu(
+     *     'name'   => '添加导航菜单',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'order'  => 10000,
+     *     'hasView'=> true,
+     *     'icon'   => '',
+     *     'remark' => '添加导航菜单',
+     *     'param'  => ''
+     * )
+     */
+    public function add()
+    {
+        $navMenuModel = new NavMenuModel();
+        $intNavId     = $this->request->param("nav_id");
+        $intParentId  = $this->request->param("parent_id");
+        $objResult    = $navMenuModel->where("nav_id", $intNavId)->order(["list_order" => "DESC"])->select();
+        $arrResult    = $objResult ? $objResult->toArray() : [];
+
+        $tree       = new Tree();
+        $tree->icon = ['&nbsp;│ ', '&nbsp;├─ ', '&nbsp;└─ '];
+        $tree->nbsp = '&nbsp;';
+        $array      = [];
+
+        foreach ($arrResult as $r) {
+            $r['str_manage'] = '<a href="' . url("NavMenu/add", ["parent_id" => $r['id']]) . '">添加子菜单</a> | <a href="'
+                . url("NavMenu/edit", ["id" => $r['id']]) . '">编辑</a> | <a class="J_ajax_del" href="'
+                . url("NavMenu/delete", ["id" => $r['id']]) . '">删除</a> ';
+            $r['status']     = $r['status'] ? "显示" : "隐藏";
+            $r['selected']   = $r['id'] == $intParentId ? "selected" : "";
+            $array[]         = $r;
+        }
+
+        $tree->init($array);
+        $str      = "<option value='\$id' \$selected>\$spacer\$name</option>";
+        $navTrees = $tree->getTree(0, $str);
+        $this->assign("nav_trees", $navTrees);
+
+        $navs = $navMenuModel->selectNavs();
+        $this->assign('navs', $navs);
+
+        $this->assign("nav_id", $intNavId);
+        return $this->fetch();
+    }
+
+    /**
+     * 添加导航菜单提交保存
+     * @adminMenu(
+     *     'name'   => '添加导航菜单提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '添加导航菜单提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function addPost()
+    {
+        $navMenuModel = new NavMenuModel();
+        $arrData      = $this->request->post();
+
+        if (isset($arrData['external_href'])) {
+            $arrData['href'] = htmlspecialchars_decode($arrData['external_href']);
+        } else {
+            $arrData['href'] = htmlspecialchars_decode($arrData['href']);
+            $arrData['href'] = base64_decode($arrData['href']);
+        }
+
+        $navMenuModel->allowField(true)->isUpdate(false)->save($arrData);
+
+        $this->adminSuccess(lang("EDIT_SUCCESS"), url("NavMenu/index", ['nav_id' => $arrData['nav_id']]));
+
+    }
+
+    /**
+     * 编辑导航菜单
+     * @adminMenu(
+     *     'name'   => '编辑导航菜单',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '编辑导航菜单',
+     *     'param'  => ''
+     * )
+     */
+    public function edit()
+    {
+        $navMenuModel = new NavMenuModel();
+        $intNavId     = $this->request->param("nav_id");
+        $intId        = $this->request->param("id");
+        $intParentId  = $this->request->param("parent_id");
+        $objResult    = $navMenuModel->where(["nav_id" => $intNavId, "id" => ["neq", $intId]])->order(["list_order" => "DESC"])->select();
+        $arrResult    = $objResult ? $objResult->toArray() : [];
+
+        $tree       = new Tree();
+        $tree->icon = ['&nbsp;│ ', '&nbsp;├─ ', '&nbsp;└─ '];
+        $tree->nbsp = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
+        $array      = [];
+        foreach ($arrResult as $r) {
+            $r['str_manage'] = '<a href="' . url("NavMenu/add", ["parent_id" => $r['id'], "nav_id" => $intNavId]) . '">添加子菜单</a> | <a href="'
+                . url("NavMenu/edit", ["id" => $r['id'], "nav_id" => $intNavId]) . '">编辑</a> | <a class="js-ajax-delete" href="'
+                . url("NavMenu/delete", ["id" => $r['id'], "nav_id" => $intNavId]) . '">删除</a> ';
+            $r['status']     = $r['status'] ? "显示" : "隐藏";
+            $r['selected']   = $r['id'] == $intParentId ? "selected" : "";
+            $array[]         = $r;
+        }
+
+        $tree->init($array);
+        $str       = "<option value='\$id' \$selected>\$spacer\$name</option>";
+        $nav_trees = $tree->getTree(0, $str);
+        $this->assign("nav_trees", $nav_trees);
+
+        $objNav = $navMenuModel->where("id", $intId)->find();
+        $arrNav = $objNav ? $objNav->toArray() : [];
+
+        $arrNav['href_old'] = $arrNav['href'];
+
+        if (strpos($arrNav['href'], "{") === 0 || $arrNav['href'] == 'home') {
+            $arrNav['href'] = base64_encode($arrNav['href']);
+        }
+
+        $this->assign($arrNav);
+
+        $navs = $navMenuModel->selectNavs();
+        $this->assign('navs', $navs);
+
+        $this->assign("nav_id", $intNavId);
+        $this->assign("parent_id", $intParentId);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑导航菜单提交保存
+     * @adminMenu(
+     *     'name'   => '编辑导航菜单提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '编辑导航菜单提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function editPost()
+    {
+        $navMenuModel = new NavMenuModel();
+        $intId        = $this->request->param('id', 0, 'intval');
+        $arrData      = $this->request->post();
+
+        if (isset($arrData['external_href'])) {
+            $arrData['href'] = htmlspecialchars_decode($arrData['external_href']);
+        } else {
+            $arrData['href'] = htmlspecialchars_decode($arrData['href']);
+            $arrData['href'] = base64_decode($arrData['href']);
+        }
+
+        $navMenuModel->update($arrData, ["id" => $intId], true);
+
+        $this->adminSuccess(lang("EDIT_SUCCESS"), url("NavMenu/index", ['nav_id' => $arrData['nav_id']]));
+
+    }
+
+    /**
+     * 删除导航菜单
+     * @adminMenu(
+     *     'name'   => '删除导航菜单',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '删除导航菜单',
+     *     'param'  => ''
+     * )
+     */
+    public function delete()
+    {
+        $navMenuModel = new NavMenuModel();
+
+        $intId    = $this->request->param("id", 0, "intval");
+        $intNavId = $this->request->param("nav_id", 0, "intval");
+
+        if (empty($intId)) {
+            $this->adminError(lang("NO_ID"));
+        }
+
+        $count = $navMenuModel->where(["parent_id" => $intId])->count();
+        if ($count > 0) {
+            $this->adminError("该菜单下还有子菜单,无法删除!");
+        }
+
+        $navMenuModel->where(["id" => $intId])->delete();
+        $this->adminSuccess(lang("DELETE_SUCCESS"), url("NavMenu/index", ['nav_id' => $intNavId]));
+
+    }
+
+    /**
+     * 导航菜单排序
+     * @adminMenu(
+     *     'name'   => '导航菜单排序',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '导航菜单排序',
+     *     'param'  => ''
+     * )
+     */
+    public function listOrder()
+    {
+        $navMenuModel = new NavMenuModel();
+        $status       = parent::listOrders($navMenuModel);
+        if ($status) {
+            $this->adminSuccess("排序更新成功!");
+        } else {
+            $this->adminError("排序更新失败!");
+        }
+    }
+
+
+}

+ 462 - 0
admin/admin/controller/PluginController.php

@@ -0,0 +1,462 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <zxxjjforever@163.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use admin\admin\model\PluginModel;
+use admin\admin\model\HookPluginModel;
+use think\Db;
+use think\Validate;
+
+/**
+ * Class PluginController
+ * @package app\admin\controller
+ * @adminMenuRoot(
+ *     'name'   =>'插件管理',
+ *     'action' =>'default',
+ *     'parent' =>'',
+ *     'display'=> true,
+ *     'order'  => 20,
+ *     'icon'   =>'cloud',
+ *     'remark' =>'插件管理'
+ * )
+ */
+class PluginController extends AdminBaseController
+{
+
+    protected $pluginModel;
+
+    public function _initialize()
+    {
+        parent::_initialize();
+    }
+
+    /**
+     * 插件列表
+     * @adminMenu(
+     *     'name'   => '插件列表',
+     *     'parent' => 'admin/Plugin/default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '插件列表',
+     *     'param'  => ''
+     * )
+     */
+    public function index()
+    {
+        $pluginModel = new PluginModel();
+        $plugins     = $pluginModel->getList();
+        $this->assign("plugins", $plugins);
+        return $this->fetch();
+    }
+
+    /**
+     * 插件启用/禁用
+     * @adminMenu(
+     *     'name'   => '插件启用禁用',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '插件启用禁用',
+     *     'param'  => ''
+     * )
+     */
+    public function toggle()
+    {
+        $id = $this->request->param('id', 0, 'intval');
+
+        $pluginModel = PluginModel::get($id);
+
+        if (empty($pluginModel)) {
+            $this->adminError('插件不存在!');
+        }
+
+        $status         = 1;
+        $successMessage = "启用成功!";
+
+        if ($this->request->param('disable')) {
+            $status         = 0;
+            $successMessage = "禁用成功!";
+        }
+
+        $pluginModel->startTrans();
+
+        try {
+            $pluginModel->save(['status' => $status], ['id' => $id]);
+
+            $hookPluginModel = new HookPluginModel();
+
+            $hookPluginModel->save(['status' => $status], ['plugin' => $pluginModel->name]);
+
+            $pluginModel->commit();
+
+        } catch (\Exception $e) {
+
+            $pluginModel->rollback();
+
+            $this->adminError('操作失败!');
+
+        }
+
+        $this->adminSuccess($successMessage);
+    }
+
+    /**
+     * 插件设置
+     * @adminMenu(
+     *     'name'   => '插件设置',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '插件设置',
+     *     'param'  => ''
+     * )
+     */
+    public function setting()
+    {
+        $id = $this->request->param('id', 0, 'intval');
+
+        $pluginModel = new PluginModel();
+        $plugin      = $pluginModel->find($id);
+
+        if (empty($plugin)) {
+            $this->adminError('插件未安装!');
+        }
+
+        $plugin = $plugin->toArray();
+
+        $pluginClass = cmf_get_plugin_class($plugin['name']);
+        if (!class_exists($pluginClass)) {
+            $this->adminError('插件不存在!');
+        }
+
+        $pluginObj = new $pluginClass;
+        //$plugin['plugin_path']   = $pluginObj->plugin_path;
+        //$plugin['custom_config'] = $pluginObj->custom_config;
+        $pluginConfigInDb = $plugin['config'];
+        $plugin['config'] = include $pluginObj->getConfigFilePath();
+
+        if ($pluginConfigInDb) {
+            $pluginConfigInDb = json_decode($pluginConfigInDb, true);
+            foreach ($plugin['config'] as $key => $value) {
+                if ($value['type'] != 'group') {
+                    if (isset($pluginConfigInDb[$key])) {
+                        $plugin['config'][$key]['value'] = $pluginConfigInDb[$key];
+                    }
+                } else {
+                    foreach ($value['options'] as $group => $options) {
+                        foreach ($options['options'] as $gkey => $value) {
+                            if (isset($pluginConfigInDb[$gkey])) {
+                                $plugin['config'][$key]['options'][$group]['options'][$gkey]['value'] = $pluginConfigInDb[$gkey];
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        $this->assign('data', $plugin);
+//        if ($plugin['custom_config']) {
+//            $this->assign('custom_config', $this->fetch($plugin['plugin_path'] . $plugin['custom_config']));
+//        }
+
+        $this->assign('id', $id);
+        return $this->fetch();
+
+    }
+
+    /**
+     * 插件设置提交
+     * @adminMenu(
+     *     'name'   => '插件设置提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '插件设置提交',
+     *     'param'  => ''
+     * )
+     */
+    public function settingPost()
+    {
+        if ($this->request->isPost()) {
+            $id = $this->request->param('id', 0, 'intval');
+
+            $pluginModel = new PluginModel();
+            $plugin      = $pluginModel->find($id)->toArray();
+
+            if (!$plugin) {
+                $this->adminError('插件未安装!');
+            }
+
+            $pluginClass = cmf_get_plugin_class($plugin['name']);
+            if (!class_exists($pluginClass)) {
+                $this->adminError('插件不存在!');
+            }
+
+            $pluginObj = new $pluginClass;
+            //$plugin['plugin_path']   = $pluginObj->plugin_path;
+            //$plugin['custom_config'] = $pluginObj->custom_config;
+            $pluginConfigInDb = $plugin['config'];
+            $plugin['config'] = include $pluginObj->getConfigFilePath();
+
+            $rules    = [];
+            $messages = [];
+
+            foreach ($plugin['config'] as $key => $value) {
+                if ($value['type'] != 'group') {
+                    if (isset($value['rule'])) {
+                        $rules[$key] = $this->_parseRules($value['rule']);
+                    }
+
+                    if (isset($value['message'])) {
+                        foreach ($value['message'] as $rule => $msg) {
+                            $messages[$key . '.' . $rule] = $msg;
+                        }
+                    }
+
+                } else {
+                    foreach ($value['options'] as $group => $options) {
+                        foreach ($options['options'] as $gkey => $value) {
+                            if (isset($value['rule'])) {
+                                $rules[$gkey] = $this->_parseRules($value['rule']);
+                            }
+
+                            if (isset($value['message'])) {
+                                foreach ($value['message'] as $rule => $msg) {
+                                    $messages[$gkey . '.' . $rule] = $msg;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            $config = $this->request->param('config/a');
+
+            $validate = new Validate($rules, $messages);
+            $result   = $validate->check($config);
+            if ($result !== true) {
+                $this->adminError($validate->getError());
+            }
+
+            $pluginModel = new PluginModel();
+            $pluginModel->save(['config' => json_encode($config)], ['id' => $id]);
+            $this->adminSuccess('保存成功', '');
+        }
+    }
+
+    /**
+     * 解析插件配置验证规则
+     * @param $rules
+     * @return array
+     */
+    private function _parseRules($rules)
+    {
+        $newRules = [];
+
+        $simpleRules = [
+            'require', 'number',
+            'integer', 'float', 'boolean', 'email',
+            'array', 'accepted', 'date', 'alpha',
+            'alphaNum', 'alphaDash', 'activeUrl',
+            'url', 'ip'];
+        foreach ($rules as $key => $rule) {
+            if (in_array($key, $simpleRules) && $rule) {
+                array_push($newRules, $key);
+            }
+        }
+
+        return $newRules;
+    }
+
+    /**
+     * 插件安装
+     * @adminMenu(
+     *     'name'   => '插件安装',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '插件安装',
+     *     'param'  => ''
+     * )
+     */
+    public function install()
+    {
+        $pluginName = $this->request->param('name', '', 'trim');
+        $class      = cmf_get_plugin_class($pluginName);
+        if (!class_exists($class)) {
+            $this->adminError('插件不存在!');
+        }
+
+        $pluginModel = new PluginModel();
+        $pluginCount = $pluginModel->where('name', $pluginName)->count();
+
+        if ($pluginCount > 0) {
+            $this->adminError('插件已安装!');
+        }
+
+        $plugin = new $class;
+        $info   = $plugin->info;
+        if (!$info || !$plugin->checkInfo()) {//检测信息的正确性
+            $this->adminError('插件信息缺失!');
+        }
+
+        $installSuccess = $plugin->install();
+        if (!$installSuccess) {
+            $this->adminError('插件预安装失败!');
+        }
+
+        $methods = get_class_methods($plugin);
+
+        foreach ($methods as $methodKey => $method) {
+            $methods[$methodKey] = cmf_parse_name($method);
+        }
+
+        $systemHooks = $pluginModel->getHooks(true);
+
+        $pluginHooks = array_intersect($systemHooks, $methods);
+
+        //$info['hooks'] = implode(",", $pluginHooks);
+
+        if (!empty($plugin->hasAdmin)) {
+            $info['has_admin'] = 1;
+        } else {
+            $info['has_admin'] = 0;
+        }
+
+        $info['config'] = json_encode($plugin->getConfig());
+
+        $pluginModel->data($info)->allowField(true)->save();
+
+        $hookPluginModel = new HookPluginModel();
+        foreach ($pluginHooks as $pluginHook) {
+            $hookPluginModel->data(['hook' => $pluginHook, 'plugin' => $pluginName, 'status' => 1])->isUpdate(false)->save();
+        }
+
+        $this->adminSuccess('安装成功!');
+    }
+
+    /**
+     * 插件更新
+     * @adminMenu(
+     *     'name'   => '插件更新',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '插件更新',
+     *     'param'  => ''
+     * )
+     */
+    public function update()
+    {
+        $pluginName = $this->request->param('name', '', 'trim');
+        $class      = cmf_get_plugin_class($pluginName);
+        if (!class_exists($class)) {
+            $this->adminError('插件不存在!');
+        }
+
+        $plugin = new $class;
+        $info   = $plugin->info;
+        if (!$info || !$plugin->checkInfo()) {//检测信息的正确性
+            $this->adminError('插件信息缺失!');
+        }
+
+        $methods = get_class_methods($plugin);
+
+        foreach ($methods as $methodKey => $method) {
+            $methods[$methodKey] = cmf_parse_name($method);
+        }
+
+        $pluginModel = new PluginModel();
+        $systemHooks = $pluginModel->getHooks(true);
+
+        $pluginHooks = array_intersect($systemHooks, $methods);
+
+        if (!empty($plugin->hasAdmin)) {
+            $info['has_admin'] = 1;
+        } else {
+            $info['has_admin'] = 0;
+        }
+
+        $config = $plugin->getConfig();
+
+        $defaultConfig = $plugin->getDefaultConfig();
+
+        $pluginModel = new PluginModel();
+
+        $config = array_merge($defaultConfig, $config);
+
+        $info['config'] = json_encode($config);
+
+        $pluginModel->allowField(true)->save($info, ['name' => $pluginName]);
+
+        $hookPluginModel = new HookPluginModel();
+
+        $pluginHooksInDb = $hookPluginModel->where('plugin', $pluginName)->column('hook');
+
+        $samePluginHooks = array_intersect($pluginHooks, $pluginHooksInDb);
+
+        $shouldDeleteHooks = array_diff($samePluginHooks, $pluginHooksInDb);
+
+        $newHooks = array_diff($pluginHooks, $samePluginHooks);
+
+        if (count($shouldDeleteHooks) > 0) {
+            $hookPluginModel->where('hook', 'in', $shouldDeleteHooks)->delete();
+        }
+
+        foreach ($newHooks as $pluginHook) {
+            $hookPluginModel->data(['hook' => $pluginHook, 'plugin' => $pluginName])->isUpdate(false)->save();
+        }
+
+        $this->adminSuccess('更新成功!');
+    }
+
+    /**
+     * 卸载插件
+     * @adminMenu(
+     *     'name'   => '卸载插件',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '卸载插件',
+     *     'param'  => ''
+     * )
+     */
+    public function uninstall()
+    {
+        $pluginModel = new PluginModel();
+        $id          = $this->request->param('id', 0, 'intval');
+
+        $result = $pluginModel->uninstall($id);
+
+        if ($result !== true) {
+            $this->adminError('卸载失败!');
+        }
+
+        $this->adminSuccess('卸载成功!');
+    }
+
+
+}

+ 152 - 0
admin/admin/controller/PublicController.php

@@ -0,0 +1,152 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use huolib\constant\MemConst;
+use think\Cookie;
+use think\Db;
+
+class PublicController extends AdminBaseController {
+    public function _initialize() {
+    }
+
+    /**
+     * 后台登陆界面
+     */
+    public function login() {
+        $loginAllowed = session("__LOGIN_BY_CMF_ADMIN_PW__");
+        if (empty($loginAllowed)) {
+            $this->adminError('非法登录!', cmf_get_root().'/');
+        }
+        $admin_id = session('ADMIN_ID');
+        if (!empty($admin_id)) {//已经登录
+            $this->insertLoginLog(1);
+            redirect(url("admin/Index/index"));
+        } else {
+            $site_admin_url_password = config("cmf_SITE_ADMIN_URL_PASSWORD");
+            $upw = session("__CMF_UPW__");
+            if (!empty($site_admin_url_password) && $upw != $site_admin_url_password) {
+                redirect(ROOT_PATH."/");
+            } else {
+                session("__SP_ADMIN_LOGIN_PAGE_SHOWED_SUCCESS__", true);
+                $result = hook_one('admin_login');
+                if (!empty($result)) {
+                    return $result;
+                }
+                return $this->fetch(":login");
+            }
+        }
+
+        return $this->fetch(":login");
+    }
+
+    /**
+     * 登录验证
+     */
+    public function doLogin() {
+        $loginAllowed = session("__LOGIN_BY_CMF_ADMIN_PW__");
+        if (empty($loginAllowed)) {
+            $this->adminError('非法登录!', cmf_get_root().'/');
+        }
+        $captcha = $this->request->param('captcha');
+        if (empty($captcha)) {
+            $this->adminError(lang('CAPTCHA_REQUIRED'));
+        }
+        //验证码
+        if (!cmf_captcha_check($captcha)) {
+            $this->adminError(lang('CAPTCHA_NOT_RIGHT'));
+        }
+        $name = $this->request->param("username");
+        if (empty($name)) {
+            $this->adminError(lang('USERNAME_OR_EMAIL_EMPTY'));
+        }
+        $pass = $this->request->param("password");
+        if (empty($pass)) {
+            $this->adminError(lang('PASSWORD_REQUIRED'));
+        }
+        if (strpos($name, "@") > 0) {//邮箱登陆
+            $where['user_email'] = $name;
+        } else {
+            $where['user_login'] = $name;
+        }
+        $result = Db::name('user')->where($where)->find();
+        if (!empty($result)) {
+            if (cmf_compare_password($pass, $result['user_pass'])) {
+                if ($result["id"] != 1 && (MemConst::STATUS_NORMAL != $result['user_status'])
+                    || empty($result['user_status'])) {
+                    $this->adminError(lang('USE_DISABLED'));
+                }
+                $_role_info = Db::name('role')->where('id', 'in', $result['role_id'])->find();
+
+                session('role_id',$_role_info['id']);
+                session('role_type',$_role_info['role_type']);
+                session('role_name',$_role_info['name']);
+                //登入成功页面跳转
+                session('ADMIN_ID', $result["id"]);
+                session('name', $result["user_login"]);
+                $result['last_login_ip'] = get_client_ip(0, true);
+                $result['last_login_time'] = time();
+                $token = cmf_generate_user_token($result["id"], 'web');
+                if (!empty($token)) {
+                    session('token', $token);
+                }
+                Db::name('user')->update($result);
+                cookie("admin_username", $name, 3600 * 24 * 30);
+                session("__LOGIN_BY_CMF_ADMIN_PW__", null);
+                $this->insertLoginLog(2);
+                $this->adminSuccess(lang('LOGIN_SUCCESS'), url("admin/Index/index"));
+            } else {
+                $this->adminError(lang('PASSWORD_NOT_RIGHT'));
+            }
+        } else {
+            $this->adminError(lang('USERNAME_NOT_EXIST'));
+        }
+    }
+
+    /**
+     * 后台管理员退出
+     */
+    public function logout() {
+        $this->insertLoginLog(3);
+        session('ADMIN_ID', null);
+        return redirect(url('/', [], false, true));
+    }
+
+    /**
+     * 语言设置
+     */
+    public function langSet() {
+        $_lang = $this->request->param('lang');
+        if (in_array($_lang, config('header_accept_lang'))) {
+            Cookie::set('think_var', $_lang);
+            $this->redirect('admin/index/index');
+        } else {
+            $this->adminError('error');
+        }
+    }
+
+    public function closeFrame() {
+        $_static = cmf_get_root().DS.'static';
+        $_html
+            = <<<  EOT
+<html>
+<script src="$_static/js/admin.js"></script>
+<script language='javascript'>
+reloadPage(window.parent);
+</script>
+</html>
+
+EOT;
+        echo $_html;
+        exit();
+    }
+}

+ 430 - 0
admin/admin/controller/RbacController.php

@@ -0,0 +1,430 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\model\menu\AdminMenuModel;
+use huo\model\user\AuthAccessModel;
+use huo\model\user\RoleModel;
+use huolib\constant\AgentConst;
+use think\Db;
+use tree\Tree;
+
+class RbacController extends AdminBaseController {
+    private $no_edit_role
+        = [
+            '1', '22', '221', '222', '223', '23', '231', '232', '233', '25', '26', '27', '271', '272',
+        ];
+
+    public function getType($role_type = 0) {
+        $_role_type = [
+            '1' => lang('ADMIN'),
+            '2' => lang('MANAGER'),
+            '3' => lang('GROUP'),
+            '4' => lang('AGENT'),
+            '5' => lang('MEMBER'),
+            '6' => lang('PC'),
+            '7' => lang('CP'),
+        ];
+        if (empty($role_type) || !isset($_role_type[$role_type])) {
+            return $_role_type;
+        }
+
+        return $_role_type[$role_type];
+    }
+
+    /**
+     * 角色管理列表
+     * @adminMenu(
+     *     'name'   => '角色管理',
+     *     'parent' => 'admin/User/default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '角色管理',
+     *     'param'  => ''
+     * )
+     */
+    public function index() {
+        $result = (new RoleModel())->order(["list_order" => "DESC", "id" => "ASC"])->select()->toArray();
+        $tree = new Tree();
+        $tree->icon = ['&nbsp;&nbsp;&nbsp;│ ', '&nbsp;&nbsp;&nbsp;├─ ', '&nbsp;&nbsp;&nbsp;└─ '];
+        $tree->nbsp = '&nbsp;&nbsp;&nbsp;';
+        foreach ($result as $key => $value) {
+            $result[$key]['parent_id_node'] = ($value['parent_id']) ? ' class="child-of-node-'.$value['parent_id'].'"'
+                : '';
+            $result[$key]['style'] = empty($value['parent_id']) ? '' : '';
+            $result[$key]['status'] = 2 == $value['status']
+                ? '<button class="btn btn-xs btn-success">'.lang("ENABLED").'</button>'
+                :
+                '<button class="btn btn-xs btn-primary">'.lang("DISABLED").'</button>';
+            $result[$key]['role_type'] = $this->getType($value['role_type']);
+            $_authorize = $value["id"] == 1 ? 'disabled' : '';
+            $_roleedit = in_array($value["id"], $this->no_edit_role) ? 'disabled' : '';
+            $_roledelete = in_array($value["id"], $this->no_edit_role) ? '' : '';
+            $result[$key]['str_manage']
+                = '<a '.$_authorize.' href="'.url("Rbac/authorize", array("id" => $value["id"])).'" 
+										data-toggle="tooltip" data-original-title="'.lang("ROLE_SETTING").'"><span class="text-success"><i class="fa fa-check"></i></span></a>
+									<a class=" '.$_roleedit.'"
+										href="'.url("Rbac/roleedit", array("id" => $value["id"])).'"
+										data-toggle="tooltip" data-original-title="'.lang("EDIT").'"><span class="text-success"><i class="fa fa-pencil"></i></span></a>
+									<a class="js-ajax-dialog-btn '.$_roledelete.'"
+									   href="'.url("Rbac/roledelete", array("id" => $value["id"])).'"
+									   data-msg="'.lang('sure to delete').'"
+									   data-toggle="tooltip" data-original-title="'.lang('DELETE').'">
+									   <span class="text-danger"><i class="fa fa-trash"></i></span>
+									</a>';
+        }
+        $tree->init($result);
+        $str
+            = "<tr id='node-\$id' \$parent_id_node style='\$style'>
+                        <td>\$id</td>
+                        <td>\$role_type</td>
+                        <td class='text-left'>\$spacer\$name</td>
+                        <td class='text-left'>\$remark</td>
+                        <td>\$status</td>
+                        <td><div class='action-buttons'>\$str_manage</div></td>
+                    </tr>";
+        $roles = $tree->getTree(0, $str);
+        $this->assign("roles", $roles);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加角色
+     * @adminMenu(
+     *     'name'   => '添加角色',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '添加角色',
+     *     'param'  => ''
+     * )
+     */
+    public function roleAdd() {
+        $tree = new Tree();
+        $parentId = $this->request->param("parent_id", 0, 'intval');
+        $result = (new RoleModel())->order(["list_order" => "ASC"])->select()->toArray();
+        $array = [];
+        foreach ($result as $r) {
+            $r['selected'] = $r['id'] == $parentId ? 'selected' : '';
+            $array[] = $r;
+        }
+        $str = "<option value='\$id' \$selected>\$spacer \$name</option>";
+        $tree->init($array);
+        $_select_roles = $tree->getTree(0, $str);
+        $this->assign("select_roles", $_select_roles);
+        $_role_type_select = Filter::selectCommon(AgentConst::getRoleType(), 'role_type', 0);
+        $this->assign("role_type_select", $_role_type_select);
+
+        return $this->fetch('rbac/roleadd');
+    }
+
+    /**
+     * 添加角色提交
+     * @adminMenu(
+     *     'name'   => '添加角色提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '添加角色提交',
+     *     'param'  => ''
+     * )
+     */
+    public function roleAddPost() {
+        if ($this->request->isPost()) {
+            $data = $this->request->param();
+            $result = $this->validate($data, 'role');
+            if ($result !== true) {
+                // 验证失败 输出错误信息
+                $this->adminError($result);
+            } else {
+                if (empty($data['role_type'])) {
+                    $_map['id'] = $this->request->param('parent_id');
+                    if (1 == $_map['id']) {
+                        $this->adminError('请选择角色类型');
+                    }
+                    $data['role_type'] = (new RoleModel())->where($_map)->value('role_type');
+                }
+                $data['create_time'] = time();
+                $data['update_time'] = time();
+                $result = (new RoleModel())->addRole($data);
+                if ($result) {
+                    $this->adminSuccess("添加角色成功", url("rbac/index"));
+                } else {
+                    $this->adminError("添加角色失败");
+                }
+            }
+        }
+    }
+
+    /**
+     * 编辑角色
+     * @adminMenu(
+     *     'name'   => '编辑角色',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '编辑角色',
+     *     'param'  => ''
+     * )
+     */
+    public function roleEdit() {
+        $id = $this->request->param("id", 0, 'intval');
+        if ($id == 1) {
+            $this->adminError("超级管理员角色不能被修改!");
+        }
+        $data = (new RoleModel())->where(["id" => $id])->find()->toArray();
+        if (!$data) {
+            $this->adminError("该角色不存在!");
+        }
+        $tree = new Tree();
+        $result = (new RoleModel())->order(["list_order" => "ASC"])->select()->toArray();
+        $array = [];
+        foreach ($result as $r) {
+            $r['selected'] = $r['id'] == $data['parent_id'] ? 'selected' : '';
+            $array[] = $r;
+        }
+        $str = "<option value='\$id' \$selected>\$spacer \$name</option>";
+        $tree->init($array);
+        $_select_roles = $tree->getTree(0, $str);
+        $this->assign("select_roles", $_select_roles);
+        $this->assign("data", $data);
+        $_role_type_select = Filter::selectCommon(AgentConst::getRoleType(), 'role_type', $data['role_type']);
+        $this->assign("role_type_select", $_role_type_select);
+
+        return $this->fetch('rbac/roleedit');
+    }
+
+    /**
+     * 编辑角色提交
+     * @adminMenu(
+     *     'name'   => '编辑角色提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '编辑角色提交',
+     *     'param'  => ''
+     * )
+     */
+    public function roleEditPost() {
+        $id = $this->request->param("id", 0, 'intval');
+        if ($id == 1) {
+            $this->adminError("超级管理员角色不能被修改!");
+        }
+        if ($this->request->isPost()) {
+            $data = $this->request->param();
+            $result = $this->validate($data, 'role');
+            if ($result !== true) {
+                // 验证失败 输出错误信息
+                $this->adminError($result);
+            } else {
+                if (empty($data['role_type'])) {
+                    $_map['id'] = $this->request->param('parent_id');
+                    if (1 == $_map['id']) {
+                        $this->adminError('请选择角色类型');
+                    }
+                    $data['role_type'] = (new RoleModel())->where($_map)->value('role_type');
+                }
+                $data['update_time'] = time();
+                $_rs = (new RoleModel())->updateRole($data);
+                if ($_rs !== false) {
+                    $this->adminSuccess("保存成功!", url('rbac/index'));
+                } else {
+                    $this->adminError("保存失败!");
+                }
+            }
+        }
+    }
+
+    /**
+     * 删除角色
+     * @adminMenu(
+     *     'name'   => '删除角色',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '删除角色',
+     *     'param'  => ''
+     * )
+     */
+    public function roleDelete() {
+        $id = $this->request->param("id", 0, 'intval');
+        if ($id == 1) {
+            $this->adminError("超级管理员角色不能被删除!");
+        }
+        $count = Db::name('RoleUser')->where(['role_id' => $id])->count();
+        if ($count > 0) {
+            $this->adminError("该角色已经有用户!");
+        } else {
+            $status = (new RoleModel())->deleteRole($id);
+            if (!empty($status)) {
+                $this->adminSuccess("删除成功!", url('rbac/index'));
+            } else {
+                $this->adminError("删除失败!");
+            }
+        }
+    }
+
+    /**
+     * 设置角色权限
+     * @adminMenu(
+     *     'name'   => '设置角色权限',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '设置角色权限',
+     *     'param'  => ''
+     * )
+     */
+    public function authorize() {
+        $AuthAccess = new AuthAccessModel();
+        $adminMenuModel = new AdminMenuModel();
+        //角色ID
+        $roleId = $this->request->param("id", 0, 'intval');
+        if (empty($roleId)) {
+            $this->adminError("参数错误!");
+        }
+        $tree = new Tree();
+        $tree->icon = ['│ ', '├─ ', '└─ '];
+        $tree->nbsp = '&nbsp;&nbsp;&nbsp;';
+        $result = $adminMenuModel->menuCache();
+        $newMenus = [];
+        $privilegeData = $AuthAccess->where(["role_id" => $roleId])->column("rule_name");//获取权限表数据
+        foreach ($result as $m) {
+            $newMenus[$m['id']] = $m;
+        }
+        foreach ($result as $n => $t) {
+            $result[$n]['checked'] = ($this->_isChecked($t, $privilegeData)) ? ' checked' : '';
+            $result[$n]['level'] = $this->_getLevel($t['id'], $newMenus);
+            $result[$n]['style'] = empty($t['parent_id']) ? '' : 'display:none;';
+            $result[$n]['parentIdNode'] = ($t['parent_id']) ? ' class="child-of-node-'.$t['parent_id'].'"' : '';
+        }
+        $str
+            = "<tr id='node-\$id'\$parentIdNode class='text-left' style='\$style'>
+                   <td class='text-left'  style='padding-left:30px;'>\$spacer<input type='checkbox' name='menuId[]' value='\$id' level='\$level' \$checked onclick='javascript:checknode(this);'> \$name</td>
+    			</tr>";
+        $tree->init($result);
+        $category = $tree->getTree(0, $str);
+        $this->assign("category", $category);
+        $this->assign("roleId", $roleId);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 角色授权提交
+     * @adminMenu(
+     *     'name'   => '角色授权提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '角色授权提交',
+     *     'param'  => ''
+     * )
+     */
+    public function authorizePost() {
+        if ($this->request->isPost()) {
+            $roleId = $this->request->param("roleId", 0, 'intval');
+            if (!$roleId) {
+                $this->adminError("需要授权的角色不存在!");
+            }
+            if (is_array($this->request->param('menuId/a')) && count($this->request->param('menuId/a')) > 0) {
+                (new AuthAccessModel())->where(["role_id" => $roleId, 'type' => 'admin_url'])->delete();
+                foreach ($_POST['menuId'] as $menuId) {
+                    $menu = Db::name("adminMenu")->where(["id" => $menuId])->field("app,controller,action")->find();
+                    if ($menu) {
+                        $app = $menu['app'];
+                        $model = $menu['controller'];
+                        $action = $menu['action'];
+                        $name = strtolower("$app/$model/$action");
+                        Db::name("authAccess")->insert(
+                            ["role_id" => $roleId, "rule_name" => $name, 'type' => 'admin_url']
+                        );
+                    }
+                }
+                $this->adminSuccess("授权成功!");
+            } else {
+                //当没有数据时,清除当前角色授权
+                Db::name("authAccess")->where(["role_id" => $roleId])->delete();
+                $this->adminError("没有接收到数据,执行清除授权成功!");
+            }
+        }
+    }
+
+    /**
+     * 检查指定菜单是否有权限
+     *
+     * @param array $menu menu表中数组
+     * @param       $privData
+     *
+     * @return bool
+     */
+    private function _isChecked($menu, $privData) {
+        $app = $menu['app'];
+        $model = $menu['controller'];
+        $action = $menu['action'];
+        $name = strtolower("$app/$model/$action");
+        if ($privData) {
+            if (in_array($name, $privData)) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 获取菜单深度
+     *
+     * @param       $id
+     * @param array $array
+     * @param int   $i
+     *
+     * @return int
+     */
+    protected function _getLevel($id, $array = [], $i = 0) {
+        if ($array[$id]['parent_id'] == 0 || empty($array[$array[$id]['parent_id']])
+            || $array[$id]['parent_id'] == $id
+        ) {
+            return $i;
+        } else {
+            $i++;
+
+            return $this->_getLevel($array[$id]['parent_id'], $array, $i);
+        }
+    }
+
+    //角色成员管理
+    public function member() {
+        //TODO 添加角色成员管理
+    }
+}
+

+ 126 - 0
admin/admin/controller/RecycleBinController.php

@@ -0,0 +1,126 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use admin\admin\model\RouteModel;
+use cmf\controller\AdminBaseController;
+use think\Db;
+
+class RecycleBinController extends AdminBaseController
+{
+    /**
+     * 回收站
+     * @adminMenu(
+     *     'name'   => '回收站',
+     *     'parent' => '',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '回收站',
+     *     'param'  => ''
+     * )
+     */
+    function index()
+    {
+        $list = Db::name('recycleBin')->order('create_time desc')->paginate(10);
+        // 获取分页显示
+        $page = $list->render();
+        $this->assign('page', $page);
+        $this->assign('list', $list);
+        return $this->fetch();
+    }
+
+    /**
+     * 回收站还原
+     * @adminMenu(
+     *     'name'   => '回收站还原',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '回收站还原',
+     *     'param'  => ''
+     * )
+     */
+    function restore()
+    {
+
+        $id     = $this->request->param('id');
+        $result = Db::name('recycleBin')->where(['id' => $id])->find();
+
+        $tableName = explode('#', $result['table_name']);
+        $tableName = $tableName[0];
+        //还原资源
+        if ($result) {
+            $res = Db::name($tableName)
+                ->where(['id' => $result['object_id']])
+                ->update(['delete_time' => '0']);
+            if ($tableName =='portal_post'){
+                Db::name('portal_category_post')->where('post_id',$result['object_id'])->update(['status'=>1]);
+                Db::name('portal_tag_post')->where('post_id',$result['object_id'])->update(['status'=>1]);
+            }
+
+            if ($res) {
+                $re = Db::name('recycleBin')->where('id', $id)->delete();
+                if ($re) {
+                    $this->adminSuccess("还原成功!");
+                }
+            }
+        }
+    }
+
+    /**
+     * 回收站彻底删除
+     * @adminMenu(
+     *     'name'   => '回收站彻底删除',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '回收站彻底删除',
+     *     'param'  => ''
+     * )
+     */
+    function delete()
+    {
+        $id     = $this->request->param('id');
+        $result = Db::name('recycleBin')->where(['id' => $id])->find();
+        //删除资源
+        if ($result) {
+
+            //页面没有单独的表.
+            if($result['table_name'] === 'portal_post#page'){
+                $re = Db::name('portal_post')->where('id', $result['object_id'])->delete();
+                //消除路由
+                $routeModel = new RouteModel();
+                $routeModel->setRoute('', 'portal/Page/index', ['id' => $result['object_id']], 2, 5000);
+                $routeModel->getRoutes(true);
+            }else{
+                $re = Db::name($result['table_name'])->where('id', $result['object_id'])->delete();
+            }
+
+            if ($re) {
+                $res = Db::name('recycleBin')->where('id', $id)->delete();
+                if($result['table_name'] === 'portal_post'){
+                    Db::name('portal_category_post')->where('post_id',$result['object_id'])->delete();
+                    Db::name('portal_tag_post')->where('post_id',$result['object_id'])->delete();
+                }
+                if ($res) {
+                    $this->adminSuccess("删除成功!");
+                }
+
+            }
+        }
+    }
+}

+ 292 - 0
admin/admin/controller/RouteController.php

@@ -0,0 +1,292 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <thinkcmf@126.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use admin\admin\model\RouteModel;
+use cmf\controller\AdminBaseController;
+use think\Db;
+
+class RouteController extends AdminBaseController
+{
+
+    public function _initialize()
+    {
+        parent::_initialize();
+    }
+
+    /**
+     * 路由规则列表
+     * @adminMenu(
+     *     'name'   => 'URL美化',
+     *     'parent' => 'admin/Setting/default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => 'URL规则管理',
+     *     'param'  => ''
+     * )
+     */
+    public function index()
+    {
+        $routeModel = new RouteModel();
+        $routes     = Db::name('route')->order("list_order asc")->select();
+        $routeModel->getRoutes(true);
+        $this->assign("routes", $routes);
+        return $this->fetch();
+    }
+
+    /**
+     * 添加路由规则
+     * @adminMenu(
+     *     'name'   => '添加路由规则',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '添加路由规则',
+     *     'param'  => ''
+     * )
+     */
+    public function add()
+    {
+        return $this->fetch();
+    }
+
+    /**
+     * 添加路由规则提交
+     * @adminMenu(
+     *     'name'   => '添加路由规则提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '添加路由规则提交',
+     *     'param'  => ''
+     * )
+     */
+    public function addPost()
+    {
+        $data       = $this->request->param();
+        $routeModel = new RouteModel();
+        $result     = $routeModel->validate(true)->allowField(true)->save($data);
+        if ($result === false) {
+            $this->adminError($routeModel->getError());
+        }
+
+        $this->adminSuccess("添加成功!", url("Route/index", ['id' => $routeModel->id]));
+    }
+
+    /**
+     * 路由规则编辑
+     * @adminMenu(
+     *     'name'   => '路由规则编辑',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '路由规则编辑',
+     *     'param'  => ''
+     * )
+     */
+    public function edit()
+    {
+        $id    = $this->request->param("id", 0, 'intval');
+        $route = Db::name('route')->where(['id' => $id])->find();
+        $this->assign($route);
+        return $this->fetch();
+    }
+
+    /**
+     * 路由规则编辑提交
+     * @adminMenu(
+     *     'name'   => '路由规则编辑提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '路由规则编辑提交',
+     *     'param'  => ''
+     * )
+     */
+    public function editPost()
+    {
+        $data       = $this->request->param();
+        $routeModel = new RouteModel();
+        $result     = $routeModel->validate(true)->allowField(true)->isUpdate(true)->save($data);
+        if ($result === false) {
+            $this->adminError($routeModel->getError());
+        }
+
+        $this->adminSuccess("保存成功!", url("Route/index"));
+    }
+
+    /**
+     * 路由规则删除
+     * @adminMenu(
+     *     'name'   => '路由规则删除',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '路由规则删除',
+     *     'param'  => ''
+     * )
+     */
+    public function delete()
+    {
+        $id = $this->request->param('id', 0, 'intval');
+        RouteModel::destroy($id);
+
+        $this->adminSuccess("删除成功!");
+    }
+
+    /**
+     * 路由规则禁用
+     * @adminMenu(
+     *     'name'   => '路由规则禁用',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '路由规则禁用',
+     *     'param'  => ''
+     * )
+     */
+    public function ban()
+    {
+        $id             = $this->request->param("id", 0, 'intval');
+        $data           = [];
+        $data['status'] = 0;
+        $data['id']     = $id;
+        $routeModel     = new RouteModel();
+
+        $routeModel->isUpdate(true)->save($data);
+        $this->adminSuccess("禁用成功!");
+    }
+
+    /**
+     * 路由规则启用
+     * @adminMenu(
+     *     'name'   => '路由规则启用',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '路由规则启用',
+     *     'param'  => ''
+     * )
+     */
+    public function open()
+    {
+        $id             = $this->request->param("id", 0, 'intval');
+        $data           = [];
+        $data['status'] = 1;
+        $data['id']     = $id;
+        $routeModel     = new RouteModel();
+
+        $routeModel->isUpdate(true)->save($data);
+        $this->adminSuccess("启用成功!");
+    }
+
+    /**
+     * 路由规则排序
+     * @adminMenu(
+     *     'name'   => '路由规则排序',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '路由规则排序',
+     *     'param'  => ''
+     * )
+     */
+    public function listOrder()
+    {
+        $routeModel = new RouteModel();
+        parent::listOrders($routeModel);
+        $this->adminSuccess("排序更新成功!");
+    }
+
+    /**
+     * 选择 URL
+     * @adminMenu(
+     *     'name'   => '选择URL',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '选择URL',
+     *     'param'  => ''
+     * )
+     */
+    public function select()
+    {
+        $routeModel = new RouteModel();
+        $urls       = $routeModel->getAppUrls();
+
+        $this->assign('urls', $urls);
+        return $this->fetch();
+    }
+
+    function _suggest_url($action, $url)
+    {
+        $actionArr = explode('/', $action);
+
+        $params = array_keys($url['vars']);
+
+        $urlDepr1Params = [];
+
+        $urlDepr2Params = [];
+
+        if (!empty($params)) {
+
+            foreach ($params as $param) {
+                if(empty($url['vars'][$param]['require'])){
+                    array_push($urlDepr1Params, "[:$param]");
+                }else{
+                    array_push($urlDepr1Params, ":$param");
+                }
+
+                array_push($urlDepr2Params, htmlspecialchars('<') . $param . htmlspecialchars('>'));
+            }
+
+        }
+
+        if ($actionArr[2] == 'index') {
+            $actionArr[1] = cmf_parse_name($actionArr[1]);
+            return empty($params) ? $actionArr[1].'$' : ($actionArr[1] . '/' . implode('/', $urlDepr1Params) /*. '或' . $actionArr[1] . '-' . implode('-', $urlDepr2Params)*/);
+        } else {
+            $actionArr[2] = cmf_parse_name($actionArr[2]);
+            return empty($params) ? $actionArr[2].'$' : ($actionArr[2] . '/' . implode('/', $urlDepr1Params) /*. '或' . $actionArr[2] . '-' . implode('-', $urlDepr2Params)*/);
+        }
+
+    }
+
+    function _url_vars($url)
+    {
+        if (!empty($url['vars'])) {
+            return implode(',', array_keys($url['vars']));
+        }
+
+        return '';
+    }
+
+}

+ 324 - 0
admin/admin/controller/SettingController.php

@@ -0,0 +1,324 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use admin\admin\model\RouteModel;
+use cmf\controller\AdminBaseController;
+
+use think\Db;
+
+/**
+ * Class SettingController
+ * @package app\admin\controller
+ * @adminMenuRoot(
+ *     'name'   =>'设置',
+ *     'action' =>'default',
+ *     'parent' =>'',
+ *     'display'=> true,
+ *     'order'  => 0,
+ *     'icon'   =>'cogs',
+ *     'remark' =>'系统设置入口'
+ * )
+ */
+class SettingController extends AdminBaseController
+{
+
+    /**
+     * 网站信息
+     * @adminMenu(
+     *     'name'   => '网站信息',
+     *     'parent' => 'default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 0,
+     *     'icon'   => '',
+     *     'remark' => '网站信息',
+     *     'param'  => ''
+     * )
+     */
+    public function site()
+    {
+        $noNeedDirs     = [".", "..", ".svn", 'fonts'];
+        $adminThemesDir = config('cmf_admin_theme_path') . config('cmf_admin_default_theme') . '/public/assets/themes/';
+        $adminStyles    = cmf_scan_dir($adminThemesDir . '*', GLOB_ONLYDIR);
+        $adminStyles    = array_diff($adminStyles, $noNeedDirs);
+        $cdnSettings    = cmf_get_option('cdn_settings');
+        $cmfSettings    = cmf_get_option('cmf_settings');
+        $adminSettings  = cmf_get_option('admin_settings');
+
+        $this->assign(cmf_get_option('site_info'));
+        $this->assign("admin_styles", $adminStyles);
+        $this->assign("templates", []);
+        $this->assign("cdn_settings", $cdnSettings);
+        $this->assign("admin_settings", $adminSettings);
+        $this->assign("cmf_settings", $cmfSettings);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 网站信息设置提交
+     * @adminMenu(
+     *     'name'   => '网站信息设置提交',
+     *     'parent' => 'site',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '网站信息设置提交',
+     *     'param'  => ''
+     * )
+     */
+    public function sitePost()
+    {
+        if ($this->request->isPost()) {
+            $result = $this->validate($this->request->param(), 'SettingSite');
+            if ($result !== true) {
+                $this->adminError($result);
+            }
+
+            $options = $this->request->param('options/a');
+            cmf_set_option('site_info', $options);
+
+            $cmfSettings = $this->request->param('cmf_settings/a');
+
+            $bannedUsernames                 = preg_replace("/[^0-9A-Za-z_\\x{4e00}-\\x{9fa5}-]/u", ",", $cmfSettings['banned_usernames']);
+            $cmfSettings['banned_usernames'] = $bannedUsernames;
+            cmf_set_option('cmf_settings', $cmfSettings);
+
+            $cdnSettings = $this->request->param('cdn_settings/a');
+            cmf_set_option('cdn_settings', $cdnSettings);
+
+            $adminSettings = $this->request->param('admin_settings/a');
+
+            $routeModel = new RouteModel();
+            if (!empty($adminSettings['admin_password'])) {
+                $routeModel->setRoute($adminSettings['admin_password'].'$', 'admin/Index/index', [], 2, 5000);
+            } else {
+                $routeModel->deleteRoute('admin/Index/index', []);
+            }
+
+            $routeModel->getRoutes(true);
+
+            cmf_set_option('admin_settings', $adminSettings);
+
+            $this->adminSuccess("保存成功!", '');
+
+        }
+    }
+
+    /**
+     * 密码修改
+     * @adminMenu(
+     *     'name'   => '密码修改',
+     *     'parent' => 'default',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '密码修改',
+     *     'param'  => ''
+     * )
+     */
+    public function password()
+    {
+        return $this->fetch();
+    }
+    /**
+     * 支付密码修改
+     * @adminMenu(
+     *     'name'   => '密码修改',
+     *     'parent' => 'default',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '密码修改',
+     *     'param'  => ''
+     * )
+     */
+    public function paypwd()
+    {
+        return $this->fetch();
+    }
+
+    /**
+     * 密码修改提交
+     * @adminMenu(
+     *     'name'   => '密码修改提交',
+     *     'parent' => 'password',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '密码修改提交',
+     *     'param'  => ''
+     * )
+     */
+    public function passwordPost()
+    {
+        if ($this->request->isPost()) {
+
+            $data = $this->request->param();
+            if (empty($data['old_password'])) {
+                $this->adminError("原始密码不能为空!");
+            }
+            if (empty($data['password'])) {
+                $this->adminError("新密码不能为空!");
+            }
+
+            $userId = cmf_get_current_admin_id();
+
+            $admin = Db::name('user')->where(["id" => $userId])->find();
+
+            $oldPassword = $data['old_password'];
+            $password    = $data['password'];
+            $rePassword  = $data['re_password'];
+
+            if (cmf_compare_password($oldPassword, $admin['user_pass'])) {
+                if ($password == $rePassword) {
+
+                    if (cmf_compare_password($password, $admin['user_pass'])) {
+                        $this->adminError("新密码不能和原始密码相同!");
+                    } else {
+                        Db::name('user')->where('id', $userId)->update(['user_pass' => cmf_password($password)]);
+                        $this->adminSuccess("密码修改成功!");
+                    }
+                } else {
+                    $this->adminError("密码输入不一致!");
+                }
+
+            } else {
+                $this->adminError("原始密码不正确!");
+            }
+        }
+    }
+
+
+    /**
+     * 支付密码修改提交
+     * @adminMenu(
+     *     'name'   => '支付密码修改提交',
+     *     'parent' => 'password',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '密码修改提交',
+     *     'param'  => ''
+     * )
+     */
+    public function payPwdPost()
+    {
+        if ($this->request->isPost()) {
+
+            $data = $this->request->param();
+            if (empty($data['old_password'])) {
+                $this->adminError("原始密码不能为空!");
+            }
+            if (empty($data['password'])) {
+                $this->adminError("新密码不能为空!");
+            }
+
+            $userId = cmf_get_current_admin_id();
+
+            $admin = Db::name('user')->where(["id" => $userId])->find();
+
+            $oldPassword = $data['old_password'];
+            $password    = $data['password'];
+            $rePassword  = $data['re_password'];
+
+            if (cmf_compare_password($oldPassword, $admin['pay_pwd'])) {
+                if ($password == $rePassword) {
+
+                    if (cmf_compare_password($password, $admin['pay_pwd'])) {
+                        $this->adminError("新密码不能和原始密码相同!");
+                    } else {
+                        Db::name('user')->where('id', $userId)->update(['pay_pwd' => cmf_password($password)]);
+                        $this->adminSuccess("密码修改成功!");
+                    }
+                } else {
+                    $this->adminError("密码输入不一致!");
+                }
+
+            } else {
+                $this->adminError("原始密码不正确!");
+            }
+        }
+    }
+
+
+    /**
+     * 上传限制设置界面
+     * @adminMenu(
+     *     'name'   => '上传设置',
+     *     'parent' => 'default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '上传设置',
+     *     'param'  => ''
+     * )
+     */
+    public function upload()
+    {
+        $uploadSetting = cmf_get_upload_setting();
+        $this->assign($uploadSetting);
+        return $this->fetch();
+    }
+
+    /**
+     * 上传限制设置界面提交
+     * @adminMenu(
+     *     'name'   => '上传设置提交',
+     *     'parent' => 'upload',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '上传设置提交',
+     *     'param'  => ''
+     * )
+     */
+    public function uploadPost()
+    {
+        if ($this->request->isPost()) {
+            //TODO 非空验证
+            $uploadSetting = $this->request->post();
+
+            cmf_set_option('upload_setting', $uploadSetting);
+            $this->adminSuccess('保存成功!');
+        }
+
+    }
+
+    /**
+     * 清除缓存
+     * @adminMenu(
+     *     'name'   => '清除缓存',
+     *     'parent' => 'default',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '清除缓存',
+     *     'param'  => ''
+     * )
+     */
+    public function clearCache()
+    {
+        cmf_clear_cache();
+        return $this->fetch();
+    }
+
+
+}

+ 83 - 0
admin/admin/controller/StorageController.php

@@ -0,0 +1,83 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <zxxjjforever@163.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+
+class StorageController extends AdminBaseController
+{
+
+    public function _initialize()
+    {
+        parent::_initialize();
+    }
+
+    /**
+     * 文件存储
+     * @adminMenu(
+     *     'name'   => '文件存储',
+     *     'parent' => 'admin/Setting/default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '文件存储',
+     *     'param'  => ''
+     * )
+     */
+    public function index()
+    {
+        $storage = cmf_get_option('storage');
+
+        if (empty($storage)) {
+            $storage['type']     = 'Local';
+            $storage['storages'] = ['Local' => ['name' => '本地']];
+        } else {
+            if (empty($storage['type'])) {
+                $storage['type'] = 'Local';
+            }
+
+            if (empty($storage['storages']['Local'])) {
+                $storage['storages']['Local'] = ['name' => '本地'];
+            }
+        }
+
+        $this->assign($storage);
+        return $this->fetch();
+    }
+
+    /**
+     * 文件存储
+     * @adminMenu(
+     *     'name'   => '文件存储设置提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '文件存储设置提交',
+     *     'param'  => ''
+     * )
+     */
+    public function settingPost()
+    {
+        $post = $this->request->post();
+
+        $storage = cmf_get_option('storage');
+
+        $storage['type'] = $post['type'];
+        cmf_set_option('storage', $storage);
+        $this->adminSuccess("设置成功!", '');
+
+    }
+
+
+}

+ 836 - 0
admin/admin/controller/ThemeController.php

@@ -0,0 +1,836 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 老猫 <zxxjjforever@163.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use admin\admin\model\ThemeModel;
+use think\Db;
+use think\Validate;
+use tree\Tree;
+
+class ThemeController extends AdminBaseController
+{
+    /**
+     * 模板管理
+     * @adminMenu(
+     *     'name'   => '模板管理',
+     *     'parent' => 'admin/Setting/default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 20,
+     *     'icon'   => '',
+     *     'remark' => '模板管理',
+     *     'param'  => ''
+     * )
+     */
+    public function index()
+    {
+
+        $themeModel = new ThemeModel();
+        $themes     = $themeModel->select();
+        $this->assign("themes", $themes);
+
+        $defaultTheme = config('cmf_default_theme');
+        if ($temp = session('cmf_default_theme')){
+            $defaultTheme = $temp;
+        }
+        $this->assign('default_theme', $defaultTheme);
+        return $this->fetch();
+    }
+
+    /**
+     * 安装模板
+     * @adminMenu(
+     *     'name'   => '安装模板',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '安装模板',
+     *     'param'  => ''
+     * )
+     */
+    public function install()
+    {
+        $themesDirs = cmf_scan_dir("themes/*", GLOB_ONLYDIR);
+
+        $themeModel = new ThemeModel();
+
+        $themesInstalled = $themeModel->column('theme');
+
+        $themesDirs = array_diff($themesDirs, $themesInstalled);
+
+        $themes = [];
+        foreach ($themesDirs as $dir) {
+            $manifest = "themes/$dir/manifest.json";
+            if (file_exists_case($manifest)) {
+                $manifest       = file_get_contents($manifest);
+                $theme          = json_decode($manifest, true);
+                $theme['theme'] = $dir;
+                array_push($themes, $theme);
+            }
+        }
+        $this->assign('themes', $themes);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 卸载模板
+     * @adminMenu(
+     *     'name'   => '卸载模板',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '卸载模板',
+     *     'param'  => ''
+     * )
+     */
+    public function uninstall()
+    {
+        $theme      = $this->request->param('theme');
+        if ($theme == "simpleboot3" || config('cmf_default_theme') == $theme ){
+            $this->adminError("官方自带模板或当前使用中的模板不可以卸载");
+        }
+
+        $themeModel = new ThemeModel();
+        $themeModel->transaction(function () use ($theme, $themeModel) {
+            $themeModel->where(['theme' => $theme])->delete();
+            Db::name('theme_file')->where(['theme' => $theme])->delete();
+        });
+
+        $this->adminSuccess("卸载成功", url("theme/index"));
+
+    }
+
+    /**
+     * 模板安装
+     * @adminMenu(
+     *     'name'   => '模板安装',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '模板安装',
+     *     'param'  => ''
+     * )
+     */
+    public function installTheme()
+    {
+        $theme      = $this->request->param('theme');
+        $themeModel = new ThemeModel();
+        $themeCount = $themeModel->where('theme', $theme)->count();
+
+        if ($themeCount > 0) {
+            $this->adminError('模板已经安装!');
+        }
+        $result = $themeModel->installTheme($theme);
+        if ($result === false) {
+            $this->adminError('模板不存在!');
+        }
+        $this->adminSuccess("安装成功", url("theme/index"));
+    }
+
+    /**
+     * 模板更新
+     * @adminMenu(
+     *     'name'   => '模板更新',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '模板更新',
+     *     'param'  => ''
+     * )
+     */
+    public function update()
+    {
+        $theme      = $this->request->param('theme');
+        $themeModel = new ThemeModel();
+        $themeCount = $themeModel->where('theme', $theme)->count();
+
+        if ($themeCount === 0) {
+            $this->adminError('模板未安装!');
+        }
+        $result = $themeModel->updateTheme($theme);
+        if ($result === false) {
+            $this->adminError('模板不存在!');
+        }
+        $this->adminSuccess("更新成功", url("theme/index"));
+    }
+
+    /**
+     * 启用模板
+     * @adminMenu(
+     *     'name'   => '启用模板',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '启用模板',
+     *     'param'  => ''
+     * )
+     */
+    public function active()
+    {
+        $theme      = $this->request->param('theme');
+
+        if ($theme == config('cmf_default_theme')){
+            $this->adminError('模板已启用',url("theme/index"));
+        }
+
+        $themeModel = new ThemeModel();
+        $themeCount = $themeModel->where('theme', $theme)->count();
+
+        if ($themeCount === 0) {
+            $this->adminError('模板未安装!');
+        }
+
+        $result = cmf_set_dynamic_config(['cmf_default_theme' => $theme]);
+
+        if ($result === false) {
+            $this->adminError('配置写入失败!');
+        }
+        session('cmf_default_theme',$theme);
+
+        $this->adminSuccess("模板启用成功",url("theme/index"));
+
+    }
+
+    /**
+     * 模板文件列表
+     * @adminMenu(
+     *     'name'   => '模板文件列表',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '启用模板',
+     *     'param'  => ''
+     * )
+     */
+    public function files()
+    {
+        $theme = $this->request->param('theme');
+        $files = Db::name('theme_file')->where(['theme' => $theme])->order('list_order DESC')->select();
+        $this->assign('files', $files);
+        return $this->fetch();
+    }
+
+    /**
+     * 模板文件设置
+     * @adminMenu(
+     *     'name'   => '模板文件设置',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '模板文件设置',
+     *     'param'  => ''
+     * )
+     */
+    public function fileSetting()
+    {
+        $tab                 = $this->request->param('tab', 'widget');
+        $fileId              = $this->request->param('file_id', 0, 'intval');
+        $file                = Db::name('theme_file')->where(['id' => $fileId])->find();
+        $file['config_more'] = json_decode($file['config_more'], true);
+        $file['more']        = json_decode($file['more'], true);
+        $this->assign('tab', $tab);
+        $this->assign('file', $file);
+        $this->assign('file_id', $fileId);
+
+        $tpl = 'file_widget_setting';
+        if ($tab == 'var') {
+            $tpl = 'file_var_setting';
+        }
+        return $this->fetch($tpl);
+    }
+
+    /**
+     * 模板文件数组数据列表
+     * @adminMenu(
+     *     'name'   => '模板文件数组数据列表',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '模板文件数组数据列表',
+     *     'param'  => ''
+     * )
+     */
+    public function fileArrayData()
+    {
+        $tab                 = $this->request->param('tab', 'widget');
+        $varName             = $this->request->param('var');
+        $widgetName          = $this->request->param('widget', '');
+        $fileId              = $this->request->param('file_id', 0, 'intval');
+        $file                = Db::name('theme_file')->where(['id' => $fileId])->find();
+        $file['config_more'] = json_decode($file['config_more'], true);
+        $file['more']        = json_decode($file['more'], true);
+        $oldMore             = $file['more'];
+
+
+        $items = [];
+        $item  = [];
+
+        if ($tab == 'var' && !empty($oldMore['vars']) && is_array($oldMore['vars'])) {
+
+            if (isset($oldMore['vars'][$varName]) && is_array($oldMore['vars'][$varName])) {
+                $items = $oldMore['vars'][$varName]['value'];
+            }
+
+            if (isset($oldMore['vars'][$varName]['item'])) {
+                $item = $oldMore['vars'][$varName]['item'];
+            }
+
+        }
+
+        if ($tab == 'widget' && !empty($oldMore['widgets'][$widgetName]) && is_array($oldMore['widgets'][$widgetName])) {
+            $widget = $oldMore['widgets'][$widgetName];
+            if (!empty($widget['vars']) && is_array($widget['vars'])) {
+                foreach ($widget['vars'] as $mVarName => $mVar) {
+                    if ($mVarName == $varName) {
+                        if (is_array($mVar['value'])) {
+                            $items = $mVar['value'];
+                        }
+
+                        if (isset($mVar['item'])) {
+                            $item = $mVar['item'];
+                        }
+                    }
+                }
+            }
+        }
+
+        $this->assign('tab', $tab);
+        $this->assign('var', $varName);
+        $this->assign('widget', $widgetName);
+        $this->assign('file_id', $fileId);
+        $this->assign('array_items', $items);
+        $this->assign('array_item', $item);
+
+        return $this->fetch('file_array_data');
+    }
+
+    /**
+     * 模板文件数组数据添加编辑
+     * @adminMenu(
+     *     'name'   => '模板文件数组数据添加编辑',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '模板文件数组数据添加编辑',
+     *     'param'  => ''
+     * )
+     */
+    public function fileArrayDataEdit()
+    {
+        $tab        = $this->request->param('tab', 'widget');
+        $varName    = $this->request->param('var');
+        $widgetName = $this->request->param('widget', '');
+        $fileId     = $this->request->param('file_id', 0, 'intval');
+        $itemIndex  = $this->request->param('item_index', '');
+
+        $file = Db::name('theme_file')->where(['id' => $fileId])->find();
+
+        $file['config_more'] = json_decode($file['config_more'], true);
+        $file['more']        = json_decode($file['more'], true);
+        $oldMore             = $file['more'];
+
+        $items = [];
+        $item  = [];
+
+        if ($tab == 'var' && !empty($oldMore['vars']) && is_array($oldMore['vars'])) {
+
+            if (isset($oldMore['vars'][$varName]) && is_array($oldMore['vars'][$varName])) {
+                $items = $oldMore['vars'][$varName]['value'];
+            }
+
+            if (isset($oldMore['vars'][$varName]['item'])) {
+                $item = $oldMore['vars'][$varName]['item'];
+            }
+
+        }
+
+        if ($tab == 'widget') {
+
+            if (empty($widgetName)) {
+                $this->adminError('未指定控件!');
+            }
+
+            if (!empty($oldMore['widgets']) && is_array($oldMore['widgets'])) {
+                foreach ($oldMore['widgets'] as $mWidgetName => $widget) {
+                    if ($mWidgetName == $widgetName) {
+                        if (!empty($widget['vars']) && is_array($widget['vars'])) {
+                            foreach ($widget['vars'] as $widgetVarName => $widgetVar) {
+                                if ($widgetVarName == $varName && $widgetVar['type'] == 'array') {
+
+                                    if (is_array($widgetVar['value'])) {
+                                        $items = $widgetVar['value'];
+                                    }
+
+                                    if (isset($widgetVar['item'])) {
+                                        $item = $widgetVar['item'];
+                                    }
+
+                                    break;
+                                }
+                            }
+                        }
+                        break;
+                    }
+
+                }
+            }
+        }
+
+        if ($itemIndex !== '') {
+            $itemIndex = intval($itemIndex);
+            if (!isset($items[$itemIndex])) {
+                $this->adminError('数据不存在!');
+            }
+
+            foreach ($item as $itemName => $vo) {
+                if (isset($items[$itemIndex][$itemName])) {
+                    $item[$itemName]['value'] = $items[$itemIndex][$itemName];
+                }
+            }
+        }
+
+        $this->assign('tab', $tab);
+        $this->assign('var', $varName);
+        $this->assign('widget', $widgetName);
+        $this->assign('file_id', $fileId);
+        $this->assign('array_items', $items);
+        $this->assign('array_item', $item);
+        $this->assign('item_index', $itemIndex);
+
+        return $this->fetch('file_array_data_edit');
+    }
+
+    /**
+     * 模板文件数组数据添加编辑提交保存
+     * @adminMenu(
+     *     'name'   => '模板文件数组数据添加编辑提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '模板文件数组数据添加编辑提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function fileArrayDataEditPost()
+    {
+        $tab        = $this->request->param('tab', 'widget');
+        $varName    = $this->request->param('var');
+        $widgetName = $this->request->param('widget', '');
+        $fileId     = $this->request->param('file_id', 0, 'intval');
+        $itemIndex  = $this->request->param('item_index', '');
+
+        $file = Db::name('theme_file')->where(['id' => $fileId])->find();
+
+        if ($this->request->isPost()) {
+
+            $post = $this->request->param();
+
+            $more = json_decode($file['more'], true);
+            if ($tab == 'var') {
+                foreach ($more['vars'] as $mVarName => $mVar) {
+
+                    if ($mVarName == $varName && $mVar['type'] == 'array') {
+                        if ($itemIndex === '') {
+                            if (!empty($mVar['value']) && is_array($mVar['value'])) {
+                                array_push($more['vars'][$mVarName]['value'], $post['item']);
+                            } else {
+                                $more['vars'][$mVarName]['value'] = [$post['item']];
+                            }
+                        } else {
+                            if (!empty($mVar['value']) && is_array($mVar['value']) && isset($mVar['value'][$itemIndex])) {
+                                $more['vars'][$mVarName]['value'][$itemIndex] = $post['item'];
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+
+            if ($tab == 'widget') {
+                foreach ($more['widgets'] as $mWidgetName => $widget) {
+                    if ($widgetName == $mWidgetName) {
+                        if (!empty($widget['vars']) && is_array($widget['vars'])) {
+                            foreach ($widget['vars'] as $widgetVarName => $widgetVar) {
+                                if ($widgetVarName == $varName && $widgetVar['type'] == 'array') {
+                                    if ($itemIndex === '') {
+                                        if (!empty($widgetVar['value']) && is_array($widgetVar['value'])) {
+                                            array_push($more['widgets'][$widgetName]['vars'][$widgetVarName]['value'], $post['item']);
+                                        } else {
+                                            $more['widgets'][$widgetName]['vars'][$widgetVarName]['value'] = [$post['item']];
+                                        }
+                                    } else {
+                                        if (!empty($widgetVar['value']) && is_array($widgetVar['value']) && isset($widgetVar['value'][$itemIndex])) {
+                                            $more['widgets'][$widgetName]['vars'][$widgetVarName]['value'][$itemIndex] = $post['item'];
+                                        }
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+
+            $more = json_encode($more);
+            Db::name('theme_file')->where(['id' => $fileId])->update(['more' => $more]);
+
+            $this->adminSuccess("保存成功!", url('theme/fileArrayData', ['tab' => $tab, 'var' => $varName, 'file_id' => $fileId, 'widget' => $widgetName]));
+
+        }
+
+    }
+
+    /**
+     * 模板文件数组数据删除
+     * @adminMenu(
+     *     'name'   => '模板文件数组数据删除',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '模板文件数组数据删除',
+     *     'param'  => ''
+     * )
+     */
+    public function fileArrayDataDelete()
+    {
+        $tab        = $this->request->param('tab', 'widget');
+        $varName    = $this->request->param('var');
+        $widgetName = $this->request->param('widget', '');
+        $fileId     = $this->request->param('file_id', 0, 'intval');
+        $itemIndex  = $this->request->param('item_index', '');
+
+        if ($itemIndex === '') {
+            $this->adminError('未指定删除元素!');
+        }
+
+        $file = Db::name('theme_file')->where(['id' => $fileId])->find();
+
+        $more = json_decode($file['more'], true);
+        if ($tab == 'var') {
+            foreach ($more['vars'] as $mVarName => $mVar) {
+
+                if ($mVarName == $varName && $mVar['type'] == 'array') {
+                    if (!empty($var['value']) && is_array($var['value']) && isset($var['value'][$itemIndex])) {
+                        array_splice($more['vars'][$mVarName]['value'], $itemIndex, 1);
+                    } else {
+                        $this->adminError('指定数据不存在!');
+                    }
+                    break;
+                }
+            }
+        }
+
+        if ($tab == 'widget') {
+            foreach ($more['widgets'] as $mWidgetName => $widget) {
+                if ($mWidgetName == $widgetName) {
+                    if (!empty($widget['vars']) && is_array($widget['vars'])) {
+                        foreach ($widget['vars'] as $widgetVarName => $widgetVar) {
+                            if ($widgetVarName == $varName && $widgetVar['type'] == 'array') {
+                                if (!empty($widgetVar['value']) && is_array($widgetVar['value']) && isset($widgetVar['value'][$itemIndex])) {
+                                    array_splice($more['widgets'][$widgetName]['vars'][$widgetVarName]['value'], $itemIndex, 1);
+                                } else {
+                                    $this->adminError('指定数据不存在!');
+                                }
+                                break;
+                            }
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+
+        $more = json_encode($more);
+        Db::name('theme_file')->where(['id' => $fileId])->update(['more' => $more]);
+
+        $this->adminSuccess("删除成功!", url('theme/fileArrayData', ['tab' => $tab, 'var' => $varName, 'file_id' => $fileId, 'widget' => $widgetName]));
+    }
+
+    /**
+     * 模板文件编辑提交保存
+     * @adminMenu(
+     *     'name'   => '模板文件编辑提交保存',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '模板文件编辑提交保存',
+     *     'param'  => ''
+     * )
+     */
+    public function settingPost()
+    {
+        if ($this->request->isPost()) {
+            $id   = $this->request->param('id', 0, 'intval');
+            $post = $this->request->param();
+            $file = Db::name('theme_file')->field('theme,more')->where(['id' => $id])->find();
+            $more = json_decode($file['more'], true);
+            if (isset($post['vars'])) {
+                $messages = [];
+                $rules    = [];
+
+                foreach ($more['vars'] as $mVarName => $mVar) {
+
+                    if (!empty($mVar['rule'])) {
+                        $rules[$mVarName] = $this->_parseRules($mVar['rule']);
+                    }
+
+                    if (!empty($mVar['message'])) {
+                        foreach ($mVar['message'] as $rule => $msg) {
+                            $messages[$mVarName . '.' . $rule] = $msg;
+                        }
+                    }
+
+                    if (isset($post['vars'][$mVarName])) {
+                        $more['vars'][$mVarName]['value'] = $post['vars'][$mVarName];
+                    }
+
+                    if (isset($post['vars'][$mVarName . '_text_'])) {
+                        $more['vars'][$mVarName]['valueText'] = $post['vars'][$mVarName . '_text_'];
+                    }
+                }
+
+                $validate = new Validate($rules, $messages);
+                $result   = $validate->check($post['vars']);
+                if (!$result) {
+                    $this->adminError($validate->getError());
+                }
+            }
+
+            if (isset($post['widget_vars'])) {
+                foreach ($more['widgets'] as $mWidgetName => $widget) {
+
+                    if (empty($post['widget'][$mWidgetName]['display'])) {
+                        $widget['display'] = 0;
+                    } else {
+                        $widget['display'] = 1;
+                    }
+
+                    if (!empty($post['widget'][$mWidgetName]['title'])) {
+                        $widget['title'] = $post['widget'][$mWidgetName]['title'];
+                    }
+
+                    $messages = [];
+                    $rules    = [];
+
+                    foreach ($widget['vars'] as $mVarName => $mVar) {
+
+                        if (!empty($mVar['rule'])) {
+                            $rules[$mVarName] = $this->_parseRules($mVar['rule']);
+                        }
+
+                        if (!empty($mVar['message'])) {
+                            foreach ($mVar['message'] as $rule => $msg) {
+                                $messages[$mVarName . '.' . $rule] = $msg;
+                            }
+                        }
+
+                        if (isset($post['widget_vars'][$mWidgetName][$mVarName])) {
+                            $widget['vars'][$mVarName]['value'] = $post['widget_vars'][$mWidgetName][$mVarName];
+                        }
+
+                        if (isset($post['widget_vars'][$mWidgetName][$mVarName . '_text_'])) {
+                            $widget['vars'][$mVarName]['valueText'] = $post['widget_vars'][$mWidgetName][$mVarName . '_text_'];
+                        }
+                    }
+
+                    if ($widget['display']) {
+                        $validate   = new Validate($rules, $messages);
+                        $widgetVars = empty($post['widget_vars'][$mWidgetName]) ? [] : $post['widget_vars'][$mWidgetName];
+                        $result     = $validate->check($widgetVars);
+                        if (!$result) {
+                            $this->adminError($widget['title'] . ':' . $validate->getError());
+                        }
+                    }
+
+                    $more['widgets'][$mWidgetName] = $widget;
+                }
+            }
+
+            $more = json_encode($more);
+            Db::name('theme_file')->where(['id' => $id])->update(['more' => $more]);
+            $this->adminSuccess("保存成功!");
+        }
+    }
+
+    /**
+     * 解析模板变量验证规则
+     * @param $rules
+     * @return array
+     */
+    private function _parseRules($rules)
+    {
+        $newRules = [];
+
+        $simpleRules = [
+            'require', 'number',
+            'integer', 'float', 'boolean', 'email',
+            'array', 'accepted', 'date', 'alpha',
+            'alphaNum', 'alphaDash', 'activeUrl',
+            'url', 'ip'];
+        foreach ($rules as $key => $rule) {
+            if (in_array($key, $simpleRules) && $rule) {
+                array_push($newRules, $key);
+            }
+        }
+
+        return $newRules;
+    }
+
+    /**
+     * 模板文件设置数据源
+     * @adminMenu(
+     *     'name'   => '模板文件设置数据源',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '模板文件设置数据源',
+     *     'param'  => ''
+     * )
+     */
+    public function dataSource()
+    {
+        $dataSource = $this->request->param('data_source');
+        $this->assign('data_source', $dataSource);
+
+        $ids         = $this->request->param('ids');
+        $selectedIds = [];
+
+        if (!empty($ids)) {
+            $selectedIds = explode(',', $ids);
+        }
+
+        if (empty($dataSource)) {
+            $this->adminError('数据源不能为空!');
+        }
+
+        $dataSource = json_decode(base64_decode($dataSource), true);
+
+        if ($dataSource === null || !isset($dataSource['api'])) {
+            $this->adminError('数据源格式不正确!');
+        }
+
+        $filters = [];
+        if (isset($dataSource['filters']) && is_array($dataSource['filters'])) {
+            $filters = $dataSource['filters'];
+
+            foreach ($filters as $key => $filter) {
+                if ($filter['type'] == 'select' && !empty($filter['api'])) {
+                    $filterData = [];
+                    try {
+                        $filterData = action($filter['api'], [], 'api');
+                        if (!is_array($filterData)) {
+                            $filterData = $filterData->toArray();
+                        }
+                    } catch (\Exception $e) {
+
+                    }
+
+                    if (empty($filterData)) {
+                        $filters[$key] = null;
+                    } else {
+                        $filters[$key]['options'] = $filterData;
+                    }
+                }
+            }
+
+            if (count($filters) > 3) {
+                $filters = array_slice($filters, 0, 3);
+            }
+        }
+
+        $vars = [];
+
+        if ($this->request->isPost()) {
+            $form    = $this->request->param();
+            $vars[0] = $form;
+            $this->assign('form', $form);
+        }
+
+        $items = action($dataSource['api'], $vars, 'api');
+
+        if ($items instanceof \think\Collection) {
+            $items = $items->toArray();
+        }
+
+        $multi = empty($dataSource['multi']) ? false : $dataSource['multi'];
+
+        foreach ($items as $key => $item) {
+            if (empty($item['parent_id'])) {
+                $item['parent_id'] = 0;
+            }
+            $item['checked'] = in_array($item['id'], $selectedIds) ? 'checked' : '';
+            $items[$key]     = $item;
+        }
+
+        $tree = new Tree();
+        $tree->init($items);
+
+        $tpl = "<tr class='data-item-tr'>
+					<td>
+                        <input type='radio' class='js-select-box' 
+                           name='ids[]'
+                           value='\$id' data-name='\$name' \$checked>
+					</td>
+					<td>\$id</td>
+					<td>\$spacer \$name</td>
+				</tr>";
+        if ($multi) {
+            $tpl = "<tr class='data-item-tr'>
+					<td>
+					    <input type='checkbox' class='js-check js-select-box' data-yid='js-check-y'
+                                   data-xid='js-check-x'
+                                   name='ids[]'
+                                   value='\$id' data-name='\$name' \$checked>
+					</td>
+					<td>\$id</td>
+					<td>\$spacer \$name</td>
+				</tr>";
+        }
+
+        $itemsTree = $tree->getTree(0, $tpl);
+        $this->assign('multi', $multi);
+        $this->assign('items_tree', $itemsTree);
+        $this->assign('selected_ids', $selectedIds);
+        $this->assign('filters', $filters);
+        return $this->fetch();
+
+    }
+
+}

+ 371 - 0
admin/admin/controller/UserController.php

@@ -0,0 +1,371 @@
+<?php
+// +----------------------------------------------------------------------
+// | ThinkCMF [ WE CAN DO IT MORE SIMPLE ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2013-2017 http://www.thinkcmf.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+// +----------------------------------------------------------------------
+// | Author: 小夏 < 449134904@qq.com>
+// +----------------------------------------------------------------------
+namespace admin\admin\controller;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\agent\AgentCache;
+use huo\model\user\RoleModel;
+use huo\model\user\RoleUserModel;
+use huo\model\user\UserModel;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use think\Db;
+
+/**
+ * Class UserController
+ *
+ * @package app\admin\controller
+ * @adminMenuRoot(
+ *     'name'   => '管理组',
+ *     'action' => 'default',
+ *     'parent' => 'user/AdminIndex/default',
+ *     'display'=> true,
+ *     'order'  => 10000,
+ *     'icon'   => '',
+ *     'remark' => '管理组'
+ * )
+ */
+class UserController extends AdminBaseController {
+    /**
+     * 管理员列表
+     * @adminMenu(
+     *     'name'   => '管理员',
+     *     'parent' => 'default',
+     *     'display'=> true,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '管理员管理',
+     *     'param'  => ''
+     * )
+     */
+    public function index() {
+        $where = [];
+        /**搜索条件**/
+        $user_login = $this->request->param('user_login');
+        $user_email = trim($this->request->param('user_email'));
+        if ($user_login) {
+            $where['user_login'] = ['like', "%$user_login%"];
+        }
+        if ($user_email) {
+            $where['user_email'] = ['like', "%$user_email%"];;
+        }
+        $role_type = [AgentConst::ROLE_TYPE_ADMIN, AgentConst::ROLE_TYPE_MANAGER, AgentConst::ROLE_TYPE_PC];
+        $_role_ids = (new RoleModel())->getIdsByRoleType($role_type);
+        if ('120.236.141.221' == get_client_ip()) {
+//            dump($role_type);
+//            dump($_role_ids);
+        }
+        $where['role_id'] = ['in', $_role_ids];
+        $users = Db::name('user')
+                   ->where($where)
+                   ->order("id DESC")
+                   ->paginate(10);
+        // 获取分页显示
+        $page = $users->render();
+        $rolesSrc = Db::name('role')->select();
+        $roles = [];
+        foreach ($rolesSrc as $r) {
+            $roleId = $r['id'];
+            $roles["$roleId"] = $r;
+        }
+        $this->assign("page", $page);
+        $this->assign("roles", $roles);
+        $this->assign("users", $users);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 管理员添加
+     * @adminMenu(
+     *     'name'   => '管理员添加',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,rbac/index.html
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '管理员添加',
+     *     'param'  => ''
+     * )
+     */
+    public function add() {
+        $_map['status'] = CommonConst::STATUS_YES;
+        $_map['role_type'] = ['in',
+                              [AgentConst::ROLE_TYPE_ADMIN, AgentConst::ROLE_TYPE_MANAGER, AgentConst::ROLE_TYPE_PC]];
+        $roles = (new RoleModel())->where($_map)->order("id DESC")->select();
+        $this->assign("roles", $roles);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 管理员添加提交
+     * @adminMenu(
+     *     'name'   => '管理员添加提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '管理员添加提交',
+     *     'param'  => ''
+     * )
+     */
+    public function addPost() {
+        if ($this->request->isPost()) {
+            if (!empty($_POST['role_id']) && is_array($_POST['role_id'])) {
+                $role_ids = $_POST['role_id'];
+                $_role_id = (int)implode(",", $role_ids);
+                $_param = $this->request->param();
+                $result = $this->validate($_param, 'User');
+                if ($result !== true) {
+                    $this->adminError($result);
+                } else {
+                    $_data['user_login'] = $_param['user_login'];
+                    $_data['user_pass'] = $_param['user_pass'];
+                    $_data['pay_pwd'] = $_param['pay_pwd'];
+                    $_data['user_email'] = $_param['user_email'];
+                    $_data['role_id'] = $_role_id;
+                    $result = (new UserModel())->addData($_data);
+                    if ($result !== false) {
+                        foreach ($role_ids as $role_id) {
+                            if (cmf_get_current_admin_id() != 1 && $role_id == 1) {
+                                $this->adminError("为了网站的安全,非网站创建者不可创建超级管理员!");
+                            }
+                            Db::name('RoleUser')->insert(["role_id" => $role_id, "user_id" => $result]);
+                        }
+                        $this->adminSuccess("添加成功!", url("user/index"));
+                    } else {
+                        $this->adminError("添加失败!");
+                    }
+                }
+            } else {
+                $this->adminError("请为此用户指定角色!");
+            }
+        }
+    }
+
+    /**
+     * 管理员编辑
+     * @adminMenu(
+     *     'name'   => '管理员编辑',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '管理员编辑',
+     *     'param'  => ''
+     * )
+     */
+    public function edit() {
+        $id = $this->request->param('id', 0, 'intval');
+        $_map = ['status' => CommonConst::STATUS_YES];
+        $_map['role_type'] = ['in',
+                              [AgentConst::ROLE_TYPE_ADMIN, AgentConst::ROLE_TYPE_MANAGER, AgentConst::ROLE_TYPE_PC]];
+        $roles = DB::name('role')->where($_map)->order("id DESC")->select();
+        $this->assign("roles", $roles);
+        $role_ids = DB::name('RoleUser')->where(["user_id" => $id])->column("role_id");
+        $this->assign("role_ids", $role_ids);
+        $user = DB::name('user')->where(["id" => $id])->find();
+        $this->assign($user);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 管理员编辑提交
+     * @adminMenu(
+     *     'name'   => '管理员编辑提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '管理员编辑提交',
+     *     'param'  => ''
+     * )
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            if (!empty($_POST['role_id']) && is_array($_POST['role_id'])) {
+                if (empty($_POST['user_pass'])) {
+                    unset($_POST['user_pass']);
+                }
+                if (empty($_POST['pay_pwd'])) {
+                    unset($_POST['pay_pwd']);
+                }
+                $role_ids = $this->request->param('role_id/a');
+                unset($_POST['role_id']);
+                $result = $this->validate($this->request->param(), 'User.edit');
+                if ($result !== true) {
+                    // 验证失败 输出错误信息
+                    $this->adminError($result);
+                } else {
+                    $result = AgentCache::ins()->updateAgent($_POST['id'], $_POST);
+                    if ($result !== false) {
+                        $uid = $this->request->param('id', 0, 'intval');
+                        DB::name("RoleUser")->where(["user_id" => $uid])->delete();
+                        foreach ($role_ids as $role_id) {
+                            if (cmf_get_current_admin_id() != 1 && $role_id == 1) {
+                                $this->adminError("为了网站的安全,非网站创建者不可创建超级管理员!");
+                            }
+                            DB::name("RoleUser")->insert(["role_id" => $role_id, "user_id" => $uid]);
+                            $_data['role_id'] = $role_id;
+                            (new UserModel())->updateData($_data, $uid);
+                        }
+                        $this->adminSuccess("保存成功!");
+                    } else {
+                        $this->adminError("保存失败!");
+                    }
+                }
+            } else {
+                $this->adminError("请为此用户指定角色!");
+            }
+        }
+    }
+
+    /**
+     * 管理员个人信息修改
+     * @adminMenu(
+     *     'name'   => '个人信息',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> true,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '管理员个人信息修改',
+     *     'param'  => ''
+     * )
+     */
+    public function userInfo() {
+        $id = cmf_get_current_admin_id();
+        $user = (new UserModel())->where(["id" => $id])->find();
+        if (is_object($user)) {
+            $user = $user->toArray();
+        }
+        $this->assign($user);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 管理员个人信息修改提交
+     * @adminMenu(
+     *     'name'   => '管理员个人信息修改提交',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '管理员个人信息修改提交',
+     *     'param'  => ''
+     * )
+     */
+    public function userInfoPost() {
+        if ($this->request->isPost()) {
+            $data = $this->request->post();
+            $data['birthday'] = strtotime($data['birthday']);
+            $data['id'] = cmf_get_current_admin_id();
+            $create_result = (new UserModel())->update($data);;
+            if ($create_result !== false) {
+                $this->adminSuccess("保存成功!");
+            } else {
+                $this->adminError("保存失败!");
+            }
+        }
+    }
+
+    /**
+     * 管理员删除
+     * @adminMenu(
+     *     'name'   => '管理员删除',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '管理员删除',
+     *     'param'  => ''
+     * )
+     */
+    public function delete() {
+        $id = $this->request->param('id', 0, 'intval');
+        if ($id == 1) {
+            $this->adminError("最高管理员不能删除!");
+        }
+        $_user_model = new UserModel();
+        $_rs = $_user_model->where(["id" => $id])->delete();
+        if (false !== $_rs) {
+            (new RoleUserModel())->where(["user_id" => $id])->delete();
+            $this->adminSuccess("删除成功!");
+        } else {
+            $this->adminError("删除失败!");
+        }
+    }
+
+    /**
+     * 停用管理员
+     * @adminMenu(
+     *     'name'   => '停用管理员',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '停用管理员',
+     *     'param'  => ''
+     * )
+     */
+    public function ban() {
+        $id = $this->request->param('id', 0, 'intval');
+        if (!empty($id)) {
+            $_user_model = new UserModel();
+            $result = $_user_model->where(["id" => $id])->setField('user_status', $_user_model::USER_STATUS_BLOCKED);
+            if ($result !== false) {
+                $this->adminSuccess("管理员停用成功!", url("user/index"));
+            } else {
+                $this->adminError('管理员停用失败!');
+            }
+        } else {
+            $this->adminError('数据传入失败!');
+        }
+    }
+
+    /**
+     * 启用管理员
+     * @adminMenu(
+     *     'name'   => '启用管理员',
+     *     'parent' => 'index',
+     *     'display'=> false,
+     *     'hasView'=> false,
+     *     'order'  => 10000,
+     *     'icon'   => '',
+     *     'remark' => '启用管理员',
+     *     'param'  => ''
+     * )
+     */
+    public function cancelBan() {
+        $id = $this->request->param('id', 0, 'intval');
+        if (!empty($id)) {
+            $_user_model = new UserModel();
+            $result = $_user_model->where(["id" => $id])->setField('user_status', $_user_model::USER_STATUS_ACTIVATED);
+            if ($result !== false) {
+                $this->adminSuccess("管理员启用成功!", url("user/index"));
+            } else {
+                $this->adminError('管理员启用失败!');
+            }
+        } else {
+            $this->adminError('数据传入失败!');
+        }
+    }
+}

+ 83 - 0
admin/admin/controller/account/AccountController.php

@@ -0,0 +1,83 @@
+<?php
+/**
+ * AccountController.php  UTF-8
+ * 小号列表
+ *
+ * @date    : 2018/7/31 11:44
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\account;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\logic\member\MemListLogic;
+use huoAccountDeal\logic\MemGameLogic;
+use huolib\constant\AccountConst;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+
+class AccountController extends AdminBaseController {
+    /**
+     * 小号列表
+     * admin/account.account/index
+     */
+    public function index() {
+        $_param = $this->request->param();
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        /*用户名查找*/
+        $_username_input = Filter::text('username', get_val($_param, 'username', ''), '输入玩家账号查找...');
+        $this->assign('username_input', $_username_input);
+        /*昵称查找*/
+        $_nickname_input = Filter::text('nickname', get_val($_param, 'nickname', ''), '输入小号昵称查找...');
+        $this->assign('nickname_input', $_nickname_input);
+        /*状态选择器*/
+        $this->_Status(get_val($_param, 'status', 0));
+        /*游戏选择器*/
+        $_app_id = get_val($_param, 'app_id', 0);
+        $_status = GameConst::GAME_STATUS_ON;
+        $_is_delete = CommonConst::CONST_NOT_DELETE;
+        $_is_sdk = GameConst::GAME_IS_SDK;
+        $_classify = [GameConst::GAME_IOS, GameConst::GAME_IOS_SWITCH, GameConst::GAME_ANDROID];
+        $this->_games($_app_id, $_status, $_is_delete, $_is_sdk, $_classify);
+        /*时间选择器*/
+        $this->_time();
+        /*获取数据*/
+        $_data = (new MemGameLogic())->getAllAccountList($_param, $_page.','.$_list_rows);
+        $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch();
+    }
+
+    private function _Status($status) {
+        $_status = AccountConst::getAccountStatuss();
+        $_status_select = Filter::selectCommon($_status, 'status', $status);
+        $this->assign('status', $_status);
+        $this->assign('status_select', $_status_select);
+    }
+
+    /**
+     * 获取游戏角色
+     * admin/account.account/role
+     */
+    public function role() {
+        $_param = $this->request->param();
+        $_role_name_input = Filter::text('role_name', get_val($_param, 'role_name', ''), '请输入角色名');
+        $this->assign('role_name_input', $_role_name_input);
+        $this->_time();
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 10);
+        $_data = (new MemListLogic())->getRoleList($_param, $_page.','.$_list_rows);
+        $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch();
+    }
+}

+ 279 - 0
admin/admin/controller/account/GoodsController.php

@@ -0,0 +1,279 @@
+<?php
+/**
+ * GoodsController.php UTF-8
+ *
+ *
+ * @date    : 2018/6/14 19:33
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\account;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\member\Member;
+use huo\logic\message\MessageLogic;
+use huo\model\member\MemberModel;
+use huoAccountDeal\logic\AccountLogic;
+use huoAccountDeal\model\AccountGoodsModel;
+use huolib\constant\AccountConst;
+use huolib\constant\CommonConst;
+use huolib\tool\Encrypt;
+use huolib\tool\StrUtils;
+
+class GoodsController extends AdminBaseController {
+    public function index() {
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_status = $this->request->param('status/d', 0);
+        $_start_time = $this->request->param('start_time', '');
+        $_end_time = $this->request->param('end_time', '');
+        $this->_time();
+        $this->_goodsStatus($_status);
+        $_map = [];
+        !empty($_status) && $_map['status'] = $_status;
+        !empty($_start_time) && $_map['start_time'] = $_start_time;
+        !empty($_end_time) && $_map['end_time'] = $_end_time;
+        $_data = (new AccountLogic())->adminGoodsList($_map, $_page.','.$_list_rows);
+        $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch();
+    }
+
+    private function _goodsStatus($status) {
+        $_goods_status = AccountConst::getStatuss();
+        $_goods_status_select = Filter::selectCommon($_goods_status, 'status', $status);
+        $this->assign('goods_status', $_goods_status);
+        $this->assign('goods_status_select', $_goods_status_select);
+    }
+
+    /**
+     * 查看审核账号
+     *
+     * @return mixed
+     */
+    public function auditAccount() {
+        $_ags_id = $this->request->param('ags_id/d');
+        $_ags_info = $this->getAgsInfo($_ags_id);
+        //判断是否有生成审核账号
+        if (empty($_ags_info['check_mem_id']) || empty($_ags_info['check_pwd'])) {
+            $_member = new Member();
+            $_username = $_member->genUsername();
+            $_password = StrUtils::getRandChars(8);
+            //创建审核玩家账号
+            $_mem_data = [
+                'username' => $_username,
+                'nickname' => $_username,
+                'password' => $_password
+            ];
+            $_audit_mem_id = (new MemberModel())->addMem($_mem_data);
+            //保存审核信息
+            $_ags_data = [
+                'check_mem_id' => $_username,
+                'check_pwd'    => Encrypt::encrypt($_password),
+            ];
+            (new AccountGoodsModel())->updateData($_ags_data, $_ags_info['id']);
+            $_ags_info['check_mem_id'] = $_username;
+            $_ags_info['check_pwd'] = $_password;
+        } else {
+            $_ags_info['check_pwd'] = Encrypt::decrypt($_ags_info['check_pwd']);
+        }
+        $this->assign('ags_info', $_ags_info);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 审核页面
+     *
+     * @return mixed
+     */
+    public function audit() {
+        $_ags_id = $this->request->param('ags_id/d');
+        $_ags_info = $this->getAgsInfo($_ags_id);
+        $this->assign('ags_info', $_ags_info);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑页面
+     *
+     * @return mixed
+     */
+    public function edit() {
+        $_ags_id = $this->request->param('ags_id/d');
+        $_ags_info = $this->getAgsInfo($_ags_id);
+        $this->assign('ags_info', $_ags_info);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 审核
+     */
+    public function doAudit() {
+        $_param = $this->request->param();
+        $_check_rs = $this->validate($_param, 'Account.doAudit');
+        if (true !== $_check_rs) {
+            $this->adminError($_check_rs);
+        }
+        $_ags_id = $this->request->param('ags_id/d');
+        $_ags_info = $this->getAgsInfo($_ags_id);
+        if ($_ags_info['status'] != AccountConst::STATUS_AUDITING) {
+            $this->adminError('当前小号商品状态不能被审核');
+        }
+        if ($_ags_info['is_delete'] == CommonConst::CONST_DELETED) {
+            $this->adminError('当前小号商品已被删除,不能被审核');
+        }
+        $_result = $this->request->param('result/d');
+        $_reason = $this->request->param('reason');
+        if ($_result == 2) {
+            //审核通过,上架商品
+            $_data = [
+                'status' => AccountConst::STATUS_PULL_ON_SHELVES,
+                'reason' => $_reason,
+            ];
+            $_rs = (new AccountGoodsModel())->updateData($_data, $_ags_info['id']);
+        } else {
+            //审核不通过,解除小号锁定状态
+            (new AccountLogic())->unlock($_ags_info['mg_mem_id']);
+            //发送系统消息
+            $_title = '小号商品审核不通过';
+            $_content = '小号商品审核不通过。原因: '.$_reason;
+            (new MessageLogic())->addMessage($_ags_info['mem_id'], $_title, $_content);
+            $_data = [
+                'status' => AccountConst::STATUS_AUDIT_NOT_PASSED,
+                'reason' => $_reason,
+            ];
+            $_rs = (new AccountGoodsModel())->updateData($_data, $_ags_info['id']);
+        }
+        if ($_rs) {
+            $this->adminSuccess('操作成功');
+        } else {
+            $this->adminError('操作失败');
+        }
+    }
+
+    /**
+     * 编辑
+     */
+    public function doEdit() {
+        $_param = $this->request->param();
+        $_check_rs = $this->validate($_param, 'Account.doEdit');
+        if (true !== $_check_rs) {
+            $this->adminError($_check_rs);
+        }
+        $_ags_id = $this->request->param('ags_id/d');
+        $_ags_info = $this->getAgsInfo($_ags_id);
+        if ($_ags_info['status'] != AccountConst::STATUS_AUDITING) {
+            $this->adminError('当前小号商品状态不能被修改');
+        }
+        if ($_ags_info['is_delete'] == CommonConst::CONST_DELETED) {
+            $this->adminError('当前小号商品已被删除,不能被修改');
+        }
+        $_data = [];
+        !empty($_param['title']) && $_data['title'] = $_param['title'];
+        !empty($_param['description']) && $_data['description'] = $_param['description'];
+        !empty($_param['price']) && $_data['price'] = $_param['price'];
+        $_rs = (new AccountGoodsModel())->updateData($_data, $_ags_id);
+        if ($_rs) {
+            $this->adminSuccess('操作成功');
+        } else {
+            $this->adminError('操作失败');
+        }
+    }
+
+    /**
+     * 删除
+     */
+    public function delete() {
+        $_ags_id = $this->request->param('ags_id/d');
+        $_ags_info = $this->getAgsInfo($_ags_id);
+        //删除商品,并下架处理
+        $_data = [
+            'is_delete'   => CommonConst::CONST_DELETED,
+            'delete_time' => time(),
+        ];
+        $_rs = (new AccountGoodsModel())->updateData($_data, $_ags_info['id']);
+        if ($_rs) {
+            $this->adminSuccess('操作成功');
+        } else {
+            $this->adminError('操作失败');
+        }
+    }
+
+    /**
+     * 下架
+     */
+    public function pullOff() {
+        $_ags_id = $this->request->param('ags_id/d');
+        $this->getAgsInfo($_ags_id);
+        $_rs = $this->updateStatus($_ags_id, AccountConst::STATUS_PULL_OFF_SHELVES);
+        if ($_rs) {
+            $this->adminSuccess('操作成功');
+        } else {
+            $this->adminError('操作失败');
+        }
+    }
+
+    /**
+     * 上架
+     */
+    public function pullOn() {
+        $_ags_id = $this->request->param('ags_id/d');
+        $this->getAgsInfo($_ags_id);
+        //上架处理
+        $_rs = $this->updateStatus($_ags_id, AccountConst::STATUS_PULL_ON_SHELVES);
+        if ($_rs) {
+            $this->adminSuccess('操作成功');
+        } else {
+            $this->adminError('操作失败');
+        }
+    }
+
+    private function updateStatus($ags_id, $status) {
+        return (new AccountGoodsModel())->updateData(['status' => $status], $ags_id);
+    }
+
+    private function getAgsInfo($ags_id) {
+        $_ags_info = (new AccountLogic())->getInfoById($ags_id);
+        if (empty($_ags_info)) {
+            $this->adminError('非法操作');
+        }
+
+        return $_ags_info;
+    }
+
+    /**
+     * 收藏列表
+     *admin/account.goods/collection
+     */
+    public function collection() {
+        $_param = $this->request->param();
+        $this->getAgsInfo(get_val($_param, 'ags_id', 0));
+        $this->_amlStatus(get_val($_param, 'status', 0));
+        $this->_time();
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_data = (new AccountLogic())->getAmlList($_param, $_page.','.$_list_rows);
+        $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+        $this->assign('ags_id', get_val($_param, 'ags_id', 0));
+
+        return $this->fetch();
+    }
+
+    private function _amlStatus($status) {
+        $_aml_status = AccountConst::getAmlStatuss();
+        $_aml_status_select = Filter::selectCommon($_aml_status, 'status', $status);
+        $this->assign('aml_status', $_aml_status);
+        $this->assign('aml_status_select', $_aml_status_select);
+    }
+}

+ 72 - 0
admin/admin/controller/account/OrderController.php

@@ -0,0 +1,72 @@
+<?php
+/**
+ * OrderController.php UTF-8
+ *
+ *
+ * @date    : 2018/6/15 15:15
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\account;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huoAccountDeal\logic\AccountOrderLogic;
+use huoAccountDeal\model\AccountOrderModel;
+
+class OrderController extends AdminBaseController {
+
+    public function index(){
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_start_time = $this->request->param('start_time', '');
+        $_end_time = $this->request->param('end_time', '');
+        $_status = $this->request->param('status/d',0);
+        $_order_id = $this->request->param('order_id/s','');
+        $_title = $this->request->param('title/s','');
+        $_sell_mem = $this->request->param('sell_mem/s','');
+        $_buy_mem = $this->request->param('buy_mem/s','');
+
+        $this->_time();
+        $this->_pay_statuses($_status);
+        $_order_input = Filter::text('order_id', $_order_id);
+        $_title_input = Filter::text('title', $_title);
+        $_sell_mem_input = Filter::text('sell_mem', $_sell_mem);
+        $_buy_mem_input = Filter::text('buy_mem', $_buy_mem);
+
+        $_map = [];
+        !empty($_start_time) && $_map['start_time'] = $_start_time;
+        !empty($_end_time) && $_map['end_time'] = $_end_time;
+        !empty($_status) && $_map['status'] = $_status;
+        !empty($_order_id) && $_map['order_id'] = $_order_id;
+        !empty($_title) && $_map['title'] = $_title;
+        !empty($_sell_mem) && $_map['sell_mem'] = $_sell_mem;
+        !empty($_buy_mem) && $_map['buy_mem'] = $_buy_mem;
+
+        $_data = (new AccountOrderLogic())->adminOrderList($_map, $_page.','.$_list_rows);
+        $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+
+        $this->assign('order_input', $_order_input);
+        $this->assign('title_input', $_title_input);
+        $this->assign('sell_mem_input', $_sell_mem_input);
+        $this->assign('buy_mem_input', $_buy_mem_input);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+        return $this->fetch();
+    }
+
+    public function detail() {
+        $_id = $this->request->param('id/d');
+        $_order_info = (new AccountOrderModel())->with('mg,game,goods,seller,buyer')->find($_id);
+        if (empty($_order_info)) {
+            $this->adminError('无效的订单');
+        }
+
+        $this->_pay_statuses(0);
+        $this->_payways(0);
+        $this->assign('info', $_order_info);
+        return $this->fetch();
+    }
+}

+ 64 - 0
admin/admin/controller/account/WapController.php

@@ -0,0 +1,64 @@
+<?php
+/**
+ * WapController.php  UTF-8
+ * 小号交易wap页面
+ *
+ * @date    : 2018/7/31 11:32
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\account;
+
+use cmf\controller\AdminBaseController;
+use huo\logic\posts\PostsLogic;
+use huo\model\posts\PostsModel;
+use huolib\constant\NewsConst;
+use think\Validate;
+
+class WapController extends AdminBaseController {
+    /**
+     * 交易须知
+     * /admin/app.rebate/guide
+     */
+    public function index() {
+        $_data = (new PostsLogic())->getDetail(NewsConst::NEWS_ID_ACCOUNT_DEAL);
+        $this->assign($_data);
+
+        return $this->fetch('richText');
+    }
+
+    /**
+     * 文章内容提交
+     * /admin/app.rebate/saveProtocol
+     */
+    public function saveProtocol() {
+        $_data = $this->request->param();
+        $validate = new Validate(
+            [
+                'post_title'   => 'require',
+                'post_content' => 'require',
+            ]
+        );
+        if (!$validate->check($_data)) {
+            $this->adminError($validate->getError());
+        }
+        $_where = [];
+        if (!empty($_data['id'])) {
+            $_where = ['id' => $_data['id']];
+            unset($_data['id']);
+        }
+        $_data['user_id'] = cmf_get_current_admin_id();
+        $_data['post_type'] = NewsConst::NEWS_TYPE_OTHER;
+        $_data['post_status'] = NewsConst::NEWS_PUBLISHED;
+        $_data['comment_status'] = NewsConst::NEWS_COMMENT_STATUS_NOT_ALLOW;
+        $_data['published_time'] = date('Y-m-d H:i:s');
+        $_protocol = new PostsModel();
+        if (false === $_protocol->save($_data, $_where)) {
+            $this->adminError(lang('ERROR'));
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+}

+ 125 - 0
admin/admin/controller/activity/IntegralActivityController.php

@@ -0,0 +1,125 @@
+<?php
+/**
+ * IntegralActivityController.php  UTF-8
+ * 积分活动管理
+ *
+ * @date    : 2018/5/18 20:41
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\activity;
+
+use admin\admin\validate\IntegralActivityValidate;
+use cmf\controller\AdminBaseController;
+use huo\controller\integral\IaCache;
+use huo\controller\sign\Sign;
+use huo\model\integral\IntegralActivityModel;
+use huo\model\sign\SignRewordModel;
+use think\Lang;
+
+class IntegralActivityController extends AdminBaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load([APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_activity'.EXT,]);
+        parent::_initialize();
+    }
+
+    /**
+     *  活动列表页
+     */
+    public function index() {
+        $_ia_list = (new IntegralActivityModel())->getIas();
+        $this->assign('data', $_ia_list);
+
+        return $this->fetch();
+    }
+
+    /***
+     *  活动编辑页
+     */
+    public function edit() {
+        $_id = $this->request->param('id/d');
+        $_ias = (new IntegralActivityModel())->getIas();
+        $_ia = $_ias[$_id];
+        if ('sign' === $_ia['ia_code']) {
+            $_sign_conf = (new SignRewordModel())->getConf();
+            $this->assign('sign_conf', $_sign_conf);
+        }
+        if (empty($_ia['ia_code'])) {
+            $this->adminError(lang('activity_not_find'));
+        }
+        $this->assign('data', $_ia);
+        if ('sign' === $_ia['ia_code']) {
+            return $this->fetch('sign_edit');
+        }
+
+        return $this->fetch('edit');
+    }
+
+    /***
+     *  活动编辑提交页
+     */
+    public function editPost() {
+        $_params = $this->request->post();
+        $validate = new IntegralActivityValidate();
+        if (!$validate->scene($_params['ia_code'])->check($_params)) {
+            $this->adminError($validate->getError());
+        }
+        unset($_params['__token__']);
+        $_params['start_time'] = isset($_params['start_time']) ? strtotime($_params['start_time']) : 0;
+        $_params['end_time'] = isset($_params['end_time']) ? strtotime($_params['end_time']) : 0;
+        $_res = (new IaCache())->updateIa($_params['id'], $_params);
+        if (false === $_res) {
+            $this->adminError(lang('update failure'));
+        }
+        $this->adminSuccess(lang('update success'), url('admin/activity.integralActivity/index'));
+    }
+
+    public function sign() {
+        $_id = 1;
+        $_ia = (new IaCache())->getIa($_id);
+        $_sign_conf = (new SignRewordModel())->getConf();
+        $this->assign('sign_conf', $_sign_conf);
+        $this->assign('data', $_ia);
+
+        return $this->fetch('sign_edit');
+    }
+
+    /**
+     *  签到奖励配置
+     */
+    public function editSignConf() {
+        $_act_id = $this->request->param('act_id/d');
+        $_id = $this->request->param('id/d');
+        $_new_integral = $this->request->param('new_integral/d');
+        $_new_name = $this->request->param('new_name/s');
+        $sc_data = array(
+            'integral' => $_new_integral,
+            'name'     => $_new_name,
+        );
+        $_res = (new sign())->updateSignConf($_id, $sc_data);
+        if (false === $_res) {
+            $this->error(lang('update failure'));
+        }
+        $this->success(
+            lang('update success'), '', 1, [], url('admin/activity.integral_activity/edit', ['id' => $_act_id])
+        );
+    }
+
+    /**
+     * 排序
+     */
+    public function listOrder() {
+        $ids = $this->request->post("list_order/a");
+        if (!empty($ids)) {
+            foreach ($ids as $key => $r) {
+                $_data = array('list_order' => $r);
+                (new IaCache())->updateIa($key, $_data);
+            }
+        }
+        $this->adminSuccess(lang('list_order_success'), url('admin/activity.integral_activity/index'));
+    }
+}

+ 254 - 0
admin/admin/controller/agent/AgentController.php

@@ -0,0 +1,254 @@
+<?php
+/**
+ * AgentController.php UTF-8
+ * 渠道控制器
+ *
+ * @date    : 2018/2/7 11:25
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : linjiebin <ljb@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\agent;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\agent\Agent;
+use huo\controller\agent\AgentCache;
+use huo\logic\agent\AgentListLogic;
+use huo\model\user\RoleModel;
+use huo\model\user\UserModel;
+use huolib\constant\AgentConst;
+use huolib\constant\MemConst;
+use huolib\status\CommonStatus;
+use think\Lang;
+
+class AgentController extends AdminbaseController {
+    protected $from_device     = ''; //有值则必为 mp 表示小游戏
+    protected $agent_role_type = [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT];
+    protected $role_id         = 0;
+
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_agent'.EXT);
+        parent::_initialize();
+    }
+
+    /**
+     * 渠道列表
+     *
+     * @return mixed
+     */
+    public function index() {
+        /* 搜索列表 */
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        $this->_agents($_param['agent_id'], false, $this->agent_role_type, true);
+        $_roles = (new RoleModel())->getIdNames([], true);
+        $this->assign('roles', $_roles);
+        $_param['role_type'] = $this->request->param('role_type/d', 0);
+        $_role_data = [
+            AgentConst::ROLE_TYPE_GROUP => '一级渠道',
+            AgentConst::ROLE_TYPE_AGENT => '二级渠道'
+        ];
+        $_role_type_select = Filter::selectCommon($_role_data, 'role_type', $_param['role_type']);
+        $this->assign('role_type_select', $_role_type_select);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_data = (new AgentListLogic())->getAgentList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch();
+    }
+
+    /**
+     * 渠道详情
+     *
+     * @return mixed
+     */
+    public function detail() {
+        $_param = $this->request->param();
+        if (!isset($_param['id']) || empty($_param['id'])) {
+            $this->adminError(lang('param error'));
+        }
+        $_agent_data = AgentCache::ins()->getInfoByAgentId($_param['id']);
+        if (empty($_agent_data)) {
+            $this->adminError(lang('param error'));
+        }
+        $_user_model = new UserModel();
+        $_agent_data['status_text'] = $_user_model->getStatusTextAttr($_agent_data['user_status']);
+        $_agent_data['parent_name'] = $_user_model->getNameById($_agent_data['parent_id']);
+        $_roles = (new RoleModel())->getIdNames([], true);
+        $this->assign('roles', $_roles);
+        $this->assign('data', $_agent_data);
+        $_login_records = [];
+        $_login_page = [];
+        $this->assign('login_records', $_login_records);
+        $this->assign('login_page', $_login_page);
+        if (MemConst::FROM_DEVICE_MP == $this->from_device) {
+            return $this->fetch('box/agent/detail');
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑渠道
+     * admin/agent.agent/editPost
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            if (isset($_param['user_id']) && !empty($_param['user_id'])) {
+                $_agent_id = $_param['user_id'];
+            } else {
+                return $this->adminError(lang('param error'));
+            }
+            if (isset($_param['name']) && !empty($_param['name'])) {
+                $_name = $_param['name'];
+            } else {
+                return $this->adminError(lang('param error'));
+            }
+            if (isset($_param['value'])) {
+                $_value = $_param['value'];
+            } else {
+                return $this->adminError(lang('param error'));
+            }
+            $_ac_class = AgentCache::ins();
+            $_agent_data = $_ac_class->getInfoByAgentId($_agent_id);
+            switch ($_name) {
+                case 'user_pass':
+                    $_agent_data['user_pass'] = $_value;
+                    break;
+                case 'mobile':
+                    $_agent_data['mobile'] = $_value;
+                    break;
+                case 'user_nicename':
+                    $_agent_data['user_nicename'] = $_value;
+                    break;
+                case 'pay_pwd':
+                    $_agent_data['pay_pwd'] = $_value;
+                    break;
+                case 'status':
+                    $_agent_data['user_status'] = $_value;
+                    break;
+                default :
+                    break;
+            }
+            $_rs = $_ac_class->updateAgent($_agent_id, $_agent_data);
+            if (true == $_rs) {
+                return $this->adminSuccess('编辑成功');
+            } else {
+                return $this->adminError(lang('param error'));
+            }
+        } else {
+            return $this->adminError(lang('param error'));
+        }
+    }
+
+    /**
+     * 冻结渠道账户
+     */
+    public function freeze() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            if (isset($_param['id']) && !empty($_param['id'])) {
+                $_agent_id = $_param['id'];
+            } else {
+                return $this->adminError(lang('param error'));
+            }
+            $_ac_class = AgentCache::ins();
+            $_agent_data = $_ac_class->getInfoByAgentId($_agent_id);
+            $_agent_data['user_status'] = MemConst::STATUS_FORBID;
+            $_rs = $_ac_class->updateAgent($_agent_id, $_agent_data);
+            if (true == $_rs) {
+                return $this->adminSuccess('冻结成功');
+            } else {
+                return $this->adminError(lang('param error'));
+            }
+        } else {
+            return $this->adminError(lang('param error'));
+        }
+    }
+
+    /**
+     * 解冻渠道账户
+     * admin/agent.agent/thaw
+     */
+    public function thaw() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            if (isset($_param['id']) && !empty($_param['id'])) {
+                $_agent_id = $_param['id'];
+            } else {
+                return $this->adminError(lang('param error'));
+            }
+            $_ac_class = AgentCache::ins();
+            $_agent_data = $_ac_class->getInfoByAgentId($_agent_id);
+            $_agent_data['user_status'] = MemConst::STATUS_NORMAL;
+            $_rs = $_ac_class->updateAgent($_agent_id, $_agent_data);
+            if (true == $_rs) {
+                return $this->adminSuccess('解冻成功');
+            } else {
+                return $this->adminError(lang('param error'));
+            }
+        } else {
+            return $this->adminError(lang('param error'));
+        }
+    }
+
+    /**
+     * 添加渠道
+     * admin/agent.agent/add
+     *
+     * @return mixed
+     */
+    public function add() {
+        $_parent_channel_type_select = Filter::selectCommon(
+            (new RoleModel())->where(['role_type' => AgentConst::ROLE_TYPE_GROUP])->column('id,name'), 'role_id', 0
+        );
+        $_ch_channel_type_select = Filter::selectCommon(
+            (new RoleModel())->where(['role_type' => AgentConst::ROLE_TYPE_AGENT])->column('id,name'), 'role_id', 0
+        );
+        $_role_level_select = Filter::selectCommon(
+            [AgentConst::ROLE_TYPE_GROUP => lang('Level_1_channel'),
+             AgentConst::ROLE_TYPE_AGENT => lang('Level_2_channel')], 'role_type', 0
+        );
+        $this->_agents(0, false, [AgentConst::ROLE_TYPE_GROUP], true);
+        $this->assign('parent_channel_type_select', $_parent_channel_type_select);
+        $this->assign('ch_channel_type_select', $_ch_channel_type_select);
+        $this->assign('role_level_select', $_role_level_select);
+        if (MemConst::FROM_DEVICE_MP == $this->from_device) {
+            return $this->fetch('box/agent/add');
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加渠道操作
+     * admin/agent.agent/addPost
+     *
+     */
+    public function addPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $_user_login = $_param['user_login'];
+            $_user_nicename = $_param['user_nicename'];
+            $_user_pass = $_param['user_pass'];
+            $_role_id = !empty($_param['role_id']) ? $_param['role_id'] : AgentConst::AGENT_ROLE_CPS;
+            $_parent_id = !empty($_param['parent_id']) ? $_param['parent_id'] : 1;
+            $_rs = (new Agent())->addAgent($_user_login, $_user_nicename, $_user_pass, $_parent_id, $_role_id);
+            if (CommonStatus::NO_ERROR == $_rs['code']) {
+                $this->adminSuccess(lang('add').lang('success'));
+            } else {
+                $this->adminError($_rs['msg']);
+            }
+        } else {
+            return $this->adminError(lang('param error'));
+        }
+    }
+}
+

+ 178 - 0
admin/admin/controller/agent/AgentGameController.php

@@ -0,0 +1,178 @@
+<?php
+/**
+ * AgentGameController.php UTF-8
+ * 渠道游戏管理
+ *
+ * @date    : 2018/5/19 14:44
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : linjiebin <ljb@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\agent;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\agent\Agent;
+use huo\controller\agent\AgentCache;
+use huo\controller\agent\AgentGame;
+use huo\controller\game\GameCache;
+use huo\controller\rate\RateCache;
+use huo\logic\agent\AgentGameLogic;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\status\CommonStatus;
+use huolib\status\RateStatus;
+use think\Lang;
+
+class AgentGameController extends AdminbaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load([APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_agentgame'.EXT,]);
+        parent::_initialize();
+    }
+
+    /**
+     * 渠道游戏管理
+     * admin/agent.agentgame/index
+     *
+     * @return mixed
+     */
+    public function index() {
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        $this->_agents($_param['agent_id'], false, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true);
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $this->_games(
+            $_param['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK
+        );
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_param['role_id'] = $this->request->param('role_id/d', 0);
+        $this->_roles($_param['role_id']);
+        $_param['status'] = $this->request->param('promote_switch/d', 0);
+        $this->_promotes($_param['status']);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_ag_logic = new AgentGameLogic();
+        $_data = $_ag_logic->getAgentGames($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('agent/agent_game/index');
+    }
+
+    /**
+     * 设置渠道页面
+     *
+     * @return mixed
+     */
+    public function edit() {
+        $_ag_id = $this->request->param('ag_id/d', 0);
+        if (empty($_ag_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+            $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_ac_class = new AgentCache();
+        $_ag_data = $_ac_class->getAgInfoByAgId($_ag_id);
+        $_app_id = $_ac_class->getAppIdByAgId($_ag_id);
+        $_agent_id = $_ac_class->getAgentIdByAgId($_ag_id);
+        $_rc_class = RateCache::ins();
+        $_game_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $_rate_data = $_rc_class->getInfoByAppIdAgentId($_app_id, $_agent_id);
+        $_gr_data = $_rc_class->getInfoByAppId($_app_id);
+        $_agent_data = $_ac_class->getInfoByAgentId($_agent_id);
+        $this->assign('ag_data', $_ag_data);
+        $this->assign('gr_data', $_gr_data);
+        $this->assign('agent', $_agent_data);
+        $this->assign('ag_id', $_ag_id);
+        $this->assign('game', $_game_data);
+        $this->assign('rate', $_rate_data);
+        $_role_type = (new Agent())->getRoleType($_agent_id);
+        if (AgentConst::ROLE_TYPE_GROUP == $_role_type) {
+            return $this->fetch('agent/agent_game/edit');
+        } elseif (AgentConst::ROLE_TYPE_AGENT == $_role_type) {
+            /*二级渠道获取父渠道折扣*/
+            $_prate_data = $_rc_class->getInfoByAppIdAgentId($_app_id, $_agent_data['parent_id']);
+            if (empty($_prate_data)) {  //空则取游戏设置
+                $_prate_data = $_gr_data;
+            }
+            $this->assign('prate', $_prate_data);
+
+            return $this->fetch('agent/agent_game/editsub');
+        } else {
+            $_code = CommonStatus::INVALID_PARAMS;
+
+            return $this->adminError(CommonStatus::getMsg($_code));
+        }
+    }
+
+    /**
+     * 设置渠道点位
+     * admin/agent.AgentGame/editPost
+     *
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            if (GameConst::GAME_H5 == $_param['classify']) {  //h5游戏设置一级代充和二级代充折扣玩家续充折扣的值,用于过检测
+                $_param['agent_rate'] = $_param['mem_rate'];
+                $_param['sub_agent_rate'] = $_param['mem_rate'];
+            }
+            $_rs = $this->validate($_param, 'Rate.agedit');
+            if (true !== $_rs) {
+                $this->adminError($_rs);
+            }
+            $_ag_id = $_param['ag_id'];
+            $_data['agent_rebate'] = $_param['agent_rebate'];
+            $_data['agent_rate'] = $_param['agent_rate'];
+            if (isset($_param['sub_agent_rebate'])) {
+                $_data['sub_agent_rebate'] = $_param['sub_agent_rebate'];
+            }
+            if (isset($_param['sub_agent_rate'])) {
+                $_data['sub_agent_rate'] = $_param['sub_agent_rate'];
+            }
+            if (isset($_param['first_mem_rate'])) {
+                $_data['first_mem_rate'] = $_param['first_mem_rate'];
+            }
+            if (isset($_param['mem_rate'])) {
+                $_data['mem_rate'] = $_param['mem_rate'];
+            }
+            $_gr_class = new AgentGame();
+            $_rs = $_gr_class->setGameRate($_ag_id, $_data);
+            if (RateStatus::NO_ERROR != $_rs['code']) {
+                $this->adminError($_rs['msg']);
+            }
+            $this->adminSuccess($_rs['msg']);
+        } else {
+            $this->adminError('请求类型错误');
+        }
+    }
+
+    /**
+     * admin/agent.AgentGame/setStatus
+     * ag_id
+     * status
+     */
+    public function setStatus() {
+        $_ag_id = $this->request->param('ag_id/d', 0);
+        $_status = $this->request->param('status/d', 0);
+        if (empty($_ag_id) || empty($_status)) {
+            $this->adminError(lang('param error'));
+        }
+        $_ac_class = AgentCache::ins();
+        $_ag_data = $_ac_class->getAgInfoByAgId($_ag_id);
+        if (empty($_ag_data)) {
+            $this->adminError(lang('param error'));
+        }
+        $_ag_data['status'] = $_status;
+        $_rs = $_ac_class->updateAg($_ag_id, $_ag_data);
+        if (true == $_rs) {
+            $this->adminSuccess('状态修改成功');
+        } else {
+            $this->adminError('状态修改失败');
+        }
+    }
+}

+ 108 - 0
admin/admin/controller/agent/BaseController.php

@@ -0,0 +1,108 @@
+<?php
+/**
+ * BaseController.php  UTF-8
+ * 渠道站点基本配置
+ *
+ * @date    : 2018/5/22 11:19
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\agent;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\wap\Option;
+use think\Lang;
+
+class BaseController extends AdminBaseController {
+    public function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load([APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_setting'.EXT,]);
+        parent::_initialize();
+    }
+
+    private function settingPost($setting_name) {
+        $_m = new Option();
+        $_setting_name = $setting_name;
+        $_option_vale = $this->request->param();
+        $_res = $_m->saveOptionData($_setting_name, json_encode($_option_vale));
+        if (!$_res) {
+            $this->adminError(lang('ERROR'));
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 通用设置
+     */
+    public function index() {
+        $_setting_name = 'agent_basic';
+        $_m = new Option();
+        $_option_vale = [
+            'title'                   => '',
+            'culture_management'      => '',
+            'record_number'           => '',
+            'describe'                => '',
+            'static_status'           => '',
+            'static_valid_time'       => '',
+            'copyright'               => '',
+            'company_name'            => '',
+            'company_address'         => ''
+        ];
+        $_item = $_m->getOptionData($_setting_name, 1, true, json_encode($_option_vale));
+        if (!empty($_item['option_value'])) {
+            $_item['option_value'] = json_decode($_item['option_value'], true);
+        }
+        $this->assign($_item);
+
+        return $this->fetch();
+    }
+
+    public function basic_post() {
+        $setting_name = 'agent_basic';
+        $this->settingPost($setting_name);
+    }
+
+    public function icon() {
+        $_setting_name = 'agent_icon';
+        $_m = new Option();
+        $_option_vale = [
+            'agent_logo' => '',
+            'agent_ico'  => '',
+        ];
+        $_item = $_m->getOptionData($_setting_name, 1, true, json_encode($_option_vale));
+        if (!empty($_item['option_value'])) {
+            $_item['option_value'] = json_decode($_item['option_value'], true);
+        }
+        $this->assign($_item);
+
+        return $this->fetch();
+    }
+
+    public function icon_post() {
+        $setting_name = 'agent_icon';
+        $this->settingPost($setting_name);
+    }
+
+    public function content() {
+        $_setting_name = 'agent_content';
+        $_m = new Option();
+        $_option_vale = [
+            'service_qq'        => '',
+        ];
+        $_item = $_m->getOptionData($_setting_name, 1, true, json_encode($_option_vale));
+        if (!empty($_item['option_value'])) {
+            $_item['option_value'] = json_decode($_item['option_value'], true);
+        }
+        $this->assign($_item);
+
+        return $this->fetch();
+    }
+
+    public function content_post() {
+        $setting_name = 'agent_content';
+        $this->settingPost($setting_name);
+    }
+}

+ 112 - 0
admin/admin/controller/agent/GameController.php

@@ -0,0 +1,112 @@
+<?php
+/**
+ * GameController.php  UTF-8
+ * 推广游戏管理
+ *
+ * @date    : 2018/5/17 9:54
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\agent;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\game\GameCache;
+use huo\controller\rate\GameRate;
+use huo\controller\rate\RateCache;
+use huo\logic\game\GamRateLogic;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\status\CommonStatus;
+use huolib\status\RateStatus;
+use think\Lang;
+
+class GameController extends AdminbaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_agent'.EXT);
+        parent::_initialize();
+    }
+
+    /**
+     * 推广游戏列表
+     * admin/agent.game/index
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function index() {
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $this->_games(
+            $_param['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK
+        );
+        $_game_model = new GamRateLogic();
+        /*过滤 H5平台只看到H5游戏*/
+        //$_param['classify'] = GameConst::GAME_H5;
+        $_obj = $_game_model->getAgentGameList($_param);
+        $this->assign('page', $_obj->render());
+        $this->assign('items', $_obj);
+
+        return $this->fetch('agent/game/index');
+    }
+
+    /**
+     * 推广游戏列表
+     * admin/agent.game/edit
+     *
+     * @return mixed
+     */
+    public function edit() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+            $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_game_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $_rate_data = RateCache::ins()->getInfoByAppId($_app_id);
+        $this->assign('app_id', $_app_id);
+        $this->assign('game', $_game_data);
+        $this->assign('rate', $_rate_data);
+
+        return $this->fetch('agent/game/edit');
+    }
+
+    /**
+     * 游戏折扣编辑
+     * admin/agent.game/editPost
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            if (GameConst::GAME_H5 == $_param['classify']) {  //h5游戏设置一级代充和二级代充折扣玩家续充折扣的值,用于过检测
+                $_param['agent_rate'] = $_param['mem_rate'];
+                $_param['sub_agent_rate'] = $_param['mem_rate'];
+            }
+            $_rs = $this->validate($_param, 'Rate.gameedit');
+            if (true !== $_rs) {
+                $this->adminError($_rs);
+            }
+            $_app_id = $_param['app_id'];
+            $_promote_switch = $_param['promote_switch'];
+            $_data['agent_rebate'] = $_param['agent_rebate'];
+            $_data['agent_rate'] = $_param['agent_rate'];
+            $_data['sub_agent_rebate'] = $_param['sub_agent_rebate'];
+            $_data['sub_agent_rate'] = $_param['sub_agent_rate'];
+            $_data['benefit_type'] = $_param['benefit_type'];
+            $_data['first_mem_rate'] = $_param['first_mem_rate'];
+            $_data['mem_rate'] = $_param['mem_rate'];
+            $_data['first_mem_rebate'] = $_param['first_mem_rebate'];
+            $_data['mem_rebate'] = $_param['mem_rebate'];
+            $_gr_class = new GameRate();
+            $_rs = $_gr_class->setGameRate($_app_id, $_promote_switch, $_data);
+            if (RateStatus::NO_ERROR != $_rs['code']) {
+                $this->adminError($_rs['msg']);
+            }
+            $this->adminSuccess($_rs['msg']);
+        } else {
+            $this->adminError('请求类型错误');
+        }
+    }
+}

+ 54 - 0
admin/admin/controller/agent/NoticeController.php

@@ -0,0 +1,54 @@
+<?php
+/**
+ * NoticeController.php  UTF-8
+ * WWW
+ *
+ * @date    : 2018/5/22 14:41
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\agent;
+use cmf\controller\ArticleBaseController;
+use huolib\constant\NewsConst;
+use think\Lang;
+
+class NoticeController extends ArticleBaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_news'.EXT);
+    }
+
+    public function index() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_AGENTNOTICE;
+        ArticleBaseController::index();
+        return $this->fetch();
+    }
+
+    public function add() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_AGENTNOTICE;
+        ArticleBaseController::add();
+        return $this->fetch();
+    }
+
+
+    public function addPost() {
+        ArticleBaseController::addPost();
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/agent.notice/index'));
+    }
+
+
+    public function edit() {
+        $this->id = $this->request->param('id', 0, 'intval');
+        ArticleBaseController::edit();
+        return $this->fetch();
+    }
+
+
+    public function editPost() {
+        ArticleBaseController::editPost();
+        $this->adminSuccess(lang('EDIT_SUCCESS'), url('admin/agent.notice/index'));
+    }
+}

+ 58 - 0
admin/admin/controller/agent/SeoController.php

@@ -0,0 +1,58 @@
+<?php
+/**
+ * SeoController.php  UTF-8
+ * 渠道seo
+ *
+ * @date    : 2018/5/22 14:19
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\agent;
+use cmf\controller\AdminBaseController;
+use huo\controller\wap\Option;
+use think\Lang;
+
+class SeoController extends AdminbaseController {
+    private $option_value;
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_seo'.EXT);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+        $this->option_value = [
+            'title'       => '',
+            'keyword'     => '',
+            'description' => '',
+        ];
+    }
+
+    private function settingPost($setting_name) {
+        $_m = new Option();
+        $_setting_name = $setting_name;
+        $_option_vale = $this->request->param();
+        $_res = $_m->saveOptionData($_setting_name, json_encode($_option_vale));
+        if (!$_res) {
+            $this->adminError(lang('ERROR'));
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    public function index($setting_name = 'agent_index_seo') {
+        $_m = new Option();
+        $_item = $_m->getOptionData($setting_name, 1, true, json_encode($this->option_value));
+        if (!empty($_item['option_value'])) {
+            $_item['option_value'] = json_decode($_item['option_value'], true);
+        }
+        $this->assign($_item);
+        $this->assign('setting_name',$setting_name);
+
+        return $this->fetch();
+    }
+
+    public function set_post($setting_name = 'agent_index_seo') {
+        $this->settingPost($setting_name);
+    }
+
+}

+ 60 - 0
admin/admin/controller/agent/SlideController.php

@@ -0,0 +1,60 @@
+<?php
+/**
+ * SlideController.php  UTF-8
+ * WWW
+ *
+ * @date    : 2018/5/22 11:42
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\agent;
+
+use admin\admin\controller\slide\SlideitemController;
+use huolib\constant\GameConst;
+use huolib\constant\SlideConst;
+
+class SlideController  extends SlideitemController {
+
+
+    public function _initialize() {
+        parent::_initialize();
+    }
+
+    public function index($device = SlideConst::SLIDE_DEVICE_AGENT, $classify = GameConst::GAME_H5) {
+        parent::index($device, $classify);
+
+        return $this->fetch();
+    }
+
+    public function add($device = SlideConst::SLIDE_DEVICE_AGENT, $classify = GameConst::GAME_H5) {
+        parent::add($device, $classify);
+        return $this->fetch();
+    }
+
+    public function addPost() {
+        if (parent::addPost()) {
+            $this->adminSuccess(lang('ADD').' '.lang('SUCCESS'),url("admin/agent.slide/index"));
+        }
+    }
+
+    public function edit($device = SlideConst::SLIDE_DEVICE_AGENT, $classify = GameConst::GAME_H5) {
+        parent::edit($device, $classify);
+        return $this->fetch();
+    }
+
+    public function editPost() {
+        parent::editPost();
+        $this->adminSuccess(lang('EDIT').' '.lang('SUCCESS'),url("admin/agent.slide/index"));
+    }
+
+    public function delete() {
+        if (parent::delete()) {
+            $this->adminSuccess(
+                lang('SUCCESS'), url("admin/agent.slide/index")
+            );
+        }
+    }
+}

+ 74 - 0
admin/admin/controller/app/BaseController.php

@@ -0,0 +1,74 @@
+<?php
+/**
+ * BaseController.php UTF-8
+ *
+ *
+ * @date    : 2018/6/15 10:40
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\app;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\wap\Option;
+use huolib\constant\OptionConst;
+use think\Lang;
+use think\Validate;
+
+class BaseController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_setting'.EXT
+        );
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    private function settingPost($setting_name) {
+        $_m = new Option();
+        $_option_vale = $this->request->param();
+        $_validate = new Validate(
+            [
+                'app_down_url' => 'url',
+            ]
+        );
+        if (!$_validate->check($_option_vale)) {
+            $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+        }
+        $_res = $_m->saveOptionData($setting_name, json_encode($_option_vale));
+        if (!$_res) {
+            $this->adminError(lang('ERROR'));
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 通用设置
+     */
+    public function index() {
+        $_setting_name = OptionConst::APP_BASIC;
+        $_m = new Option();
+        $_option_vale = [
+            OptionConst::APP_BASIC_QQ_GROUP => '',
+            OptionConst::APP_BASIC_GM_NAME  => '',
+            OptionConst::APP_BASIC_PTB_NAME => '',
+            OptionConst::APP_BASIC_DOWN_URL => '',
+        ];
+        $_item = $_m->getOptionData($_setting_name, 1, true, json_encode($_option_vale));
+        if (!empty($_item['option_value'])) {
+            $_item['option_value'] = json_decode($_item['option_value'], true);
+            $_item['option_value'] = array_merge($_option_vale, $_item['option_value']);
+        }
+        $this->assign('item', $_item);
+
+        return $this->fetch();
+    }
+
+    public function basic_post() {
+        $setting_name = OptionConst::APP_BASIC;
+        $this->settingPost($setting_name);
+    }
+}

+ 386 - 0
admin/admin/controller/app/GameAppController.php

@@ -0,0 +1,386 @@
+<?php
+/**
+ * GameAndroidController.php UTF-8
+ * 安卓游戏管理
+ *
+ * @date    : 2017/11/22 15:12
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : guxiannong <gxn@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+namespace admin\admin\controller\app;
+
+use admin\admin\model\GameInfoModel;
+use admin\admin\model\GameModel;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use think\Lang;
+
+class GameAppController extends AdminbaseController {
+    private $game_info_Model;/* 默认model */
+    private $lang_ext                       = 'game_app';/* 语言文件 */
+    private $lang_namespaces                = 'game app ';/* 语言前缀 */
+    private $auto_select                    = '';/* 默认选择项 */
+    private $choose_state                   = '';/* 选择状态*/
+    private $choose_game                    = '';/* 选择游戏 */
+    private $choose_category                = '';/* 选择标签 */
+    private $game_tags                      = '';/* 游戏标签 */
+    private $current_status                 = '';/* 当前状态 */
+    private $game_name                      = '';/* 游戏名称 */
+    private $game_platform                  = '';/* 游戏平台 */
+    private $choose_platform                = '';/* 选择平台 */
+    private $start_time                     = '';/* 开始时间 */
+    private $end_time                       = '';/* 结束时间 */
+    private $app_game_management            = '';/* app游戏管理 */
+    private $app_game_param_lost            = '';/* 参数不全 */
+    private $app_game_offline_success       = '';/* 下线成功 */
+    private $app_game_online_success        = '';/* 上线成功 */
+    private $app_game_set_hot_success       = '';/* 设置热门成功 */
+    private $app_game_off_hot_success       = '';/* 取消热门成功 */
+    private $app_game_set_recommend_success = '';/* 推荐成功 */
+    private $app_game_off_recommend_success = '';/* 取消推荐成功 */
+    private $app_game_offline_fail          = '';/* 下线失败 */
+    private $app_game_online_fail           = '';/* 上线失败 */
+    private $app_game_set_hot_fail          = '';/* 设置热门失败 */
+    private $app_game_off_hot_fail          = '';/* 取消热门失败 */
+    private $app_game_set_recommend_fail    = '';/* 推荐失败 */
+    private $app_game_off_recommend_fail    = '';/* 取消推荐失败 */
+    function _initialize() {
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.$this->lang_ext.EXT
+        );
+        $this->game_info_Model = new GameInfoModel($this->lang, $this->lang_ext);
+        parent::_initialize();
+        $this->setLang();
+    }
+
+    /**
+     * @param $name
+     *
+     * @return Lang
+     */
+    public function addSpacesLang($name) {
+        return lang($this->lang_namespaces.$name);
+    }
+
+    /**
+     *设置当前控制器所用语句
+     */
+    public function setLang() {
+        $this->auto_select = $this->addSpacesLang('default choice');
+        $this->choose_state = $this->addSpacesLang('choose the state');
+        $this->choose_game = $this->addSpacesLang('choose a game');
+        $this->choose_category = $this->addSpacesLang('all tags');
+        $this->game_tags = $this->addSpacesLang('game tags');
+        $this->current_status = $this->addSpacesLang('current status');
+        $this->game_name = $this->addSpacesLang('game name');
+        $this->game_platform = $this->addSpacesLang('game platform');
+        $this->choose_platform = $this->addSpacesLang('choose a platform');
+        $this->start_time = $this->addSpacesLang('start time');
+        $this->end_time = $this->addSpacesLang('end time');
+        $this->app_game_management = $this->addSpacesLang('app game management');
+        $this->app_game_offline_success = $this->addSpacesLang('offline success');
+        $this->app_game_online_success = $this->addSpacesLang('online success');
+        $this->app_game_set_hot_success = $this->addSpacesLang('set hot success');
+        $this->app_game_off_hot_success = $this->addSpacesLang('off hot success');
+        $this->app_game_set_recommend_success = $this->addSpacesLang('set recommend success');
+        $this->app_game_off_recommend_success = $this->addSpacesLang('off recommend success');
+        $this->app_game_offline_fail = $this->addSpacesLang('offline fail');
+        $this->app_game_online_fail = $this->addSpacesLang('online fail');
+        $this->app_game_set_hot_fail = $this->addSpacesLang('set hot fail');
+        $this->app_game_off_hot_fail = $this->addSpacesLang('off hot fail');
+        $this->app_game_set_recommend_fail = $this->addSpacesLang('set recommend fail');
+        $this->app_game_off_recommend_fail = $this->addSpacesLang('off recommend fail');
+    }
+
+    /**
+     * 安卓游戏列表(包括手动排行)
+     */
+    public function index() {
+        $_status = $this->request->param('status/d', 0);
+        $_game_id = $this->request->param('game_id/d', 0);
+        $_game_name = $this->request->param('game_name/d', 0);
+        $_category = $this->request->param('category/d', 0);
+        $_start_time = $this->request->param('start_time');
+        $_end_time = $this->request->param('end_time');
+        $_platform = $this->request->param('platform');
+        $page = $this->request->param('page/d', 0);
+        $offset = $this->request->param('offset/d', 10);
+        $_url_data = $this->request->param();
+        $_back_url = url('App.gameApp/index', $_url_data);
+        $_is_delete = 2;
+        $_page_show = 1;
+        $_map = [];
+        $_map['game_id'] = $_game_id;
+        $_map['game_name'] = $_game_name;
+        $_map['category'] = $_category;
+        $_map['status'] = $_status;
+        $_map['is_delete'] = $_is_delete;
+        $_map['create_start_time'] = $_start_time;
+        $_map['create_end_time'] = $_end_time;
+        $_map['classify'] = $_platform;
+        $_order = array();
+        $_order['list_order'] = 'desc';
+        $_order['id'] = 'desc';
+        $this->GetDataList($_order, $_map, $page, $offset, $_back_url, $_page_show);
+        $_search_data = $_map;
+        $_search_data['platform'] = $_platform;
+        $this->assign('search_data', $_search_data);
+        $this->assign('back_url', $_back_url);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 获取数据列表
+     *
+     * @param array  $order_arr
+     * @param array  $map
+     * @param        $page
+     * @param        $offset
+     * @param string $back_url
+     * @param int    $page_show
+     *
+     * @internal param $game_id
+     * @internal param $status
+     */
+    public function GetDataList(
+        $order_arr = array(), $map = array(), $page, $offset, $back_url = '', $page_show = 1
+    ) {
+        $_game_info_Model = $this->game_info_Model;
+        $_games_data = $_game_info_Model->appGameList(
+            $order_arr, $map, $page, $offset, $back_url, $page_show
+        );
+        $_games_select = $_game_info_Model->getVal($_games_data, 'game_name_list', []);
+        $_games_list = $_game_info_Model->getVal($_games_data, 'game_list', []);
+        $_category_name_list = $_game_info_Model->getVal($_games_data, 'category_name_list', []);
+        $_game_status_list = $_game_info_Model->getVal($_games_data, 'game_status_list', []);
+        $_game_classify_list = $_game_info_Model->getVal($_games_data, 'game_classify_list', []);
+        $_page_show = $_game_info_Model->getVal($_games_list, 'page_show', '');
+        $_count = $_game_info_Model->getVal($_games_list, 'count', '');
+        $_start_time = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_end_time = $this->request->param('end_time', date('Y-m-d'));
+//        $_please_select = $this->auto_select;
+//        $_games_select = array('' => $_please_select) + $_games_select;
+//        $_category_name_list = array('' => $_please_select) + $_category_name_list;
+//        $_game_status_list = array('' => $_please_select) + $_game_status_list;
+//        $_game_classify_list = array('' => $_please_select) + $_game_classify_list;
+        $this->assign('games_list', $_games_list);
+        $this->assign('games_select', $_games_select);
+        $this->assign('category_name_list', $_category_name_list);
+        $this->assign('game_status_list', $_game_status_list);
+        $this->assign('game_classify_list', $_game_classify_list);
+        $_app_id = $_game_info_Model->getVal($map, 'game_id', '');
+        $_games_select_str = Filter::selectCommon($_games_select, 'game_id', $_app_id);
+        $this->assign('games_select_str', $_games_select_str);
+        $_category_id = $_game_info_Model->getVal($map, 'category', '');
+        $_games_category_select_str = Filter::selectCommon($_category_name_list, 'category', $_category_id);
+        $this->assign('games_category_select_str', $_games_category_select_str);
+        $_status = $_game_info_Model->getVal($map, 'status', '');
+        $_games_status_select_str = Filter::selectCommon($_game_status_list, 'status', $_status);
+        $this->assign('games_status_select_str', $_games_status_select_str);
+        $_platform = $_game_info_Model->getVal($map, 'classify', '');
+        $_games_platform_select_str = Filter::selectCommon($_game_classify_list, 'platform', $_platform);
+        $this->assign('games_platform_select_str', $_games_platform_select_str);
+        $_time_choose = Filter::timeChoose($_start_time, $_end_time, 'yyyy-mm-dd');
+        $this->assign('time_choose', $_time_choose);
+        $this->assign('page_show', $_page_show);
+        $this->assign('count', $_count);
+        $this->assign('page', $page);
+        $this->assign('offset', $offset);
+    }
+
+    /**
+     * 批量上线
+     */
+    public function online() {
+        $ids = $this->request->param('ids/a');
+        if (empty($ids)) {
+            $ids = array($this->request->param('game_id'));
+        }
+        if (empty($ids)) {
+            return array(
+                'code' => 0,
+                'msg'  => $this->app_game_param_lost
+            );
+        }
+        $_game_info_Model = $this->game_info_Model;
+        $_re = [];
+        $_error_msg = '';
+        $_code = 0;
+        foreach ($ids as $id) {
+            $_rs_v = $_game_info_Model->onlineGame($id);
+            $_error = $_game_info_Model->getVal($_rs_v, 'error', '');
+            if (200 != $_error) {
+                $_error_msg .= ' id:'.$id.' msg:'.$_game_info_Model->getVal($_rs_v, 'msg', '');
+            }
+            $_re[] = $_rs_v;
+        }
+        if ($_error_msg) {
+            return array(
+                'code' => $_code,
+                'msg'  => $_error_msg,
+                'data' => $_re,
+            );
+        }
+
+        return array(
+            'code' => 1,
+            'msg'  => $this->app_game_online_success,
+            'data' => $_re,
+        );
+    }
+
+    /**
+     * 批量下线
+     */
+    public function offline() {
+        $ids = $this->request->param('ids/a');
+        if (empty($ids)) {
+            $ids = array($this->request->param('game_id'));
+        }
+        if (empty($ids)) {
+            return array(
+                'code' => 0,
+                'msg'  => $this->app_game_param_lost
+            );
+        }
+        $_game_model = new GameModel();
+        $_re = $_game_model->where(['id' => ['in', $ids]])->update(['status' => 3]);
+        if ($_re) {
+            return array(
+                'code'  => 1,
+                'error' => 200,
+                'msg'   => $this->app_game_offline_success
+            );
+        } else {
+            return array(
+                'code'  => 0,
+                'error' => 500,
+                'msg'   => $this->app_game_offline_fail
+            );
+        }
+    }
+
+    /**
+     * 批量设置热门
+     */
+    public function setHot() {
+        $ids = $this->request->param('ids/a');
+        if (empty($ids)) {
+            $ids = array($this->request->param('game_id'));
+        }
+        if (empty($ids)) {
+            return array(
+                'code' => 0,
+                'msg'  => $this->app_game_param_lost
+            );
+        }
+        $_game_model = new GameModel();
+        $_re = $_game_model->where(['id' => ['in', $ids]])->update(['hot_order' => 1]);
+        if ($_re) {
+            return array(
+                'code' => 1,
+                'msg'  => $this->app_game_set_hot_success
+            );
+        } else {
+            return array(
+                'code' => 0,
+                'msg'  => $this->app_game_set_hot_fail
+            );
+        }
+    }
+
+    /**
+     * 批量取消热门
+     */
+    public function offHot() {
+        $ids = $this->request->param('ids/a');
+        if (empty($ids)) {
+            $ids = array($this->request->param('game_id'));
+        }
+        if (empty($ids)) {
+            return array(
+                'code' => 0,
+                'msg'  => $this->app_game_param_lost
+            );
+        }
+        $_game_model = new GameModel();
+        $_re = $_game_model->where(['id' => ['in', $ids]])->update(['hot_order' => 0]);
+        if ($_re) {
+            return array(
+                'code' => 1,
+                'msg'  => $this->app_game_off_hot_success
+            );
+        } else {
+            return array(
+                'code' => 0,
+                'msg'  => $this->app_game_off_hot_fail
+            );
+        }
+    }
+
+    /**
+     * 批量设置推荐
+     */
+    public function setRecommend() {
+        $ids = $this->request->param('ids/a');
+        if (empty($ids)) {
+            $ids = array($this->request->param('game_id'));
+        }
+        if (empty($ids)) {
+            return array(
+                'code' => 0,
+                'msg'  => $this->app_game_param_lost
+            );
+        }
+        $_game_model = new GameModel();
+        $_re = $_game_model->where(['id' => ['in', $ids]])->update(['list_order' => 1]);
+        if ($_re) {
+            return array(
+                'code' => 1,
+                'msg'  => $this->app_game_set_recommend_success
+            );
+        } else {
+            return array(
+                'code' => 1,
+                'msg'  => $this->app_game_set_recommend_fail
+            );
+        }
+    }
+
+    /**
+     * 批量取消推荐
+     */
+    public function offRecommend() {
+        $ids = $this->request->param('ids/a');
+        if (empty($ids)) {
+            $ids = array($this->request->param('game_id'));
+        }
+        if (empty($ids)) {
+            return array(
+                'code' => 0,
+                'msg'  => $this->app_game_param_lost
+            );
+        }
+        $_game_model = new GameModel();
+        $_re = $_game_model->where(['id' => ['in', $ids]])->update(['list_order' => 0]);
+        if ($_re) {
+            return array(
+                'code' => 1,
+                'msg'  => $this->app_game_off_recommend_success
+            );
+        } else {
+            return array(
+                'code' => 1,
+                'msg'  => $this->app_game_off_recommend_fail
+            );
+        }
+    }
+
+    public function menuDefault() {
+        exit;
+    }
+}
+

+ 235 - 0
admin/admin/controller/app/GameRebateController.php

@@ -0,0 +1,235 @@
+<?php
+/**
+ * GameRebateController.php  UTF-8
+ * 游戏返利管理
+ *
+ * @date    : 2018/7/30 15:10
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\app;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\OptionConst;
+use huolib\constant\OrderConst;
+use huolib\tool\Export;
+use huolib\tool\Page;
+use huoRebate\logic\RebateLogic;
+
+class GameRebateController extends AdminbaseController {
+    /*返利状态选择器*/
+    protected function _statuses_select($status) {
+        $_status = [
+            OrderConst::REBATE_STATUS_NOT  => '待处理',
+            OrderConst::REBATE_STATUS_SUC  => '成功',
+            OrderConst::REBATE_STATUS_FAIL => '失败'
+        ];
+        $_status_select = Filter::selectCommon($_status, 'status', $status);
+        $this->assign('statuses_select', $_status_select);
+        $this->assign('statuses', $_status);
+    }
+
+    /***
+     * 游戏返利列表
+     * /admin/app.game_rebate/index
+     */
+    public function index() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIndex();
+        }
+        $_param = $this->request->param();
+        $_order_input = Filter::text('order_id', get_val($_param, 'order_id', ''), '请输入订单ID');
+        $this->assign('order_input', $_order_input);
+        $_username_input = Filter::text('username', get_val($_param, 'username', ''), '请输入玩家账号');
+        $this->assign('username_input', $_username_input);
+        $this->_statuses_select(get_val($_param, 'status', ''));
+        $this->_time(
+            get_val($_param, 'start_time', date('Y-m-d', strtotime('-1 month'))),
+            get_val($_param, 'end_time', date('Y-m-d'))
+        );
+        $this->_games(
+            get_val($_param, 'app_id', 0), GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE,
+            GameConst::GAME_IS_SDK
+        );
+        $this->_cp(get_val($_param, 'cp', 0));
+        $_mg_mem_id_input = Filter::text('mg_mem_id', get_val($_param, 'mg_mem_id', ''), '请输入小号ID');
+        $this->assign('mg_mem_id_input', $_mg_mem_id_input);
+        $_page = $this->request->param('page/d', 1);
+        $_listRows = $this->request->param('listRows/d', 10);
+        $_list = (new RebateLogic())->getAdminList($_param, $_page.','.$_listRows);
+        $_items = $_list['list'];
+        $_items = (new Page())->paginate($_list['count'], $_items, $_page, $_listRows);
+        $this->assign('page', $_items->render());
+        $this->assign('items', $_items);
+        $this->assign('members', $_list['members']);
+        $this->assign('sum', $_list['sum']);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 导出订单数据
+     *
+     * @param int $is_handle
+     * @param int $cp_status
+     */
+    public function exportIndex() {
+        $_param = $this->request->param();
+        $_order_input = Filter::text('order_id', get_val($_param, 'order_id', ''), '请输入订单ID');
+        $this->assign('order_input', $_order_input);
+        $_username_input = Filter::text('username', get_val($_param, 'username', ''), '请输入玩家账号');
+        $this->assign('username_input', $_username_input);
+        $this->_statuses_select(get_val($_param, 'status', ''));
+        $this->_time(
+            get_val($_param, 'start_time', date('Y-m-d', strtotime('-1 month'))),
+            get_val($_param, 'end_time', date('Y-m-d'))
+        );
+        $this->_games(
+            get_val($_param, 'app_id', 0), GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE,
+            GameConst::GAME_IS_SDK
+        );
+        $_cp = $this->_cp(0, true);
+        $_mg_mem_id_input = Filter::text('mg_mem_id', get_val($_param, 'mg_mem_id', ''), '请输入小号ID');
+        $this->assign('mg_mem_id_input', $_mg_mem_id_input);
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new RebateLogic())->getAdminList($_param, $_page.','.$_offset);
+        $_members = $_data['members'];
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                'ID',
+                '订单号',
+                '用户',
+                'CP名称',
+                '游戏',
+                '区服',
+                '角色ID',
+                '角色',
+                '金额',
+                '状态',
+                '申请时间',
+                '小号ID',
+                '备注'
+            ];
+            $_export_datas = [];
+            if (1 == $_p) {
+                $_data_sum['total'] = '汇总';
+                $_data_sum['order_id'] = '--';
+                $_data_sum['mem'] = '--';
+                $_data_sum['cp'] = '--';
+                $_data_sum['gamename'] = '--';
+                $_data_sum['server_name'] = '--';
+                $_data_sum['role_id'] = '--';
+                $_data_sum['role_name'] = '--';
+                $_data_sum['amount'] = $_data['sum'];
+                $_data_sum['status'] = '--';
+                $_data_sum['create_time'] = '--';
+                $_data_sum['mg_mem_id'] = '--';
+                $_data_sum['remark'] = '--';
+                $_export_datas[] = $_data_sum;
+            }
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['id'] = $_val['id'];
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['mem'] = isset($_members[$_val['mem_id']]) ? $_members[$_val['mem_id']] : '';
+                $_export_data['cp'] = isset($_cp[$_val['cp_id']]) ? $_cp[$_val['cp_id']] : '';
+                $_export_data['gamename'] = $_val['gamename'];
+                $_export_data['server_name'] = $_val['server_name'];
+                $_export_data['role_id'] = $_val['role_id'];
+                $_export_data['role_name'] = $_val['role_name'];
+                $_export_data['amount'] = $_val['amount'];
+                $_export_data['status'] = $_val['status_txt'];
+                $_export_data['create_time'] = date('Y-m-d H:i', $_val['apply_time']);
+                $_export_data['mg_mem_id'] = $_val['mg_mem_id'];
+                $_export_data['remark'] = $_val['remark'];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '返利订单', '.csv', true);
+                break;
+            } else {
+                $_file_name = '返利订单'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new RebateLogic())->getAdminList($_param, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '返利订单');
+    }
+
+    /**
+     * 订单审核
+     * /admin/app.game_rebate/setStatus
+     */
+    public function setStatus() {
+        $_id = $this->request->param('oid/d', 0);
+        $_status = $this->request->param('sts/d', 1);
+        $_remark = $this->request->param('remark/s', '');
+        if (empty($_id)) {
+            $this->adminError(lang('param error'));
+        }
+        if (OrderConst::REBATE_STATUS_FAIL == $_status && empty($_remark)) {
+            $this->adminError('请输入审核不通过原因!');
+        }
+        $_rs = (new RebateLogic())->setStatus($_id, $_status, $_remark);
+        if (false == $_rs) {
+            $this->adminError('修改失败');
+        }
+        $this->adminSuccess('修改成功');
+    }
+
+    /**
+     * 订单详情
+     * /admin/app.game_rebate/detail
+     */
+    public function detail() {
+        $_id = $this->request->param('oid/d', 0);
+        $_data = (new RebateLogic())->getRoInfo($_id);
+        $this->_statuses_select(0);
+        $this->assign('order', $_data['ro_info']);
+        $this->assign('ro_list', $_data['ro_list']['list']);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 获取最小值设定
+     */
+    public function minSet() {
+        $_value = (new RebateLogic())->getMinSet();
+        $this->assign('value', $_value);
+
+        return $this->fetch('minSet');
+    }
+
+    /**
+     * 设定最小值
+     */
+    public function setMinSet() {
+        $_value = $this->request->param('rebate_min_set/d', 0);
+        $_rs = (new RebateLogic())->setMinSet(OptionConst::REBATE_MIN_SET, $_value);
+        if ($_rs) {
+            return $this->adminSuccess('设定成功!');
+        }
+
+        return $this->adminError('设定失败!');
+    }
+}

+ 180 - 0
admin/admin/controller/app/MessageController.php

@@ -0,0 +1,180 @@
+<?php
+/**
+ * MessageController.php UTF-8
+ * APP消息管理
+ *
+ * @date    : 2018/6/19 15:00
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\app;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\game\GameCache;
+use huo\logic\member\MemberLogic;
+use huo\logic\message\MessageLogic;
+use huo\logic\user\UserLogic;
+use huo\model\user\UserModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\MessageConst;
+
+class MessageController extends AdminbaseController {
+
+    public function _initialize() {
+        parent::_initialize();
+    }
+
+    /**
+     * 消息列表
+     */
+    public function index() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_type = $this->request->param('type/d', 0);
+
+        $_param = $this->request->param();
+        $_page = $this->request->param('page/d', 1);
+        $_offset = $this->request->param('offset/d', 10);
+        $_msg_class = new MessageLogic();
+        $_data = $_msg_class->adminList($_param, $_page.','.$_offset);
+        $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_offset);
+        $this->_games($_app_id, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE);
+        $_types = MessageConst::getTypeMsg(0, true);
+        $_types_select = Filter::selectCommon($_types, 'type', $_type);
+        $this->assign('types', $_types);
+        $this->assign('types_select', $_types_select);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+        return $this->fetch('index');
+    }
+
+    /**
+     * 发送消息页面
+     */
+    public function add() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_send_types = $this->_sendTypes();
+        $_send_types_radio = Filter::radioCommon($_send_types, 'send_type', 'to_all');
+        $this->_games($_app_id, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE);
+        $this->assign('send_types_radio', $_send_types_radio);
+        return $this->fetch('add');
+    }
+
+    /**
+     * 发送消息
+     */
+    public function addPost() {
+        $_param = $this->request->param();
+        $_check_rs = $this->validate($_param, 'Message.add');
+        if (true !== $_check_rs) {
+            $this->adminError($_check_rs);
+        }
+
+        $_send_type = get_val($_param, 'send_type');
+        $_title = get_val($_param, 'title');
+        $_content = get_val($_param, 'content');
+        $_mem_name = get_val($_param, 'mem_name', '');
+        $_agent_name = get_val($_param, 'agent_name', '');
+        $_app_id = get_val($_param, 'app_id', 0);
+
+        if (!array_key_exists($_send_type, $this->_sendTypes())) {
+            $this->adminError('发送类型错误');
+        }
+
+        $_member_id = $_agent_id = 0;
+        if (!empty($_mem_name)) {
+            $_member_id = (new MemberLogic())->getIdByName($_mem_name);
+            if (empty($_member_id)) {
+                $this->adminError('玩家账号不存在');
+            }
+        }
+//        if (!empty($_agent_name)) {
+//            $_agent_id = (new UserModel())->getIdByName($_agent_name);
+//            if (empty($_agent_id)) {
+//                $this->adminError('渠道账号不存在');
+//            }
+//        }
+
+        if (!empty($_app_id)) {
+            if (!GameCache::ins()->getInfoByAppId($_app_id)) {
+                $this->adminError('游戏不存在');
+            }
+        }
+
+        $_rs = (new MessageLogic())->addMessage($_member_id, $_title, $_content, MessageConst::TYPE_SYSTEM, $_app_id);
+        if ($_rs) {
+            $this->adminSuccess('操作成功');
+        } else {
+            $this->adminError('操作失败');
+        }
+    }
+
+    public function edit() {
+        $_msg_id = $this->request->param('id/d', 0);
+        $_message = $this->getMessage($_msg_id);
+
+        $_app_id = !empty($_message['app_id']) ? $_message['app_id'] : 0;
+        $this->_games($_app_id, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE);
+
+        $_send_types = $this->_sendTypes();
+        $this->assign('send_types', $_send_types);
+        $this->assign('message', $_message);
+        return $this->fetch('edit');
+    }
+
+    public function editPost() {
+        $_param = $this->request->param();
+        $_check_rs = $this->validate($_param, 'Message.edit');
+        if (true !== $_check_rs) {
+            $this->adminError($_check_rs);
+        }
+
+        $_msg_id = get_val($_param, 'id');
+        $_title = get_val($_param, 'title');
+        $_content = get_val($_param, 'content');
+        $_app_id = get_val($_param, 'app_id', 0);
+
+        $_message = $this->getMessage($_msg_id);
+        if (!empty($_app_id)) {
+            if (!GameCache::ins()->getInfoByAppId($_app_id)) {
+                $this->adminError('游戏不存在');
+            }
+        }
+
+        $_data = [];
+        isset($_title) && $_data['title'] = $_title;
+        isset($_content) && $_data['content'] = $_content;
+        isset($_app_id) && $_data['app_id'] = $_app_id;
+
+        $_rs = (new MessageLogic())->updateData($_data, $_msg_id);
+        if ($_rs) {
+            $this->adminSuccess('操作成功');
+        } else {
+            $this->adminError('操作失败');
+        }
+    }
+
+    private function getMessage($msg_id){
+        $_message = (new MessageLogic())->adminDetail($msg_id);
+        if (empty($_message)) {
+            $this->adminError('非法消息');
+        }
+        return $_message;
+    }
+
+    /**
+     * 发送类型
+     * @return array
+     */
+    private function _sendTypes(){
+        return [
+            'to_all'   => '全体',
+            'to_mem'   => '玩家',
+//            'to_agent' => '渠道',
+        ];
+    }
+}

+ 76 - 0
admin/admin/controller/app/RebateController.php

@@ -0,0 +1,76 @@
+<?php
+/**
+ * RebateController.php  UTF-8
+ * 返利富文本
+ *
+ * @date    : 2018/7/30 14:31
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\app;
+
+use cmf\controller\AdminBaseController;
+use huo\model\posts\PostsModel;
+use huolib\constant\NewsConst;
+use huoRebate\controller\RichText;
+use think\Validate;
+
+class RebateController extends AdminbaseController {
+    /**
+     * 返利指南
+     * /admin/app.rebate/guide
+     */
+    public function guide() {
+        $_data = (new RichText())->getDetail(NewsConst::NEWS_ID_REBATE_EXPLAIN);
+        $this->assign($_data['data']);
+        $this->assign('active', 'guide');
+
+        return $this->fetch('richText');
+    }
+
+    /**
+     * 角色id说明
+     * /admin/app.rebate/roleidexplain
+     */
+    public function roleidexplain() {
+        $_data = (new RichText())->getDetail(NewsConst::NEWS_ID_ROLEID_EXPLAIN);
+        $this->assign($_data['data']);
+        $this->assign('active', 'roleidexplain');
+        return $this->fetch('richText');
+    }
+
+    /**
+     * 文章内容提交
+     * /admin/app.rebate/saveProtocol
+     */
+    public function saveProtocol() {
+        $_data = $this->request->param();
+        $validate = new Validate(
+            [
+                'post_title'   => 'require',
+                'post_content' => 'require',
+            ]
+        );
+        if (!$validate->check($_data)) {
+            $this->adminError($validate->getError());
+        }
+        $_where = [];
+        if (!empty($_data['id'])) {
+            $_where = ['id' => $_data['id']];
+            unset($_data['id']);
+        }
+        $_data['user_id'] = cmf_get_current_admin_id();
+        $_data['post_type'] = NewsConst::NEWS_TYPE_OTHER;
+        $_data['post_status'] = NewsConst::NEWS_PUBLISHED;
+        $_data['comment_status'] = NewsConst::NEWS_COMMENT_STATUS_NOT_ALLOW;
+        $_data['published_time'] = date('Y-m-d H:i:s');
+        $_protocol = new PostsModel();
+        if (false === $_protocol->save($_data, $_where)) {
+            $this->adminError(lang('ERROR'));
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+}

+ 206 - 0
admin/admin/controller/app/SpcController.php

@@ -0,0 +1,206 @@
+<?php
+/**
+ * SdkPluginConfController.php  UTF-8
+ * SDK更新
+ *
+ * @date    : 2018/5/31 14:54
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\app;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\logic\app\SdkPluginConfLogic;
+use huo\model\game\GameversionModel;
+use huolib\constant\GameConst;
+use huolib\tool\Page;
+use think\Lang;
+
+class SpcController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_sdk'.EXT);
+    }
+
+    /*SPC 选择器*/
+    protected function _getSpc($code=''){
+        $_spc = (new SdkPluginConfLogic())->getCodeNames();
+        $_spc_select = Filter::selectCommon($_spc,'code',$code);
+        $this->assign('spc_select',$_spc_select);
+        $this->assign('spc',$_spc);
+    }
+   /*客户端id选择器*/
+    protected function _getClient($client_id=0){
+        $_game_version_name=(new GameversionModel())->getClientIdName();
+        $_client_select = Filter::selectCommon($_game_version_name,'client_id',$client_id);
+        $this->assign('client_select',$_client_select);
+    }
+    /**
+     * 插件列表
+     * admin/app.sdk_plugin_conf/index
+     * @throws
+    */
+    public function index(){
+        /*搜索条件*/
+        $_param['code'] = $this->request->param('code/s','');
+        $this->_getSpc($_param['code']);
+        $_param['client_id'] = $this->request->param('client_id/d',0);
+        $this->_getClient($_param['client_id']);
+        $_param['version'] = $this->request->param('version/s', '');
+        $_version_input = Filter::text('version', $_param['version'], lang('version'));
+        $this->assign('version_input', $_version_input);
+        $_param['start_time'] = $this->request->param('start_time', '');
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_is_default = GameConst::getIsDefaultMsg($this->request->param('is_default/d', 0),true);
+        $_is_default_select = Filter::selectCommon($_is_default,'is_default',0);
+        $this->assign('is_default_select',$_is_default_select);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_items =(new SdkPluginConfLogic())->getPluginList($_param,$_page.','.$_list_rows);
+        $_page_data = Page::paginate($_items['count'], $_items['list'], $_page, $_list_rows);
+        $this->assign('items',$_items['list']);
+        $this->assign('page',$_page_data);
+        return $this->fetch();
+    }
+
+    /***
+     * 添加插件
+     * admin/app.sdk_plugin_conf/add
+    **/
+    public function add(){
+        $this->_getSpc();
+        $this->_getClient();
+        $_has_so_radio = Filter::radioCommon(GameConst::getHasSoMsg(0,true),'has_so',1);
+        $this->assign('has_so_radio',$_has_so_radio);
+        return $this->fetch();
+    }
+
+    /**
+     * 添加提交
+     * admin/app.sdk_plugin_conf/addPost
+    */
+    public function addPost(){
+        $_param = $this->request->param();
+//        if( 1 == $_param['is_file']){  //上传的文件url解析为标准url
+//            $_param['url']=url($_param['url'],'',false,true);
+//        }
+        $_v_res = $this->validate($_param, 'SdkPluginConf');
+        if ($_v_res !== true) {
+            $this->adminError($_v_res);
+        }
+        $_param['create_time']=time();
+        $_param['update_time']=time();
+        $_res=(new SdkPluginConfLogic())->addSdkPlugin($_param);
+        if(false == $_res){
+            $this->adminError(lang('add').lang('failure'));
+        }
+        $this->adminSuccess(lang('add').lang('success'), url('admin/app.spc/index'));
+
+    }
+
+    /**
+     * 编辑插件
+     * admin/app.sdk_plugin_conf/edit
+     * @throws
+    */
+    public function edit(){
+        $_id = $this->request->param('id/d',0);
+        if(empty($_id)){
+            $this->adminError(lang('param error'));
+        }
+        $_data =(new SdkPluginConfLogic())->getDetail($_id);
+        if(empty($_data)){
+            $this->adminError(lang('param error'));
+        }
+        $this->_getSpc($_data['code']);
+        $this->_getClient($_data['client_id']);
+        $_has_so_radio = Filter::radioCommon(GameConst::getHasSoMsg($_data['has_so'],true),'has_so',1);
+        $this->assign('has_so_radio',$_has_so_radio);
+        $this->assign('data',$_data);
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑插件提交
+     * admin/app.sdk_plugin_conf/editPost
+    */
+    public function editPost(){
+        $_param = $this->request->param();
+//        if( 1 == $_param['is_file']){  //上传的文件url解析为标准url
+//            $_param['url']=url($_param['url'],'',false,true);
+//        }
+        if(empty($_param['id'])){
+            $this->adminError(lang('param error'));
+        }
+        $_v_res = $this->validate($_param, 'SdkPluginConf');
+        if ($_v_res !== true) {
+            $this->adminError($_v_res);
+        }
+        $_param['update_time']=time();
+        $_res=(new SdkPluginConfLogic())->updateSdkPlugin($_param['id'],$_param);
+        if(false == $_res){
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/app.spc/index'));
+    }
+
+    /**
+     * 编辑状态
+     * admin/app.sdk_plugin_conf/setStatus
+     */
+    public function setStatus(){
+        $_param['id'] = $this->request->param('id/d',0);
+        $_param['is_default'] = $this->request->param('is_default/d',1);
+        if(empty($_param['id'])){
+            $this->adminError(lang('param error'));
+        }
+        $_param['update_time']=time();
+        $_res=(new SdkPluginConfLogic())->updateSdkPlugin($_param['id'],$_param);
+        if(false == $_res){
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/app.spc/index'));
+    }
+
+    /**
+     * 编辑插件下载地址
+     * admin/app.sdk_plugin_conf/url
+     * @throws
+     */
+    public function url(){
+        $_id =$this->request->param('id/d',0);
+        $_field=['id','code','url'];
+        $_data =(new SdkPluginConfLogic())->getDetail($_id,$_field);
+        if(empty($_data)){
+            $this->adminError(lang('param error'));
+        }
+        $this->_getSpc();
+        $this->assign('data',$_data);
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑插件地址提交
+     * admin/app.sdk_plugin_conf/editUrl
+     */
+    public function editUrl(){
+        $_param['id'] = $this->request->param('id/d',0);
+        $_param['url'] = $this->request->param('url/s','');
+        if(empty($_param['id'])){
+            $this->adminError(lang('param error'));
+        }
+        if(empty($_param['url'])){
+            $this->adminError(lang('url').lang('param error'));
+        }
+        $_param['update_time']=time();
+        $_res=(new SdkPluginConfLogic())->updateSdkPlugin($_param['id'],$_param);
+        if(false == $_res){
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/app.spc/index'));
+    }
+}

+ 336 - 0
admin/admin/controller/app/VersionController.php

@@ -0,0 +1,336 @@
+<?php
+/**
+ * VersionController.php UTF-8
+ * APP版本管理
+ *
+ * @date    : 2017/12/1 17:55
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\app;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\game\Gamepack;
+use huo\exception\HuoException;
+use huo\model\game\GameModel;
+use huo\model\game\GameversionModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use think\Lang;
+use think\Validate;
+
+class VersionController extends AdminbaseController {
+    protected $app_id;
+
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.'version'.EXT
+        );
+        $this->app_id = $this->request->param('app_id', config('app_app_id'));
+    }
+
+    /**
+     * 游戏状态
+     */
+    public function _versionStatus() {
+        $_version_status = [
+            GameConst::GAME_STATUS_ACCESS => lang('not_line'),
+            GameConst::GAME_STATUS_ON     => lang('online'),
+            GameConst::GAME_STATUS_OFF    => lang('offline'),
+        ];
+        $this->assign('version_status', $_version_status);
+
+        return $_version_status;
+    }
+
+    /**
+     *
+     */
+    public function index() {
+        $this->getAppInfo();
+        $this->_versionStatus();
+        $this->getList($this->app_id);
+
+        return $this->fetch();
+    }
+
+    public function getAppInfo() {
+        $_game_info = GameModel::useGlobalScope(false)
+                               ->where('id', $this->app_id)
+                               ->find()->toArray();
+        $this->assign('icon', $_game_info['icon']);
+
+        return $_game_info;
+    }
+
+    /**
+     * 添加游戏母包
+     */
+    public function addPackageUrl() {
+        $_ver_id = $this->request->param('id/d', 0);
+        $_update = $this->request->param('update/d', 0);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+        if (empty($_ver_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_version_data = $this->getDetail($_ver_id);
+        if (empty($_version_data)) {
+            $this->adminError(lang('ERROR'));
+        }
+        if (empty($_update) && !empty($_version_data['package_url'])) {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+        $this->assign($_version_data);
+        $_game_info = $this->getAppInfo();
+        if (empty($_game_info)) {
+            $this->adminError(lang('ERROR'));
+        }
+        $this->assign('game', $_game_info);
+        $_gp_class = new Gamepack($this->app_id);
+        try {
+            $_gp_class->setPinyin($_game_info['en_abbr']);
+            $_gp_class->setAgentgame($_game_info['en_abbr']);
+            $_gp_class->setVerId($_ver_id);
+            $_gp_class->pack();
+            $_data = $_gp_class->getData();
+        } catch (HuoException $_he) {
+            $_data = $_he->getData();
+        }
+        if (empty($_data)) {
+            return $this->fetch('app/version/addpackageurl');
+        }
+        if (is_array($_data) && isset($_data['size'])) {
+            $_gv_model = new GameversionModel();
+            $_map['id'] = $_ver_id;
+            $_gv_data['package_url'] = $_data['url'];
+            $_gv_data['size'] = $_data['size'];
+            $_gv_data['version'] = $_data['vername'];
+            $_rs = $_gv_model->save($_gv_data, $_map);
+            if (false !== $_rs) {
+                $_game_model = new GameModel();
+                $_g_data['package_name'] = $_data['pakagename'];
+                $_g_map['id'] = $_version_data['app_id'];
+                $_game_model->save($_g_data, $_g_map);
+                $this->redirect($this->request->server('HTTP_REFERER'));
+            }
+        }
+
+        return $this->fetch('app/version/addpackageurl');
+    }
+
+    /**
+     * 获取对接参数
+     */
+    public function param() {
+        $_ver_id = $this->request->param('id/d', 0);
+        if (empty($_ver_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->assign($this->getDetail($_ver_id));
+
+        return $this->fetch();
+    }
+
+    /**
+     * @param int $ver_id
+     *
+     * @return array
+     */
+    public function getDetail($ver_id) {
+        $_data = GameversionModel::useGlobalScope(false)
+                                 ->cache('game_version_'.$ver_id)
+                                 ->where('id', $ver_id)
+                                 ->find()
+                                 ->toArray();
+
+        return $_data;
+    }
+
+    public function getList($app_id) {
+        $_map['app_id'] = $app_id;
+        $_items = GameversionModel::useGlobalScope(false)
+                                  ->where($_map)
+                                  ->useSoftDelete('delete_time', ['eq', 0])
+                                  ->order('id', 'desc')
+                                  ->paginate(10);
+        $this->assign('page', $_items->render());
+        $this->assign('items', $_items);
+
+        return $_items;
+    }
+
+    /**
+     * 添加APP
+     *
+     * @return string
+     */
+    public function addApp() {
+        $_param['id'] = $this->app_id;
+        $_param['is_sdk'] = GameConst::GAME_IS_NOT_SDK;
+        $_param['is_online'] = GameConst::GAME_IS_ON_LINE;
+        $_param['cp_id'] = 0;
+        $_param['en_name'] = 'A P P';
+        $_param['name'] = 'APP';
+        $_param['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_param['status'] = GameConst::GAME_STATUS_ACCESS;
+        $_param['delete_time'] = time();
+        $_game_model = new GameModel();
+        $_rs = $_game_model->addGames($_param);
+        if ($_rs) {
+            return 'success';
+        }
+
+        return 'error';
+    }
+
+    /**
+     *添加
+     */
+    public function add() {
+        $this->getAppInfo();
+
+        return $this->fetch();
+    }
+
+    /**
+     *添加提交
+     */
+    public function addPost() {
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'version' => 'require|token',
+                ]
+            );
+            $_param = $this->request->param();
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_param['app_id'] = $this->app_id;
+            $_version_model = new GameversionModel();
+            $_rs = $_version_model->addVersion($_param);
+            if ($_rs) {
+                $_g_data['icon'] = $this->request->param('icon');
+                GameModel::update($_g_data, ['id' => $this->app_id], true);
+                $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/public/closeFrame'));
+            } else {
+                $this->adminSuccess(lang('ADD_FAILED'));
+            }
+        } else {
+            $this->adminError(lang('REQUEST_ERROR'));
+        }
+    }
+
+    /**
+     *添加
+     */
+    public function edit() {
+        $this->getAppInfo();
+        $_ver_id = $this->request->param('id/d', 0);
+        if (empty($_ver_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->assign($this->getDetail($_ver_id));
+
+        return $this->fetch();
+    }
+
+    /**
+     *添加提交
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'id'      => 'require|number',
+                    'version' => 'require|token',
+                ]
+            );
+            $_param = $this->request->param();
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_data['content'] = $this->request->post('content', '');
+            $_data['version'] = $this->request->post('version', '');
+            $_map['id'] = $_param['id'];
+            $_rs = GameversionModel::update($_data, $_map);
+            if ($_rs) {
+                $_g_data['icon'] = $this->request->param('icon');
+                GameModel::update($_g_data, ['id' => $this->app_id], true);
+                $this->adminSuccess(lang('EDIT_SUCCESS'), url('admin/public/closeFrame'));
+            } else {
+                $this->adminSuccess(lang('EDIT_FAILED'));
+            }
+        } else {
+            $this->adminError(lang('REQUEST_ERROR'));
+        }
+    }
+
+    /**
+     * 设置状态 上线 下线
+     */
+    public function setStatus() {
+        $_ver_id = $this->request->param('id/d', 0);
+        $_status = $this->request->param('is_default/d', 1);
+        if (empty($_ver_id) || empty($_status)) {
+            $this->adminError(lang('param error'));
+        }
+        $_version_data = $this->getDetail($_ver_id);
+        if (2 == $_status) {
+            if (empty($_version_data['package_url'])) {
+                $this->adminError(lang('no_package'));
+            }
+            $_msg = lang('online');
+        } else {
+            $_msg = lang('offline');
+        }
+        $_data['is_default'] = $_status;
+        $_map['app_id'] = $this->app_id;
+        $_map['id'] = $_ver_id;
+        $_version_model = new GameversionModel();
+        $_rs = $_version_model->allowField(true)->isUpdate(true)->save($_data, $_map);
+        if (false !== $_rs && 2 == $_status) {
+            $_map['id'] = ['neq', $_ver_id];
+            $_data['is_default'] = 3;
+            $_rs = $_version_model->allowField(true)->isUpdate(true)->save($_data, $_map);
+        }
+        if (false === $_rs) {
+            $this->adminError($_msg.lang('ERROR'));
+        } else {
+            $this->adminSuccess($_msg.lang('SUCCESS'));
+        }
+    }
+
+    /**
+     *下线
+     */
+    public function offline() {
+        echo ' offline todo';
+        exit;
+    }
+
+    /**
+     *删除
+     */
+    public function delete() {
+        $_ver_id = $this->request->param('id/d', 0);
+        if (empty($_ver_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_map['id'] = $_ver_id;
+        $_data['is_delete'] = 1;
+        $_data['delete_time'] = time();
+        $_version_model = new GameversionModel();
+        $_rs = $_version_model->allowField(true)->isUpdate(true)->save($_data, $_map);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+}
+

+ 59 - 0
admin/admin/controller/article/ActivityController.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * NewsController.php UTF-8
+ * 资讯 管理
+ *
+ * @date    : 2017/11/27 14:20
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\article;
+
+use cmf\controller\ArticleBaseController;
+use huolib\constant\NewsConst;
+use think\Lang;
+
+class ActivityController extends ArticleBaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_news'.EXT
+        );
+    }
+
+
+    public function index() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_STRATEGY;
+        ArticleBaseController::index();
+        return $this->fetch();
+    }
+
+    public function add() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_STRATEGY;
+        ArticleBaseController::add();
+        return $this->fetch();
+    }
+
+
+    public function addPost() {
+        ArticleBaseController::addPost();
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/article.activity/index'));
+    }
+
+
+    public function edit() {
+        $this->id = $this->request->param('id', 0, 'intval');
+        ArticleBaseController::edit();
+        return $this->fetch();
+    }
+
+
+    public function editPost() {
+        ArticleBaseController::editPost();
+        $this->adminSuccess(lang('EDIT_SUCCESS'), url('admin/article.activity/index'));
+    }
+
+}

+ 59 - 0
admin/admin/controller/article/NewsController.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * NewsController.php UTF-8
+ * 资讯 管理
+ *
+ * @date    : 2017/11/27 14:20
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\article;
+
+use cmf\controller\ArticleBaseController;
+use huolib\constant\NewsConst;
+use think\Lang;
+
+class NewsController extends ArticleBaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_news'.EXT
+        );
+    }
+
+
+    public function index() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_NEWS;
+        ArticleBaseController::index();
+        return $this->fetch();
+    }
+
+    public function add() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_NEWS;
+        ArticleBaseController::add();
+        return $this->fetch();
+    }
+
+
+    public function addPost() {
+        ArticleBaseController::addPost();
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/article.news/index'));
+    }
+
+
+    public function edit() {
+        $this->id = $this->request->param('id', 0, 'intval');
+        ArticleBaseController::edit();
+        return $this->fetch();
+    }
+
+
+    public function editPost() {
+        ArticleBaseController::editPost();
+        $this->adminSuccess(lang('EDIT_SUCCESS'), url('admin/article.news/index'));
+    }
+
+}

+ 59 - 0
admin/admin/controller/article/NoticeController.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * NewsController.php UTF-8
+ * 资讯 管理
+ *
+ * @date    : 2017/11/27 14:20
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\article;
+
+use cmf\controller\ArticleBaseController;
+use huolib\constant\NewsConst;
+use think\Lang;
+
+class NoticeController extends ArticleBaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_news'.EXT
+        );
+    }
+
+
+    public function index() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_NOTICE;
+        ArticleBaseController::index();
+        return $this->fetch();
+    }
+
+    public function add() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_NOTICE;
+        ArticleBaseController::add();
+        return $this->fetch();
+    }
+
+
+    public function addPost() {
+        ArticleBaseController::addPost();
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/article.notice/index'));
+    }
+
+
+    public function edit() {
+        $this->id = $this->request->param('id', 0, 'intval');
+        ArticleBaseController::edit();
+        return $this->fetch();
+    }
+
+
+    public function editPost() {
+        ArticleBaseController::editPost();
+        $this->adminSuccess(lang('EDIT_SUCCESS'), url('admin/article.notice/index'));
+    }
+
+}

+ 59 - 0
admin/admin/controller/article/WalkthroughController.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * NewsController.php UTF-8
+ * 资讯 管理
+ *
+ * @date    : 2017/11/27 14:20
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\article;
+
+use cmf\controller\ArticleBaseController;
+use huolib\constant\NewsConst;
+use think\Lang;
+
+class WalkthroughController extends ArticleBaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_news'.EXT
+        );
+    }
+
+
+    public function index() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_ACTIVITY;
+        ArticleBaseController::index();
+        return $this->fetch();
+    }
+
+    public function add() {
+        $this->param['post_type'] = NewsConst::NEWS_TYPE_ACTIVITY;
+        ArticleBaseController::add();
+        return $this->fetch();
+    }
+
+
+    public function addPost() {
+        ArticleBaseController::addPost();
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/article.walkthrough/index'));
+    }
+
+
+    public function edit() {
+        $this->id = $this->request->param('id', 0, 'intval');
+        ArticleBaseController::edit();
+        return $this->fetch();
+    }
+
+
+    public function editPost() {
+        ArticleBaseController::editPost();
+        $this->adminSuccess(lang('EDIT_SUCCESS'), url('admin/article.walkthrough/index'));
+    }
+
+}

+ 330 - 0
admin/admin/controller/conf/PaywayController.php

@@ -0,0 +1,330 @@
+<?php
+/**
+ * PaywayController.php  UTF-8
+ * 支付方式配置
+ *
+ * @date    : 2020/3/10 11:21
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOOA 1.0
+ */
+
+namespace admin\admin\controller\conf;
+
+use admin\admin\validate\PaywayValidate;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\logic\conf\PaywayLogic;
+use huo\model\conf\PaywayModel;
+use huolib\constant\CommonConst;
+use menu\controller\Menu;
+
+class PaywayController extends AdminBaseController {
+    function _initialize() {
+        parent::_initialize();
+    }
+
+    /**
+     * 支付方式列表
+     * admin/conf.payway/index
+     */
+    public function index() {
+        $_param = $this->getSearchParam();
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_data = (new PaywayLogic())->getAdminList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('index');
+    }
+
+    /**
+     * 添加支付方式
+     * admin/conf.payway/add
+     */
+    public function add() {
+        $this->_getCode();
+
+        return $this->fetch('add');
+    }
+
+    /**
+     * 添加支付方式提交
+     * admin/conf.payway/addPost
+     */
+    public function addPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            /*校验参数*/
+            $_validate = new PaywayValidate('add');
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError());
+            }
+            $_param['is_config'] = 2; //默认后台配置
+            $_param['status'] = 1; //默认不启用
+            $_rs = (new PaywayModel())->addData($_param);
+            if (false === $_rs) {
+                $this->adminError('添加失败!');
+            }
+            $this->adminSuccess('添加成功!');
+        } else {
+            $this->adminError('提交类型错误!');
+        }
+    }
+
+    /**
+     * 编辑支付方式
+     * admin/conf.payway/edit
+     */
+    public function edit() {
+        $_id = $this->request->param('id/d', CommonConst::CONST_ZERO);
+        $_data = (new PaywayModel())->getInfoById($_id);
+        $this->_getCode($_data['code'], 'disabled');
+        $this->assign('data', $_data);
+
+        return $this->fetch('edit');
+    }
+
+    /**
+     * 编辑支付方式提交
+     * admin/conf.payway/editPost
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            /*校验参数*/
+            $_validate = new PaywayValidate('edit');
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError());
+            }
+            $_rs = (new PaywayModel())->updateData($_param, $_param['id']);
+            if (false === $_rs) {
+                $this->adminError('修改失败!');
+            }
+            $this->adminSuccess('修改成功!');
+        } else {
+            $this->adminError('提交类型错误!');
+        }
+    }
+
+    /***
+     * 支付配置
+     * admin/conf.payway/editConf
+     */
+    public function editConf() {
+        $_id = $this->request->param('id/d', CommonConst::CONST_ZERO);
+        $_data = (new PaywayModel())->getInfoById($_id);
+        $this->assign('data', $_data);
+        $_template = 'wxpay_conf';
+        if ('alipay' == $_data['code']) {
+            $_template = 'alipay_conf';
+        }
+        $_config = $this->_getDefaultConf($_data['code']);
+        $_config = !empty($_data['config']) ? $_data['config'] : $_config;
+        $this->assign('config', $_config);
+
+        return $this->fetch($_template);
+    }
+
+    /**
+     * 编辑支付配置提交
+     * admin/conf.payway/editConfPost
+     */
+    public function editConfPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            if (empty($_param['code'])) {
+                $this->adminError('缺少参数code!');
+            }
+            /*校验参数*/
+            $_validate = new PaywayValidate($_param['code']);
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError());
+            }
+            $_default_conf = $this->_getDefaultConf($_param['code']);
+            foreach ($_default_conf as $_k => $_v) {
+                $_default_conf[$_k] = get_val($_param, $_k, '');
+            }
+            if (isset($_default_conf['app_id'])) {
+                $_default_conf['js_app_id'] = $_default_conf['app_id'];
+            }
+            if (isset($_default_conf['app_secret'])) {
+                $_default_conf['js_app_secret'] = $_default_conf['app_secret'];
+            }
+            $_data = ['config' => $_default_conf];
+            $_rs = (new PaywayModel())->updateData($_data, $_param['id']);
+            if (false === $_rs) {
+                $this->adminError('修改失败!');
+            }
+            $this->adminSuccess('修改成功!');
+        } else {
+            $this->adminError('提交类型错误!');
+        }
+    }
+
+    /**
+     * 设置状态
+     * admin/conf.payway/setStatus
+     */
+    public function setStatus() {
+        $_id = $this->request->param('id/d');
+        $_status = $this->request->param('status/d', 0);
+        if (empty($_id) || empty($_status)) {
+            $this->adminError('参数错误!');
+        }
+        $_model = new PaywayModel();
+        $_info = $_model->getInfoById($_id);
+        if (empty($_info['config'])) {
+            $this->adminError('必须填写配置信息才可使用!');
+        }
+        $_data['status'] = $_status;
+        $_rs = $_model->updateData($_data, $_id);
+        if (false === $_rs) {
+            $this->adminError('修改失败!');
+        }
+        $this->adminSuccess('修改成功!');
+    }
+
+    /**
+     * 获取查找条件
+     */
+    public function getSearchParam() {
+        $_param = [];
+        /* 支付方式查找 */
+        $_param['payname'] = $this->request->param('payway/s', '');
+        $this->_payways($_param['payname']);
+        /* 状态查找 */
+        $_param['status'] = $this->request->param('status/d', CommonConst::CONST_ZERO);
+        $this->_status($_param['status']);
+        /* 类型查找 */
+        $_param['code'] = $this->request->param('code/s', '');
+        $this->_getCode($_param['code']);
+        /* 只显示需要后台配置的 */
+        $_param['is_config'] = CommonConst::STATUS_YES;
+
+        return $_param;
+    }
+
+    /**
+     * 类型选中器
+     *
+     * @param string $code
+     *
+     * @param string $disable
+     *
+     * @return array
+     */
+    public function _getCode($code = '', $disable = '') {
+        $_code_arr = [
+            'alipay' => '支付宝',
+            'wxpay'  => '微信'
+        ];
+        $_code_select = Filter::selectCommon($_code_arr, 'code', $code, 'select_2', $disable);
+        $this->assign('code_arr', $_code_arr);
+        $this->assign('code_select', $_code_select);
+
+        return $_code_arr;
+    }
+
+    /**
+     * 微信基本配置
+     *
+     * @param $code
+     *
+     * @return mixed
+     */
+    public function _getDefaultConf($code) {
+        $_conf = [
+            'wxpay'  => [
+                'mch_id'        => '', /* 商户号(必须配置,开户邮件中可查看) */
+                'js_app_id'     => '', /* 绑定支付的APPID(必须配置,开户邮件中可查看)*/
+                'js_app_secret' => '', /* 公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置),*/
+                'app_id'        => '', /* 绑定支付的APPID(必须配置,开户邮件中可查看)*/
+                'key'           => '', /* 商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置) */
+                'app_secret'    => '', /* 公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置),*/
+                'notify_url'    => MPSITE.'/wxpay/notify',
+            ],
+            'alipay' => [
+                'partner'          => '',  /* 合作者pid */
+                'key'              => '',  /* md5密钥 */
+                'sign_type'        => 'MD5',/* 签名方式 */
+                'seller_email'     => '', /* 支付宝账户 */
+                'private_key_path' => '', /* 私钥路径 */
+                'public_key_path'  => '', /* 公钥路径 */
+                'notify_url'       => APISITE.'/alipay/notify',
+            ]
+        ];
+
+        return $_conf[$code];
+    }
+
+    /**
+     * 添加菜单
+     *admin/conf.payway/addMenu
+     *
+     * @param int $parent_id
+     * @param int $list_order
+     *
+     * @return int|mixed
+     */
+    public function addMenu($parent_id = 365, $list_order = 90) {
+        $_controller = 'conf.payway';/* 控制器名 */
+        $_name = '支付配置'; /* 菜单名称 */
+        $_en_name = 'Payway Config'; /* 菜单英文名称 */
+        $_icon = 'yen'; /* 菜单图标 */
+        $_app = 'admin'; /* 应用名 */
+        $_menu_class = new Menu();
+        $_menu_class->setApp($_app);
+        /* 删除原有菜单 */
+        $_menu_class->deleteMenu($_controller);
+        $_menu_class->deleteMenu($_controller, $_app);
+        $_parent_id = 0;
+        if (empty($_parent_id)) {
+            $_parent_id = $this->request->param('parent_id/d', $parent_id);
+        }
+        $_list_order = 0;
+        if (empty($_list_order)) {
+            $_list_order = $this->request->param('list_order/d', $list_order);
+        }
+        /* 添加默认菜单 */
+        $_parent_id = $_menu_class->addDefaultMenu($_controller, $_parent_id, $_list_order, $_name, $_en_name, $_icon);
+        {
+            $_data = [
+                'parent_id'  => $_parent_id,
+                'type'       => 2,/* 菜单类型;1:有界面可访问菜单,2:无界面可访问菜单,0:只作为菜单 */
+                'status'     => 0,/* 状态;1:显示,0:不显示 */
+                'list_order' => 600,
+                'app'        => $_app,
+                'controller' => $_controller,
+                'action'     => 'editConf',
+                'param'      => '',
+                'name'       => '支付配置',
+                'en_name'    => 'editConf',
+                'icon'       => '',
+                'remark'     => '支付配置'
+            ];
+            $_menu_class->addMenu($_data);
+            $_data = [
+                'parent_id'  => $_parent_id,
+                'type'       => 2,/* 菜单类型;1:有界面可访问菜单,2:无界面可访问菜单,0:只作为菜单 */
+                'status'     => 0,/* 状态;1:显示,0:不显示 */
+                'list_order' => 500,
+                'app'        => $_app,
+                'controller' => $_controller,
+                'action'     => 'editConfPost',
+                'param'      => '',
+                'name'       => '支付配置提交',
+                'en_name'    => 'editConfPost',
+                'icon'       => '',
+                'remark'     => '支付配置提交'
+            ];
+            $_menu_class->addMenu($_data);
+        }
+        (new \admin\admin\controller\MenuController())->exportMenuLang();
+
+        return $_parent_id;
+    }
+}

+ 542 - 0
admin/admin/controller/data/DataController.php

@@ -0,0 +1,542 @@
+<?php
+/**
+ * DataController.php UTF-8
+ * 总体数据
+ *
+ * @date    : 2018/1/19 11:41
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\data;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\logic\agent\AgentLogic;
+use huo\logic\data\StatisticsLogic;
+use huo\logic\game\GameLogic;
+use huo\model\data\DayAgentModel;
+use huo\model\data\DayGameModel;
+use huo\model\data\DayModel;
+use huo\model\game\GameModel;
+use huo\model\order\OrderModel;
+use huo\model\user\AgentExtModel;
+use huo\model\user\RoleModel;
+use huo\model\user\UserModel;
+use huolib\constant\AgentConst;
+use huolib\constant\OrderConst;
+use think\Lang;
+
+class DataController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'statics'.EXT);
+    }
+
+    /**
+     * 总览
+     * admin/data.data/index
+     */
+    public function index() {
+        $_mem_model = new \huo\model\member\MemberModel();
+        $_order_model = new OrderModel();
+        $_user_model = new UserModel();
+        $_ae_model = new AgentExtModel();
+        $_game_model = new GameModel();
+        $_role_type = [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT];
+        $_role_ids = (new RoleModel())->getIdsByRoleType($_role_type);
+        $_role_map['role_id'] = ['in', $_role_ids];
+        $_oa_map = $_role_map;
+        $_map = [];
+        $_game_map = [];
+        if (!empty($this->cp_app_id)) {
+            $_map['app_id'] = ['in', $this->cp_app_id];
+            $_game_map['id'] = ['in', $this->cp_app_id];
+        }
+        if ($this->isAgent()) {
+            $_map['agent_id'] = $this->map['agent_id'];
+            $_map['is_switch'] = OrderConst::PAY_SWITCH_NO;
+            $_oa_map['parent_id'] = $this->map['agent_id'];
+        }
+        $_assign = [
+            'user_total'        => format_ten_thousand($_mem_model->total($_map)),
+            'user_paid'         => format_ten_thousand($_mem_model->paidCount($_map)),
+            'sum_money'         => format_ten_thousand($_order_model->totalMoney($_map)),
+            'online_agent'      => format_ten_thousand($_user_model->onlineCount($_oa_map)),
+            'online_game'       => format_ten_thousand($_game_model->onlineCount($_game_map)),
+            'user_non_agent'    => format_ten_thousand($_mem_model->nonAgentUserCount($_map)),
+            'user_agent'        => format_ten_thousand($_mem_model->agentUserCount($_map)),
+            'agent_sum_money'   => format_ten_thousand($_ae_model->sumMoney()),
+            'user_today'        => format_ten_thousand($_mem_model->todayCount($_map)),
+            'user_this_week'    => format_ten_thousand($_mem_model->thisWeekCount($_map)),
+            'user_this_month'   => format_ten_thousand($_mem_model->thisMonthCount($_map)),
+            'active_today'      => format_ten_thousand($_mem_model->todayActive($_map)),
+            'active_this_week'  => format_ten_thousand($_mem_model->thisWeekActive($_map)),
+            'active_this_month' => format_ten_thousand($_mem_model->thisMonthActive($_map)),
+            'money_today'       => format_ten_thousand($_order_model->todayMoney($_map)),
+            'money_this_week'   => format_ten_thousand($_order_model->thisWeekMoney($_map)),
+            'money_this_month'  => format_ten_thousand($_order_model->thisMonthMoney($_map)),
+        ];
+        $this->assign('data', $_assign);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 获取图标数据
+     *
+     * @return \think\response\Json
+     * @throws \Exception
+     */
+    public function chartData() {
+        $_result = [];
+        $_model = new DayModel();
+        $_start_date = date('Y-m-01');
+        $_end_date = date('Y-m-d');
+        $_today_data = (new StatisticsLogic())->getTodayData([]);
+        $_today_date = date('m-d');
+        switch ($this->request->request('type')) {
+            case 'active':
+                $_result['title'] = '活跃';
+                $_data = $_model->getByDate('user_cnt', $_start_date, $_end_date);
+                $_data[$_today_date] = $_today_data['user_cnt'];
+                break;
+            case 'register':
+                $_result['title'] = '新增';
+                $_data = $_model->getByDate('reg_cnt', $_start_date, $_end_date);
+                $_data[$_today_date] = $_today_data['reg_cnt'];
+                break;
+            case 'money':
+                $_result['title'] = '单日流水';
+                $_data = $_model->getByDate('sum_money', $_start_date, $_end_date);
+                $_data[$_today_date] = $_today_data['sum_money'];
+                break;
+            case 'ARPU':
+                $_result['title'] = 'ARPU';
+                $_data = $_model->getByDate('ROUND(sum_money/user_cnt, 2) arpu', $_start_date, $_end_date, 'arpu');
+                $_data[$_today_date] = $_today_data['arpu'];
+                break;
+            case 'pay_rate':
+                $_result['title'] = '付费率(%)';
+                $_result['percent'] = true;
+                $_data = $_model->getByDate(
+                    'ROUND(pay_user_cnt * 100 /user_cnt, 2) pay_rate', $_start_date, $_end_date, 'pay_rate'
+                );
+                $_data[$_today_date] = ($_today_data['pay_user_cnt'] / $_today_data['user_cnt']) * 100;
+                break;
+            case 'ARPPU':
+                $_result['title'] = 'ARPPU';
+                $_data = $_model->getByDate(
+                    'ROUND(sum_money/pay_user_cnt, 2) arppu', $_start_date, $_end_date, 'arppu'
+                );
+                $_data[$_today_date] = $_today_data['arppu'];
+                break;
+            default:
+                throw new \Exception('参数错误');
+        }
+        $_result['xData'] = array_keys($_data);
+        $_result['realxValue'] = array_values($_data);
+
+        return json($_result);
+    }
+
+    /**
+     * 实时数据
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function realTime() {
+        $_map = [];
+        $_agents = $this->_channels();
+        $_agents_select = Filter::selectCommon($_agents, 'agent_id', $this->request->param('agent_id/d', 0));
+        $this->assign('agents_select', $_agents_select);
+        $_agent_id = $this->request->param('agent_id/d', 0, 'intval');
+        if (!empty($_agent_id)) {
+            $_map['agent_id'] = $_agent_id;
+        }
+        $_games = $this->_game();
+        $_games_select = Filter::selectCommon($_games, 'app_id', $this->request->param('app_id/d', 0));
+        $this->assign('games_select', $_games_select);
+        $_app_id = $this->request->param('app_id/d', 0, 'intval');
+        if (!empty($_app_id)) {
+            $_map['app_id'] = $_app_id;
+        }
+        $this->assign('agent_id', $_agent_id);
+        $this->assign('app_id', $_app_id);
+        $_model = null;
+        if (!empty($_agent_id) && !empty($_app_id)) {
+            $_model = new DayAgentGameModel();
+            $_model->order('id');
+        } else if (!empty($_agent_id) && empty($_app_id)) {
+            $_model = new DayAgentModel();
+            $_model->order('agent_id');
+        } else if (empty($_agent_id) && !empty($_app_id)) {
+            $_model = new DayGameModel();
+            $_model->order('app_id');
+        } else {
+            $_model = new DayAgentGameModel();
+        }
+        $_items = $_model->where($_map)->paginate();
+        $_param = $this->request->param();
+        $_items->appends($_param);
+        $this->assign('page', $_items->render());
+        $this->assign('items', $_items);
+
+        return $this->fetch();
+    }
+
+    /**
+     * admin/data.data/testdata
+     */
+    public function testdata() {
+        $_cnt = $this->request->param('cnt/d', '90');
+        $_agents = (new AgentLogic())->getIdNames(26);
+        $_games = (new GameLogic())->getIdNames();
+        $_data = [];
+        foreach ($_agents as $_ck => $_cv) {
+            foreach ($_games as $_gk => $_gv) {
+                $_reg_cnt = 0;
+                for ($_i = 1; $_i <= $_cnt; $_i++) {
+                    $_data['agent_id'] = $_ck;
+                    $_data['app_id'] = $_gk;
+                    $_j = $_cnt - $_i;
+                    $_data['date'] = date('Y-m-d', strtotime("-$_j day"));
+                    $_data['reg_pay_cnt'] = rand(100, 10000);
+                    $_data['reg_cnt'] = $_data['reg_pay_cnt'] + rand(100, 10000);
+                    $_reg_cnt += $_data['reg_cnt'];
+                    $_data['user_cnt'] = rand($_data['reg_cnt'], $_reg_cnt);
+                    $_data['pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['reg_cnt']);
+                    $_data['first_pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['pay_user_cnt']);
+                    $_data['history_user_cnt'] = $_reg_cnt;
+                    $_data['reg_device_cnt'] = rand(1, $_data['reg_cnt']);
+                    $_data['first_pay_sum_money'] = rand(100, 1000000) / 100;
+                    $_data['reg_sum_money'] = rand(100, 1000000) / 100;
+                    $_data['sum_money'] = $_data['reg_sum_money'] + $_data['first_pay_sum_money'] + rand(100, 1000000)
+                                                                                                    / 100;
+                    $_data['day2'] = $_data['reg_cnt'] * rand(30, 60) / 100;
+                    $_data['day3'] = $_data['reg_cnt'] * rand(10, 40) / 100;
+                    $_data['day4'] = $_data['reg_cnt'] * rand(10, 40) / 100;
+                    $_data['day5'] = $_data['reg_cnt'] * rand(5, 30) / 100;
+                    $_data['day6'] = $_data['reg_cnt'] * rand(5, 30) / 100;
+                    $_data['day7'] = $_data['reg_cnt'] * rand(1, 20) / 100;
+                    $_data['day15'] = $_data['reg_cnt'] * rand(1, 10) / 100;
+                    $_data['day30'] = $_data['reg_cnt'] * rand(0, 5) / 100;
+                    $_data['device_day2'] = $_data['reg_device_cnt'] * rand(30, 60) / 100;
+                    $_data['device_day3'] = $_data['reg_device_cnt'] * rand(10, 40) / 100;
+                    $_data['device_day4'] = $_data['reg_device_cnt'] * rand(10, 40) / 100;
+                    $_data['device_day5'] = $_data['reg_device_cnt'] * rand(5, 30) / 100;
+                    $_data['device_day6'] = $_data['reg_device_cnt'] * rand(5, 30) / 100;
+                    $_data['device_day7'] = $_data['reg_device_cnt'] * rand(1, 20) / 100;
+                    $_data['device_day15'] = $_data['reg_device_cnt'] * rand(1, 10) / 100;
+                    $_data['device_day30'] = $_data['reg_device_cnt'] * rand(0, 5) / 100;
+                    db('day_game_agent')->insert($_data, true);
+                }
+            }
+        }
+//        $_month_cnt = ceil($_cnt / 30);
+//        $_data = [];
+//        foreach ($_agents as $_ck => $_cv) {
+//            foreach ($_games as $_gk => $_gv) {
+//                $_reg_cnt = 0;
+//                for ($_i = 1; $_i <= $_month_cnt; $_i++) {
+//                    $_data['agent_id'] = $_ck;
+//                    $_data['app_id'] = $_gk;
+//                    $_j = $_cnt - $_i;
+//                    $_data['date'] = date('Y-m-01', strtotime("-$_j month"));
+//                    $_data['reg_pay_cnt'] = rand(100, 10000);
+//                    $_data['reg_cnt'] = $_data['reg_pay_cnt'] + rand(100, 10000);
+//                    $_reg_cnt += $_data['reg_cnt'];
+//                    $_data['user_cnt'] = rand($_data['reg_cnt'], $_reg_cnt);
+//                    $_data['pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['reg_cnt']);
+//                    $_data['first_pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['pay_user_cnt']);
+//                    $_data['history_user_cnt'] = $_reg_cnt;
+//                    $_data['reg_device_cnt'] = rand(1, $_data['reg_cnt']);
+//                    $_data['first_pay_sum_money'] = rand(100, 1000000) / 100;
+//                    $_data['reg_sum_money'] = rand(100, 1000000) / 100;
+//                    $_data['sum_money'] = $_data['reg_sum_money'] + $_data['first_pay_sum_money'] + rand(100, 1000000)
+//                                                                                                    / 100;
+//                    db('month_game_agent')->insert($_data, true);
+//                }
+//            }
+//        }
+        $_data = [];
+        foreach ($_agents as $_ck => $_cv) {
+            $_reg_cnt = 0;
+            for ($_i = 1; $_i <= $_cnt; $_i++) {
+                $_data['agent_id'] = $_ck;
+                $_j = $_cnt - $_i;
+                $_data['date'] = date('Y-m-d', strtotime("-$_j day"));
+                $_data['reg_pay_cnt'] = rand(100, 10000);
+                $_data['reg_cnt'] = $_data['reg_pay_cnt'] + rand(100, 10000);
+                $_reg_cnt += $_data['reg_cnt'];
+                $_data['user_cnt'] = rand($_data['reg_cnt'], $_reg_cnt);
+                $_data['pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['reg_cnt']);
+                $_data['first_pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['pay_user_cnt']);
+                $_data['history_user_cnt'] = $_reg_cnt;
+                $_data['reg_device_cnt'] = rand(1, $_data['reg_cnt']);
+                $_data['first_pay_sum_money'] = rand(100, 1000000) / 100;
+                $_data['reg_sum_money'] = rand(100, 1000000) / 100;
+                $_data['sum_money'] = $_data['reg_sum_money'] + $_data['first_pay_sum_money'] + rand(100, 1000000)
+                                                                                                / 100;
+                $_data['day2'] = $_data['reg_cnt'] * rand(30, 60) / 100;
+                $_data['day3'] = $_data['reg_cnt'] * rand(10, 40) / 100;
+                $_data['day4'] = $_data['reg_cnt'] * rand(10, 40) / 100;
+                $_data['day5'] = $_data['reg_cnt'] * rand(5, 30) / 100;
+                $_data['day6'] = $_data['reg_cnt'] * rand(5, 30) / 100;
+                $_data['day7'] = $_data['reg_cnt'] * rand(1, 20) / 100;
+                $_data['day15'] = $_data['reg_cnt'] * rand(1, 10) / 100;
+                $_data['day30'] = $_data['reg_cnt'] * rand(0, 5) / 100;
+                $_data['device_day2'] = $_data['reg_device_cnt'] * rand(30, 60) / 100;
+                $_data['device_day3'] = $_data['reg_device_cnt'] * rand(10, 40) / 100;
+                $_data['device_day4'] = $_data['reg_device_cnt'] * rand(10, 40) / 100;
+                $_data['device_day5'] = $_data['reg_device_cnt'] * rand(5, 30) / 100;
+                $_data['device_day6'] = $_data['reg_device_cnt'] * rand(5, 30) / 100;
+                $_data['device_day7'] = $_data['reg_device_cnt'] * rand(1, 20) / 100;
+                $_data['device_day15'] = $_data['reg_device_cnt'] * rand(1, 10) / 100;
+                $_data['device_day30'] = $_data['reg_device_cnt'] * rand(0, 5) / 100;
+                db('day_agent')->insert($_data, true);
+            }
+        }
+        $_data = [];
+//        $_month_cnt = ceil($_cnt / 30);
+//        foreach ($_agents as $_ck => $_cv) {
+//            $_reg_cnt = 0;
+//            for ($_i = 1; $_i <= $_month_cnt; $_i++) {
+//                $_data['agent_id'] = $_ck;
+//                $_j = $_cnt - $_i;
+//                $_data['date'] = date('Y-m-01', strtotime("-$_j month"));
+//                $_data['reg_pay_cnt'] = rand(100, 10000);
+//                $_data['reg_cnt'] = $_data['reg_pay_cnt'] + rand(100, 10000);
+//                $_reg_cnt += $_data['reg_cnt'];
+//                $_data['user_cnt'] = rand($_data['reg_cnt'], $_reg_cnt);
+//                $_data['pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['reg_cnt']);
+//                $_data['first_pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['pay_user_cnt']);
+//                $_data['history_user_cnt'] = $_reg_cnt;
+//                $_data['reg_device_cnt'] = rand(1, $_data['reg_cnt']);
+//                $_data['first_pay_sum_money'] = rand(100, 1000000) / 100;
+//                $_data['reg_sum_money'] = rand(100, 1000000) / 100;
+//                $_data['sum_money'] = $_data['reg_sum_money'] + $_data['first_pay_sum_money'] + rand(100, 1000000)
+//                                                                                                / 100;
+//                db('month_agent')->insert($_data, true);
+//            }
+//        }
+        $_data = [];
+        foreach ($_games as $_gk => $_gv) {
+            $_reg_cnt = 0;
+            for ($_i = 1; $_i <= $_cnt; $_i++) {
+                $_data['app_id'] = $_gk;
+                $_j = $_cnt - $_i;
+                $_data['date'] = date('Y-m-d', strtotime("-$_j day"));
+                $_data['reg_pay_cnt'] = rand(100, 10000);
+                $_data['reg_cnt'] = $_data['reg_pay_cnt'] + rand(100, 10000);
+                $_reg_cnt += $_data['reg_cnt'];
+                $_data['user_cnt'] = rand($_data['reg_cnt'], $_reg_cnt);
+                $_data['pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['reg_cnt']);
+                $_data['first_pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['pay_user_cnt']);
+                $_data['history_user_cnt'] = $_reg_cnt;
+                $_data['reg_device_cnt'] = rand(1, $_data['reg_cnt']);
+                $_data['first_pay_sum_money'] = rand(100, 1000000) / 100;
+                $_data['reg_sum_money'] = rand(100, 1000000) / 100;
+                $_data['sum_money'] = $_data['reg_sum_money'] + $_data['first_pay_sum_money'] + rand(100, 1000000)
+                                                                                                / 100;
+                $_data['day2'] = $_data['reg_cnt'] * rand(30, 60) / 100;
+                $_data['day3'] = $_data['reg_cnt'] * rand(10, 40) / 100;
+                $_data['day4'] = $_data['reg_cnt'] * rand(10, 40) / 100;
+                $_data['day5'] = $_data['reg_cnt'] * rand(5, 30) / 100;
+                $_data['day6'] = $_data['reg_cnt'] * rand(5, 30) / 100;
+                $_data['day7'] = $_data['reg_cnt'] * rand(1, 20) / 100;
+                $_data['day15'] = $_data['reg_cnt'] * rand(1, 10) / 100;
+                $_data['day30'] = $_data['reg_cnt'] * rand(0, 5) / 100;
+                $_data['device_day2'] = $_data['reg_device_cnt'] * rand(30, 60) / 100;
+                $_data['device_day3'] = $_data['reg_device_cnt'] * rand(10, 40) / 100;
+                $_data['device_day4'] = $_data['reg_device_cnt'] * rand(10, 40) / 100;
+                $_data['device_day5'] = $_data['reg_device_cnt'] * rand(5, 30) / 100;
+                $_data['device_day6'] = $_data['reg_device_cnt'] * rand(5, 30) / 100;
+                $_data['device_day7'] = $_data['reg_device_cnt'] * rand(1, 20) / 100;
+                $_data['device_day15'] = $_data['reg_device_cnt'] * rand(1, 10) / 100;
+                $_data['device_day30'] = $_data['reg_device_cnt'] * rand(0, 5) / 100;
+                db('day_game')->insert($_data, true);
+            }
+        }
+//        $_data = [];
+//        $_month_cnt = ceil($_cnt / 30);
+//        foreach ($_games as $_gk => $_gv) {
+//            $_reg_cnt = 0;
+//            for ($_i = 1; $_i <= $_month_cnt; $_i++) {
+//                $_data['app_id'] = $_gk;
+//                $_j = $_cnt - $_i;
+//                $_data['date'] = date('Y-m-01', strtotime("-$_j month"));
+//                $_data['reg_pay_cnt'] = rand(100, 10000);
+//                $_data['reg_cnt'] = $_data['reg_pay_cnt'] + rand(100, 10000);
+//                $_reg_cnt += $_data['reg_cnt'];
+//                $_data['user_cnt'] = rand($_data['reg_cnt'], $_reg_cnt);
+//                $_data['pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['reg_cnt']);
+//                $_data['first_pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['pay_user_cnt']);
+//                $_data['history_user_cnt'] = $_reg_cnt;
+//                $_data['reg_device_cnt'] = rand(1, $_data['reg_cnt']);
+//                $_data['first_pay_sum_money'] = rand(100, 1000000) / 100;
+//                $_data['reg_sum_money'] = rand(100, 1000000) / 100;
+//                $_data['sum_money'] = $_data['reg_sum_money'] + $_data['first_pay_sum_money'] + rand(100, 1000000)
+//                                                                                                / 100;
+//                db('month_game')->insert($_data, true);
+//            }
+//        }
+        $_data = [];
+        $_reg_cnt = 0;
+        for ($_i = 1; $_i <= $_cnt; $_i++) {
+            $_j = $_cnt - $_i;
+            $_data['date'] = date('Y-m-d', strtotime("-$_j day"));
+            $_data['reg_pay_cnt'] = rand(100, 10000);
+            $_data['reg_cnt'] = $_data['reg_pay_cnt'] + rand(100, 10000);
+            $_reg_cnt += $_data['reg_cnt'];
+            $_data['user_cnt'] = rand($_data['reg_cnt'], $_reg_cnt);
+            $_data['pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['reg_cnt']);
+            $_data['first_pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['pay_user_cnt']);
+            $_data['history_user_cnt'] = $_reg_cnt;
+            $_data['reg_device_cnt'] = rand(1, $_data['reg_cnt']);
+            $_data['first_pay_sum_money'] = rand(100, 1000000) / 100;
+            $_data['reg_sum_money'] = rand(100, 1000000) / 100;
+            $_data['sum_money'] = $_data['reg_sum_money'] + $_data['first_pay_sum_money'] + rand(100, 1000000)
+                                                                                            / 100;
+            $_data['day2'] = $_data['reg_cnt'] * rand(30, 60) / 100;
+            $_data['day3'] = $_data['reg_cnt'] * rand(10, 40) / 100;
+            $_data['day4'] = $_data['reg_cnt'] * rand(10, 40) / 100;
+            $_data['day5'] = $_data['reg_cnt'] * rand(5, 30) / 100;
+            $_data['day6'] = $_data['reg_cnt'] * rand(5, 30) / 100;
+            $_data['day7'] = $_data['reg_cnt'] * rand(1, 20) / 100;
+            $_data['day15'] = $_data['reg_cnt'] * rand(1, 10) / 100;
+            $_data['day30'] = $_data['reg_cnt'] * rand(0, 5) / 100;
+            $_data['device_day2'] = $_data['reg_device_cnt'] * rand(30, 60) / 100;
+            $_data['device_day3'] = $_data['reg_device_cnt'] * rand(10, 40) / 100;
+            $_data['device_day4'] = $_data['reg_device_cnt'] * rand(10, 40) / 100;
+            $_data['device_day5'] = $_data['reg_device_cnt'] * rand(5, 30) / 100;
+            $_data['device_day6'] = $_data['reg_device_cnt'] * rand(5, 30) / 100;
+            $_data['device_day7'] = $_data['reg_device_cnt'] * rand(1, 20) / 100;
+            $_data['device_day15'] = $_data['reg_device_cnt'] * rand(1, 10) / 100;
+            $_data['device_day30'] = $_data['reg_device_cnt'] * rand(0, 5) / 100;
+            db('day')->insert($_data, true);
+        }
+//        $_data = [];
+//        $_month_cnt = ceil($_cnt / 30);
+//        $_reg_cnt = 0;
+//        for ($_i = 1; $_i <= $_month_cnt; $_i++) {
+//            $_j = $_cnt - $_i;
+//            $_data['date'] = date('Y-m-01', strtotime("-$_j month"));
+//            $_data['reg_pay_cnt'] = rand(100, 10000);
+//            $_data['reg_cnt'] = $_data['reg_pay_cnt'] + rand(100, 10000);
+//            $_reg_cnt += $_data['reg_cnt'];
+//            $_data['user_cnt'] = rand($_data['reg_cnt'], $_reg_cnt);
+//            $_data['pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['reg_cnt']);
+//            $_data['first_pay_user_cnt'] = rand($_data['reg_pay_cnt'], $_data['pay_user_cnt']);
+//            $_data['history_user_cnt'] = $_reg_cnt;
+//            $_data['reg_device_cnt'] = rand(1, $_data['reg_cnt']);
+//            $_data['first_pay_sum_money'] = rand(100, 1000000) / 100;
+//            $_data['reg_sum_money'] = rand(100, 1000000) / 100;
+//            $_data['sum_money'] = $_data['reg_sum_money'] + $_data['first_pay_sum_money'] + rand(100, 1000000)
+//                                                                                            / 100;
+//            db('month')->insert($_data, true);
+//        }
+        echo 'ok';
+        exit;
+    }
+
+    /**
+     * 自然日数据
+     *
+     * @return mixed
+     */
+    public function day() {
+        $_map = [];
+        $_agents = $this->_channels();
+        $_agents_select = Filter::selectCommon($_agents, 'agent_id', $this->request->param('agent_id/d', 0));
+        $this->assign('agents_select', $_agents_select);
+        $_agent_id = $this->request->param('agent_id/d', 0, 'intval');
+        if (!empty($_agent_id)) {
+            $_map['agent_id'] = $_agent_id;
+        }
+        $_games = $this->_game();
+        $_games_select = Filter::selectCommon($_games, 'app_id', $this->request->param('app_id/d', 0));
+        $this->assign('games_select', $_games_select);
+        $_app_id = $this->request->param('app_id/d', 0, 'intval');
+        if (!empty($_app_id)) {
+            $_map['app_id'] = $_app_id;
+        }
+        $this->assign('agent_id', $_agent_id);
+        $this->assign('app_id', $_app_id);
+        $_start_time = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_end_time = $this->request->param('end_time', date('Y-m-d'));
+        $_time_choose = Filter::timeChoose($_start_time, $_end_time, 'yyyy-mm-dd');
+        $_map['date'] = ['between', $_start_time.','.$_end_time];
+        $this->assign('time_choose', $_time_choose);
+        if (!empty($_agent_id) && !empty($_app_id)) {
+            $_model = new DayAgentGameModel();
+        } else if (!empty($_agent_id) && empty($_app_id)) {
+            $_model = new DayAgentModel();
+        } else if (empty($_agent_id) && !empty($_app_id)) {
+            $_model = new DayGameModel();
+        } else {
+            $_model = new DayModel();
+        }
+        $_items = $_model->where($_map)->order('date desc')->paginate();
+        $_param = $this->request->param();
+        $_items->appends($_param);
+        $this->assign('page', $_items->render());
+        $this->assign('items', $_items);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 自然月数据
+     *
+     * @return mixed
+     */
+    public function month() {
+//        try {
+        $_map = [];
+        $_agents = $this->_channels();
+        $_agents_select = Filter::selectCommon($_agents, 'agent_id', $this->request->param('agent_id/d', 0));
+        $this->assign('agents_select', $_agents_select);
+        $_agent_id = $this->request->param('agent_id/d', 0, 'intval');
+        if (!empty($_agent_id)) {
+            $_map['agent_id'] = $_agent_id;
+        }
+        $this->assign('agent_id', $_agent_id);
+        $_games = $this->_game();
+        $_games_select = Filter::selectCommon($_games, 'app_id', $this->request->param('app_id/d', 0));
+        $this->assign('games_select', $_games_select);
+        $_app_id = $this->request->param('app_id/d', 0, 'intval');
+        if (!empty($_app_id)) {
+            $_map['app_id'] = $_app_id;
+        }
+        $this->assign('app_id', $_app_id);
+        $_start_time = $this->request->param('start_time', date('Y-m', strtotime('-100 month')));
+        $_end_time = $this->request->param('end_time', date('Y-m'));
+        $_time_choose = Filter::timeChoose($_start_time, $_end_time, 'yyyy-mm');
+        $_map['date'] = ['between', $_start_time.'-01,'.$_end_time.'-01'];
+        $this->assign('time_choose', $_time_choose);
+        if (!empty($_agent_id) && !empty($_app_id)) {
+            $_model = new MonthGameAgentModel();
+        } else if (!empty($_agent_id) && empty($_app_id)) {
+            $_model = new MonthAgentModel();
+        } else if (empty($_agent_id) && !empty($_app_id)) {
+            $_model = new MonthGameModel();
+        } else {
+            $_model = new MonthModel();
+        }
+        $_items = $_model->where($_map)->order('date desc')->paginate();
+        $_param = $this->request->param();
+        $_items->appends($_param);
+        $this->assign('page', $_items->render());
+        $this->assign('items', $_items);
+
+        return $this->fetch();
+//        } catch (Exception $_e) {
+//            return $this->error($_e->getMessage());
+//        }
+    }
+}
+

+ 665 - 0
admin/admin/controller/data/DayController.php

@@ -0,0 +1,665 @@
+<?php
+/**
+ * PayDataController.php UTF-8
+ *
+ *
+ * @date    : 2017/12/18 11:16
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : liguanglong <lgl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\data;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\agent\AgentGame;
+use huo\logic\agent\AgentLogic;
+use huo\logic\data\DayDataLogic;
+use huo\logic\data\DayDataSwitchLogic;
+use huo\logic\data\GenDataLogic;
+use huo\logic\data\StatisticsLogic;
+use huo\logic\data\StatisticsSwitchLogic;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\tool\Export;
+use huolib\tool\StrUtils;
+use think\Lang;
+
+class DayController extends AdminbaseController {
+    protected $data_games  = [];
+    protected $data_agents = [];
+
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'statics'.EXT);
+    }
+
+    /**
+     * 获取数据仓库配置
+     */
+    public function getDbConfig() {
+        $_db_dw = [    // 数据库类型
+                       'type'            => '',
+                       // 服务器地址
+                       'hostname'        => '',
+                       // 数据库名
+                       'database'        => '',
+                       // 用户名
+                       'username'        => '',
+                       // 密码
+                       'password'        => '',
+                       // 端口
+                       'hostport'        => '',
+                       // 数据库编码默认采用utf8
+                       'charset'         => 'utf8mb4',
+                       // 数据库表前缀
+                       'prefix'          => 'dw_',
+                       // 连接dsn
+                       'dsn'             => '',
+                       // 数据库连接参数
+                       'params'          => [],
+                       // 数据库调试模式
+                       'debug'           => true,
+                       // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
+                       'deploy'          => 0,
+                       // 数据库读写是否分离 主从式有效
+                       'rw_separate'     => false,
+                       // 读写分离后 主服务器数量
+                       'master_num'      => 1,
+                       // 指定从服务器序号
+                       'slave_no'        => '',
+                       // 是否严格检查字段是否存在
+                       'fields_strict'   => true,
+                       // 数据集返回类型
+                       'resultset_type'  => 'collection',
+                       // 自动写入时间戳字段
+                       'auto_timestamp'  => false,
+                       // 时间字段取出后的默认时间格式
+                       'datetime_format' => false,
+                       // 是否需要进行SQL性能分析
+                       'sql_explain'     => false,];
+        if (file_exists(CMF_ROOT.'data/conf/database_dw.php')) {
+            $_db_dw = include CMF_ROOT.'data/conf/database_dw.php';
+        }
+//        $_db_dw['username'] = 'root';
+//        $_db_dw['password'] = 'A5zX;jAYsK6iYKQN';
+
+        return $_db_dw;
+    }
+
+    /**
+     * 每个自然日数据导出
+     */
+    public function exportIndex() {
+        list($_param, $_order) = $this->_getSearchParam();
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new DayDataLogic())->getAdminList($_param, $_page, $_order);
+        $_data['sum'] = (new StatisticsLogic())->getStatisticsData($_param);
+        $_total_cnt = $_data['count'];
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_today_data = [];
+        $_now_time = time();
+        if (!empty($_param['start_time'])) {
+            $_start_time = strtotime($_param['start_time']);
+        }
+        if (empty($_start_time)) {
+            $_start_time = 0;
+        }
+        if (!empty($_param['end_time'])) {
+            $_end_time = strtotime($_param['end_time']) + CommonConst::CONST_DAY_SECONDS;
+        }
+        if (empty($_end_time)) {
+            $_end_time = $_now_time;
+        }
+        if ($_now_time > $_start_time && $_now_time <= $_end_time && '-date' == $_order) {
+            $_today_data = (new StatisticsLogic())->getTodayData($_param);
+        }
+        $_head = ['日期'];
+        if (!empty($_param['app_id'])) {
+            array_push($_head, '游戏');
+        }
+        if (!empty($_param['agent_id'])) {
+            array_push($_head, '渠道');
+        }
+        $_head2 = [
+            '新增用户',
+            '新增创角',
+            //                '新增设备',
+            '活跃用户',
+            //                '新增即付费人数',
+            //                '新增即付费金额',
+            '新增付费人数',
+            '新增付费金额',
+            '新用户订单',
+            '总订单',
+            '总付费人数',
+            '总付费金额',
+            '新增付费率',
+            '活跃付费率',
+            '新增注册ARPU',
+            '活跃ARPU',
+            '付费ARPU',
+        ];
+        $_head = array_merge($_head, $_head2);
+        $_export_datas = [];
+        $_data_sum['total'] = '汇总';
+        if (!empty($_param['app_id'])) {
+            $_data_sum['game'] = '--';
+        }
+        if (!empty($_param['agent_id'])) {
+            $_data_sum['agent'] = '--';
+        }
+        $_data_sum['reg_cnt'] = $_data['sum']['reg_cnt'];
+        $_data_sum['role_cnt'] = $_data['sum']['role_cnt'];
+//                $_data_sum['reg_device_cnt'] = $_data['sum']['reg_device_cnt'];
+        $_data_sum['user_cnt'] = $_data['sum']['user_cnt'];
+//                $_data_sum['reg_pay_cnt'] = $_data['sum']['reg_pay_cnt'];
+//                $_data_sum['reg_sum_money'] = $_data['sum']['reg_sum_money'];
+        $_data_sum['first_pay_user_cnt'] = $_data['sum']['reg_pay_cnt'];
+        $_data_sum['first_pay_sum_money'] = $_data['sum']['reg_sum_money'];
+        $_data_sum['reg_order_cnt'] = $_data['sum']['reg_order_cnt'];
+        $_data_sum['order_cnt'] = $_data['sum']['order_cnt'];
+        $_data_sum['pay_user_cnt'] = $_data['sum']['pay_user_cnt'];
+        $_data_sum['sum_money'] = $_data['sum']['sum_money'];
+        $_data_sum['reg_pay_rate'] = $_data['sum']['reg_pay_rate'];
+        $_data_sum['user_pay_rate'] = $_data['sum']['user_pay_rate'];
+        $_data_sum['reg_arpu'] = $_data['sum']['reg_arpu'];
+        $_data_sum['arpu'] = $_data['sum']['arpu'];
+        $_data_sum['arppu'] = $_data['sum']['arppu'];
+        $_export_datas[] = $_data_sum;
+        if (!empty($_today_data)) {
+            $_val = $_today_data;
+            $_export_data['date'] = date('Y-m-d');
+            if (!empty($_param['app_id'])) {
+                $_export_data['game'] = $this->data_games[$_GET['app_id']];
+            }
+            if (!empty($_GET['agent_id']) || !empty($_GET['director_id']) || !empty($_GET['group_id'])) {
+                if (!empty($_GET['data_summary']) && 2 == $_GET['data_summary']) {
+                    if (!empty($_GET['agent_id'])) {
+                        $_export_data['agent'] = $this->data_agents[$_GET['agent_id']];
+                    }
+                } else {
+                    $_export_data['agent'] = $this->data_agents[$_GET['agent_id']];
+                }
+            }
+            $_export_data['reg_cnt'] = $_val['reg_cnt'];
+            $_export_data['role_cnt'] = $_val['role_cnt'];
+//                $_export_data['reg_device_cnt'] = $_val['reg_device_cnt'];
+            $_export_data['user_cnt'] = $_val['user_cnt'];
+//                $_export_data['reg_pay_cnt'] = $_val['reg_pay_cnt'];
+//                $_export_data['reg_sum_money'] = $_val['reg_sum_money'];
+            $_export_data['first_pay_user_cnt'] = $_val['reg_pay_cnt'];
+            $_export_data['first_pay_sum_money'] = $_val['reg_sum_money'];
+            $_export_data['reg_order_cnt'] = $_val['reg_order_cnt'];
+            $_export_data['order_cnt'] = $_val['order_cnt'];
+            $_export_data['pay_user_cnt'] = $_val['pay_user_cnt'];
+            $_export_data['sum_money'] = $_val['sum_money'];
+            $_export_data['reg_pay_rate'] = $_val['reg_pay_rate'];
+            $_export_data['user_pay_rate'] = $_val['user_pay_rate'];
+            $_export_data['reg_arpu'] = $_val['reg_arpu'];
+            $_export_data['arpu'] = $_val['arpu'];
+            $_export_data['arppu'] = $_val['arppu'];
+            $_export_datas[] = $_export_data;
+        }
+        $_for_cnt = empty($_for_cnt) ? 1 : $_for_cnt;
+        while ($_p <= $_for_cnt) {
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['date'] = $_val['date'];
+                if (!empty($_param['app_id'])) {
+                    $_export_data['game'] = $this->data_games[$_val['app_id']];
+                }
+                if (!empty($_GET['agent_id']) || !empty($_GET['director_id']) || !empty($_GET['group_id'])) {
+                    if (!empty($_GET['data_summary']) && 2 == $_GET['data_summary']) {
+                        if (!empty($_GET['agent_id'])) {
+                            $_export_data['agent'] = $this->data_agents[$_GET['agent_id']];
+                        }
+                    } else {
+                        $_export_data['agent'] = $this->data_agents[$_GET['agent_id']];
+                    }
+                }
+                $_export_data['reg_cnt'] = $_val['reg_cnt'];
+                $_export_data['role_cnt'] = $_val['role_cnt'];
+//                $_export_data['reg_device_cnt'] = $_val['reg_device_cnt'];
+                $_export_data['user_cnt'] = $_val['user_cnt'];
+//                $_export_data['reg_pay_cnt'] = $_val['reg_pay_cnt'];
+//                $_export_data['reg_sum_money'] = $_val['reg_sum_money'];
+                $_export_data['first_pay_user_cnt'] = $_val['reg_pay_cnt'];
+                $_export_data['first_pay_sum_money'] = $_val['reg_sum_money'];
+                $_export_data['reg_order_cnt'] = $_val['reg_order_cnt'];
+                $_export_data['order_cnt'] = $_val['order_cnt'];
+                $_export_data['pay_user_cnt'] = $_val['pay_user_cnt'];
+                $_export_data['sum_money'] = $_val['sum_money'];
+                $_export_data['reg_pay_rate'] = $_val['reg_pay_rate'];
+                $_export_data['user_pay_rate'] = $_val['user_pay_rate'];
+                $_export_data['reg_arpu'] = $_val['reg_arpu'];
+                $_export_data['arpu'] = $_val['arpu'];
+                $_export_data['arppu'] = $_val['arppu'];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '每日数据', '.csv', true);
+                break;
+            } else {
+                $_file_name = '每日数据'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new DayDataLogic())->getAdminList($_param, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '每日数据');
+    }
+
+    /**
+     * 每个自然日数据
+     *
+     * admin/data.day/index
+     *
+     */
+    public function index() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIndex();
+        }
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        list($_param, $_order) = $this->_getSearchParam();
+        if ($this->isAgent()) {
+            $_agent_ids = (new AgentLogic())->getAgentIds($this->admin_id, true);
+            $_param['agent_id'] = ['in', $_agent_ids];
+            $_data = (new DayDataSwitchLogic())->getAdminList($_param, $_page.','.$_list_rows, $_order);
+        } else {
+            $_data = (new DayDataLogic())->getAdminList($_param, $_page.','.$_list_rows, $_order);
+        }
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        $_today_data = [];
+        $_now_time = time();
+        if (!empty($_param['start_time'])) {
+            $_start_time = strtotime($_param['start_time']);
+        }
+        if (empty($_start_time)) {
+            $_start_time = 0;
+        }
+        if (!empty($_param['end_time'])) {
+            $_end_time = strtotime($_param['end_time']) + CommonConst::CONST_DAY_SECONDS;
+        }
+        if (empty($_end_time)) {
+            $_end_time = $_now_time;
+        }
+        if ($_now_time > $_start_time && $_now_time <= $_end_time && '-date' == $_order) {
+            if ($this->isAgent()) {
+                $_today_data = (new StatisticsSwitchLogic())->getTodayData($_param);
+            } else {
+                $_today_data = (new StatisticsLogic())->getTodayData($_param);
+            }
+            foreach ($_today_data as $_k => $_v) {
+                if (isset($_data['sum'][$_k])) {
+                    if (is_numeric($_v)) {
+                        $_data['sum'][$_k] += $_v;
+                    }
+                } else {
+                    $_data['sum'][$_k] = $_v;
+                }
+            }
+            if (isset($_data['sum']['reg_pay_cnt']) && isset($_data['sum']['reg_cnt'])) {
+                $_data['sum']['reg_pay_rate'] = StrUtils::getRate(
+                    $_data['sum']['reg_pay_cnt'], $_data['sum']['reg_cnt']
+                );
+            }
+            if (isset($_data['sum']['pay_user_cnt']) && isset($_data['sum']['user_cnt'])) {
+                $_data['sum']['user_pay_rate'] = StrUtils::getRate(
+                    $_data['sum']['pay_user_cnt'], $_data['sum']['user_cnt']
+                );
+            }
+            if (isset($_data['sum']['reg_sum_money']) && isset($_data['sum']['reg_cnt'])) {
+                $_data['sum']['reg_arpu'] = StrUtils::getArpu($_data['sum']['reg_sum_money'], $_data['sum']['reg_cnt']);
+            }
+            if (isset($_data['sum']['sum_money']) && isset($_data['sum']['user_cnt'])) {
+                $_data['sum']['arpu'] = StrUtils::getArpu($_data['sum']['sum_money'], $_data['sum']['user_cnt']);
+            }
+            if (isset($_data['sum']['sum_money']) && isset($_data['sum']['pay_user_cnt'])) {
+                $_data['sum']['arppu'] = StrUtils::getArpu($_data['sum']['sum_money'], $_data['sum']['pay_user_cnt']);
+            }
+            $_today_data = [$_today_data];
+        }
+        $this->assign('sum', $_data['sum']);
+        $this->assign('today_data', $_today_data);
+
+        return $this->fetch('data/day/index');
+    }
+
+    /**
+     * cpas自然日数据导出
+     */
+    public function exportCpa() {
+        list($_param, $_order) = $this->_getSearchParam();
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new DayDataLogic())->getAdminList($_param, $_page, $_order);
+        $_total_cnt = $_data['count'];
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_sum_data = (new StatisticsLogic())->getStatisticsData($_param);
+        $_data['sum'] = $_sum_data;
+        $_today_data = [];
+        $_now_time = time();
+        if (!empty($_param['start_time'])) {
+            $_start_time = strtotime($_param['start_time']);
+        }
+        if (empty($_start_time)) {
+            $_start_time = 0;
+        }
+        if (!empty($_param['end_time'])) {
+            $_end_time = strtotime($_param['end_time']) + CommonConst::CONST_DAY_SECONDS;
+        }
+        if (empty($_end_time)) {
+            $_end_time = $_now_time;
+        }
+        if ($_now_time > $_start_time && $_now_time <= $_end_time && '-date' == $_order) {
+            $_today_data = (new StatisticsLogic())->getTodayData($_param);
+        }
+        $_head = ['日期'];
+        if (!empty($_param['app_id'])) {
+            array_push($_head, '游戏');
+        }
+        if (!empty($_param['agent_id'])) {
+            array_push($_head, '渠道');
+        }
+        $_head2 = [
+            '新增用户',
+            //                'CPA有效用户',
+            '注册IP',
+            '活跃IP',
+            '新增微信openid',
+            '活跃用户',
+            '总付费人数',
+            '新增付费人数',
+            '活跃付费率',
+            '总付费金额',
+        ];
+        $_head = array_merge($_head, $_head2);
+        $_export_datas = [];
+        $_data_sum['total'] = '汇总';
+        if (!empty($_param['app_id'])) {
+            $_data_sum['game'] = '--';
+        }
+        if (!empty($_param['agent_id'])) {
+            $_data_sum['agent'] = '--';
+        }
+        $_data_sum['reg_cnt'] = $_data['sum']['reg_cnt'];
+//                $_data_sum['cpa_cnt'] = $_data['sum']['cpa_cnt'];
+        $_data_sum['reg_ip_cnt'] = $_data['sum']['reg_ip_cnt'];
+        $_data_sum['ip_cnt'] = $_data['sum']['ip_cnt'];
+        $_data_sum['openid_cnt'] = $_data['sum']['openid_cnt'];
+        $_data_sum['user_cnt'] = $_data['sum']['user_cnt'];
+        $_data_sum['pay_user_cnt'] = $_data['sum']['pay_user_cnt'];
+        $_data_sum['reg_pay_cnt'] = $_data['sum']['reg_pay_cnt'];
+        $_data_sum['user_pay_rate'] = $_data['sum']['user_pay_rate'];
+        $_data_sum['sum_money'] = $_data['sum']['sum_money'];
+        $_export_datas[] = $_data_sum;
+        if (!empty($_today_data)) {
+            $_val = $_today_data;
+            $_export_data['date'] = date('Y-m-d');
+            if (!empty($_param['app_id'])) {
+                $_export_data['game'] = $this->data_games[$_GET['app_id']];
+            }
+            if (!empty($_GET['agent_id']) || !empty($_GET['director_id']) || !empty($_GET['group_id'])) {
+                if (!empty($_GET['data_summary']) && 2 == $_GET['data_summary']) {
+                    if (!empty($_GET['agent_id'])) {
+                        $_export_data['agent'] = $this->data_agents[$_GET['agent_id']];
+                    }
+                } else {
+                    $_export_data['agent'] = $this->data_agents[$_GET['agent_id']];
+                }
+            }
+            $_export_data['reg_cnt'] = $_val['reg_cnt'];
+//                $_export_data['cpa_cnt'] = $_val['cpa_cnt'];
+            $_export_data['reg_ip_cnt'] = $_val['reg_ip_cnt'];
+            $_export_data['ip_cnt'] = $_val['ip_cnt'];
+            $_export_data['openid_cnt'] = $_val['openid_cnt'];
+            $_export_data['user_cnt'] = $_val['user_cnt'];
+            $_export_data['pay_user_cnt'] = $_val['pay_user_cnt'];
+            $_export_data['reg_pay_cnt'] = $_val['reg_pay_cnt'];
+            $_export_data['user_pay_rate'] = $_val['user_pay_rate'];
+            $_export_data['sum_money'] = $_val['sum_money'];
+            $_export_datas[] = $_export_data;
+        }
+        $_for_cnt = empty($_for_cnt) ? 1 : $_for_cnt;
+        while ($_p <= $_for_cnt) {
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['date'] = $_val['date'];
+                if (!empty($_param['app_id'])) {
+                    $_export_data['game'] = $this->data_games[$_val['app_id']];
+                }
+                if (!empty($_GET['agent_id']) || !empty($_GET['director_id']) || !empty($_GET['group_id'])) {
+                    if (!empty($_GET['data_summary']) && 2 == $_GET['data_summary']) {
+                        if (!empty($_GET['agent_id'])) {
+                            $_export_data['agent'] = $this->data_agents[$_GET['agent_id']];
+                        }
+                    } else {
+                        $_export_data['agent'] = $this->data_agents[$_val['agent_id']];
+                    }
+                }
+                $_export_data['reg_cnt'] = $_val['reg_cnt'];
+//                $_export_data['cpa_cnt'] = $_val['cpa_cnt'];
+                $_export_data['reg_ip_cnt'] = $_val['reg_ip_cnt'];
+                $_export_data['ip_cnt'] = $_val['ip_cnt'];
+                $_export_data['openid_cnt'] = $_val['openid_cnt'];
+                $_export_data['user_cnt'] = $_val['user_cnt'];
+                $_export_data['pay_user_cnt'] = $_val['pay_user_cnt'];
+                $_export_data['reg_pay_cnt'] = $_val['reg_pay_cnt'];
+                $_export_data['user_pay_rate'] = $_val['user_pay_rate'];
+                $_export_data['sum_money'] = $_val['sum_money'];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '每日cpa数据', '.csv', true);
+                break;
+            } else {
+                $_file_name = '每日cpa数据'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new DayDataLogic())->getAdminList($_param, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '每日cpa数据');
+    }
+
+    /**
+     * 每个自然日数据
+     *
+     * admin/data.day/cpa
+     *
+     */
+    public function cpa() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportCpa();
+        }
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        list($_param, $_order) = $this->_getSearchParam();
+        $_data = (new DayDataLogic())->getAdminList($_param, $_page.','.$_list_rows, $_order);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        $_sum_data = (new StatisticsLogic())->getStatisticsData($_param);
+        $this->assign('sum', $_sum_data);
+        $_today_data = [];
+        $_now_time = time();
+        if (!empty($_param['start_time'])) {
+            $_start_time = strtotime($_param['start_time']);
+        }
+        if (empty($_start_time)) {
+            $_start_time = 0;
+        }
+        if (!empty($_param['end_time'])) {
+            $_end_time = strtotime($_param['end_time']) + CommonConst::CONST_DAY_SECONDS;
+        }
+        if (empty($_end_time)) {
+            $_end_time = $_now_time;
+        }
+        if ($_now_time > $_start_time && $_now_time <= $_end_time && '-date' == $_order) {
+            $_today_data = (new StatisticsLogic())->getTodayData($_param);
+            $_today_data = [$_today_data];
+        }
+        $this->assign('today_data', $_today_data);
+
+        return $this->fetch('data/day/cpa');
+    }
+
+    /**
+     * 获取搜索数据
+     */
+    public function _getSearchParam() {
+        $_rq_data = $this->request->param();
+        $this->assign('rq_data', $_rq_data);
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_param['order_field'] = $this->request->param('order_field/s', 'date');
+        $_param['order_type'] = $this->request->param('order_type/s', 'DESC');
+        $_include_agent = $this->request->param('include_agent/d', 2);
+        $this->_orderField($_param['order_field']);
+        $this->_orderType($_param['order_type']);
+        $this->_cpaOrderField($_param['order_field']);
+        $this->includeAgent($_include_agent);
+        //日期按钮
+        $_time_range = $this->request->param('time_range', 'seven_days');
+        switch ($_time_range) {
+            case 'seven_days':
+                $_start_time = date('Y-m-d', strtotime('-6 days'));
+                $_end_time = date('Y-m-d');
+                break;
+            case 'this_month':
+                $_start_time = date('Y-m-01', strtotime(date("Y-m-d")));
+                $_end_time = date('Y-m-d');
+                break;
+            case 'thirty_days':
+            default:
+                $_start_time = $this->request->param('start_time/s', date('Y-m-d', strtotime('-1 month')));
+                $_end_time = $this->request->param('end_time/s', date('Y-m-d'));
+                break;
+        }
+        $this->assign('time_range', $_time_range);
+        list($_param['start_time'], $_param['end_time']) = $this->_time($_start_time, $_end_time);
+        $_param['agent_id'] = $this->request->param('agent_id/d', CommonConst::CONST_ZERO);
+        $this->data_agents = $this->_agents($_param['agent_id']);
+        /* 游戏筛选 */
+        $_game_where = [];
+        if (!empty($this->map['agent_id'])) {
+            if (empty($_param['agent_id'])) {
+                $_param['agent_id'] = $this->map['agent_id'];
+            }
+            /* 获取渠道游戏 */
+            $_app_ids = (new AgentGame())->getGameIds($this->map);
+            $_game_where['id'] = 0;
+            if (!empty($_app_ids)) {
+                $_game_where['id'] = ['in', $_app_ids];
+            }
+        }
+        if (!empty($_param['agent_id']) && empty($this->map['agent_id']) && -1 != $_param['agent_id']
+            && 2 == $_include_agent) {
+            $_agent_ids = (new AgentLogic())->getAgentIds($_param['agent_id'], true);
+            if (!empty($_agent_ids)) {
+                $_param['agent_id'] = ['in', $_agent_ids];
+            }
+        }
+        /* cp游戏 */
+        if (!empty($this->cp_app_id)) {
+            $_game_where['id'] = ['in', $this->cp_app_id];
+            $_param['cp_app_id'] = $this->cp_app_id;
+        }
+        $this->data_games = $this->_games(
+            $_param['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE,
+            GameConst::GAME_IS_SDK, 0, false, true, $_game_where
+        );
+        if (empty($_param['order_field'])) {
+            $_param['order_field'] = 'date';
+        }
+        $_order = '-'.$_param['order_field'];
+        if ('ASC' == $_param['order_type']) {
+            $_order = '+'.$_param['order_field'];
+        }
+
+        return [$_param, $_order];
+    }
+
+    public function update() {
+        /* 执行定时任务更新当天数据 */
+        $_date = date('Y-m-d');
+        (new GenDataLogic())->archiveDaily($_date);
+
+        return $this->index();
+    }
+
+    /**
+     * 排序字段
+     *
+     * @param string $field
+     */
+    protected function _orderField($field = '') {
+        $_array = [
+            'date'                => '日期',
+            'reg_cnt'             => '新增用户',
+            //            'reg_device_cnt'      => '新增设备',
+            'user_cnt'            => '活跃用户',
+            'reg_pay_cnt'         => '新增即付费人数',
+            'reg_sum_money'       => '新增即付费金额',
+            'first_pay_user_cnt'  => '新增付费人数',
+            'first_pay_sum_money' => '新增付费金额',
+            'reg_order_cnt'       => '新用户订单',
+            'order_cnt'           => '总订单',
+            'pay_user_cnt'        => '总付费人数',
+            'sum_money'           => '总付费金额'
+        ];
+        $_of_select = Filter::selectCommon($_array, 'order_field', $field);
+        $this->assign('of_select', $_of_select);
+        $this->assign('order_field', $field);
+    }
+
+    protected function _cpaOrderField($field = '') {
+        $_array = [
+            'date'               => '日期',
+            'reg_cnt'            => '新增用户',
+            //            'cpa_cnt'            => 'CPA有效用户',
+            'openid_cnt'         => '新增微信openid',
+            'reg_ip_cnt'         => '注册IP',
+            'ip_cnt'             => '活跃IP',
+            'user_cnt'           => '活跃用户',
+            'first_pay_user_cnt' => '新增付费人数',
+            'pay_user_cnt'       => '总付费人数',
+            'sum_money'          => '总付费金额'
+        ];
+        $_of_select = Filter::selectCommon($_array, 'order_field', $field);
+        $this->assign('cof_select', $_of_select);
+        $this->assign('cpa_order_field', $field);
+    }
+
+    /**
+     * 排序方式
+     *
+     * @param string $type
+     */
+    protected function _orderType($type = '') {
+        $_type_arr = [
+            'DESC' => '降序',
+            'ASC'  => '升序'
+        ];
+        $_ot_select = Filter::selectCommon($_type_arr, 'order_type', $type);
+        $this->assign('ot_select', $_ot_select);
+    }
+}

+ 170 - 0
admin/admin/controller/data/LtvController.php

@@ -0,0 +1,170 @@
+<?php
+/**
+ * LtvController.php  UTF-8
+ * LTV 数据
+ *
+ * @date    : 2019/5/27 15:51
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\data;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\agent\AgentGame;
+use huo\controller\pay\SdkOrderCache;
+use huo\logic\agent\AgentLogic;
+use huo\model\order\OrderModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\tool\Page;
+use reyun\api\reyun;
+use think\Lang;
+
+class LtvController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'data_ltv'.EXT);
+    }
+
+    /**
+     * ltv
+     * admin/data.ltv/index
+     */
+    public function index() {
+        $_param = $this->_getSearchParams();
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 10);
+        $_logic = new \huoLtv\logic\DayLogic();
+        $_items = $_logic->getAdminList($_param, $_page.','.$_list_rows);
+        $_items = (new Page())->paginate($_items['count'], $_items['list'], $_page, $_list_rows);
+        $this->assign('page', $_items->render());
+        $this->assign('items', $_items->items());
+
+        return $this->fetch();
+    }
+
+    /**
+     * 获取查询数据
+     */
+    public function _getSearchParams() {
+        $_param = $this->request->param();
+        $this->assign('rq_data', $_param);
+        $_start_time = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_end_time = $this->request->param('end_time', date('Y-m-d'));
+        $_time_choose = Filter::timeChoose($_start_time, $_end_time, 'yyyy-mm-dd');
+        $this->assign('time_choose', $_time_choose);
+        $_param['agent_id'] = $this->request->param('agent_id/d', CommonConst::CONST_ZERO);
+        $this->_agents($_param['agent_id'], true);
+        $_include_agent = $this->request->param('include_agent/d', 0);
+        $this->includeAgent($_include_agent);
+        /* 游戏筛选 */
+        $_game_where = [];
+        if (!empty($this->map['agent_id'])) {
+            if (empty($_param['agent_id'])) {
+                $_param['agent_id'] = $this->map['agent_id'];
+            }
+            /* 获取渠道游戏 */
+            $_app_ids = (new AgentGame())->getGameIds($this->map);
+            $_game_where['id'] = 0;
+            if (!empty($_app_ids)) {
+                $_game_where['id'] = ['in', $_app_ids];
+            }
+        }
+        if (!empty($_param['agent_id']) && empty($this->map['agent_id']) && -1 != $_param['agent_id']
+            && 2 == $_include_agent) {
+            $_agent_ids = (new AgentLogic())->getAgentIds($_param['agent_id'], true);
+            if (!empty($_agent_ids)) {
+                $_param['agent_id'] = ['in', $_agent_ids];
+            }
+        }
+        /* cp游戏 */
+        if (!empty($this->cp_app_id)) {
+            $_game_where['id'] = ['in', $this->cp_app_id];
+            $_param['cp_app_id'] = $this->cp_app_id;
+        }
+        $this->_games(
+            get_val($_param, 'app_id', CommonConst::CONST_ZERO), GameConst::GAME_STATUS_ON,
+            CommonConst::CONST_NOT_DELETE,
+            GameConst::GAME_IS_SDK, 0, false, true, $_game_where
+        );
+
+        return $_param;
+    }
+
+    public function repair() {
+        /* 充值时计算LTV */
+        $_model = new OrderModel();
+        $_map['status'] = 2;
+        $_datas = $_model->where($_map)->column('order_id');
+        if (empty($_datas)) {
+            echo '无数据';
+            exit;
+        }
+        foreach ($_datas as $_v) {
+            $order_id = $_v;
+            $_soc_class = SdkOrderCache::ins();
+            $_order_data = $_soc_class->getInfoByOrderId($order_id);
+            $_ltv_class = new \ltv\Ltv();
+            $_mem_data = (new \huo\model\member\MemberModel())->getInfoById(
+                $_order_data['mem_id']
+            );
+            $_ltv_class->charge(
+                $_mem_data['app_id'],
+                $_mem_data['agent_id'],
+                $_order_data['app_id'],
+                $_order_data['amount'],
+                $_order_data['update_time'],
+                $_mem_data['create_time']
+            );
+        }
+    }
+
+    public function repairReg() {
+        /* LTV统计 */
+        $_map = [];
+        $_data = (new \huo\model\member\MemberModel())->getMemIds($_map);
+        if (empty($_data)) {
+            echo '无数据';
+            exit;
+        }
+        foreach ($_data as $_v) {
+            $_mem_data = (new \huo\model\member\MemberModel())->getInfoById($_v);
+            $_ltv_class = new \ltv\Ltv();
+            $_ltv_class->reg($_mem_data['app_id'], $_mem_data['agent_id'], $_mem_data['create_time']);
+        }
+    }
+
+    public function repairReyun() {
+        $_datas = array();
+        foreach ($_datas as $_v) {
+            $order_id = $_v;
+            $_soc_class = SdkOrderCache::ins();
+            $_order_data = $_soc_class->getInfoByOrderId($order_id);
+            $_mem_data = (new \huo\model\member\MemberModel())->getInfoById(
+                $_order_data['mem_id']
+            );
+            /* 开启热云API请求 */
+            $_device_id = !empty($_order_data['payext']['device_id']) ? $_order_data['payext']['device_id'] : '';
+            if (empty($_device_id)) {
+                $_device_id = !empty($_mem_data['device_id']) ? $_mem_data['device_id'] : '';
+            }
+            $_reyun_class = new reyun();
+            $_params = [];
+            $_params['idfa'] = $_device_id;
+            $_params['app_id'] = $_order_data['app_id'];
+            $_params['order_id'] = $_order_data['order_id'];
+            $_params['payway'] = $_order_data['payway'];
+            $_params['amount'] = $_order_data['amount'];
+            $_params['mem_id'] = $_order_data['mem_id'];
+            $_params['agent_id'] = $_order_data['agent_id'];
+            $_params['device_id'] = $_device_id;
+            $_params['ip'] = !empty($_order_data['payext']['ip']) ? $_order_data['payext']['ip'] : '';
+            $_params['from'] = GameConst::GAME_H5;
+            $_reyun_class->payment($_params);
+        }
+    }
+}

+ 590 - 0
admin/admin/controller/data/RankController.php

@@ -0,0 +1,590 @@
+<?php
+/**
+ * RankController.php UTF-8
+ * 排行
+ *
+ * @date    : 5/17/2018 3:51 PM
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\data;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\logic\data\RankDataLogic;
+use huo\model\member\MemberModel;
+use huo\model\member\MgRoleModel;
+use huo\model\user\RoleModel;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use huolib\status\CommonStatus;
+use huolib\tool\Export;
+use huolib\tool\Time;
+use think\Lang;
+use think\Request;
+
+class RankController extends AdminbaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_rank'.EXT);
+    }
+
+    /**
+     * Top500玩家数据导出
+     *
+     * @return mixed
+     */
+    public function exportMember() {
+        $_time_range = $this->request->param('time_range', 'all');
+        $_file_name = 'TOP500玩家';
+        list($_day_start, $_day_end) = Time::today();
+        list($_week_start, $_week_end) = Time::week();
+        list($_month_start, $_month_end) = Time::month();
+        $_field = 'id,username';
+        $_field .= ',IF(last_pay_time>'.$_day_start.',day_money, 0) as day_money';
+        $_field .= ',IF(last_pay_time>'.$_week_start.',week_money, 0) as week_money';
+        $_field .= ',IF(last_pay_time>'.$_month_start.',month_money, 0) as month_money';
+        switch ($_time_range) {
+            case 'today':
+                $_start_time = $_day_start;
+                $_end_time = $_day_end;
+                $order = 'day_money desc';
+                $_file_name .= '-今日金额排行';
+                break;
+            case 'week':
+                $_start_time = $_week_start;
+                $_end_time = $_week_end;
+                $order = 'week_money desc';
+                $_file_name .= '-本周金额排行';
+                break;
+            case 'month':
+                $_start_time = $_month_start;
+                $_end_time = $_month_end;
+                $order = 'month_money desc';
+                $_file_name .= '-本月金额排行';
+                break;
+            default:
+                $_start_time = 0;
+                $_end_time = CommonConst::CONST_MAX_INT;
+                $order = 'sum_money desc';
+                $_file_name .= '-总金额排行';
+        }
+        $_map = [
+            'last_pay_time' => ['between', [$_start_time, $_end_time]],
+        ];
+        if (!empty($this->map['agent_id'])) {
+            $_map['agent_id'] = $this->map['agent_id'];
+        }
+        if (!empty($this->cp_app_id)) {
+            $_map['app_id'] = ['in', $this->cp_app_id];
+        }
+        $_data = (new MemberModel())->with('ext,mg')
+                                    ->field($_field)
+                                    ->where($_map)
+                                    ->order($order)
+                                    ->limit(500)
+                                    ->select()->toArray();
+        $_mg_role_model = new MgRoleModel();
+        foreach ($_data as $_key => $_value) {
+            $_value_arr = $_value;
+            $_mem_game_ids = array_column($_value_arr['mg'], 'id');
+            $_max_money_role = $_mg_role_model->getMaxMoneyMgRoleData($_mem_game_ids);
+            $_value['max_money_role'] = $_max_money_role;
+            $_data[$_key] = $_value;
+        }
+        $_head = ['排名', 'UID', '账号', '总金额', '今日金额', '本周金额', '本月金额', '最近金额', '区服', '角色名', '角色充值金额', '最近支付时间'];
+        $_export_datas = [];
+        foreach ($_data as $_key => $_val) {
+            $_export_data['key'] = $_key + 1;
+            $_export_data['id'] = $_val['id'];
+            $_export_data['username'] = $_val['username'];
+            $_export_data['sum_money'] = $_val['ext']['sum_money'];
+            $_export_data['day_money'] = $_val['ext']['day_money'];
+            $_export_data['week_money'] = $_val['ext']['week_money'];
+            $_export_data['month_money'] = $_val['ext']['month_money'];
+            $_export_data['last_money'] = $_val['ext']['last_money'];
+            $_export_data['server_name'] = $_val['max_money_role']['server_name'];
+            $_export_data['role_name'] = $_val['max_money_role']['role_name'];
+            $_export_data['money'] = $_val['max_money_role']['money'];
+            $_export_data['last_pay_time'] = date('Y-m-d H:i:s', $_val['ext']['last_pay_time']);
+            $_export_datas[] = $_export_data;
+        }
+        Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+    }
+
+    /**
+     * 游戏排行数据导出
+     *
+     * @throws
+     */
+    public function exportGame() {
+        $_agent_id = $this->request->param('agent_id');
+        $_game_name = $this->request->param('game_name');
+        $_classify = $this->request->param('classify');
+        $_rank_by = $this->request->param('rank_by');
+        list($_start_time, $_end_time) = $this->resolveTimeRange();
+        $this->_agents($_agent_id, true, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true);
+        $this->_time($_start_time, $_end_time);
+        $this->_gameClassifies($_classify);
+        $this->assignRankBySelect($_rank_by);
+        $_map = [
+            'start_time' => $_start_time,
+            'end_time'   => $_end_time,
+        ];
+        if (isset($_game_name)) {
+            $_map['game_name'] = $_game_name;
+        }
+        if (isset($_classify)) {
+            $_map['classify'] = $_classify;
+        }
+        if (isset($_rank_by) && in_array($_rank_by, array_keys($this->getRankByList()))) {
+            $_map['rank_by'] = $_rank_by;
+        }
+        //$_map['classify'] = GameConst::GAME_H5; //只显示 h5游戏
+        $_map['agent_id'] = $_agent_id;
+        if (empty($_agent_id) && !empty($this->map['agent_id'])) {
+            $_map['agent_id'] = $this->map['agent_id'];
+        }
+        /* cp游戏 */
+        if (!empty($this->cp_app_id)) {
+            $_map['app_id'] = ['in', $this->cp_app_id];
+        }
+        $_map['app_id'] = $this->request->param('app_id/d', 0);
+        $_map = $this->trimAll($_map);
+        $rq_data = $this->request->param();
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_data = (new RankDataLogic())->game($_map, $_offset)->toArray();
+        $_total_cnt = $_data['total'];
+        if ($_total_cnt <= 0) {
+            $this->adminError(CommonStatus::getMsg(CommonStatus::CNT_IS_ZERO));
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            $_head = ['排行', '游戏名称', '客户端', '充值金额', '新增用户', '活跃用户', '付费ARPU', '活跃ARPU', '新增付费率', '活跃付费率'];
+            if(empty($rq_data['agent_id']) && !empty($rq_data['app_id'])) {
+                $_head[] = '渠道';
+            }
+            $_export_datas = [];
+            foreach ($_data['data'] as $_key => $_val) {
+                $_export_data['key'] = ($_p - 1) * $_offset + $_key + 1;
+                $_export_data['game'] = $_val['game']['name'];
+                $_export_data['classify'] = $_val['game']['classify'];
+                $_export_data['sum_money'] = $_val['sum_money'];
+                $_export_data['reg_cnt'] = $_val['reg_cnt'];
+//                $_export_data['reg_device_cnt'] = $_val['reg_device_cnt'];
+                $_export_data['user_cnt'] = $_val['user_cnt'];
+                $_export_data['PaidARPU'] = empty($_val['pay_user_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['sum_money']
+                          / $_val['pay_user_cnt'], 2
+                      ) * 100 .'%';
+                $_export_data['ActiveARPU'] = empty($_val['user_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['sum_money']
+                          / $_val['user_cnt'], 2
+                      ) * 100 .'%';
+                $_export_data['NewPaymentRate'] = empty($_val['reg_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['reg_pay_cnt']
+                          / $_val['reg_cnt'], 2
+                      ) * 100 .'%';
+                $_export_data['ActivePaymentRate'] = empty($_val['user_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['pay_user_cnt']
+                          / $_val['user_cnt'], 2
+                      ) * 100 .'%';
+                if(empty($rq_data['agent_id']) && !empty($rq_data['app_id'])) {
+                    $_export_data['agent_name'] = $_val['agent']['user_login'];
+                }
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '游戏排行', '.csv', true);
+                break;
+            } else {
+                $_file_name = '游戏排行'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    Request::instance()->get(['page' => $_p]);
+                    $_data = (new RankDataLogic())->game($_map, $_offset)->toArray();
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '游戏排行');
+    }
+
+    /**
+     * 渠道排行数据导出
+     *
+     * @throws
+     */
+    public function exportAgent() {
+        $_agent_id = $this->request->param('agent_id');
+        $_rank_by = $this->request->param('rank_by');
+        $_agent_summary = $this->request->param('agent_summary');
+        list($_start_time, $_end_time) = $this->resolveTimeRange();
+        $this->_agents($_agent_id, true, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true);
+        $this->_time($_start_time, $_end_time);
+        $this->assignRankBySelect($_rank_by);
+        $this->assignAgentSummarySelect($_agent_summary);
+        $_map = [
+            'start_time' => $_start_time,
+            'end_time'   => $_end_time,
+        ];
+        $_map['agent_id'] = $_agent_id;
+        if (empty($_agent_id) && !empty($this->map['agent_id'])) {
+            $_map['agent_id'] = $this->map['agent_id'];
+        }
+        if (isset($_agent_summary) && in_array($_agent_summary, array_keys($this->getAgentSummaryList()))) {
+            //渠道汇总处理,勾选则 查询一级渠道和它的二级渠道
+            if ($_agent_summary == 'true') {
+                $_map['agent_summary'] = true;
+            }
+        }
+        if (isset($_rank_by) && in_array($_rank_by, array_keys($this->getRankByList()))) {
+            $_map['rank_by'] = $_rank_by;
+        }
+        $_map['app_id'] = $this->request->param('app_id/d', 0);
+        $rq_data = $this->request->param();
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_data = (new RankDataLogic())->agent($_map, $_offset)->toArray();
+        $_roles = (new RoleModel())->getIdNames([], true);
+        $_total_cnt = $_data['total'];
+        if ($_total_cnt <= 0) {
+            $this->adminError(CommonStatus::getMsg(CommonStatus::CNT_IS_ZERO));
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            $_head = ['排行', '渠道账号', '渠道名称', '渠道等级', '父渠道', '充值金额', '新增用户', '活跃用户', '付费ARPU', '活跃ARPU', '新增付费率',
+                      '活跃付费率'];
+            if(!empty($rq_data['agent_id']) && empty($rq_data['app_id'])){
+                $_head[]='游戏';
+            }
+
+            $_export_datas = [];
+            foreach ($_data['data'] as $_key => $_val) {
+                $_export_data['key'] = ($_p - 1) * $_offset + $_key + 1;
+                $_export_data['agent'] = isset($_val['agent']['user_login']) ? $_val['agent']['user_login'] : '';
+                $_export_data['user_nicename'] = isset($_val['agent']['user_nicename']) ? $_val['agent']['user_nicename'] : '';
+                $_export_data['roles'] = isset($_val['agent']['role_id'])
+                    ? $_roles[$_val['agent']['role_id']]['role_type_text'] : '';
+                $_export_data['parent'] = isset($_val['agent']['parent']['user_login'])
+                    ? $_val['agent']['parent']['user_login'] : '';
+                $_export_data['sum_money'] = $_val['sum_money'];
+                $_export_data['reg_cnt'] = $_val['reg_cnt'];
+//                $_export_data['reg_device_cnt'] = $_val['reg_device_cnt'];
+                $_export_data['user_cnt'] = $_val['user_cnt'];
+                $_export_data['PaidARPU'] = empty($_val['pay_user_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['sum_money']
+                          / $_val['pay_user_cnt'], 2
+                      ) * 100 .'%';
+                $_export_data['ActiveARPU'] = empty($_val['user_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['sum_money']
+                          / $_val['user_cnt'], 2
+                      ) * 100 .'%';
+                $_export_data['NewPaymentRate'] = empty($_val['reg_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['reg_pay_cnt']
+                          / $_val['reg_cnt'], 2
+                      ) * 100 .'%';
+                $_export_data['ActivePaymentRate'] = empty($_val['user_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['pay_user_cnt']
+                          / $_val['user_cnt'], 2
+                      ) * 100 .'%';
+                if(!empty($rq_data['agent_id']) && empty($rq_data['app_id'])){
+                    $_export_data['game_name'] =  $_val['game']['name'];
+                }
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '渠道排行', '.csv', true);
+                break;
+            } else {
+                $_file_name = '渠道排行'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    Request::instance()->get(['page' => $_p]);
+                    $_data = (new RankDataLogic())->game($_map, $_offset)->toArray();
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '渠道排行');
+    }
+
+    /**
+     * 玩家排行
+     * admin/data.rank/member
+     *
+     * @throws
+     */
+    public function member() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportMember();
+        }
+        $_time_range = $this->request->param('time_range', 'all');
+        list($_day_start, $_day_end) = Time::today();
+        list($_week_start, $_week_end) = Time::week();
+        list($_month_start, $_month_end) = Time::month();
+        $_field = 'id,username';
+        $_field .= ',IF(last_pay_time>'.$_day_start.',day_money, 0) as day_money';
+        $_field .= ',IF(last_pay_time>'.$_week_start.',week_money, 0) as week_money';
+        $_field .= ',IF(last_pay_time>'.$_month_start.',month_money, 0) as month_money';
+        switch ($_time_range) {
+            case 'today':
+                $_start_time = $_day_start;
+                $_end_time = $_day_end;
+                $order = 'day_money desc';
+                break;
+            case 'week':
+                $_start_time = $_week_start;
+                $_end_time = $_week_end;
+                $order = 'week_money desc';
+                break;
+            case 'month':
+                $_start_time = $_month_start;
+                $_end_time = $_month_end;
+                $order = 'month_money desc';
+                break;
+            default:
+                $_start_time = 0;
+                $_end_time = CommonConst::CONST_MAX_INT;
+                $order = 'sum_money desc';
+        }
+        $_map = [
+            'last_pay_time' => ['between', [$_start_time, $_end_time]],
+        ];
+        if (!empty($this->map['agent_id'])) {
+            $_map['agent_id'] = $this->map['agent_id'];
+        }
+        if (!empty($this->cp_app_id)) {
+            $_map['app_id'] = ['in', $this->cp_app_id];
+        }
+        $_member_exts = (new MemberModel())->with('ext,mg')
+                                           ->field($_field)
+                                           ->where($_map)
+                                           ->order($order)
+                                           ->limit(500)
+                                           ->select();
+        $_mg_role_model = new MgRoleModel();
+        foreach ($_member_exts as $_key => $_value) {
+            $_value_arr = $_value->toArray();
+            $_mem_game_ids = array_column($_value_arr['mg'], 'id');
+            $_max_money_role = $_mg_role_model->getMaxMoneyMgRoleData($_mem_game_ids);
+            $_value['max_money_role'] = $_max_money_role;
+            $_member_exts[$_key] = $_value;
+        }
+        $this->assign('time_range', $_time_range);
+        $this->assign('items', $_member_exts);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 游戏排行
+     * admin/data.rank/game
+     *
+     * @throws
+     */
+    public function game() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportGame();
+        }
+        $_agent_id = $this->request->param('agent_id');
+        $_game_name = $this->request->param('game_name', '');
+        $_classify = $this->request->param('classify', 0);
+        $_rank_by = $this->request->param('rank_by/s', 'sum_money');
+        $_list_rows = $this->request->param('list_rows', 10);
+        list($_start_time, $_end_time) = $this->resolveTimeRange();
+        $this->_agents($_agent_id, true, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true);
+        $this->_time($_start_time, $_end_time);
+        $this->_gameClassifies($_classify);
+        $this->assignRankBySelect($_rank_by);
+        $_map = [
+            'start_time' => $_start_time,
+            'end_time'   => $_end_time,
+        ];
+        if (!empty($_game_name)) {
+            $_map['game_name'] = $_game_name;
+        }
+        if (!empty($_classify)) {
+            $_map['classify'] = $_classify;
+        }
+        if (!empty($_rank_by) && in_array($_rank_by, array_keys($this->getRankByList()))) {
+            $_map['rank_by'] = $_rank_by;
+        }
+        $_map['agent_id'] = $_agent_id;
+        if (empty($_agent_id) && !empty($this->map['agent_id'])) {
+            $_map['agent_id'] = $this->map['agent_id'];
+        }
+        $_map['app_id'] = $this->request->param('app_id/d', 0);
+        $this->_games($_map['app_id']);
+        /* cp游戏 */
+        if (!empty($this->cp_app_id)) {
+            $_map['app_id'] = ['in', $this->cp_app_id];
+        }
+        $_map = $this->trimAll($_map);
+        $items = (new RankDataLogic())->game($_map, $_list_rows);
+        $_offset = (($items->currentPage() - 1) * $_list_rows);
+        $this->assign('offset', $_offset);
+        $this->assign('game_name', $_game_name);
+        $this->assign('items', $items->items());
+        $this->assign('page', $items->render());
+        $_rq_data = $this->request->param();
+        $this->assign('rq_data', $_rq_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 渠道排行
+     * admin/data.rank/game
+     */
+    public function agent() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportAgent();
+        }
+        $_agent_id = $this->request->param('agent_id');
+        $_rank_by = $this->request->param('rank_by/s', 'sum_money');
+        $_agent_summary = $this->request->param('agent_summary');
+        $_list_rows = $this->request->param('list_rows', 10);
+        $_game_name = $this->request->param('game_name', '');
+        list($_start_time, $_end_time) = $this->resolveTimeRange();
+        $this->_agents($_agent_id, true, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true);
+        $this->_time($_start_time, $_end_time);
+        $this->assignRankBySelect($_rank_by);
+        $this->assignAgentSummarySelect($_agent_summary);
+        $_map = [
+            'start_time' => $_start_time,
+            'end_time'   => $_end_time,
+        ];
+        $_map['agent_id'] = $_agent_id;
+        if (empty($_agent_id) && !empty($this->map['agent_id'])) {
+            $_map['agent_id'] = $this->map['agent_id'];
+        }
+        if (isset($_agent_summary) && in_array($_agent_summary, array_keys($this->getAgentSummaryList()))) {
+            //渠道汇总处理,勾选则 查询一级渠道和它的二级渠道
+            if ($_agent_summary == 'true') {
+                $_map['agent_summary'] = true;
+            }
+        }
+        if (isset($_rank_by) && in_array($_rank_by, array_keys($this->getRankByList()))) {
+            $_map['rank_by'] = $_rank_by;
+        }
+        if (!empty($_game_name)) {
+            $_map['game_name'] = $_game_name;
+        }
+        $_map['app_id'] = $this->request->param('app_id/d', 0);
+        $this->_games($_map['app_id']);
+        $items = (new RankDataLogic())->agent($_map, $_list_rows);
+        $_roles = (new RoleModel())->getIdNames([], true);
+        $this->assign('roles', $_roles);
+        $_offset = (($items->currentPage() - 1) * $_list_rows);
+        $this->assign('offset', $_offset);
+        $this->assign('items', $items->items());
+        $this->assign('page', $items->render());
+        $this->assign('game_name', $_game_name);
+        $_rq_data = $this->request->param();
+        $this->assign('rq_data', $_rq_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 解析日期范围
+     * 今日:today
+     * 昨日:yesterday
+     * 七天:seven_days
+     * 当月:this_month
+     * 30天:thirty_days
+     *
+     * @return array
+     */
+    protected function resolveTimeRange() {
+        $_time_range = $this->request->param('time_range/s', '');
+        switch ($_time_range) {
+            case 'today':
+                list($_start_time, $_end_time) = Time::today();
+                break;
+            case 'yesterday':
+                list($_start_time, $_end_time) = Time::yesterday();
+                break;
+            case 'seven_days':
+                list($_start_time, $_end_time) = Time::lastSeven();
+                break;
+            case 'this_month':
+                list($_start_time, $_end_time) = Time::month();
+                break;
+            case 'thirty_days':
+                list($_start_time, $_end_time) = Time::lastThirty();
+                break;
+            default:
+                $_start_time = strtotime($this->request->param('start_time/s', date('Y-m-d', strtotime('-1 month'))));
+                $_end_time = strtotime($this->request->param('end_time/s', date('Y-m-d')));
+        }
+        if (!empty($_start_time)) {
+            $_start_time = date('Y-m-d', $_start_time);
+        }
+        if (!empty($_end_time)) {
+            $_end_time = date('Y-m-d', $_end_time);
+        }
+        $this->assign('time_range', $_time_range);
+
+        return [$_start_time, $_end_time];
+    }
+
+    protected function assignRankBySelect($rank_by) {
+        $_rank_by_list = $this->getRankByList();
+        $_rank_by_select = Filter::selectCommon($_rank_by_list, 'rank_by', $rank_by);
+        $this->assign('rank_by_list', $_rank_by_list);
+        $this->assign('rank_by', $rank_by);
+        $this->assign('rank_by_select', $_rank_by_select);
+    }
+
+    protected function assignAgentSummarySelect($agent_summary) {
+        $_agent_summary_list = $this->getAgentSummaryList();
+        $_agent_summary_select = Filter::selectCommon($_agent_summary_list, 'agent_summary', $agent_summary);
+        $this->assign('agent_summary_list', $_agent_summary_list);
+        $this->assign('agent_summary_select', $_agent_summary_select);
+    }
+
+    protected function getRankByList() {
+        return [
+            'sum_money'      => '充值金额',
+            'reg_cnt'        => '新增用户',
+//            'reg_device_cnt' => '新增设备',
+            'user_cnt'       => '活跃用户',
+        ];
+    }
+
+    protected function getAgentSummaryList() {
+        return [
+            'true'  => '渠道汇总',
+            'false' => '不渠道汇总',
+        ];
+    }
+}
+

+ 321 - 0
admin/admin/controller/data/RemainController.php

@@ -0,0 +1,321 @@
+<?php
+/**
+ * PayDataController.php UTF-8
+ *
+ *
+ * @date    : 2017/12/18 11:16
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : liguanglong <lgl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\data;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\agent\AgentGame;
+use huo\logic\agent\AgentLogic;
+use huo\logic\data\GenDataLogic;
+use huo\logic\data\RemainDataLogic;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\status\CommonStatus;
+use huolib\tool\Export;
+use think\Lang;
+use think\Request;
+
+class RemainController extends AdminbaseController {
+    protected $pub_where   = [];
+    protected $data_games  = [];
+    protected $data_agents = [];
+
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'remain'.EXT);
+    }
+
+    /**
+     * 留存数据导出
+     *
+     * @param $param
+     *
+     * @return mixed
+     */
+    public function exportIndex($param) {
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        Request::instance()->get(['page' => 1]);
+        Request::instance()->get(['list_rows' => $_offset]);
+        if (!empty($param['app_id']) && !empty($param['agent_id'])) {
+            $_data = (new RemainDataLogic())->gameAgent($param)->toArray();
+        } else if (empty($param['app_id']) && !empty($param['agent_id'])) {
+            $_data = (new RemainDataLogic())->agent($param)->toArray();
+        } else if (!empty($param['app_id']) && empty($param['agent_id'])) {
+            $_data = (new RemainDataLogic())->game($param)->toArray();
+        } else if (!empty($_param['cp_app_id'])) {
+            $_data = (new RemainDataLogic())->cpgame($_param)->toArray();
+        } else {
+            $_data = (new RemainDataLogic())->main($param)->toArray();
+        }
+        $_total_cnt = $_data['total'];
+        if ($_total_cnt <= 0) {
+            $this->adminError(CommonStatus::getMsg(CommonStatus::CNT_IS_ZERO));
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            $_head = ['时间'];
+            if (!empty($param['app_id'])) {
+                array_push($_head, '游戏');
+            }
+            if (!empty($param['agent_id'])) {
+                array_push($_head, '渠道');
+            }
+            $_head2 = [
+                '注册用户',
+                '2日',
+                '3日',
+                '4日',
+                '5日',
+                '6日',
+                '7日',
+                '15日',
+                '30日',
+            ];
+            $_head = array_merge($_head, $_head2);
+            $_export_datas = [];
+            foreach ($_data['data'] as $_key => $_val) {
+                if (!empty($_val['reg_cnt'])) {
+                    $_day2 = '('.round($_val['day2'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day3 = '('.round($_val['day3'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day4 = '('.round($_val['day4'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day5 = '('.round($_val['day5'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day6 = '('.round($_val['day6'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day7 = '('.round($_val['day7'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day15 = '('.round($_val['day15'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day30 = '('.round($_val['day30'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                } else {
+                    $_day2 = '(0%)';
+                    $_day3 = '(0%)';
+                    $_day4 = '(0%)';
+                    $_day5 = '(0%)';
+                    $_day6 = '(0%)';
+                    $_day7 = '(0%)';
+                    $_day15 = '(0%)';
+                    $_day30 = '(0%)';
+                }
+                $_export_data['date'] = $_val['date'];
+                if (!empty($param['app_id'])) {
+                    $_export_data['game'] = $this->data_games[$_val['app_id']];
+                }
+                if (!empty($_GET['agent_id'])) {
+                    if (!empty($_GET['data_summary']) && 2 == $_GET['data_summary']) {
+                        $_export_data['agent'] = $this->data_agents[$_val['agent_id']];
+                    } else {
+                        $_export_data['agent'] = $this->data_agents[$_val['agent_id']];
+                    }
+                }
+                $_export_data['reg_cnt'] = $_val['reg_cnt'];
+                $_export_data['day2'] = $_val['day2'].$_day2;
+                $_export_data['day3'] = $_val['day3'].$_day3;
+                $_export_data['day4'] = $_val['day4'].$_day4;
+                $_export_data['day5'] = $_val['day5'].$_day5;
+                $_export_data['day6'] = $_val['day6'].$_day6;
+                $_export_data['day7'] = $_val['day7'].$_day7;
+                $_export_data['day15'] = $_val['day15'].$_day15;
+                $_export_data['day30'] = $_val['day30'].$_day30;
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '留存分析', '.csv', true);
+                break;
+            } else {
+                $_file_name = '留存分析'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    Request::instance()->get(['page' => $_p]);
+                    if (!empty($param['app_id']) && !empty($param['agent_id'])) {
+                        $_data = (new RemainDataLogic())->gameAgent($param)->toArray();
+                    } else if (empty($param['app_id']) && !empty($param['agent_id'])) {
+                        $_data = (new RemainDataLogic())->agent($param)->toArray();
+                    } else if (!empty($param['app_id']) && empty($param['agent_id'])) {
+                        $_data = (new RemainDataLogic())->game($param)->toArray();
+                    } else if (!empty($_param['cp_app_id'])) {
+                        $_data = (new RemainDataLogic())->cpgame($_param)->toArray();
+                    } else {
+                        $_data = (new RemainDataLogic())->main($param)->toArray();
+                    }
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '留存分析');
+    }
+
+    /**
+     * 留存数据
+     * admin/data.remain/index
+     */
+    public function index() {
+        $_param = $this->_getSearchParam();
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIndex($_param);
+        }
+        if (!empty($_param['app_id']) && !empty($_param['agent_id'])) {
+            return $this->gameAgent($_param);
+        } else if (empty($_param['app_id']) && !empty($_param['agent_id'])) {
+            return $this->agent($_param);
+        } else if (!empty($_param['app_id']) && empty($_param['agent_id'])) {
+            return $this->game($_param);
+        } else if (!empty($_param['cp_app_id'])) {
+            return $this->cpgame($_param);
+        }
+
+        return $this->main($_param);
+    }
+
+    public function update() {
+        /* 执行定时任务更新当天数据 */
+        $_date = date('Y-m-d');
+        (new GenDataLogic())->archiveDaily($_date);
+
+        return $this->index();
+    }
+
+    /**
+     * 总体数据
+     *
+     * @param $_param
+     *
+     * @return mixed
+     */
+    public function main($_param) {
+        list($_data, $sum) = (new RemainDataLogic())->main($_param, '-date', true);
+        $this->assign('sum', $sum);
+        $this->assign('items', $_data);
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('data/remain/index');
+    }
+
+    /**
+     * 游戏渠道
+     *
+     * @param $_param
+     *
+     * @return mixed
+     */
+    public function gameAgent($_param) {
+        list($_data, $sum) = (new RemainDataLogic())->gameAgent($_param, '-date', true);
+        $this->assign('sum', $sum);
+        $this->assign('items', $_data);
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('data/remain/index');
+    }
+
+    /**
+     * 游戏
+     *
+     * @param $_param
+     *
+     * @return mixed
+     */
+    public function game($_param) {
+        list($_data, $sum) = (new RemainDataLogic())->game($_param, '-date', true);
+        $this->assign('sum', $sum);
+        $this->assign('items', $_data);
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('data/remain/index');
+    }
+
+    /**
+     * cp游戏
+     *
+     * @param $_param
+     *
+     * @return mixed
+     */
+    public function cpgame($_param) {
+        $_data = (new RemainDataLogic())->cpgame($_param);
+        $this->assign('items', $_data);
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('data/remain/index');
+    }
+
+    /**
+     * 渠道
+     *
+     * @param $_param
+     *
+     * @return mixed
+     */
+    public function agent($_param) {
+        list($_data, $sum) = (new RemainDataLogic())->agent($_param, '-date', true);
+        $this->assign('sum', $sum);
+        $this->assign('items', $_data);
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('data/remain/index');
+    }
+
+    /***
+     * 获取筛选数据
+     */
+    public function _getSearchParam() {
+        $_rq_data = $this->request->param();
+        $this->assign('rq_data', $_rq_data);
+        if (!input('?get.page')) {
+            Request::instance()->get(['page' => 1]);
+        }
+        if (!input('?get.list_rows')) {
+            Request::instance()->get(['list_rows' => 10]);
+        }
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_param['data_summary'] = $this->request->param('data_summary/d', 0);
+        list($_param['start_time'], $_param['end_time']) = $this->_time();
+        $_param['agent_id'] = $this->request->param('agent_id/d', CommonConst::CONST_ZERO);
+        $this->data_agents = $this->_agents($_param['agent_id']);
+        $_include_agent = $this->request->param('include_agent/d', 2);
+        $this->includeAgent($_include_agent);
+        /* 游戏筛选 */
+        $_game_where = [];
+        if (!empty($this->map['agent_id'])) {
+            if (empty($_param['agent_id'])) {
+                $_param['agent_id'] = $this->map['agent_id'];
+            }
+            /* 获取渠道游戏 */
+            $_app_ids = (new AgentGame())->getGameIds($this->map);
+            $_game_where['id'] = 0;
+            if (!empty($_app_ids)) {
+                $_game_where['id'] = ['in', $_app_ids];
+            }
+        }
+        if (!empty($_param['agent_id']) && empty($this->map['agent_id']) && -1 != $_param['agent_id']
+            && 2 == $_include_agent) {
+            $_agent_ids = (new AgentLogic())->getAgentIds($_param['agent_id'], true);
+            if (!empty($_agent_ids)) {
+                $_param['agent_id'] = ['in', $_agent_ids];
+            }
+        }
+        /* cp游戏 */
+        if (!empty($this->cp_app_id)) {
+            $_game_where['id'] = ['in', $this->cp_app_id];
+            $_param['cp_app_id'] = $this->cp_app_id;
+        }
+        $this->data_games = $this->_games(
+            $_param['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE,
+            GameConst::GAME_IS_SDK, 0, false, true, $_game_where
+        );
+        $_percent = $this->request->param('percent', null);
+        if (is_null($_percent)) {
+            $_GET['percent'] = 1;
+        }
+
+        return $_param;
+    }
+}

+ 2121 - 0
admin/admin/controller/distribution/AbsController.php

@@ -0,0 +1,2121 @@
+<?php
+/**
+ * AbsController.php UTF-8
+ * 广告数据
+ *
+ * @date    : 2018/5/30 11:32
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : linjiebin <ljb@huosdk.com>
+ * @version : HUOSDK 7.2
+ */
+
+namespace admin\admin\controller\distribution;
+
+use cmf\view\Filter;
+use huo\model\agent\AgentGameModel;
+use huo\logic\agent\AgentGameLogic;
+use huo\model\distribution\GamelandingpageModel;
+use huo\model\distribution\PromotiondomainModel;
+use huo\model\distribution\PromotionplanModel;
+use huo\model\distribution\PromotiondetailModel;
+use huo\model\distribution\PlatformModel;
+use huo\controller\agent\Agent;
+use huo\logic\agent\AgentLogic;
+use huo\model\game\GameModel;
+use huo\model\user\UserModel;
+use huo\controller\agent\AgentGame;
+use think\Log;
+use huolib\status\GameStatus;
+
+class AbsController extends BaseController {
+    protected $where;
+    protected $today_start_time;
+    protected $today_end_time;
+    protected $today_date;
+    protected $buy_agents;
+    protected $abs_row;
+
+    function _initialize() {
+        parent::_initialize();
+        $this->genPlatforms();
+        $this->abs_row = 30;
+//        $this->buy_agents = $_agents = M('users')->where(['user_type' => ['in', [7, 9]]])->getField('id', true);
+    }
+
+    /* public function genUsers() {
+         $_map['is_delete'] = 2;
+         $_map['user_type'] = $this->cpa_type;
+         if (2 < $this->role_type) {
+             $_map['id'] = get_current_admin_id();
+         }
+         $_data = M("users")->where($_map)->getField("id,user_login", "true");
+         $cates = array(
+             "0" => "全部渠道"
+         );
+         if (empty($_data)) {
+             $_data = [];
+         }
+         $_agents = $cates + $_data;
+         $this->assign("agents", $_agents);
+     }*/
+    /**
+     * 买量员数据
+     */
+    public function optimizer() {
+        echo '买量员数据';
+        exit;
+        $this->getOptimizer();
+
+        return $this->fetch();
+    }
+
+    public function getOptimizer() {
+//        $this->genUsers();
+//        $this->_games();
+//        if (3 == $this->role_type) {
+//            $this->where = " pp.owner_id".$this->agentwhere;
+//        } else {
+////            $this->where = " 1 ";
+//            $_agent_ids = implode(',', $this->buy_agents);
+//            $this->where = " pp.owner_id in (".$_agent_ids.") ";
+//        }
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $this->_initTodayData();
+//            $_day_model = M('tmp_day_promotion');
+//        } else {
+//            $_day_model = M('day_promotion');
+//        }
+//        $platform_id = I('platform_id');
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $app_id = I('app_id');
+//        $agent_id = I('agent_id/d', 0);
+//        $plan_id = I('plan_id/d', '');
+//        $pd_id = I('pd_id/d', '');
+//        /* 导出参数 */
+//        $_csv_do = I('csv_do', 1);
+//        $_csv_page = I('csv_page', 1);
+//        $_csv_offset = I('csv_offset', 1000);
+//        $_csv_file = I('csv_file', '');
+//        $_explore_csv_class = new \Huosdk\Data\ExportCsv();
+//        $where = $this->where;
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($agent_id) && !empty($agent_id)) {
+//            $where .= " AND pp.owner_id=".$agent_id;
+//        }
+//        if (isset($plan_id) && !empty($plan_id)) {
+//            $where .= " AND pp.id=".$plan_id;
+//        }
+//        if (isset($app_id) && !empty($app_id)) {
+//            $where .= " AND pd.app_id=".$app_id;
+//        }
+//        if (isset($platform_id) && !empty($platform_id)) {
+//            $where .= " AND pp.platform_id = '".$platform_id."'";
+//        }
+//        if (isset($pd_id) && !empty($pd_id)) {
+//            $where .= " AND pd.id = '".$pd_id."'";
+//        }
+//        $count = $_day_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        if (2 == $_csv_do) {
+//            $items = $_day_model
+//                ->alias('d')
+//                ->field('d.*,pd.app_id,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id,pd.id pd_id')
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->order('d.id DESC')
+//                ->page($_csv_page, $_csv_offset)
+//                ->select();
+//            if (!empty($items) && is_array($items)) {
+//                $_title = '买量专员数据';
+//                $_expCellName = array('日期', '买量专员	', '落地页ID', '投放渠道', '游戏名称', '点击数量', '下载数量', '注册', '新增设备数',
+//                                      '新增付费数	',
+//                                      '新增付费率', '新增付费金额',
+//                                      '活跃',
+//                                      '付费人数', '付费金额', '活跃付费率', '活跃arpu', '付费arpu', 'ltv 1日', 'ltv 7日', 'ltv 15日',
+//                                      '留存 1日', '留存 7日', '留存 15日'
+//                );
+//                $_export_data = [];
+//                $agents = M('users')->where(
+//                    array('id' => array('in', implode(',', array_unique(array_column($items, 'agent_id')))))
+//                )->getField("id,user_login agentname", true);
+//                $games = M('game')->where(
+//                    array('id' => array('in', implode(',', array_unique(array_column($items, 'app_id')))))
+//                )->getField('id,name', true);
+//                $platforms = M('platform')->getField("id,name platform", true);
+//                foreach ($items as $k => $v) {
+//                    $_where = " `date`='".$v['date']."' AND `agent_id`='".$v['agent_id']."'";
+//                    $_ltv = $this->getLtvData($_where);
+//                    $_day_map = [
+//                        'agent_id' => $v['agent_id'],
+//                        'date'     => $v['date'],
+//                        'app_id'   => $v['app_id']
+//                    ];
+//                    $_day_log = $this->getPromotionDayLog($_day_map);
+//                    $_v = [];
+//                    $_v['date'] = $v['date'];
+//                    $_v['agent_id'] = (isset($agents[$v['owner_id']]) ? $agents[$v['owner_id']] : '官包')."\t";
+//                    $_v['pd_id'] = $v['pd_id'];
+//                    $_v['platform'] = $platforms[$v['platform_id']];
+//                    $_v['game'] = $games[$v['app_id']];
+//                    $_v['check_cnt'] = $_day_log['distinct_visit_cnt'];
+//                    $_v['down_cnt'] = $_day_log['distinct_down_cnt'];
+//                    $_v['reg_cnt'] = $v['reg_cnt'];
+//                    $_v['reg_device'] = $v['reg_device'];
+//                    $_v['reg_pay_cnt'] = $v['reg_pay_cnt'];
+//                    $_v['new_payment_rate'] = $this->_percentageConversion($v['reg_pay_cnt'], $v['reg_cnt']);
+//                    $_v['sum_reg_money'] = $v['sum_reg_money'];
+//                    $_v['user_cnt'] = $v['user_cnt'];
+//                    $_v['pay_user_cnt'] = $v['pay_user_cnt'];
+//                    $_v['sum_money'] = $v['sum_money'];
+//                    $_v['active_pay_rate'] = $this->_percentageConversion($v['pay_user_cnt'], $v['user_cnt']);
+//                    $_v['active_arpu'] = number_format($v['sum_money'] / $v['user_cnt'], 2, '.', '');
+//                    $_v['pay_arpu'] = number_format($v['sum_money'] / $v['pay_user_cnt'], 2, '.', '');
+//                    $_v['ltv1'] = isset($_ltv[0]['day1']) ? $_ltv[0]['day1'] : 0;
+//                    $_v['ltv7'] = isset($_ltv[0]['day7']) ? $_ltv[0]['day7'] : 0;
+//                    $_v['ltv15'] = isset($_ltv[0]['day15']) ? $_ltv[0]['day15'] : 0;
+//                    $_v['day2'] = $this->_showRegPoint($v['day2'], $v['reg_cnt']);
+//                    $_v['day7'] = $this->_showRegPoint($v['day7'], $v['reg_cnt']);
+//                    $_v['day15'] = $this->_showRegPoint($v['day15'], $v['reg_cnt']);
+//                    $_export_data[] = $_v;
+//                }
+//                $_explore_csv_class->exportCsv(
+//                    $_title, $_expCellName, $_export_data, $_csv_file, $count, $_csv_page, $_csv_offset
+//                );
+//            } else {
+//                $_arr['error'] = 0;
+//                $_arr['msg'] = '';
+//                $_arr['data'] = '';
+//                $this->ajaxReturn($_arr);
+//            }
+//        } else {
+//            $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//            $page = $this->page($count, $rows);
+//            $items = $_day_model
+//                ->alias('d')
+//                ->field('d.*,pd.app_id,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id,pd.id pd_id')
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->order('d.id DESC')
+//                ->limit($page->firstRow.','.$page->listRows)
+//                ->select();
+//            $_check_cnt = $_down_cnt = 0;
+//            $_ltv_agent_ids = [];
+//            foreach ($items as $_k => $_v) {
+//                if (!in_array($_v['agent_id'], $_ltv_agent_ids)) {
+//                    $_ltv_agent_ids[] = $_v['agent_id'];
+//                }
+//                $_where = " `date`='".$_v['date']."' AND `agent_id`='".$_v['agent_id']."'";
+//                $_ltv = $this->getLtvData($_where);
+//                $items[$_k]['ltv'] = $_ltv[0];
+//                $_day_map = [
+//                    'agent_id' => $_v['agent_id'],
+//                    'date'     => $_v['date'],
+//                    'app_id'   => $_v['app_id']
+//                ];
+//                $_day_log = $this->getPromotionDayLog($_day_map);
+//                $items[$_k]['check_cnt'] = $_day_log['distinct_visit_cnt'];
+//                $items[$_k]['down_cnt'] = $_day_log['distinct_down_cnt'];
+//                $_check_cnt += $_day_log['distinct_visit_cnt'];
+//                $_down_cnt += $_day_log['distinct_down_cnt'];
+//                $items[$_k]['day2'] = $this->_showRegPoint($_v['day2'], $_v['reg_cnt']);
+//                $items[$_k]['day7'] = $this->_showRegPoint($_v['day7'], $_v['reg_cnt']);
+//                $items[$_k]['day15'] = $this->_showRegPoint($_v['day15'], $_v['reg_cnt']);
+//            }
+//            /* 汇总数据 */
+//            $_sum_field
+//                = "sum(d.reg_cnt) reg_cnt,sum(d.reg_device) reg_device,sum(d.reg_pay_cnt) reg_pay_cnt,
+//                   sum(d.sum_reg_money) sum_reg_money,sum(d.user_cnt) user_cnt,sum(d.pay_user_cnt) pay_user_cnt,
+//                   sum(d.sum_money) sum_money,sum(d.day2) day2,sum(d.day7) day7,sum(d.day15) day15
+//                   ";
+//            $_sum_items = $_day_model
+//                ->alias('d')
+//                ->field($_sum_field)
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->select();
+//
+//            $_prom_data = M("promotion_day")
+//                ->alias('d')
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->field("sum(`distinct_visit_cnt`) distinct_visit_cnt,sum(`distinct_down_cnt`) distinct_down_cnt")
+//                ->select();
+//            $_sum_items[0]['check_cnt'] = $_prom_data[0]['distinct_visit_cnt'];
+//            $_sum_items[0]['down_cnt'] = $_prom_data[0]['distinct_down_cnt'];
+//            if (3 == $this->role_type) {
+//                $_ltv_where = " agent_id".$this->agentwhere;
+//            } else {
+//                if (!empty( $this->buy_agents)) {
+//                    $_agent_ids = implode(',', $this->buy_agents);
+//                    $_ltv_where = " agent_id in (".$_agent_ids.") ";
+//                } else {
+//                    $_ltv_where = " 1 ";
+//                }
+//            }
+//            if ('今日' == $_is_today) {
+//                $_ltv_where .= " and `date`='".date('Y-m-d')."'";
+//                $where .= " and d.`date`='".date('Y-m-d')."'";
+//                $_prom_data = M("promotion_day")
+//                    ->alias('d')
+//                    ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//                    ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                    ->where($where)
+//                    ->field("sum(`distinct_visit_cnt`) distinct_visit_cnt,sum(`distinct_down_cnt`) distinct_down_cnt")
+//                    ->select();
+//                $_sum_items[0]['check_cnt'] = !empty($_prom_data[0]['distinct_visit_cnt']) ? $_prom_data[0]['distinct_visit_cnt'] : 0;
+//                $_sum_items[0]['down_cnt'] = !empty($_prom_data[0]['distinct_down_cnt']) ? $_prom_data[0]['distinct_down_cnt'] : 0;
+//            }
+//            $_ltv = $this->getLtvData($_ltv_where);
+//            $_sum_items[0]['ltv'] = $_ltv[0];
+//            $_sum_items[0]['day2'] = $this->_showRegPoint($_sum_items[0]['day2'], $_sum_items[0]['reg_cnt']);
+//            $_sum_items[0]['day7'] = $this->_showRegPoint($_sum_items[0]['day7'], $_sum_items[0]['reg_cnt']);
+//            $_sum_items[0]['day15'] = $this->_showRegPoint($_sum_items[0]['day15'], $_sum_items[0]['reg_cnt']);
+//            $_export_button = $_explore_csv_class->exportButton('数据导出', 'input', 1000, 'btn btn-primary');
+//            $this->assign("export_button", $_export_button);
+//            $this->assign("pays", $items);
+//            $this->assign("sum_items", $_sum_items);
+//            $this->assign($_GET);
+//            $this->assign("Page", $page->show('Admin'));
+//        }
+    }
+
+    public function getOthers($where, $items) {
+        return [
+            'agent_id' => 1154
+        ];
+    }
+
+    /**
+     * 买量员留存
+     */
+    public function optimizerRetain() {
+        echo '买量员留存';
+        exit;
+//        $this->genUsers();
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $_day_model = M('tmp_day_promotion');
+//        } else {
+//            $_day_model = M('day_promotion');
+//        }
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $_plan_id = I('plan_id');
+//        $_agent_id = I('agent_id');
+//        $where = " 1 ";
+//        if (isset($_agent_id) && !empty($_agent_id)) {
+//            $where .= " AND pp.owner_id = '".$_agent_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($_plan_id) && !empty($_plan_id)) {
+//            $where .= " AND pp.id=".$_plan_id;
+//        }
+//        $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//        $count = $_day_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        $page = $this->page($count, $rows);
+//        $items = $_day_model
+//            ->alias('d')
+//            ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->limit($page->firstRow.','.$page->listRows)
+//            ->select();
+//        foreach ($items as $key => $value) {
+//            for ($i = 2; $i <= 60; $i++) {
+//                $_name = 'day'.$i;
+//                if (isset($value[$_name])) {
+//                    $items[$key][$_name] = $this->_showRegPoint($value[$_name], $value['reg_cnt']);
+//                }
+//            }
+//        }
+//        $this->assign("items", $items);
+//        $this->assign($_GET);
+//        $this->assign("Page", $page->show('Admin'));
+//        $this->display();
+    }
+
+    /**
+     * 买量员LTV
+     */
+    public function optimizerLtv() {
+        echo '买量员LTV';
+        exit;
+//        $this->genUsers();
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $_day_model = M('tmp_day_promotion');
+//        } else {
+//            $_day_model = M('day_promotion');
+//        }
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $_plan_id = I('plan_id');
+//        $_agent_id = I('agent_id');
+//        $where = " 1 ";
+//        if (isset($_agent_id) && !empty($_agent_id)) {
+//            $where .= " AND pp.owner_id = '".$_agent_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($_plan_id) && !empty($_plan_id)) {
+//            $where .= " AND pp.id=".$_plan_id;
+//        }
+//        $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//        $count = $_day_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        $page = $this->page($count, $rows);
+//        $items = $_day_model
+//            ->alias('d')
+//            ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->limit($page->firstRow.','.$page->listRows)
+//            ->select();
+//        foreach ($items as $_k => $_v) {
+//            $_where = " `date`='".$_v['date']."' AND `agent_id`='".$_v['agent_id']."'";
+//            $_ltv = $this->getLtvData($_where);
+//            $items[$_k]['ltv'] = $_ltv[0];
+//        }
+//        $this->assign("items", $items);
+//        $this->assign($_GET);
+//        $this->assign("Page", $page->show('Admin'));
+//        $this->display();
+    }
+
+    public function _percentageConversion($cnt, $molecule) {
+        if ($molecule) {
+            return number_format($cnt * 100 / $molecule, 2, '.', '')."%";
+        } else {
+            return '(nan%)';
+        }
+    }
+
+    /**
+     * 分链接统计
+     */
+    public function plan() {
+        echo '分链接统计';
+        exit;
+//        $this->genUsers();
+//        $this->_games();
+//        if (3 == $this->role_type) {
+//            $this->where = " pp.owner_id".$this->agentwhere;
+//        } else {
+////            $this->where = " 1 ";
+//            $_agent_ids = implode(',', $this->buy_agents);
+//            $this->where = " pp.owner_id in (".$_agent_ids.") ";
+//        }
+//        $this->_getPlan();
+//        $this->display();
+    }
+
+    public function _getPlan() {
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $this->_initTodayData();
+//            $_game_model = M('tmp_day_promotion_game');
+//        } else {
+//            $_game_model = M('day_promotion_game');
+//        }
+////        $platform = I('platform');
+//        $platform_id = I('platform_id');
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $app_id = I('app_id');
+//        $landing_page_id = I('landing_page_id/d', '');
+//        /* 导出参数 */
+//        $_csv_do = I('csv_do', 1);
+//        $_csv_page = I('csv_page', 1);
+//        $_csv_offset = I('csv_offset', 1000);
+//        $_csv_file = I('csv_file', '');
+//        $_explore_csv_class = new \Huosdk\Data\ExportCsv();
+//        $where = $this->where;
+////        if (isset($platform) && !empty($platform)) {
+////            $_platform_ids = M('platform')->where(['name' => ['like', "%$platform%"]])->getField('id', true);
+////            $idstr = implode(',', $_platform_ids);
+////            $where .= " AND pp.platform_id in ('".$idstr."') ";
+////        }
+//        if (isset($platform_id) && !empty($platform_id)) {
+//            $where .= " AND pp.platform_id = '".$platform_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($app_id) && !empty($app_id)) {
+//            $where .= " AND d.app_id=".$app_id;
+//        }
+//        if (isset($landing_page_id) && !empty($landing_page_id)) {
+//            $where .= " AND pd.landing_page_id = '".$landing_page_id."'";
+//        }
+//        $count = $_game_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        if (2 == $_csv_do) {
+//            $items = $_game_model
+//                ->alias('d')
+//                ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->order('d.id DESC')
+//                ->page($_csv_page, $_csv_offset)
+//                ->select();
+//            if (!empty($items) && is_array($items)) {
+//                $_title = '落地页统计';
+//                $_expCellName = array('日期', '落地页ID', '游戏名称', '投放渠道', '落地页点击', '下载量', '下载转化率', '注册', '新增设备', '新增付费数	',
+//                                      '新增付费率', '新增付费金额', '活跃',
+//                                      '付费人数', '活跃付费率', '活跃arpu', '付费arpu', 'ltv 1日', 'ltv 7日', 'ltv 15日',
+//                                      '留存 1日', '留存 7日', '留存 15日'
+//                );
+//                $_export_data = [];
+//                $games = M('game')->where(
+//                    array('id' => array('in', implode(',', array_unique(array_column($items, 'app_id')))))
+//                )->getField('id,name', true);
+//                $platforms = M('platform')->getField("id,name platform", true);
+//                foreach ($items as $k => $v) {
+//                    $_where = " `date`='".$v['date']."' AND `agent_id`='".$v['agent_id']."' AND `app_id`='".$v['app_id']
+//                              ."'";
+//                    $_ltv = $this->getLtvData($_where);
+//                    $_day_map = [
+//                        'agent_id' => $v['agent_id'],
+//                        'date'     => $v['date'],
+//                        'app_id'   => $v['app_id']
+//                    ];
+//                    $_day_log = $this->getPromotionDayLog($_day_map);
+//                    $_v = [];
+//                    $_v['date'] = $v['date'];
+//                    $_v['landing_page_id'] = $v['landing_page_id'];
+//                    $_v['game'] = $games[$v['app_id']];
+//                    $_v['platform'] = $platforms[$v['platform_id']];
+//                    $_v['check_cnt'] = $_day_log['distinct_visit_cnt'];
+//                    $_v['down_cnt'] = $_day_log['distinct_down_cnt'];
+//                    $_v['down_rate'] = ($_day_log['distinct_down_cnt'] / $_day_log['distinct_visit_cnt']) * 100 .'%';
+//                    $_v['reg_cnt'] = $v['reg_cnt'];
+//                    $_v['reg_device'] = $v['reg_device'];
+//                    $_v['reg_pay_cnt'] = $v['reg_pay_cnt'];
+//                    $_v['new_payment_rate'] = $this->_percentageConversion($v['reg_pay_cnt'], $v['reg_cnt']);
+//                    $_v['sum_reg_money'] = $v['sum_reg_money'];
+//                    $_v['user_cnt'] = $v['user_cnt'];
+//                    $_v['pay_user_cnt'] = $v['pay_user_cnt'];
+//                    $_v['active_pay_rate'] = $this->_percentageConversion($v['pay_user_cnt'], $v['user_cnt']);
+//                    $_v['active_arpu'] = number_format($v['sum_money'] / $v['user_cnt'], 2, '.', '');
+//                    $_v['pay_arpu'] = number_format($v['sum_money'] / $v['pay_user_cnt'], 2, '.', '');
+//                    $_v['ltv1'] = isset($_ltv[0]['day1']) ? $_ltv[0]['day1'] : 0;
+//                    $_v['ltv7'] = isset($_ltv[0]['day7']) ? $_ltv[0]['day7'] : 0;
+//                    $_v['ltv15'] = isset($_ltv[0]['day15']) ? $_ltv[0]['day15'] : 0;
+//                    $_v['day2'] = $this->_showRegPoint($v['day2'], $v['reg_cnt']);
+//                    $_v['day7'] = $this->_showRegPoint($v['day7'], $v['reg_cnt']);
+//                    $_v['day15'] = $this->_showRegPoint($v['day15'], $v['reg_cnt']);
+//                    $_export_data[] = $_v;
+//                }
+//                $_explore_csv_class->exportCsv(
+//                    $_title, $_expCellName, $_export_data, $_csv_file, $count, $_csv_page, $_csv_offset
+//                );
+//            } else {
+//                $_arr['error'] = 0;
+//                $_arr['msg'] = '';
+//                $_arr['data'] = '';
+//                $this->ajaxReturn($_arr);
+//            }
+//        } else {
+//            $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//            $page = $this->page($count, $rows);
+//            $items = $_game_model
+//                ->alias('d')
+//                ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->order('d.id DESC')
+//                ->limit($page->firstRow.','.$page->listRows)
+//                ->select();
+//            $_check_cnt = $_down_cnt = 0;
+//            $_ltv_agent_ids = [];
+//            foreach ($items as $_k => $_v) {
+//                $_ltv_agent_ids[] = $_v['agent_id'];
+//                $_where = " `date`='".$_v['date']."' AND `agent_id`='".$_v['agent_id']."' AND `app_id`='".$_v['app_id']
+//                          ."'";
+//                $_ltv = $this->getLtvData($_where);
+//                $items[$_k]['ltv'] = $_ltv[0];
+//                $_day_map = [
+//                    'agent_id' => $_v['agent_id'],
+//                    'date'     => $_v['date'],
+//                    'app_id'   => $_v['app_id']
+//                ];
+//                $_day_log = $this->getPromotionDayLog($_day_map);
+//                $items[$_k]['check_cnt'] = $_day_log['distinct_visit_cnt'];
+//                $items[$_k]['down_cnt'] = $_day_log['distinct_down_cnt'];
+//                $_check_cnt += $_day_log['distinct_visit_cnt'];
+//                $_down_cnt += $_day_log['distinct_down_cnt'];
+//                $items[$_k]['day2'] = $this->_showRegPoint($_v['day2'], $_v['reg_cnt']);
+//                $items[$_k]['day7'] = $this->_showRegPoint($_v['day7'], $_v['reg_cnt']);
+//                $items[$_k]['day15'] = $this->_showRegPoint($_v['day15'], $_v['reg_cnt']);
+//            }
+//            /* 汇总数据 */
+//            $_sum_field
+//                = "sum(d.reg_cnt) reg_cnt,sum(d.reg_device) reg_device,sum(d.reg_pay_cnt) reg_pay_cnt,
+//                   sum(d.sum_reg_money) sum_reg_money,sum(d.user_cnt) user_cnt,sum(d.pay_user_cnt) pay_user_cnt,
+//                   sum(d.sum_money) sum_money,sum(d.day2) day2,sum(d.day7) day7,sum(d.day15) day15,sum(d.check_cnt) check_cnt,
+//                   sum(d.down_cnt) down_cnt,sum(reg_device) reg_device
+//                   ";
+//            $_sum_items = $_game_model
+//                ->alias('d')
+//                ->field($_sum_field)
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->select();
+//            $_prom_data = M("promotion_day")
+//                ->alias('d')
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->field("sum(`distinct_visit_cnt`) distinct_visit_cnt,sum(`distinct_down_cnt`) distinct_down_cnt")
+//                ->select();
+//            $_sum_items[0]['check_cnt'] = $_prom_data[0]['distinct_visit_cnt'];
+//            $_sum_items[0]['down_cnt'] = $_prom_data[0]['distinct_down_cnt'];
+//            $_sum_items[0]['day2'] = $this->_showRegPoint($_sum_items[0]['day2'], $_sum_items[0]['reg_cnt']);
+//            $_sum_items[0]['day7'] = $this->_showRegPoint($_sum_items[0]['day7'], $_sum_items[0]['reg_cnt']);
+//            $_sum_items[0]['day15'] = $this->_showRegPoint($_sum_items[0]['day15'], $_sum_items[0]['reg_cnt']);
+//            if (3 == $this->role_type) {
+//                $_ltv_where = " agent_id".$this->agentwhere;
+//            } else {
+//                if (!empty( $this->buy_agents)) {
+//                    $_agent_ids = implode(',', $this->buy_agents);
+//                    $_ltv_where = " agent_id in (".$_agent_ids.") ";
+//                } else {
+//                    $_ltv_where = " 1 ";
+//                }
+//            }
+//            /*if ('今日' == $_is_today) {
+//                $_ltv_where .= " and `date`='".date('Y-m-d')."'";
+//            }*/
+//            if ('今日' == $_is_today) {
+//                $_ltv_where .= " and `date`='".date('Y-m-d')."'";
+//                $where .= " and d.`date`='".date('Y-m-d')."'";
+//                $_prom_data = M("promotion_day")
+//                    ->alias('d')
+//                    ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id")
+//                    ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                    ->where($where)
+//                    ->field("sum(`distinct_visit_cnt`) distinct_visit_cnt,sum(`distinct_down_cnt`) distinct_down_cnt")
+//                    ->select();
+//                $_sum_items[0]['check_cnt'] = !empty($_prom_data[0]['distinct_visit_cnt']) ? $_prom_data[0]['distinct_visit_cnt'] : 0;
+//                $_sum_items[0]['down_cnt'] = !empty($_prom_data[0]['distinct_down_cnt']) ? $_prom_data[0]['distinct_down_cnt'] : 0;
+//            }
+//            $_ltv = $this->getLtvData($_ltv_where);
+//            $_sum_items[0]['ltv'] = $_ltv[0];
+//            $_export_button = $_explore_csv_class->exportButton('数据导出', 'input', 1000, 'btn btn-primary');
+//            $this->assign("export_button", $_export_button);
+//            $this->assign("pays", $items);
+//            $this->assign("sum_items", $_sum_items);
+//            $this->assign($_GET);
+//            $this->assign("Page", $page->show('Admin'));
+//        }
+    }
+
+    /**
+     * 分链接留存
+     */
+    public function planRetain() {
+        echo '分链接留存';
+        exit;
+//        $this->_game();
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $_game_model = M('tmp_day_promotion_game');
+//        } else {
+//            $_game_model = M('day_promotion_game');
+//        }
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $_app_id = I('app_id');
+//        $_plan_id = I('plan_id');
+//        $landing_page_id = I('landing_page_id/d', '');
+//        $platform_id = I('platform_id');
+//        $where = " 1 ";
+//        if (isset($_app_id) && !empty($_app_id)) {
+//            $where .= " AND d.app_id = '".$_app_id."'";
+//        }
+//        if (isset($_agent_id) && !empty($_agent_id)) {
+//            $where .= " AND pp.owner_id = '".$_agent_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($platform_id) && !empty($platform_id)) {
+//            $where .= " AND pp.platform_id = '".$platform_id."'";
+//        }
+//        if (isset($landing_page_id) && !empty($landing_page_id)) {
+//            $where .= " AND pd.landing_page_id = '".$landing_page_id."'";
+//        }
+//        if (isset($_plan_id) && !empty($_plan_id)) {
+//            $where .= " AND pp.id=".$_plan_id;
+//        }
+//        $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//        $count = $_game_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        $page = $this->page($count, $rows);
+//        $items = $_game_model
+//            ->alias('d')
+//            ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->limit($page->firstRow.','.$page->listRows)
+//            ->select();
+//        foreach ($items as $key => $value) {
+//            for ($i = 2; $i <= 60; $i++) {
+//                $_name = 'day'.$i;
+//                if (isset($value[$_name])) {
+//                    $items[$key][$_name] = $this->_showRegPoint($value[$_name], $value['reg_cnt']);
+//                }
+//            }
+//        }
+//        $this->assign("items", $items);
+//        $this->assign("Page", $page->show('Admin'));
+//        $this->assign($_GET);
+//        $this->display();
+    }
+
+    /**
+     * 分链接LTV
+     */
+    public function planLtv() {
+        echo '分链接LTV';
+        exit;
+//        $this->_game();
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $_game_model = M('tmp_day_promotion_game');
+//        } else {
+//            $_game_model = M('day_promotion_game');
+//        }
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $_app_id = I('app_id');
+//        $_plan_id = I('plan_id');
+//        $landing_page_id = I('landing_page_id/d', '');
+//        $platform_id = I('platform_id');
+//        $where = " 1 ";
+//        if (isset($_app_id) && !empty($_app_id)) {
+//            $where .= " AND d.app_id = '".$_app_id."'";
+//        }
+//        if (isset($_agent_id) && !empty($_agent_id)) {
+//            $where .= " AND pp.owner_id = '".$_agent_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($platform_id) && !empty($platform_id)) {
+//            $where .= " AND pp.platform_id = '".$platform_id."'";
+//        }
+//        if (isset($landing_page_id) && !empty($landing_page_id)) {
+//            $where .= " AND pd.landing_page_id = '".$landing_page_id."'";
+//        }
+//        if (isset($_plan_id) && !empty($_plan_id)) {
+//            $where .= " AND pp.id=".$_plan_id;
+//        }
+//        $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//        $count = $_game_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        $page = $this->page($count, $rows);
+//        $items = $_game_model
+//            ->alias('d')
+//            ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->limit($page->firstRow.','.$page->listRows)
+//            ->select();
+//        foreach ($items as $_k => $_v) {
+//            $_where = " `date`='".$_v['date']."' AND `agent_id`='".$_v['agent_id']."' AND `app_id`='".$_v['app_id']."'";
+//            $_ltv = $this->getLtvData($_where);
+//            $items[$_k]['ltv'] = $_ltv[0];
+//        }
+//        $this->assign("items", $items);
+//        $this->assign("Page", $page->show('Admin'));
+//        $this->assign($_GET);
+//        $this->display();
+    }
+
+    /**
+     * 渠道数据
+     */
+    public function agent() {
+        echo '渠道数据';
+        exit;
+//        $this->genUsers();
+//        $this->_game();
+//        if (3 == $this->role_type) {//|| 2 == $this->role_type
+//            $this->where = " pp.owner_id".$this->agentwhere;
+//        } else {
+////            $this->where = " 1 ";
+//            $_agent_ids = implode(',', $this->buy_agents);
+//            $this->where = " pp.owner_id in (".$_agent_ids.") ";
+//        }
+//        $this->_getAgent();
+//        $this->display();
+    }
+
+    public function _getAgent() {
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $this->_initTodayData();
+//            $_day_model = M('tmp_day_promotion_game');
+//            $_table = 'c_tmp_day_promotion_game';
+//        } else {
+//            $_day_model = M('day_promotion_game');
+//            $_table = 'c_day_promotion_game';
+//        }
+//        $platform_id = I('platform_id', '');
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $agent_id = I('agent_id/d', 0);
+//        $app_id = I('app_id/d', '');
+//        /* 导出参数 */
+//        $_csv_do = I('csv_do', 1);
+//        $_csv_page = I('csv_page', 1);
+//        $_csv_offset = I('csv_offset', 1000);
+//        $_csv_file = I('csv_file', '');
+//        $_explore_csv_class = new \Huosdk\Data\ExportCsv();
+//        $where = $this->where;
+//        if (isset($platform_id) && !empty($platform_id)) {
+//            $where .= " AND pp.platform_id = '".$platform_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($agent_id) && !empty($agent_id)) {
+//            $where .= " AND pp.owner_id=".$agent_id;
+//        }
+//        if (isset($app_id) && !empty($app_id)) {
+//            $where .= " AND d.app_id=".$app_id;
+//        }
+//        $count_sql = "SELECT count(*) as tp_count  FROM (SELECT d.id FROM {$_table} d LEFT JOIN "
+//                     .C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id
+//                      LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id
+//                      WHERE {$where} GROUP BY d.date,d.app_id) taba";
+//        $count_info = M()->query($count_sql);
+//        $count = isset($count_info[0]['tp_count']) ? $count_info[0]['tp_count'] : 0;
+////        $count = $_day_model
+////            ->alias('d')
+////            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+////            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+////            ->where($where)
+////            ->count();
+//        if (2 == $_csv_do) {
+////            $_fields = 'd.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id';
+//            $_fields
+//                = 'd.date,d.app_id,sum(d.reg_cnt) reg_cnt,sum(d.reg_device) reg_device,sum(d.reg_pay_cnt) reg_pay_cnt,sum(d.sum_reg_money) sum_reg_money,';
+//            $_fields .= 'sum(d.user_cnt) user_cnt,sum(d.pay_user_cnt) pay_user_cnt,sum(d.sum_money) sum_money,';
+//            $_fields .= 'sum(d.day2) day2,sum(d.day7) day7,sum(d.day15) day15';
+//            $items = $_day_model
+//                ->alias('d')
+//                ->field($_fields)
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->order('d.id DESC')
+//                ->page($_csv_page, $_csv_offset)
+//                ->group('d.date,d.app_id')
+//                ->select();
+//            if (!empty($items) && is_array($items)) {
+//                $_title = '渠道数据';
+//                $_expCellName = array('日期', '游戏名称', '注册	', '新增设备', '新增付费数', '新增付费率',
+//                                      '新增付费金额', '活跃', '付费人数', '付费金额', '活跃付费率', '活跃arpu', '付费arpu', 'ltv 1日', 'ltv 7日',
+//                                      'ltv 15日', '留存 1日', '留存 7日', '留存 15日'
+//                );
+//                $_export_data = [];
+//                $games = M('game')->where(
+//                    array('id' => array('in', implode(',', array_unique(array_column($items, 'app_id')))))
+//                )->getField('id,name', true);
+//                foreach ($items as $k => $v) {
+//                    $_where = " `date`='".$v['date']."' AND `app_id`='".$v['app_id']."'";
+//                    $_ltv = $this->getLtvData($_where);
+//                    $_v = [];
+//                    $_v['date'] = $v['date'];
+//                    $_v['game'] = $games[$v['app_id']];
+//                    $_v['reg_cnt'] = $v['reg_cnt'];
+//                    $_v['reg_device'] = $v['reg_device'];
+//                    $_v['reg_pay_cnt'] = $v['reg_pay_cnt'];
+//                    $_v['reg_pay_rate'] = (number_format($v['reg_pay_cnt'] / $v['reg_cnt'], 2, '.', '') * 100).'%';
+//                    $_v['sum_reg_money'] = $v['sum_reg_money'];
+//                    $_v['user_cnt'] = $v['user_cnt'];
+//                    $_v['pay_user_cnt'] = $v['pay_user_cnt'];
+//                    $_v['sum_money'] = $v['sum_money'];
+//                    $_v['active_pay_rate'] = (number_format($v['pay_user_cnt'] / $v['user_cnt'], 2, '.', '') * 100).'%';
+//                    $_v['active_arpu'] = number_format($v['sum_money'] / $v['user_cnt'], 2, '.', '');
+//                    $_v['pay_arpu'] = number_format($v['sum_money'] / $v['pay_user_cnt'], 2, '.', '');
+//                    $_v['ltv1'] = isset($_ltv[0]['day1']) ? $_ltv[0]['day1'] : 0;
+//                    $_v['ltv7'] = isset($_ltv[0]['day7']) ? $_ltv[0]['day7'] : 0;
+//                    $_v['ltv15'] = isset($_ltv[0]['day15']) ? $_ltv[0]['day15'] : 0;
+//                    $_v['day2'] = $this->_showRegPoint($v['day2'], $v['reg_cnt']);
+//                    $_v['day7'] = $this->_showRegPoint($v['day7'], $v['reg_cnt']);
+//                    $_v['day15'] = $this->_showRegPoint($v['day15'], $v['reg_cnt']);
+//                    $_export_data[] = $_v;
+//                }
+//                $_explore_csv_class->exportCsv(
+//                    $_title, $_expCellName, $_export_data, $_csv_file, $count, $_csv_page, $_csv_offset
+//                );
+//            } else {
+//                $_arr['error'] = 0;
+//                $_arr['msg'] = '';
+//                $_arr['data'] = '';
+//                $this->ajaxReturn($_arr);
+//            }
+//        } else {
+//            $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//            $page = $this->page($count, $rows);
+////            $_fields = 'd.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id';
+//            $_fields
+//                = 'd.date,d.app_id,sum(d.reg_cnt) reg_cnt,sum(d.reg_device) reg_device,sum(d.reg_pay_cnt) reg_pay_cnt,sum(d.sum_reg_money) sum_reg_money,';
+//            $_fields .= 'sum(d.user_cnt) user_cnt,sum(d.pay_user_cnt) pay_user_cnt,sum(d.sum_money) sum_money,';
+//            $_fields .= 'sum(d.day2) day2,sum(d.day7) day7,sum(d.day15) day15';
+//            $items = $_day_model
+//                ->alias('d')
+//                ->field($_fields)
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->order('d.id DESC')
+//                ->limit($page->firstRow.','.$page->listRows)
+//                ->group('d.date,d.app_id')
+//                ->select();
+//            foreach ($items as $_k => $_v) {
+////                $_where = " `date`='".$_v['date']."' AND `agent_id`='".$_v['agent_id']."' AND `app_id`='".$_v['app_id']
+////                          ."'";
+//                $_where = " `date`='".$_v['date']."' AND `app_id`='".$_v['app_id']
+//                          ."'";
+//                $_ltv = $this->getLtvData($_where);
+//                $items[$_k]['ltv'] = $_ltv[0];
+//                $items[$_k]['day2'] = $this->_showRegPoint($_v['day2'], $_v['reg_cnt']);
+//                $items[$_k]['day7'] = $this->_showRegPoint($_v['day7'], $_v['reg_cnt']);
+//                $items[$_k]['day15'] = $this->_showRegPoint($_v['day15'], $_v['reg_cnt']);
+//            }
+//            /* 汇总数据 */
+//            $_sum_field
+//                = "sum(d.reg_cnt) reg_cnt,sum(d.reg_device) reg_device,sum(d.reg_pay_cnt) reg_pay_cnt,
+//                   sum(d.sum_reg_money) sum_reg_money,sum(d.user_cnt) user_cnt,sum(d.pay_user_cnt) pay_user_cnt,
+//                   sum(d.sum_money) sum_money,sum(d.day2) day2,sum(d.day7) day7,sum(d.day15) day15
+//                   ";
+//            $_sum_items = $_day_model
+//                ->alias('d')
+//                ->field($_sum_field)
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and d.app_id=pd.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->select();
+//            if (3 == $this->role_type) {
+//                $_ltv_where = " agent_id".$this->agentwhere;
+//            } else {
+//                if (!empty( $this->buy_agents)) {
+//                    $_agent_ids = implode(',', $this->buy_agents);
+//                    $_ltv_where = " agent_id in (".$_agent_ids.") ";
+//                } else {
+//                    $_ltv_where = " 1 ";
+//                }
+//            }
+//            if ('今日' == $_is_today) {
+//                $_ltv_where .= " and `date`='".date('Y-m-d')."'";
+//            }
+//            $_ltv = $this->getLtvData($_ltv_where);
+//            $_sum_items[0]['ltv'] = $_ltv[0];
+//            $_sum_items[0]['day2'] = $this->_showRegPoint($_sum_items[0]['day2'], $_sum_items[0]['reg_cnt']);
+//            $_sum_items[0]['day7'] = $this->_showRegPoint($_sum_items[0]['day7'], $_sum_items[0]['reg_cnt']);
+//            $_sum_items[0]['day15'] = $this->_showRegPoint($_sum_items[0]['day15'], $_sum_items[0]['reg_cnt']);
+//            $_export_button = $_explore_csv_class->exportButton('数据导出', 'input', 1000, 'btn btn-primary');
+//            $this->assign("export_button", $_export_button);
+//            $this->assign("pays", $items);
+//            $this->assign("sum_items", $_sum_items);
+//            $this->assign($_GET);
+//            $this->assign("Page", $page->show('Admin'));
+//        }
+    }
+
+    /**
+     * 渠道留存
+     */
+    public function agentRetain() {
+        echo '渠道留存';
+        exit;
+//        $this->_games();
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $_game_model = M('tmp_day_promotion_game');
+//        } else {
+//            $_game_model = M('day_promotion_game');
+//        }
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $_agent_id = I('agent_id');
+//        $_app_id = I('app_id');
+//        $platform_id = I('platform_id');
+//        $where = " 1 ";
+//        if (isset($_app_id) && !empty($_app_id)) {
+//            $where .= " AND d.app_id = '".$_app_id."'";
+//        }
+//        if (isset($_agent_id) && !empty($_agent_id)) {
+//            $where .= " AND pp.owner_id = '".$_agent_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($platform_id) && !empty($platform_id)) {
+//            $where .= " AND pp.platform_id = '".$platform_id."'";
+//        }
+//        $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//        $count = $_game_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        $page = $this->page($count, $rows);
+//        $items = $_game_model
+//            ->alias('d')
+//            ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->limit($page->firstRow.','.$page->listRows)
+//            ->select();
+//        foreach ($items as $key => $value) {
+//            for ($i = 2; $i <= 60; $i++) {
+//                $_name = 'day'.$i;
+//                if (isset($value[$_name])) {
+//                    $items[$key][$_name] = $this->_showRegPoint($value[$_name], $value['reg_cnt']);
+//                }
+//            }
+//        }
+//        $this->assign("items", $items);
+//        $this->assign($_GET);
+//        $this->assign("Page", $page->show('Admin'));
+//        $this->display();
+    }
+
+    /**
+     * 渠道LTV
+     */
+    public function agentLtv() {
+        echo '渠道LTV';
+        exit;
+//        $this->_game();
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $_game_model = M('tmp_day_promotion_game');
+//        } else {
+//            $_game_model = M('day_promotion_game');
+//        }
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $_agent_id = I('agent_id');
+//        $_app_id = I('app_id');
+//        $platform_id = I('platform_id');
+//        $where = " 1 ";
+//        if (isset($_app_id) && !empty($_app_id)) {
+//            $where .= " AND d.app_id = '".$_app_id."'";
+//        }
+//        if (isset($_agent_id) && !empty($_agent_id)) {
+//            $where .= " AND pp.owner_id = '".$_agent_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($platform_id) && !empty($platform_id)) {
+//            $where .= " AND pp.platform_id = '".$platform_id."'";
+//        }
+//        $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//        $count = $_game_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        $page = $this->page($count, $rows);
+//        $items = $_game_model
+//            ->alias('d')
+//            ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->limit($page->firstRow.','.$page->listRows)
+//            ->select();
+//        foreach ($items as $_k => $_v) {
+//            $_where = " `date`='".$_v['date']."' AND `agent_id`='".$_v['agent_id']."' AND `app_id`='".$_v['app_id']."'";
+//            $_ltv = $this->getLtvData($_where);
+//            $items[$_k]['ltv'] = $_ltv[0];
+//        }
+//        $this->assign("items", $items);
+//        $this->assign($_GET);
+//        $this->assign("Page", $page->show('Admin'));
+//        $this->display();
+    }
+
+    public function getPromotionDayLog($where) {
+//        $_pd_map['agent_id'] = $where['agent_id'];
+//        $_is_ocpc = M('promotion_detail')->where($_pd_map)->getField('toutiao_key');
+//        if (!empty($_is_ocpc)){
+//            $_table = "promotion_day";
+//        }else{
+//            $_table = "promotion_day_log";
+//        }
+//        $_record['distinct_visit_cnt'] = 0;
+//        $_record['distinct_down_cnt'] = 0;
+//        $_info = M($_table)->field('distinct_visit_cnt,distinct_down_cnt')->where($where)->find();
+//        if (!empty($_info)) {
+//            $_record = $_info;
+//        }
+//
+//        return $_record;
+    }
+
+    public function getPromotionByowner($date, $owner_id, $app_id, $platform_id) {
+//        $_record['distinct_visit_cnt'] = 0;
+//        $_record['distinct_down_cnt'] = 0;
+//        $_p_map['owner_id'] = $owner_id;
+//        $_p_map['platform_id'] = $platform_id;
+//        $_plans = M('promotion_plan')->where($_p_map)->getField('id',true);
+//        if (empty($_plans)){
+//            return $_record;
+//        }
+//        $_pd_map['app_id'] = $app_id;
+//        $_pd_map['promotion_plan_id'] = array('in',$_plans);
+//        $_agents = M('promotion_detail')->where($_pd_map)->getField('agent_id',true);
+//        if (empty($_agents)){
+//            return $_record;
+//        }
+//        /*$_ptd_map['date'] = $date;
+//        $_ptd_map['agent_id'] = array('in',$_agents);
+//        $_field = "sum(distinct_visit_cnt) distinct_visit_cnt,sum(distinct_down_cnt) distinct_down_cnt";
+//        $_info = M('promotion_day')->field($_field)->where($_ptd_map)->find();
+//        if (!empty($_info)) {
+//            $_record = $_info;
+//        }*/
+//        foreach ($_agents as $_v){
+//            $_pd_map['agent_id'] = $_v;
+//            $_is_ocpc = M('promotion_detail')->where($_pd_map)->getField('toutiao_key');
+//            if (!empty($_is_ocpc)){
+//                $_table = "promotion_day";
+//            }else{
+//                $_table = "promotion_day_log";
+//            }
+//            $_ptd_map['date'] = $date;
+//            $_ptd_map['agent_id'] = $_v;
+//            $_info = M($_table)->field('distinct_visit_cnt,distinct_down_cnt')->where($_ptd_map)->find();
+//            $_record['distinct_visit_cnt'] += $_info['distinct_visit_cnt'];
+//            $_record['distinct_down_cnt'] += $_info['distinct_down_cnt'];
+//        }
+//
+//        return $_record;
+    }
+
+    public function getSumPromotionDayLog($where) {
+//        $_record['sum_distinct_visit_cnt'] = 0;
+//        $_record['sum_distinct_down_cnt'] = 0;
+//        $_info = M('promotion_day_log')->field(
+//            'sum(distinct_visit_cnt) sum_distinct_visit_cnt,sum(distinct_down_cnt) sum_distinct_down_cnt'
+//        )->where($where)->select();
+//        if (!empty($_info)) {
+//            $_record = $_info[0];
+//        }
+//
+//        return $_record;
+    }
+
+    /**
+     * 下级渠道数据(按计划--每个渠道下有多个计划)
+     */
+    public function subAgent() {
+        $do_export = false;
+        if ('1' == $this->request->param('export/d', 0)) {
+            $do_export = true;
+        }
+        if (!$do_export) {
+            $this->genUsers();
+            $this->genPlatforms();
+        }
+        $this->_getSubAgent($do_export);
+
+        return $this->fetch();
+    }
+
+    public function _getSubAgent($do_export = false) {
+        $_is_today = $this->request->param("is_today", '今日');
+        $platform_id = $this->request->param("platform_id");
+        $start = $this->request->param("start_time");
+        $end = $this->request->param("end_time");
+        $app_id = $this->request->param("app_id");
+        $agent_id = $this->request->param("agent_id/d", 0);
+        $plan_id = $this->request->param("plan_id/d", 0);
+        $landing_page_id = $this->request->param("landing_page_id/d", 0);
+        $son_agent_id = $this->request->param("son_agent_id/d", 0);
+        $sub_back = $this->request->param("sub_back", '');
+        if (!$do_export) {
+            $this->_games($app_id);
+        }
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', $this->abs_row);
+        $_data_list = $this->_getSubAgentList(
+            $_is_today, $platform_id, $start, $end, $app_id, $agent_id, $plan_id, $landing_page_id, $son_agent_id,
+            $_page, $_list_rows
+        );
+        if (!$do_export) {
+            $this->assign("sub_back", $sub_back);
+            $this->assign("pays", null);
+            $this->assign("is_today", $_is_today);
+            $this->assign("agent_id", $agent_id);
+            $this->assign("platform_id", $platform_id);
+            $this->assign("start_time", $start);
+            $this->assign("end_time", $end);
+            $this->assign("app_id", $app_id);
+            $this->assign("plan_id", $plan_id);
+            $this->assign("landing_page_id", $landing_page_id);
+            $this->assign("son_agent_id", $son_agent_id);
+            $this->assign("sum_items", null);
+            $this->assign("Page", null);
+        }
+    }
+
+    public function _getSubAgentList(
+        $is_today, $platform_id, $start, $end, $app_id, $agent_id, $plan_id, $landing_page_id, $son_agent_id, $page,
+        $list_rows
+    ) {
+//
+//        /* 导出参数 */
+//        $_csv_do = I('csv_do', 1);
+//        $_csv_page = I('csv_page', 1);
+//        $_csv_offset = I('csv_offset', 1000);
+//        $_csv_file = I('csv_file', '');
+//        $_explore_csv_class = new \Huosdk\Data\ExportCsv();
+//        $where = $this->where;
+//        $sum_where = [];
+//        if (isset($platform_id) && !empty($platform_id)) {
+//            $where .= " AND pp.platform_id = '".$platform_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($agent_id) && !empty($agent_id)) {
+//            $where .= " AND pp.owner_id=".$agent_id;
+//        }
+//        if (isset($son_agent_id) && !empty($son_agent_id)) {
+//            $where .= " AND pd.agent_id=".$son_agent_id;
+//        }
+//        if (isset($plan_id) && !empty($plan_id)) {
+//            $where .= " AND pd.promotion_plan_id=".$plan_id;
+//        }
+//        if (isset($material_id) && !empty($material_id)) {
+//            $landing_page_ids = M('game_landing_page')->where(['material_id' => $material_id])->getField('id', true);
+//            $idstr = implode(',', $landing_page_ids);
+//            $where .= " AND glp.id in ('".$idstr."') ";
+//        }
+//        if (isset($app_id) && !empty($app_id)) {
+//            $where .= " AND d.app_id=".$app_id;
+//        }
+//        if (isset($landing_page_id) && !empty($landing_page_id)) {
+//            $where .= " AND glp.id = '".$landing_page_id."'";
+//        }
+//        $count_sql
+//            = "SELECT count(*) as tp_count  FROM (SELECT d.id FROM {$_table} d
+//                      LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and pd.app_id=d.app_id
+//                      LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id
+//                      LEFT JOIN ".C('DB_PREFIX')."game_landing_page glp ON glp.id=pd.landing_page_id
+//                      WHERE {$where} GROUP BY d.date,d.app_id,pp.owner_id,pp.platform_id) taba";
+//        $count_info = M()->query($count_sql);
+//        $count = isset($count_info[0]['tp_count']) ? $count_info[0]['tp_count'] : 0;
+////        $count = $_day_model
+////            ->alias('d')
+////            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+////            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+////            ->join("LEFT JOIN ".C('DB_PREFIX')."game_landing_page glp ON glp.id=pd.landing_page_id")
+////            ->where($where)
+////            ->count();
+//        if (2 == $_csv_do) {
+////            $_fields = 'd.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id';
+//            $_fields
+//                = "d.date,d.app_id,pp.platform_id,d.agent_id,sum(d.reg_cnt) reg_cnt,sum(d.reg_device) reg_device,sum(d.reg_pay_cnt) reg_pay_cnt,";
+//            $_fields .= "sum(d.sum_reg_money) sum_reg_money,sum(d.user_cnt) user_cnt,sum(d.pay_user_cnt) pay_user_cnt,";
+//            $_fields .= "sum(d.sum_money) sum_money,pp.owner_id,";
+//            $_fields .= 'sum(d.day2) day2,sum(d.day7) day7,sum(d.day15) day15';
+//            $items = $_day_model
+//                ->alias('d')
+//                ->field($_fields)
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id  and pd.app_id=d.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."game_landing_page glp ON glp.id=pd.landing_page_id")
+//                ->where($where)
+//                ->order('d.id DESC')
+//                ->page($_csv_page, $_csv_offset)
+//                ->group('d.date,d.app_id,pp.owner_id,pp.platform_id')
+//                ->select();
+//            if (!empty($items) && is_array($items)) {
+//                $_title = '投放数据';
+//                $_expCellName = array('日期', '买量专员', '投放渠道', '游戏名称', '点击数量', '下载数量', '注册', '新增设备', '新增付费数', '新增付费率',
+//                                      '新增付费金额', '活跃', '付费人数', '付费金额', '活跃付费率', '活跃arpu', '付费arpu', 'ltv 1日', 'ltv 7日',
+//                                      'ltv 15日', '留存 1日', '留存 7日', '留存 15日'
+//                );
+//                $_export_data = [];
+//                $agents = M('users')->where(
+//                    array('id' => array('in', implode(',', array_unique(array_column($items, 'agent_id')))))
+//                )->getField("id,user_login agentname", true);
+//                $games = M('game')->where(
+//                    array('id' => array('in', implode(',', array_unique(array_column($items, 'app_id')))))
+//                )->getField('id,name', true);
+//                $platforms = M('platform')->getField("id,name platform", true);
+//                foreach ($items as $k => $v) {
+//                    $_where = " `date`='".$v['date']."' AND `agent_id`='".$v['agent_id']."' AND `app_id`='".$v['app_id']
+//                              ."'";
+//                    $_ltv = $this->getLtvData($_where);
+//                    $_day_map = [
+//                        'agent_id' => $v['agent_id'],
+//                        'date'     => $v['date'],
+//                        'app_id'   => $v['app_id']
+//                    ];
+//                    //$_day_log = $this->getPromotionDayLog($_day_map);
+//                    $_day_log = $this->getPromotionByowner($v['date'],$v['owner_id'],$v['app_id'],$v['platform_id']);
+//                    $_v = [];
+//                    $_v['date'] = $v['date'];
+//                    $_v['agent_id'] = (isset($agents[$v['owner_id']]) ? $agents[$v['owner_id']] : '官包')."\t";
+//                    $_v['platform'] = $platforms[$v['platform_id']];
+//                    $_v['game'] = $games[$v['app_id']];
+//                    $_v['check_cnt'] = $_day_log['distinct_visit_cnt'];
+//                    $_v['down_cnt'] = $_day_log['distinct_down_cnt'];
+//                    $_v['reg_cnt'] = $v['reg_cnt'];
+//                    $_v['reg_device'] = $v['reg_device'];
+//                    $_v['reg_pay_cnt'] = $v['reg_pay_cnt'];
+//                    $_v['reg_pay_rate'] = (number_format($v['reg_pay_cnt'] / $v['reg_cnt'], 2, '.', '') * 100).'%';
+//                    $_v['sum_reg_money'] = $v['sum_reg_money'];
+//                    $_v['user_cnt'] = $v['user_cnt'];
+//                    $_v['pay_user_cnt'] = $v['pay_user_cnt'];
+//                    $_v['sum_money'] = $v['sum_money'];
+//                    $_v['active_pay_rate'] = (number_format($v['pay_user_cnt'] / $v['user_cnt'], 2, '.', '') * 100).'%';
+//                    $_v['active_arpu'] = number_format($v['sum_money'] / $v['user_cnt'], 2, '.', '');
+//                    $_v['pay_arpu'] = number_format($v['sum_money'] / $v['pay_user_cnt'], 2, '.', '');
+//                    $_v['ltv1'] = isset($_ltv[0]['day1']) ? $_ltv[0]['day1'] : 0;
+//                    $_v['ltv7'] = isset($_ltv[0]['day7']) ? $_ltv[0]['day7'] : 0;
+//                    $_v['ltv15'] = isset($_ltv[0]['day15']) ? $_ltv[0]['day15'] : 0;
+//                    $_v['day2'] = $this->_showRegPoint($v['day2'], $v['reg_cnt']);
+//                    $_v['day7'] = $this->_showRegPoint($v['day7'], $v['reg_cnt']);
+//                    $_v['day15'] = $this->_showRegPoint($v['day15'], $v['reg_cnt']);
+//                    $_export_data[] = $_v;
+//                }
+//                $_explore_csv_class->exportCsv(
+//                    $_title, $_expCellName, $_export_data, $_csv_file, $count, $_csv_page, $_csv_offset
+//                );
+//            } else {
+//                $_arr['error'] = 0;
+//                $_arr['msg'] = '';
+//                $_arr['data'] = '';
+//                $this->ajaxReturn($_arr);
+//            }
+//        } else {
+//            $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//            $page = $this->page($count, $rows);
+////            $_fields = 'd.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id';
+//            $_fields
+//                = "d.date,d.app_id,pp.platform_id,d.agent_id,sum(d.reg_cnt) reg_cnt,sum(d.reg_device) reg_device,sum(d.reg_pay_cnt) reg_pay_cnt,";
+//            $_fields .= "sum(d.sum_reg_money) sum_reg_money,sum(d.user_cnt) user_cnt,sum(d.pay_user_cnt) pay_user_cnt,";
+//            $_fields .= "sum(d.sum_money) sum_money,pp.owner_id,";
+//            $_fields .= 'sum(d.day2) day2,sum(d.day7) day7,sum(d.day15) day15';
+//            $items = $_day_model
+//                ->alias('d')
+//                ->field($_fields)
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and pd.app_id=d.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."game_landing_page glp ON glp.id=pd.landing_page_id")
+//                ->where($where)
+//                ->order('d.id DESC')
+//                ->limit($page->firstRow.','.$page->listRows)
+//                ->group('d.date,d.app_id,pp.owner_id,pp.platform_id')
+//                ->select();
+//            $_check_cnt = $_down_cnt = 0;
+//            $_ltv_agent_ids = [];
+//            foreach ($items as $_k => $_v) {
+//                $_ltv_agent_ids[] = $_v['agent_id'];
+//                $_where = " `date`='".$_v['date']."' AND `agent_id`='".$_v['agent_id']."' AND `app_id`='".$_v['app_id']
+//                          ."'";
+//                $_ltv = $this->getLtvData($_where);
+//                $items[$_k]['ltv'] = $_ltv[0];
+//                $_day_map = [
+//                    'agent_id' => $_v['agent_id'],
+//                    'date'     => $_v['date'],
+//                    'app_id'   => $_v['app_id']
+//                ];
+//                //$_day_log = $this->getPromotionDayLog($_day_map);
+//                $_day_log = $this->getPromotionByowner($_v['date'],$_v['owner_id'],$_v['app_id'],$_v['platform_id']);
+//                $items[$_k]['check_cnt'] = $_day_log['distinct_visit_cnt'];
+//                $items[$_k]['down_cnt'] = $_day_log['distinct_down_cnt'];
+//                $_check_cnt += $_day_log['distinct_visit_cnt'];
+//                $_down_cnt += $_day_log['distinct_down_cnt'];
+//                $items[$_k]['day2'] = $this->_showRegPoint($_v['day2'], $_v['reg_cnt']);
+//                $items[$_k]['day7'] = $this->_showRegPoint($_v['day7'], $_v['reg_cnt']);
+//                $items[$_k]['day15'] = $this->_showRegPoint($_v['day15'], $_v['reg_cnt']);
+//            }
+//            /* 汇总数据 */
+//            $_sum_field
+//                = "sum(d.reg_cnt) reg_cnt,sum(d.reg_device) reg_device,sum(d.reg_pay_cnt) reg_pay_cnt,
+//                   sum(d.sum_reg_money) sum_reg_money,sum(d.user_cnt) user_cnt,sum(d.pay_user_cnt) pay_user_cnt,
+//                   sum(d.sum_money) sum_money,sum(d.day2) day2,sum(d.day7) day7,sum(d.day15) day15,sum(d.check_cnt) check_cnt,
+//                   sum(d.down_cnt) down_cnt,sum(reg_device) reg_device
+//                   ";
+//            $_sum_items = $_day_model
+//                ->alias('d')
+//                ->field($_sum_field)
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and pd.app_id=d.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."game_landing_page glp ON glp.id=pd.landing_page_id")
+//                ->where($where)
+//                ->select();
+//            $_prom_data = M("promotion_day")
+//                ->alias('d')
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and pd.app_id=d.app_id")
+//                ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                ->where($where)
+//                ->field("sum(`distinct_visit_cnt`) distinct_visit_cnt,sum(`distinct_down_cnt`) distinct_down_cnt")
+//                ->select();
+//            $_sum_items[0]['check_cnt'] = $_prom_data[0]['distinct_visit_cnt'];
+//            $_sum_items[0]['down_cnt'] = $_prom_data[0]['distinct_down_cnt'];
+//            //$_sum_items[0]['check_cnt'] = $_check_cnt;
+//            //$_sum_items[0]['down_cnt'] = $_down_cnt;
+//            if (3 == $this->role_type) {
+//                $_where = " agent_id".$this->agentwhere;
+//            } else {
+//                if (!empty($_ltv_agent_ids)) {
+//                    $_agent_ids = implode(',', $_ltv_agent_ids);
+//                    $_where = " agent_id in (".$_agent_ids.") ";
+//                } else {
+//                    $_where = " 1 ";
+//                }
+//            }
+//            /*if ('今日' == $_is_today) {
+//                $_where .= " and `date`='".date('Y-m-d')."'";
+//            }*/
+//            if ('今日' == $_is_today) {
+//                $_where .= " and `date`='".date('Y-m-d')."'";
+//                $where .= " and d.`date`='".date('Y-m-d')."'";
+//                $_prom_data = M("promotion_day")
+//                    ->alias('d')
+//                    ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id and pd.app_id=d.app_id")
+//                    ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//                    ->where($where)
+//                    ->field("sum(`distinct_visit_cnt`) distinct_visit_cnt,sum(`distinct_down_cnt`) distinct_down_cnt")
+//                    ->select();
+//                $_sum_items[0]['check_cnt'] = !empty($_prom_data[0]['distinct_visit_cnt']) ? $_prom_data[0]['distinct_visit_cnt'] : 0;
+//                $_sum_items[0]['down_cnt'] = !empty($_prom_data[0]['distinct_down_cnt']) ? $_prom_data[0]['distinct_down_cnt'] : 0;
+//            }
+//            $_ltv = $this->getLtvData($_where);
+//            $_sum_items[0]['ltv'] = $_ltv[0];
+//            $_sum_items[0]['day2'] = $this->_showRegPoint($_sum_items[0]['day2'], $_sum_items[0]['reg_cnt']);
+//            $_sum_items[0]['day7'] = $this->_showRegPoint($_sum_items[0]['day7'], $_sum_items[0]['reg_cnt']);
+//            $_sum_items[0]['day15'] = $this->_showRegPoint($_sum_items[0]['day15'], $_sum_items[0]['reg_cnt']);
+//            $_export_button = $_explore_csv_class->exportButton('数据导出', 'input', 1000, 'btn btn-primary');
+//            $this->assign("export_button", $_export_button);
+//            $this->assign("pays", $items);
+//            $this->assign($_GET);
+//            $this->assign("sum_items", $_sum_items);
+//            $this->assign("Page", $page->show('Admin'));
+//        }
+    }
+
+    /**
+     *  下级渠道留存
+     */
+    public function subAgentRetain() {
+        echo '下级渠道留存';
+        exit;
+//        $this->_game();
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $_game_model = M('tmp_day_promotion_game');
+//        } else {
+//            $_game_model = M('day_promotion_game');
+//        }
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $_app_id = I('app_id');
+//        $_plan_id = I('plan_id');
+//        $_agent_id = I('agent_id');
+//        $landing_page_id = I('landing_page_id/d', '');
+//        $platform_id = I('platform_id', '');
+//        $where = " 1 ";
+//        if (isset($_app_id) && !empty($_app_id)) {
+//            $where .= " AND d.app_id = '".$_app_id."'";
+//        }
+//        if (isset($_agent_id) && !empty($_agent_id)) {
+//            $where .= " AND pp.owner_id = '".$_agent_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($platform_id) && !empty($platform_id)) {
+//            $where .= " AND pp.platform_id = '".$platform_id."'";
+//        }
+//        if (isset($landing_page_id) && !empty($landing_page_id)) {
+//            $where .= " AND pd.landing_page_id = '".$landing_page_id."'";
+//        }
+//        if (isset($_plan_id) && !empty($_plan_id)) {
+//            $where .= " AND pp.id=".$_plan_id;
+//        }
+//        $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//        $count = $_game_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        $page = $this->page($count, $rows);
+//        $items = $_game_model
+//            ->alias('d')
+//            ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->limit($page->firstRow.','.$page->listRows)
+//            ->select();
+//        foreach ($items as $key => $value) {
+//            for ($i = 2; $i <= 60; $i++) {
+//                $_name = 'day'.$i;
+//                if (isset($value[$_name])) {
+//                    $items[$key][$_name] = $this->_showRegPoint($value[$_name], $value['reg_cnt']);
+//                }
+//            }
+//        }
+//        $this->assign("items", $items);
+//        $this->assign($_GET);
+//        $this->assign("Page", $page->show('Admin'));
+//        $this->display();
+    }
+
+    /**
+     * 下级渠道LTV
+     */
+    public function subAgentLtv() {
+        echo '下级渠道LTV';
+        exit;
+//        $this->_game();
+//        $_is_today = I('is_today', '今日');
+//        if ('今日' == $_is_today) {
+//            $_game_model = M('tmp_day_promotion_game');
+//        } else {
+//            $_game_model = M('day_promotion_game');
+//        }
+//        $start = I('start_time');
+//        $end = I('end_time');
+//        $_app_id = I('app_id');
+//        $_plan_id = I('plan_id');
+//        $landing_page_id = I('landing_page_id/d', '');
+//        $where = " 1 ";
+//        if (isset($_app_id) && !empty($_app_id)) {
+//            $where .= " AND d.app_id = '".$_app_id."'";
+//        }
+//        if (isset($_agent_id) && !empty($_agent_id)) {
+//            $where .= " AND pp.owner_id = '".$_agent_id."'";
+//        }
+//        if (isset($start) && !empty($start)) {
+//            $where .= " AND d.date >= '".$start."'";
+//        }
+//        if (isset($end) && !empty($end)) {
+//            $where .= " AND d.date <= '".$end."'";
+//        }
+//        if (isset($landing_page_id) && !empty($landing_page_id)) {
+//            $where .= " AND pd.landing_page_id = '".$landing_page_id."'";
+//        }
+//        if (isset($_plan_id) && !empty($_plan_id)) {
+//            $where .= " AND pp.id=".$_plan_id;
+//        }
+//        $rows = isset($_POST['rows']) ? intval($_POST['rows']) : $this->abs_row;
+//        $count = $_game_model
+//            ->alias('d')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->count();
+//        $page = $this->page($count, $rows);
+//        $items = $_game_model
+//            ->alias('d')
+//            ->field('d.*,pd.promotion_plan_id,pd.landing_page_id,pp.platform_id,pp.owner_id')
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_detail pd ON pd.agent_id=d.agent_id")
+//            ->join("LEFT JOIN ".C('DB_PREFIX')."promotion_plan pp ON pp.id=pd.promotion_plan_id")
+//            ->where($where)
+//            ->limit($page->firstRow.','.$page->listRows)
+//            ->select();
+//        foreach ($items as $_k => $_v) {
+//            $_where = " `date`='".$_v['date']."' AND `agent_id`='".$_v['agent_id']."' AND `app_id`='".$_v['app_id']."'";
+//            $_ltv = $this->getLtvData($_where);
+//            $items[$_k]['ltv'] = $_ltv[0];
+//        }
+//        $this->assign("items", $items);
+//        $this->assign($_GET);
+//        $this->assign("Page", $page->show('Admin'));
+//        $this->display();
+    }
+
+    /**
+     * 获取LTV数据
+     *
+     * @param string $where
+     *
+     * @return array|mixed
+     */
+    public function getLtvData($where = "") {
+        echo '获取LTV数据';
+        exit;
+//        if (empty($where)) {
+//            return ['0' => []];
+//        }
+//        $_sql = "show tables like 'h_ltv_game_agent'";
+//        $_rs = M()->query($_sql);
+//        if (empty($_rs)) {
+//            return ['0' => []];
+//        }
+//        $_sql
+//            = "
+//            SELECT
+//                SUM(`day1`) AS `day1`,
+//                SUM(`day2`) AS `day2`,
+//                SUM(`day3`) AS `day3`,
+//                SUM(`day4`) AS `day4`,
+//                SUM(`day5`) AS `day5`,
+//                SUM(`day6`) AS `day6`,
+//                SUM(`day7`) AS `day7`,
+//                SUM(`day8`) AS `day8`,
+//                SUM(`day9`) AS `day9`,
+//                SUM(`day10`) AS `day10`,
+//                SUM(`day11`) AS `day11`,
+//                SUM(`day12`) AS `day12`,
+//                SUM(`day13`) AS `day13`,
+//                SUM(`day14`) AS `day14`,
+//                SUM(`day15`) AS `day15`,
+//                SUM(`day21`) AS `day21`,
+//                SUM(`day30`) AS `day30`,
+//                SUM(`day35`) AS `day35`,
+//                SUM(`day42`) AS `day42`,
+//                SUM(`day45`) AS `day45`,
+//                SUM(`day60`) AS `day60`,
+//                SUM(`day180`) AS `day120`
+//            FROM `h_ltv_game_agent`
+//            WHERE ".$where;
+//        $_res = M()->query($_sql);
+//        if (false === $_res) {
+//            return ['0' => []];
+//        }
+//
+//        return $_res;
+    }
+
+    /**
+     * 初始化实时数据
+     */
+    public function _initTodayData() {
+        echo '初始化实时数据';
+        exit;
+//        $this->today_date = date('Y-m-d');
+//        $this->today_start_time = strtotime($this->today_date);
+//        $this->today_end_time = time();
+//        $_agents = M('users')->where(['user_type' => ['in', [7, 9]]])->getField('id', true);
+//        if (!empty($_agents)) {
+//            $_agent_ids = implode(',', $_agents);
+//            $_sql
+//                = "
+//            TRUNCATE c_tmp_promotion_logindata;
+//            ALTER TABLE c_tmp_promotion_logindata DISABLE KEYS;
+//            INSERT INTO c_tmp_promotion_logindata
+//            (
+//                `mem_id`,
+//                `app_id`,
+//                `login_date`,
+//                `reg_date`,
+//                `login_cnt`,
+//                `agent_id`,
+//                `imei`,
+//                `imei_cnt`,
+//                `regdays`
+//            )
+//            SELECT
+//                `ll`.`mem_id` AS `mem_id`,
+//                `ll`.`app_id` AS `app_id`,
+//                DATE_FORMAT(FROM_UNIXTIME(`ll`.`login_time`),'%Y-%m-%d') AS `login_date`,
+//                DATE_FORMAT(FROM_UNIXTIME(IFNULL(`m`.`reg_time`,0)),'%Y-%m-%d') AS `reg_date`,
+//                COUNT(`ll`.`id`) AS `login_cnt`,
+//                IFNULL(`m`.`agent_id` , '0') AS `agent_id`,
+//                `ll`.`imei` AS `imei`,
+//                COUNT(DISTINCT(`ll`.`imei`)) AS `imei_cnt`,
+//                (TO_DAYS(FROM_UNIXTIME(`ll`.`login_time`)) - TO_DAYS(FROM_UNIXTIME(IFNULL(`m`.`reg_time`,0)))) AS `regdays`
+//            FROM
+//                (`c_login_log` `ll`)
+//                LEFT JOIN `c_members` m ON ll.mem_id = m.id
+//            WHERE
+//                (`ll`.`login_time` >= ".$this->today_start_time." AND `ll`.`login_time` < ".$this->today_end_time
+//                  ." AND `ll`.`agent_id` in (".$_agent_ids.") AND (`ll`.`app_id` > 0)) AND (`ll`.`app_id` = `m`.`app_id`)
+//            GROUP BY `ll`.`mem_id` , `ll`.`app_id`;
+//            ALTER TABLE c_tmp_promotion_logindata ENABLE KEYS;
+//
+//
+//            TRUNCATE c_tmp_promotion_paydata;
+//            ALTER TABLE c_tmp_promotion_paydata DISABLE KEYS;
+//            INSERT INTO c_tmp_promotion_paydata
+//            (
+//                `mem_id`,
+//                `app_id`,
+//                `agent_id`,
+//                `login_date`,
+//                `reg_date`,
+//                `order_cnt`,
+//                `sum_money`,
+//                `imei`,
+//                `imei_cnt`,
+//                `regdays`
+//            )
+//            SELECT
+//                `p`.`mem_id` AS `mem_id`,
+//                `p`.`app_id` AS `app_id`,
+//                IFNULL(`m`.`agent_id` , '0') AS `agent_id`,
+//                DATE_FORMAT(FROM_UNIXTIME(`p`.`create_time`),'%Y-%m-%d') AS `login_date`,
+//                DATE_FORMAT(FROM_UNIXTIME(IFNULL(`m`.`reg_time`,0)),'%Y-%m-%d') AS `reg_date`,
+//                COUNT(`p`.`id`) AS `order_cnt`,
+//                SUM(`p`.`amount`) AS `sum_money`,
+//                `m`.`imei` AS `imei`,
+//                COUNT(DISTINCT(`m`.`imei`)) AS `imei_cnt`,
+//                (TO_DAYS(FROM_UNIXTIME(`p`.`create_time`)) - TO_DAYS(FROM_UNIXTIME(IFNULL(`m`.`reg_time`,0)))) AS `regdays`
+//            FROM
+//                `c_pay` p
+//                LEFT JOIN `c_members` m ON p.mem_id = m.id
+//            WHERE
+//                ((`p`.`status` = 2)
+//                AND `p`.`create_time` >= ".$this->today_start_time."
+//                AND `p`.`create_time` < ".$this->today_end_time."
+//                AND `m`.`agent_id` in (".$_agent_ids.")
+//                )
+//            GROUP BY `p`.`mem_id` , `p`.`app_id`;
+//            ALTER TABLE c_tmp_promotion_paydata ENABLE KEYS;
+//
+//
+//            TRUNCATE c_tmp_promotion_daypayuser;
+//            ALTER TABLE c_tmp_promotion_daypayuser DISABLE KEYS;
+//            INSERT INTO c_tmp_promotion_daypayuser
+//            (
+//                `login_date`,
+//                `reg_date`,
+//                `mem_id`,
+//                `app_id`,
+//                `agent_id`,
+//                `sum_money`,
+//                `order_cnt`,
+//                `login_cnt`,
+//                `imei`,
+//                `imei_cnt`,
+//                `regdays`
+//            )
+//            SELECT
+//                `a`.`login_date` AS `login_date`,
+//                IFNULL(`a`.`reg_date`, '1970-01-01') AS `reg_date`,
+//                `a`.`mem_id` AS `mem_id`,
+//                `a`.`app_id` AS `app_id`,
+//                IFNULL(`a`.`agent_id`, 0) AS `agent_id`,
+//                IFNULL(`b`.`sum_money`, 0) AS `sum_money`,
+//                IFNULL(`b`.`order_cnt`, 0) AS `order_cnt`,
+//                `a`.`login_cnt` AS `login_cnt`,
+//                `a`.`imei` AS `imei`,
+//                `a`.`imei_cnt` AS `imei_cnt`,
+//                `a`.`regdays` AS `regdays`
+//            FROM
+//                (`c_tmp_promotion_logindata` `a`
+//                LEFT JOIN `c_tmp_promotion_paydata` `b` ON (((`a`.`login_date` = `b`.`login_date`)
+//                    AND (`a`.`mem_id` = `b`.`mem_id`)
+//                    AND (`a`.`app_id` = `b`.`app_id`))))
+//            WHERE
+//                (`a`.`login_date` = '".$this->today_date."')
+//            UNION SELECT
+//                `b`.`login_date` AS `login_date`,
+//                IFNULL(`b`.`reg_date`, '1970-01-01') AS `reg_date`,
+//                `b`.`mem_id` AS `mem_id`,
+//                `b`.`app_id` AS `app_id`,
+//                IFNULL(`b`.`agent_id`, 0) AS `agent_id`,
+//                `b`.`sum_money` AS `sum_money`,
+//                `b`.`order_cnt` AS `order_cnt`,
+//                IFNULL(`a`.`login_cnt`, 0) AS `login_cnt`,
+//                IFNULL(`b`.`imei`, '000000000000000') AS `imei`,
+//                IFNULL(`b`.`imei_cnt`, 0) AS `imei_cnt`,
+//                IFNULL(`b`.`regdays`, 100000) AS `regdays`
+//            FROM
+//                (`c_tmp_promotion_paydata` `b`
+//                LEFT JOIN `c_tmp_promotion_logindata` `a` ON (((`a`.`login_date` = `b`.`login_date`)
+//                    AND (`a`.`mem_id` = `b`.`mem_id`)
+//                    AND (`a`.`app_id` = `b`.`app_id`))))
+//            WHERE
+//                `b`.`login_date` = '".$this->today_date."';
+//            ALTER TABLE c_tmp_promotion_daypayuser ENABLE KEYS;
+//
+//
+//            TRUNCATE c_tmp_promotion_dayagentgame;
+//            ALTER TABLE c_tmp_promotion_dayagentgame DISABLE KEYS;
+//            INSERT INTO c_tmp_promotion_dayagentgame
+//            (
+//                `date`,
+//                `reg_date`,
+//                `regdays`,
+//                `agent_id`,
+//                `app_id`,
+//                `user_cnt`,
+//                `sum_money`,
+//                `pay_user_cnt`,
+//                `order_cnt`,
+//                `reg_device`
+//            )
+//            SELECT
+//                '".$this->today_date."' AS `date`,
+//                `reg_date` AS `reg_date`,
+//                `regdays` AS `regdays`,
+//                `agent_id` AS `agent_id`,
+//                `app_id` AS `app_id`,
+//                COUNT(DISTINCT `mem_id`) AS `user_cnt`,
+//                SUM(`sum_money`) AS `sum_money`,
+//                COUNT(DISTINCT(CASE  WHEN `sum_money`>0 THEN `mem_id` END)) AS `pay_user_cnt`,
+//                SUM(`order_cnt`) AS `order_cnt`,
+//                (SELECT COUNT(DISTINCT t1.`imei`) FROM `c_tmp_promotion_daypayuser` t1 WHERE t1.`regdays`='0' AND t1.`agent_id`=c_tmp_promotion_daypayuser.`agent_id` AND t1.`app_id`=c_tmp_promotion_daypayuser.`app_id` AND t1.`reg_date`=c_tmp_promotion_daypayuser.`reg_date`) AS imei_cnt
+//            FROM `c_tmp_promotion_daypayuser`
+//            GROUP BY `agent_id`,`app_id`,`reg_date`;
+//            ALTER TABLE c_tmp_promotion_dayagentgame ENABLE KEYS;
+//
+//
+//            TRUNCATE c_tmp_day_promotion;
+//            ALTER TABLE c_tmp_day_promotion DISABLE KEYS;
+//            REPLACE INTO `c_tmp_day_promotion`
+//            (
+//                `date`,
+//                `agent_id`,
+//                `user_cnt`,
+//                `sum_money`,
+//                `order_cnt`,
+//                `reg_order_cnt`,
+//                `pay_user_cnt`,
+//                `reg_pay_cnt`,
+//                `sum_reg_money`,
+//                `reg_cnt`,
+//                `reg_device`
+//            )
+//            (SELECT
+//                 '".$this->today_date."' AS `date`,
+//                `agent_id`,
+//                COUNT(DISTINCT `mem_id`) AS `user_cnt`,
+//                SUM(`sum_money`) AS `sum_money`,
+//                SUM(`order_cnt`) AS `order_cnt`,
+//                SUM(CASE  WHEN `regdays`=0 THEN `order_cnt` ELSE 0 END) AS `reg_order_cnt`,
+//                COUNT(DISTINCT(CASE  WHEN `sum_money`>0 THEN `mem_id` END)) AS `pay_user_cnt`,
+//                COUNT(DISTINCT(CASE  WHEN `regdays`=0 AND  `sum_money`>0 THEN `mem_id` END)) AS `reg_pay_cnt`,
+//                SUM(CASE  WHEN `regdays`=0 THEN `sum_money` ELSE 0 END) AS `sum_reg_money`,
+//                COUNT(DISTINCT(CASE WHEN `regdays`=0 THEN `mem_id` END)) AS `reg_cnt`,
+//                COUNT(DISTINCT(CASE  WHEN `regdays`=0 THEN `imei` END)) AS imei_cnt
+//            FROM `c_tmp_promotion_daypayuser`
+//            GROUP BY agent_id)
+//			UNION
+//			(SELECT
+//                '".$this->today_date."' AS `date`,
+//                `agent_id`,
+//                0 AS `user_cnt`,
+//                0 AS `sum_money`,
+//                0 AS `order_cnt`,
+//                0 AS `reg_order_cnt`,
+//                0 AS `pay_user_cnt`,
+//                0 AS `reg_pay_cnt`,
+//                0 AS `sum_reg_money`,
+//                0 AS `reg_cnt`,
+//                0 AS `imei_cnt`
+//            FROM
+//                `c_promotion_day` WHERE `agent_id` NOT IN (SELECT agent_id FROM c_tmp_promotion_daypayuser WHERE agent_id IS NOT NULL )
+//				AND
+//                `date` = '".$this->today_date."');
+//            ALTER TABLE c_tmp_day_promotion ENABLE KEYS;
+//
+//            TRUNCATE c_tmp_day_promotion_game;
+//            ALTER TABLE c_tmp_day_promotion_game DISABLE KEYS;
+//            REPLACE INTO `c_tmp_day_promotion_game`
+//            (
+//                `date`,
+//                `agent_id`,
+//                `app_id`,
+//                `user_cnt`,
+//                `sum_money`,
+//                `order_cnt`,
+//                `reg_order_cnt`,
+//                `pay_user_cnt`,
+//                `reg_pay_cnt`,
+//                `sum_reg_money`,
+//                `reg_cnt`,
+//                `reg_device`
+//            )
+//            (SELECT
+//                `date`,
+//                `agent_id`,
+//                `app_id`,
+//                SUM(user_cnt) AS `user_cnt`,
+//                SUM(sum_money) AS `sum_money`,
+//                SUM(order_cnt) AS `order_cnt`,
+//                SUM(CASE  WHEN `regdays`=0 THEN `order_cnt` ELSE 0 END) AS `reg_order_cnt`,
+//                SUM(pay_user_cnt) AS `pay_user_cnt`,
+//                SUM(CASE  WHEN `regdays`=0 THEN `pay_user_cnt` ELSE 0 END) AS `reg_pay_cnt`,
+//                SUM(CASE  WHEN `regdays`=0 THEN `sum_money` ELSE 0 END) AS `sum_reg_money`,
+//                SUM(CASE  WHEN `regdays`=0 THEN `user_cnt` ELSE 0 END) AS `reg_cnt`,
+//                SUM(`reg_device`) AS `reg_device`
+//            FROM c_tmp_promotion_dayagentgame
+//            GROUP BY agent_id, app_id)
+//						UNION
+//			(SELECT
+//                '".$this->today_date."' AS `date`,
+//                `agent_id`,
+//                `app_id`,
+//                0 AS `user_cnt`,
+//                0 AS `sum_money`,
+//                0 AS `order_cnt`,
+//                0 AS `reg_order_cnt`,
+//                0 AS `pay_user_cnt`,
+//                0 AS `reg_pay_cnt`,
+//                0 AS `sum_reg_money`,
+//                0 AS `reg_cnt`,
+//                0 AS `reg_device`
+//            FROM
+//                `c_promotion_day` WHERE `agent_id` NOT IN (SELECT agent_id FROM c_tmp_promotion_dayagentgame WHERE agent_id IS NOT NULL )
+//				AND
+//                `date` = '".$this->today_date."');
+//            ALTER TABLE c_tmp_day_promotion_game ENABLE KEYS;
+//            ";
+//            M()->execute($_sql);
+//            $this->doDayPromotionGame();
+//            $this->doDayPromotion();
+//        }
+    }
+
+    /**
+     * 操作tmp_day_promotion_game留存数据
+     */
+    public function doDayPromotionGame() {
+        echo '操作tmp_day_promotion_game留存数据';
+        exit;
+//        $_fields = "reg_date,app_id,agent_id,regdays,COUNT(DISTINCT `mem_id`) AS `user_cnt`";
+//        $_map['regdays'] = [
+//            'in' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 29, 59]
+//        ];
+//        $_list = M('tmp_promotion_daypayuser')->field($_fields)->where($_map)->group(
+//            'app_id,agent_id,regdays'
+//        )->select();
+//        if (!empty($_list)) {
+//            foreach ($_list as $_k => $_v) {
+//                $_field = "";
+//                switch ($_v['regdays']) {
+//                    CASE 1:
+//                        $_field = "day2";
+//                        break;
+//                    CASE 2:
+//                        $_field = "day3";
+//                        break;
+//                    CASE 3:
+//                        $_field = "day4";
+//                        break;
+//                    CASE 4:
+//                        $_field = "day5";
+//                        break;
+//                    CASE 5:
+//                        $_field = "day6";
+//                        break;
+//                    CASE 7:
+//                        $_field = "day8";
+//                        break;
+//                    CASE 8:
+//                        $_field = "day9";
+//                        break;
+//                    CASE 9:
+//                        $_field = "day10";
+//                        break;
+//                    CASE 10:
+//                        $_field = "day11";
+//                        break;
+//                    CASE 11:
+//                        $_field = "day12";
+//                        break;
+//                    CASE 12:
+//                        $_field = "day13";
+//                        break;
+//                    CASE 13:
+//                        $_field = "day14";
+//                        break;
+//                    CASE 14:
+//                        $_field = "day15";
+//                        break;
+//                    CASE 20:
+//                        $_field = "day21";
+//                        break;
+//                    CASE 29:
+//                        $_field = "day30";
+//                        break;
+//                    CASE 59:
+//                        $_field = "day60";
+//                        break;
+//                }
+//                if (!empty($_field)) {
+//                    $_map = [
+//                        'date'     => $_v['reg_date'],
+//                        'agent_id' => $_v['agent_id'],
+//                        'app_id'   => $_v['app_id']
+//                    ];
+//                    M('tmp_day_promotion_game')->where($_map)->setField($_field, $_v['user_cnt']);
+//                }
+//            }
+//        }
+    }
+
+    /**
+     * 操作tmp_day_promotion表留存数据
+     */
+    public function doDayPromotion() {
+        echo '操作tmp_day_promotion表留存数据';
+        exit;
+//        $_map['regdays'] = [
+//            'in' => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 20, 29, 59]
+//        ];
+//        $_fields = "reg_date,agent_id,regdays,COUNT(DISTINCT `mem_id`) AS `user_cnt`";
+//        $_list = M('tmp_promotion_daypayuser')->field($_fields)->where($_map)->group('agent_id,regdays')
+//                                              ->select();
+//        if (!empty($_list)) {
+//            foreach ($_list as $_k => $_v) {
+//                $_field = "";
+//                switch ($_v['regdays']) {
+//                    CASE 1:
+//                        $_field = "day2";
+//                        break;
+//                    CASE 2:
+//                        $_field = "day3";
+//                        break;
+//                    CASE 3:
+//                        $_field = "day4";
+//                        break;
+//                    CASE 4:
+//                        $_field = "day5";
+//                        break;
+//                    CASE 5:
+//                        $_field = "day6";
+//                        break;
+//                    CASE 7:
+//                        $_field = "day8";
+//                        break;
+//                    CASE 8:
+//                        $_field = "day9";
+//                        break;
+//                    CASE 9:
+//                        $_field = "day10";
+//                        break;
+//                    CASE 10:
+//                        $_field = "day11";
+//                        break;
+//                    CASE 11:
+//                        $_field = "day12";
+//                        break;
+//                    CASE 12:
+//                        $_field = "day13";
+//                        break;
+//                    CASE 13:
+//                        $_field = "day14";
+//                        break;
+//                    CASE 14:
+//                        $_field = "day15";
+//                        break;
+//                    CASE 20:
+//                        $_field = "day21";
+//                        break;
+//                    CASE 29:
+//                        $_field = "day30";
+//                        break;
+//                    CASE 59:
+//                        $_field = "day60";
+//                        break;
+//                }
+//                if (!empty($_field)) {
+//                    $_map = [
+//                        'date'     => $_v['reg_date'],
+//                        'agent_id' => $_v['agent_id']
+//                    ];
+//                    M('tmp_day_promotion')->where($_map)->setField($_field, $_v['user_cnt']);
+//                }
+//            }
+//        }
+    }
+
+    function _showRegPoint($cnt, $reg) {
+        if ($reg) {
+            return $cnt.'('.number_format($cnt * 100 / $reg, 2, '.', '').'%)';
+        } else {
+            return $cnt.'(0.00%)';
+        }
+    }
+}

+ 305 - 0
admin/admin/controller/distribution/BaseController.php

@@ -0,0 +1,305 @@
+<?php
+/**
+ * BaseController.php UTF-8
+ * 买量基类
+ *
+ * @date    : 2018/6/8 23:33
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : ouzhongfu <ozf@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\distribution;
+
+use cmf\controller\AdminBaseController;
+use think\Lang;
+use huolib\constant\PromotionConst;
+use huo\model\distribution\PromotiondetailModel;
+use huo\model\agent\AgentGameModel;
+use huo\model\game\GameModel;
+use huolib\constant\AgentConst;
+use huolib\constant\GameConst;
+use huo\logic\agent\AgentLogic;
+use huo\logic\agent\AgentGameLogic;
+use huo\controller\agent\AgentGame;
+use huolib\status\GameStatus;
+use huo\model\user\UserModel;
+use huo\model\distribution\PlatformModel;
+use cmf\view\Filter;
+
+class BaseController extends AdminbaseController {
+    protected $cpa_role_id;
+    protected $page_role_id;
+    protected $default_pass;
+    protected $base_name;
+    protected $ag_model;
+    protected $db_prefix;
+    protected $not_admin;
+    protected $agent_game_url;
+    protected $base_url;
+    protected $game_ios;
+
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'distribution'.EXT);
+        $this->cpa_role_id = AgentConst::AGENT_ROLE_CPA_AGENT;
+        $this->page_role_id = AgentConst::AGENT_ROLE_PAGE_AGENT;
+        $this->default_pass = PromotionConst::DEFAULT_PASSWORD;
+        $this->base_name = PromotionConst::BASE_NAME;
+        $this->db_prefix = \think\Config::get('database.prefix');
+        $this->ag_model = (new AgentGameModel());
+        $this->not_admin = (AgentConst::ROLE_TYPE_MANAGER <= $this->role_type) ? true : false;
+        $this->agent_game_url = '/down/down?id=';
+        $this->base_url = SDKSITE;
+        $this->game_ios = GameConst::GAME_IOS;
+    }
+
+    public function genStatus() {
+        $_tg_status = array(
+            PromotionConst::GEN_STATUS_WAIT  => lang('distribution waiting'),
+            PromotionConst::GEN_STATUS_SUC   => lang('distribution delivery'),
+            PromotionConst::GEN_STATUS_PAUSE => lang('distribution pause'),
+            PromotionConst::GEN_STATUS_END   => lang('distribution end'),
+        );
+        $this->assign("tg_status", $_tg_status);
+    }
+
+    /**
+     * ajax返回
+     *
+     * @param        $data
+     * @param string $type
+     * @param int    $json_option
+     */
+    public function ajaxReturn($data, $type = '', $json_option = 0) {
+        $data['referer'] = (isset($data['url']) && $data['url']) ? $data['url'] : "";
+        $data['state'] = (isset($data['status']) && $data['status']) ? "success" : "fail";
+        if (empty($type)) {
+            $type = \think\config::get('default_return_type');
+        }
+        header('Content-Type:application/json; charset=utf-8');
+        echo json_encode($data, $json_option);
+        exit;
+//        switch (strtoupper($type)) {
+//            case 'JSON' :
+//                // 返回JSON数据格式到客户端 包含状态信息
+//                header('Content-Type:application/json; charset=utf-8');
+//                echo json_encode($data, $json_option);
+//                exit;
+//            case 'XML'  :
+//                // 返回xml格式数据
+//                header('Content-Type:text/xml; charset=utf-8');
+//                echo xml_encode($data);
+//                exit;
+//            case 'JSONP':
+//                // 返回JSON数据格式到客户端 包含状态信息
+//                header('Content-Type:application/json; charset=utf-8');
+//                $_var_jsonp_handler = \think\config::get('default_jsonp_handler');
+//                $handler = isset($_GET[$_var_jsonp_handler])
+//                    ? $_GET[$_var_jsonp_handler]
+//                    : $_var_jsonp_handler;
+//                echo $handler.'('.json_encode($data, $json_option).')';
+//                exit;
+//            case 'EVAL' :
+//                // 返回可执行的js脚本
+//                header('Content-Type:text/html; charset=utf-8');
+//                echo $data;
+//                exit;
+//            case 'AJAX_UPLOAD':
+//                // 返回JSON数据格式到客户端 包含状态信息
+//                header('Content-Type:text/html; charset=utf-8');
+//                echo json_encode($data, $json_option);
+//                exit;
+//            default :
+//                // 用于扩展其他返回格式数据
+//                var_export($data);
+//        }
+    }
+
+    /**获取推广链接
+     *
+     * @param int $agent_id
+     * @param int $app_id
+     *
+     * @return string
+     */
+    public function getAgUrl($agent_id = 0, $app_id = 0) {
+        if (empty($agent_id) || empty($app_id)) {
+            return '';
+        }
+        $_map["agent_id"] = $agent_id;
+        $_map["app_id"] = $app_id;
+        $_map["status"] = 2;
+        $_ag_id = (new AgentGameModel())->where($_map)->value("id");
+        if (empty($_ag_id)) {
+            return '';
+        }
+        $_url = $this->agent_game_url.base_convert($_ag_id, 10, 36);
+
+        return $_url;
+    }
+
+    /**
+     * 基础域名
+     *
+     * @param int $detail_id
+     *
+     * @return mixed|string
+     */
+    public function getBaseUrl($detail_id = 0) {
+        if (empty($detail_id)) {
+            return $this->base_url;
+        }
+        $_map['pd.id'] = $detail_id;
+        $_map['pdm.is_delete'] = 2;
+        $_base_url = (new PromotiondetailModel())
+            ->alias('pd')
+            ->join($this->db_prefix."promotion_domain pdm ", "pdm.id = pd.domain_id", "left")
+            ->where($_map)
+            ->value('domain');
+        if (empty($_base_url)) {
+            return $this->base_url;
+        } else {
+            return $_base_url;
+        }
+    }
+
+    /**获取下载链接
+     *
+     * @param int $agent_id
+     * @param int $app_id
+     *
+     * @return string
+     */
+    public function getDownUrl($agent_id = 0, $app_id = 0) {
+        if (empty($agent_id) || empty($app_id)) {
+            return '';
+        }
+        $_ag_model = new AgentGameModel();
+        $_ag_id = $_ag_model->getAgIdByAgentIdAppId($agent_id, $app_id);
+        $_ag_logic = new AgentGameLogic();
+        $_url = $_ag_logic->getPackageUrl('', $app_id, $agent_id, $_ag_id);
+
+        return $_url;
+    }
+
+    /**
+     * 分包
+     *
+     * @param int $detail_id
+     * @param int $type
+     *
+     * @return array
+     */
+    public function subpackage($detail_id = 0, $type = 0) {
+        //获取参数
+        $_detail_id = $detail_id;
+        $_type = $type;
+        $_is_ajax = false;
+        if (empty($_detail_id)) {
+            $_detail_id = $this->request->param("detail_id/d", 0);
+            $_is_ajax = 1;
+        }
+        if (empty($_type)) {
+            $_type = $this->request->param("type/d", 1);
+        }
+        if (empty($_detail_id)) {
+        }
+        $_pd_data = (new PromotiondetailModel())->getInfoById($_detail_id);;
+        if (empty($_pd_data)) {
+            $_return = ['error' => '1', 'msg' => lang('distribution parameter error')];
+            if ($_is_ajax) {
+                $this->ajaxReturn($_return);
+            }
+
+            return $_return;
+        }
+        $_agent_id = $_pd_data['agent_id'];
+        $_app_id = $_pd_data['app_id'];
+        $_ag_model = new AgentGameModel();
+        $_ag_info_id = $_ag_model->getAgIdByAgentIdAppId($_agent_id, $_app_id);
+        if (empty($_ag_info_id)) {
+            $_agent_game_class = new AgentGame();
+            $_rs = $_agent_game_class->addGame($_agent_id, $_app_id);
+            if (!$_rs) {
+                $_return = ['error' => '1', 'msg' => lang('distribution server error'), '$_rs' => $_rs];
+                if ($_is_ajax) {
+                    $this->ajaxReturn($_return);
+                }
+
+                return $_return;
+            }
+            $_ag_info_id = $_ag_model->getAgIdByAgentIdAppId($_agent_id, $_app_id);
+        }
+        $_rs = (new AgentGame())->pack($_agent_id, $_ag_info_id);
+        if ($_rs['code'] == GameStatus::NO_ERROR) {
+            if ($_type == 1) {
+                $_return = ['error' => '0', 'msg' => '生成成功'];
+            } else {
+                $_return = ['error' => '0', 'msg' => '更新成功'];
+            }
+            if ($_is_ajax) {
+                $this->ajaxReturn($_return);
+            }
+
+            return $_return;
+        };
+        $_return = ['error' => '1', 'msg' => lang('distribution server error')];
+        if ($_is_ajax) {
+            $this->ajaxReturn($_return);
+        }
+
+        return $_return;
+    }
+
+    /**
+     * 批量处理分包
+     */
+    public function batchPackage() {
+        $_ids = $this->request->param("ids/a");
+        if (empty($_ids) || !is_array($_ids)) {
+            $this->error("请选择更新选项");
+            exit;
+        }
+        foreach ($_ids as $_v) {
+            $this->subpackage($_v, 2);
+        }
+        $this->adminSuccess("更新成功");
+        exit;
+    }
+
+    public function genPlatforms() {
+        $_map = array();
+        $_map['is_delete'] = 2;
+        $_data = (new PlatformModel())->getIdNames($_map, "name");
+        $this->assign("platform", $_data);
+    }
+
+    public function genUsers() {
+        $_map['user_status'] = 2;
+        $_map['role_id'] = $this->cpa_role_id;
+        $_data = (new UserModel())->getIdNames($_map, true);
+        $this->assign("owner_data", $_data);
+    }
+
+    /**
+     * 设定及编辑toutiao_key
+     */
+    public function setToutiaoKey() {
+        $_id = $this->request->param("id/d", 0);
+        $_toutiao_key = $this->request->param("toutiao_key", '');
+        if (empty($_id)) {
+            return $this->ajaxReturn(['error' => '1', 'msg' => '参数错误']);
+        }
+        $_data['toutiao_key'] = $_toutiao_key;
+        $_data['update_time'] = time();
+        $_map['id'] = $_id;
+        $_rs = (new PromotiondetailModel())->updateData($_data, $_map);
+        if ($_rs) {
+            return $this->ajaxReturn(['error' => '0', 'msg' => '成功']);
+        } else {
+            return $this->ajaxReturn(['error' => '1', 'msg' => '修改失败']);
+        }
+    }
+}

+ 357 - 0
admin/admin/controller/distribution/LandingPageController.php

@@ -0,0 +1,357 @@
+<?php
+/**
+ * 游戏素材管理
+ * MaterialController.php UTF-8
+ *
+ *
+ * @date    : 2018/5/29 18:28
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : ouzhongfu <ozf@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\distribution;
+
+use huo\model\game\GameversionModel;
+use huolib\constant\AgentConst;
+use huolib\constant\GameConst;
+use huo\logic\agent\AgentLogic;
+use huo\model\distribution\GamelandingpageModel;
+use think\Lang;
+use cmf\view\Filter;
+
+class LandingPageController extends BaseController {
+    protected $down_view_path;
+    protected $view_url_path;
+
+    function _initialize() {
+        parent::_initialize();
+        $this->down_view_path = ROOT_PATH."public/themes/api/down/down/";
+        $this->view_url_path = SDKSITE."/down/down/index?";
+    }
+
+    public function landingPage() {
+        $_app_id = $this->request->param("app_id/d", 0);
+        $_start_time = trim($this->request->param("start_time", ''));
+        $_end_time = trim($this->request->param("end_time", ''));
+        $_is_delete = $this->request->param("is_delete", 2);
+        $_landing_page_id = $this->request->param("landing_page_id", 0);
+        $_offset = $this->request->param("offset", 10);
+        $_param = $this->request->param();
+        $_is_show_del = 1;
+        if ($this->not_admin) {
+            $_owner_id = $this->admin_id;
+            $_map['glp.owner_id'] = array('in', [1, $_owner_id]);
+            $_is_show_del = 2;
+        }
+        if (!empty($_app_id)) {
+            $_map['glp.app_id'] = $_app_id;
+        }
+        $where_time = $this->_dateToTime($_start_time, $_end_time);
+        if (!empty($where_time)) {
+            $_map['glp.create_time'] = $this->_dateToTime($_start_time, $_end_time);
+        }
+        if (!empty($_landing_page_id)) {
+            $_map['glp.id'] = $_landing_page_id;
+        }
+        $_time_chose = $this->_time($_start_time, $_end_time);
+        if ($_time_chose) {
+        }
+        $_map['glp.is_delete'] = $_is_delete;
+        $_field = "glp.id,glp.create_time,glp.image,glp.file_url,g.name gamename,glp.app_id";
+        $_data = (new GamelandingpageModel())
+            ->alias('glp')
+            ->where($_map)
+            ->join($this->db_prefix."game g ", "g.id = glp.app_id", "left")
+            ->field($_field)
+            ->paginate($_offset);
+        $_items_array = $_data->toArray();
+        $_page = $_data->render();
+        $_items = array();
+        if (!empty($_items_array)) {
+            $_items = isset($_items_array['data']) ? $_items_array['data'] : array();
+            if (!empty($_items)) {
+                foreach ($_items as $_k => $_v) {
+                    if (strpos($_v['image'], STATICSITE) === false) {
+                        $_items[$_k]['image'] = STATICSITE.'/upload/'.$_v['image'];
+                    }
+                    if (empty($_v['file_url'])) {
+                        $_items[$_k]['view_url'] = '';
+                    } else {
+                        $_items[$_k]['view_url'] = $this->view_url_path."game_id=".$_v['app_id']."&lp_id=".$_v['id'];
+                    }
+                }
+            }
+        }
+        if (1 == $_is_delete) {
+            $this->assign("delete_active", "active");
+            $this->assign("yes_active", '');
+            $_search_url = url('admin/distribution.landing_page/landingPage', array('is_delete' => 1));
+        } else {
+            $this->assign("delete_active", "");
+            $this->assign("yes_active", 'active');
+            $_search_url = url('admin/distribution.landing_page/landingPage');
+        }
+        $this->assign("search_url", $_search_url);
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', 'uri' => $_search_url]
+        );
+        $this->_games($_app_id);
+        $this->assign('data', $_param);
+        $this->assign('formget', $_param);
+        $this->assign('data_items', $_items);
+        $this->assign('Page', $_page);
+        $this->assign("is_show_del", $_is_show_del);
+        $this->assign('filter_button', $_filter_button);
+        $this->assign('filter_button_clear', $_filter_button_clear);
+
+        return $this->fetch('landingPage');
+    }
+
+    public function addLandingPage() {
+//        $_app_id = I("app_id", 0);
+        $_app_id = $this->request->param("app_id/d", 0);
+        $this->assign("app_id", $_app_id);
+
+        return $this->fetch('addLandingPage');
+    }
+
+    public function addLandingPagePost() {
+        $_app_id = $this->request->param("app_id/d", 0);
+        $_images = $this->request->param("photos_url/a");
+        $_landing_pages = $this->request->param("landing_url/a");
+        $_data['app_id'] = $_app_id;
+        $_data['owner_id'] = $this->admin_id;
+        $_data['create_time'] = time();
+        $_data['update_time'] = $_data['create_time'];
+        if (is_array($_images)) {
+            foreach ($_images as $_k => $_v) {
+                $_data['image'] = $_v;
+                $_rs = (new GamelandingpageModel())->addData($_data);
+                if ($_rs) {
+                    $_base_url = $this->down_view_path;
+                    $_url = $_base_url.$_app_id."/".$_rs;
+                    $_time = date("YmdHis");
+                    if (!empty($_landing_pages[$_k])) {
+                        $_udata = $this->mvZip($_landing_pages[$_k], $_time, $_url);
+                        $_updata['file_url'] = $_udata['file_name'];
+                        $_updata['src_url'] = $_udata['src_url'];
+                        $_glp_map['id'] = $_rs;
+                        (new GamelandingpageModel())->updateData($_updata, $_glp_map);
+                    }
+                }
+            }
+            $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/distribution.landing_page/landingPage'));
+        }
+        $this->adminError(lang('ADD').lang('FAILURE'));
+    }
+
+    public function mvZip($file_url, $time, $url) {
+        $_file_url = str_replace('admin', 'upload', $_SERVER['DOCUMENT_ROOT']).'/'.$file_url;
+        /*/huosdk/test/313/public/admin/admin/20180730/9e1a6bb8b138472b79d6592d63d6f040.zip*/
+//        /huosdk/test/313/public/upload/admin/20180730/9e1a6bb8b138472b79d6592d63d6f040.zip
+        $_file_name = basename($file_url);
+        $_redicturl = $url.'/'.$_file_name;
+        if (file_exists($_redicturl)) {
+            // $this->adminError( '同文件名已存在');
+            $this->adminError(lang('distribution same file name already exists'));
+            exit();
+        }
+        if (!file_exists($url)) {  // 判断存放文件目录是否存在
+            mkdir($url, 0777, true);
+        }
+        \think\Log::write('$_redicturl:'.$_redicturl, 'error');
+        if (!copy($_file_url, $_redicturl)) {
+            //$this->adminError("移动文件出错.");
+            $this->adminError(lang('distribution error moving files'));
+            exit();
+        }
+        $_zip = new \ZipArchive();
+        if ($_zip->open($_redicturl) === true) {
+            $_zip->extractTo($url);
+            $_zip->close();
+        }
+        $_return_src_url = '';
+        if ($_zip->open($_file_url) === true) {
+            $_file_path = pathinfo($_file_url);
+            \think\Log::write('pathinfo($_file_url):', 'error');
+            \think\Log::write($_file_path, 'error');
+            $_src_url = $_file_path['dirname'].'/'.$_file_path['filename'];
+            $_return_src_url = str_replace(strrchr($file_url, "."), "", $file_url).'/';
+            if (!file_exists($_src_url)) {  // 判断存放文件目录是否存在
+                mkdir($_src_url, 0777, true);
+            }
+            $_zip->extractTo($_src_url);
+            $_zip->close();
+        }
+        $_rdata['file_name'] = $_redicturl;
+        $_rdata['src_url'] =  STATICSITE.'/upload/'.$_return_src_url;
+
+        return $_rdata;
+    }
+
+    public function uploadZip($up_info, $time, $url) {
+        $_arr_type = array('application/x-zip-compressed', 'application/x-compressed');
+        $_fname = $up_info['name'];
+        if (!is_uploaded_file($up_info['tmp_name'])) { //判断上传文件是否存在
+            //   $this->adminError('上传文件不存在.');
+            $this->adminError(lang('distribution upload file does not exist'));
+            exit();
+        }
+        if (!in_array($up_info['type'], $_arr_type)) {  //判断图片文件的格式
+            //$this->adminError("上传文件格式不对.".$up_info['type']);
+            $this->adminError(lang('distribution upload file format is wrong').$up_info['type']);
+            exit();
+        }
+        if (!file_exists($url)) {  // 判断存放文件目录是否存在
+            mkdir($url, 0777, true);
+        }
+        $_ftypearr = explode('.', $_fname);
+        $_ftype = $_ftypearr[count($_ftypearr) - 1];//文件类型
+        $_fname = $time.'.'.$_ftype;
+        $_file_name = $url."/".$_fname;
+        if (file_exists($_file_name)) {
+//            $this->adminError("同文件名已存在.");
+            $this->adminError(lang('distribution same file name already exists'));
+            exit();
+        }
+        if (!move_uploaded_file($up_info['tmp_name'], $_file_name)) {
+//            $this->adminError("移动文件出错.");
+            $this->adminError(lang('distribution error moving files'));
+            exit();
+        }
+        $_zip = new \ZipArchive();
+        if ($_zip->open($_file_name) === true) {
+            $_zip->extractTo($url);
+            $_zip->close();
+        }
+
+        return $_fname;
+    }
+
+    public function delLandingPage() {
+        $_landing_page_id = $this->request->param("id/d", 0);
+        $_data["is_delete"] = 1;
+        $_data["update_time"] = time();
+        $_data["delete_time"] = $_data["update_time"];
+        $_map['id'] = $_landing_page_id;
+        $_rs = (new GamelandingpageModel())->updateData($_data, $_map);
+        if ($_rs) {
+            $this->adminSuccess(
+                lang('distribution landingPage delete success'), url('admin/distribution.landing_page/landingPage')
+            );
+            exit;
+        }
+        $this->adminError(lang('distribution landingPage delete error'));
+    }
+
+    public function editLandingPage() {
+        $_landing_page_id = $this->request->param("id/d", 0);
+        $_data = (new GamelandingpageModel())->getInfoById($_landing_page_id);
+        $this->assign("data", $_data);
+
+        return $this->fetch('editLandingPage');
+    }
+
+    public function editLandingPagePost() {
+        $_landing_page_id = $this->request->param("landing_page_id/d", 0);
+        $_image = $this->request->param("thumbnail", '');
+        $_landing_page = $this->request->param("landing_page");
+        $_map['id'] = $_landing_page_id;
+        if (!empty($_image)) {
+            $_data['image'] = $_image;
+        }
+        $_data['owner_id'] = $this->admin_id;
+        $_data['update_time'] = time();
+        $_rs = (new GamelandingpageModel())->updateData($_data, $_map);
+        if ($_rs && !empty($_landing_page)) {
+            $_base_url = $this->down_view_path;
+            $_app_id = (new GamelandingpageModel())->where(['id' => $_landing_page_id])->value("app_id");
+            $_url = $_base_url.$_app_id."/".$_landing_page_id;
+            $_time = date("YmdHis");
+            $this->deldir($_url);
+            $_udata = $this->mvZip($_landing_page, $_time, $_url);
+            $_updata['file_url'] = $_udata['file_name'];
+            $_updata['src_url'] = $_udata['src_url'];
+            $_glp_map['id'] = $_landing_page_id;
+            (new GamelandingpageModel())->updateData($_updata, $_glp_map);
+        }
+        $this->adminSuccess(
+            lang('distribution landingPage delete success'), url('admin/distribution.landing_page/landingPage')
+        );
+    }
+
+    public function deldir($dir = '') {
+        //删除目录下的文件:
+        if (empty($dir)) {
+            return;
+        }
+        $_dh = opendir($dir);
+        while ($_file = readdir($_dh)) {
+            if ($_file != "." && $_file != "..") {
+                $_fullpath = $dir."/".$_file;
+                if (!is_dir($_fullpath)) {
+                    unlink($_fullpath);
+                } else {
+                    $this->deldir($_fullpath);
+                    @rmdir($_fullpath);
+                }
+            }
+        }
+        closedir($_dh);
+    }
+
+    //下载指定文件的方法
+    public function downdetails() {
+        $_id = $this->request->param("id/d", 0);
+        $_map['id'] = $_id;
+        $_file_path = (new GamelandingpageModel())->where($_map)->value("file_url");
+        header("Content-type:text/html;charset=utf-8");
+        //首先要判断给定的文件存在与否
+        if (!file_exists($_file_path)) {
+//            echo "没有该文件文件";
+            echo lang('distribution landingPage no such file');
+
+            return;
+        }
+        $_fp = fopen($_file_path, "r");
+        $_file_size = filesize($_file_path);
+        //下载文件需要用到的头
+        Header("Content-type: application/octet-stream");
+        Header("Accept-Ranges: bytes");
+        Header("Accept-Length:".$_file_size);
+        Header("Content-Disposition: attachment; filename=".$_file_path);
+        $_buffer = 1024;
+        $_file_count = 0;
+        //向浏览器返回数据
+        while (!feof($_fp) && $_file_count < $_file_size) {
+            $_file_con = fread($_fp, $_buffer);
+            $_file_count += $_buffer;
+            echo $_file_con;
+        }
+        fclose($_fp);
+    }
+
+    /**
+     * 恢复
+     */
+    public function recoverLandingPage() {
+        $_landing_page_id = $this->request->param("id/d", 0);
+        $_data["is_delete"] = 2;
+        $_data["update_time"] = time();
+        $_map['id'] = $_landing_page_id;
+        $_rs = (new GamelandingpageModel())->updateData($_data, $_map);
+        if ($_rs) {
+            // $this->success("恢复成功", U("Game/Material/landingPage"));
+            $this->adminSuccess(
+                lang('distribution landingPage recover success'), url('admin/distribution.landing_page/landingPage')
+            );
+            exit;
+        }
+//        $this->error("恢复失败");
+        $this->adminError(lang('distribution landingPage recover error'));
+    }
+}
+

+ 188 - 0
admin/admin/controller/distribution/PackageController.php

@@ -0,0 +1,188 @@
+<?php
+/**
+ * PackageController.php UTF-8
+ * 分包相关
+ *
+ * @date    : 2018/6/8 23:03
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : ouzhongfu <ozf@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\distribution;
+
+use cmf\view\Filter;
+use huo\model\agent\AgentGameModel;
+use huo\logic\agent\AgentGameLogic;
+use huo\model\distribution\GamelandingpageModel;
+use huo\model\distribution\PromotiondomainModel;
+use huo\model\distribution\PromotionplanModel;
+use huo\model\distribution\PromotiondetailModel;
+use huo\model\distribution\PlatformModel;
+use huo\controller\agent\Agent;
+use huo\logic\agent\AgentLogic;
+use huo\model\game\GameModel;
+use huo\model\user\UserModel;
+use huo\controller\agent\AgentGame;
+use think\Log;
+use huolib\status\GameStatus;
+
+class PackageController extends BaseController {
+    protected $promotion_detail_model;
+    protected $monitor_base_url;
+    protected $monitor_and_param;
+    protected $monitor_ios_param;
+    protected $baidu_monitor_base_url;
+    protected $baidu_monitor_and_param;
+    protected $baidu_monitor_ios_param;
+
+    function _initialize() {
+        parent::_initialize();
+        $this->promotion_detail_model = (new PromotiondetailModel());
+        $this->monitor_base_url = SDKSITE."/api/toutiao/start/pmtid/";
+        $this->baidu_monitor_base_url = SDKSITE."/api/baidu/start/pmtid/";
+        $this->monitor_and_param
+            = "adid=__AID__&cid=__CID__&imei=__IMEI__&mac=__MAC__&androidid=__ANDROIDID1__&os=__OS__&timestamp=__TS__&callback_url=__CALLBACK_URL__";
+        $this->monitor_ios_param
+            = "adid=__AID__&cid=__CID__&idfa=__IDFA__&mac=__MAC__&os=__OS__&timestamp=__TS__&callback_url=__CALLBACK_URL__";
+        $this->baidu_monitor_ios_param
+            = "idfa={{IDFA}}&os={{OS}}&ip={{IP}}&ua={{UA}}&ts={{TS}}&userid={{USER_ID}}&pid={{PLAN_ID}}&uid={{UNIT_ID}}&aid={{IDEA_ID}}&click_id={{CLICK_ID}}&callback_url={{CALLBACK_URL}}&sign={{SIGN}}";
+        $this->baidu_monitor_and_param
+            = "imei_md5={{IMEI_MD5}}&os={{OS}}&ip={{IP}}&ua={{UA}}&ts={{TS}}&userid={{USER_ID}}&pid={{PLAN_ID}}&uid={{UNIT_ID}}&aid={{IDEA_ID}}&click_id={{CLICK_ID}}&callback_url={{CALLBACK_URL}}&sign={{SIGN}}";
+    }
+
+    /**获取检测地址
+     *
+     * @param string $classify
+     * @param int    $platform_id
+     * @param int    $pd_id
+     *
+     * @return string
+     */
+    public function getMonitorUrl($classify = '', $platform_id = 0, $pd_id = 0) {
+        if (empty($classify) || empty($platform_id) || empty($pd_id)) {
+            return '--';
+        }
+        $_map['id'] = $platform_id;
+        $_data = (new PlatformModel())->getInfoById($platform_id);
+        if (empty($_data)) {
+            return '--';
+        }
+        $_url = SDKSITE.$_data['route'].$pd_id.'?';
+        if (4 == substr($classify, 0, 1)) {
+            $_params = $_data['ios_params'];
+        } else {
+            $_params = $_data['and_params'];
+        }
+        if (empty($_params)) {
+            return '--';
+        } else {
+            return $_url.$_params;
+        }
+    }
+
+    public function index() {
+        $_is_show_del = 1;
+        if ($this->not_admin) {
+            $_owner_id = $this->admin_id;
+            $_map['pp.owner_id'] = $_owner_id;
+            $_is_show_del = 2;
+        }
+        $_app_id = $this->request->param("app_id/d", 0);
+        $_select_owner_id = $this->request->param("owner_id/d", 0);
+        $_platform_id = $this->request->param("platform_id/d", 0);
+        $_start_time = trim($this->request->param("start_time"));
+        $_end_time = trim($this->request->param("end_time"));
+        $_plan_id = $this->request->param("plan_id/d", 0);
+        $_detail_id = $this->request->param("detail_id/d", 0);
+        $_landing_page_id = $this->request->param("landing_page_id/d", 0);
+        $_offset = $this->request->param("offset/d", 20);
+        if (!empty($_app_id)) {
+            $_map['pd.app_id'] = $_app_id;
+        }
+        if (!empty($_select_owner_id)) {
+            $_map['pp.owner_id'] = $_select_owner_id;
+        }
+        if (!empty($_platform_id)) {
+            $_map['pp.platform_id'] = $_platform_id;
+        }
+        $where_time = $this->_dateToTime($_start_time, $_end_time);
+        if (!empty($where_time)) {
+            $_map['pd.create_time'] = $this->_dateToTime($_start_time, $_end_time);
+        }
+        if (!empty($_plan_id)) {
+            $_map['pd.promotion_plan_id'] = $_plan_id;
+        }
+        if (!empty($_detail_id)) {
+            $_map['pd.id'] = $_detail_id;
+        }
+        if (!empty($_landing_page_id)) {
+            $_map['pd.landing_page_id'] = $_landing_page_id;
+        }
+        $_map['pd.is_delete'] = 2;
+        $_map['g.is_delete'] = 2;
+        $_map['glp.is_delete'] = 2;
+        $_field
+            = "ag.create_time,ag.update_time,g.name gamename,g.classify,pd.promotion_plan_id,ag.package_url as url,pd.status,
+        pd.agent_id,pd.app_id,pd.id,pp.owner_id,pp.platform_id,pd.landing_page_id,glp.image,pd.toutiao_key";
+        $_data_list = (new PromotiondetailModel())
+            ->alias('pd')
+            ->where($_map)
+            ->join($this->db_prefix."agent_game ag", " ag.agent_id=pd.agent_id and pd.app_id=ag.app_id", 'left')
+            ->join($this->db_prefix."game g ", "g.id=pd.app_id", 'left')
+            ->join($this->db_prefix."promotion_plan pp", "pd.promotion_plan_id = pp.id", 'left')
+            ->join($this->db_prefix."game_landing_page glp", " glp.id = pd.landing_page_id", 'left')
+            ->order('pd.id desc')
+            ->field($_field)
+            ->paginate($_offset);
+        $_data = array();
+        if (!empty($_data_list)) {
+            $_data_array = $_data_list->toArray();
+            if (!empty($_data_array)) {
+                $_data = isset($_data_array['data']) ? $_data_array['data'] : array();
+            }
+            foreach ($_data as $_k => $_v) {
+                $_ag_string = $this->getAgUrl($_v['agent_id'], $_v['app_id']);
+                if ($_ag_string) {
+                    $_data[$_k]['landing_page_url'] = $this->getBaseUrl($_v['id']).$_ag_string;
+                } else {
+                    $_data[$_k]['landing_page_url'] = '';
+                }
+                //$_data[$_k]['landing_page_url'] = $this->getAgUrl($_v['agent_id'], $_v['app_id']);
+                $_data[$_k]['down_url'] = $this->getDownUrl($_v['agent_id'], $_v['app_id']);
+                $_data[$_k]['image'] = STATICSITE.'/upload/'.$_v['image'];
+                $_data[$_k]['monitor_url'] = $this->getMonitorUrl($_v['classify'], $_v['platform_id'], $_v['id']);
+            }
+        }
+        $this->genStatus();
+        $this->genUsers();
+        $this->genPlatforms();
+        $this->_games($_app_id);
+        $this->assign('data', $_data);
+        $this->assign("formget", $this->request->param());
+        $this->assign("Page", $_data_list->render());
+        $this->assign("is_show_del", $_is_show_del);
+
+        return $this->fetch();
+    }
+
+    public function del() {
+        $_id = $this->request->param("id/d", 0);//I('id', 0);
+        if (empty($_id)) {
+            $this->adminError('参数错误');
+        }
+        $_map = array();
+        $_map['id'] = $_id;
+        $_up = array();
+        $_up['is_delete'] = 1;
+        $_up['delete_time'] = time();
+        $_up['update_time'] = $_up['delete_time'];
+        $_rs = (new PromotiondetailModel())->updateData($_up, $_map);//->where($_map)->setField("is_delete", 1);
+        if ($_rs) {
+            return $this->adminSuccess('删除成功');
+        } else {
+            return $this->adminError('删除失败');
+        }
+    }
+}

+ 460 - 0
admin/admin/controller/distribution/PlanController.php

@@ -0,0 +1,460 @@
+<?php
+/**推广计划管理
+ * PlanController.php UTF-8
+ *
+ *
+ * @date    : 2018/6/1 15:46
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : ouzhongfu <ozf@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\distribution;
+
+use cmf\view\Filter;
+use huo\model\agent\AgentGameModel;
+use huo\logic\agent\AgentGameLogic;
+use huo\model\distribution\GamelandingpageModel;
+use huo\model\distribution\PromotiondomainModel;
+use huo\model\distribution\PromotionplanModel;
+use huo\model\distribution\PromotiondetailModel;
+use huo\model\distribution\PlatformModel;
+use huo\controller\agent\Agent;
+use huo\logic\agent\AgentLogic;
+use huo\model\game\GameModel;
+use huo\model\user\UserModel;
+use huo\controller\agent\AgentGame;
+use think\Log;
+use huolib\status\GameStatus;
+
+class PlanController extends BaseController {
+    function _initialize() {
+        parent::_initialize();
+    }
+
+    function index() {
+        $_map = array();
+        if ($this->not_admin) {
+            $_owner_id = $this->admin_id;
+            $_map['pp.owner_id'] = $_owner_id;
+        }
+        $_select_owner_id = $this->request->param("owner_id/d", 0);
+        $_platform_id = $this->request->param("platform_id/d", 0);
+        $_offset = $this->request->param("offset/d", 10);
+        $_formget = $this->request->param();
+        $_start_time = trim($this->request->param("start_time"));
+        $_end_time = trim($this->request->param("end_time"));
+        $_time_w = $this->_time($_start_time, $_end_time);
+        if ($_time_w) {
+        }
+        $where_time = $this->_dateToTime($_start_time, $_end_time);
+        if (!empty($where_time)) {
+            $_map['pp.create_time'] = $this->_dateToTime($_start_time, $_end_time);
+        }
+        if (!empty($_select_owner_id)) {
+            $_map['pp.owner_id'] = $_select_owner_id;
+        }
+        if (!empty($_platform_id)) {
+            $_map['pp.platform_id'] = $_platform_id;
+        }
+        $_map['pp.is_delete'] = 2;
+        $_field = "pp.id,pp.create_time,p.name platform_name,u.user_login,u.user_nicename";
+        $_data_list = (new PromotionplanModel())
+            ->alias('pp')
+            ->where($_map)
+            ->join($this->db_prefix."platform p", "p.id = pp.platform_id", 'left')
+            ->join($this->db_prefix."user u ", "u.id = pp.owner_id", "left")
+            ->field($_field)
+            ->order("pp.id desc")
+            ->paginate($_offset);
+        $_data = array();
+        if (!empty($_data_list)) {
+            $_data_array = $_data_list->toArray();
+            if (!empty($_data_array)) {
+                $_data = isset($_data_array['data']) ? $_data_array['data'] : array();
+            }
+            if (!empty($_data)) {
+                foreach ($_data as $_k => $_v) {
+                    if (!isset($_v['id'])) {
+                        unset($_data[$_k]);
+                        continue;
+                    }
+                    $_game_cnt_map = array();
+                    $_game_cnt_map['is_delete'] = 2;
+                    $_game_cnt_map['promotion_plan_id'] = $_v['id'];
+                    $_data[$_k]['game_cnt'] = (new PromotiondetailModel())->where($_game_cnt_map)->count(
+                        'DISTINCT app_id'
+                    );
+                    $_data[$_k]['plan_cnt'] = (new PromotiondetailModel())->where($_game_cnt_map)->count();
+                }
+            }
+        }
+        $_platform_list = array();
+        $_pf_map = array();
+        $_pf_map['is_delete'] = 2;
+        $_platform_list_list = (new PlatformModel())->where($_pf_map)->select()->toArray();
+        if (!empty($_platform_list_list)) {
+            if (isset($_platform_list_list['data']) && !empty($_platform_list_list['data'])) {
+                $_platform_list = $_platform_list_list['data'];
+            } else {
+                $_platform_list = $_platform_list_list;
+            }
+        }
+        $_ol_map = array();
+        $_ol_map['role_id'] = $this->cpa_role_id;
+        if ($this->not_admin) {
+            $_ol_map['id'] = $this->admin_id;
+        }
+        $_owner_list = (new UserModel())->getIdNames($_ol_map, true);
+        $this->assign("owner_list", $_owner_list);
+        $this->assign("platform_list", $_platform_list);
+        $this->assign('Page', $_data_list->render());
+        $this->assign('data', $_data);
+        $this->assign('formget', $_formget);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加
+     */
+    function add() {
+        $_platform_ids = $this->request->post('platform_id');
+        $_owner_ids = $this->request->post('owner_id');
+        $_platform_ids = htmlspecialchars_decode($_platform_ids);
+        $_owner_ids = htmlspecialchars_decode($_owner_ids);
+        $_platform_arr = json_decode($_platform_ids, true);
+        $_owner_arr = json_decode($_owner_ids, true);
+        foreach ($_platform_arr as $_v) {
+            foreach ($_owner_arr as $_val) {
+                $this->insertPlan($_v, $_val);
+            }
+        }
+        $this->adminSuccess('添加成功');
+    }
+
+    /**写入表c_promotion_plan
+     *
+     * @param $platform_id
+     * @param $owner_id
+     */
+    public function insertPlan($platform_id, $owner_id) {
+        $_data['platform_id'] = $platform_id;
+        $_data['owner_id'] = $owner_id;
+        $_data['create_time'] = time();
+        $_data['update_time'] = $_data['create_time'];
+        $_check_map['platform_id'] = $_data['platform_id'];
+        $_check_map['owner_id'] = $_data['owner_id'];
+        $_check_map['is_delete'] = 2;
+        $_check = (new PromotionplanModel())->where($_check_map)->find();
+        if (empty($_check)) {
+            $_re = (new PromotionplanModel())->addData($_data);
+            if ($_re) {
+            }
+        }
+    }
+
+    function show() {
+        $_owner_platform_id = $this->request->param("id/d", 0);
+        $_select_app_id = $this->request->param("select_app_id/d", 0);
+        $_select_owner_id = $this->request->param("owner_id/d", 0);
+        $_platform_id = $this->request->param("platform_id/d", 0);
+        $_select_plan_id = $this->request->param("select_plan_id/d", 0);
+        $_detail_id = $this->request->param("detail_id/d", 0);
+        $_select_landing_page_id = $this->request->param("select_landing_page_id/d", 0);
+        $_start_time = trim($this->request->param("start_time"));
+        $_end_time = trim($this->request->param("end_time"));
+        $_formget = $this->request->param();
+        $_back_url=urlencode(url('admin/distribution.plan/show',$_formget));
+        $_time_w = $this->_time($_start_time, $_end_time);
+        if ($_time_w) {
+        }
+        $_field
+            = 'pd.id,pd.agent_id,pd.create_time,pd.landing_page_id,pd.budget,pd.status,pd.start_time launch_start_time
+            ,pd.app_id,pd.end_time launch_end_time,g.name gamename,glp.image,pd.promotion_plan_id plan_id
+            ,pp.owner_id,pp.platform_id';
+        $_map['pd.is_delete'] = 2;
+        $_map['g.is_delete'] = 2;
+        $_map['glp.is_delete'] = 2;
+        $_map['pd.promotion_plan_id'] = $_owner_platform_id;
+        if (!empty($_select_app_id)) {
+            $_map['pd.app_id'] = $_select_app_id;
+        }
+        if (!empty($_select_owner_id)) {
+            $_map['pp.owner_id'] = $_select_owner_id;
+        }
+        if (!empty($_platform_id)) {
+            $_map['pp.platform_id'] = $_platform_id;
+        }
+        $where_time = $this->_dateToTime($_start_time, $_end_time);
+        if (!empty($where_time)) {
+            $_map['pd.create_time'] = $this->_dateToTime($_start_time, $_end_time);
+        }
+        if (!empty($_select_plan_id)) {
+            $_map['pd.promotion_plan_id'] = $_select_plan_id;
+        }
+        if (!empty($_detail_id)) {
+            $_map['pd.id'] = $_detail_id;
+        }
+        if (!empty($_select_landing_page_id)) {
+            $_map['pd.landing_page_id'] = $_select_landing_page_id;
+        }
+        $_data_list = (new PromotiondetailModel())
+            ->alias('pd')
+            ->where($_map)
+            ->join($this->db_prefix."game g", "g.id = pd.app_id", "left")
+            ->join($this->db_prefix."game_landing_page glp", "glp.id = pd.landing_page_id", 'left')
+            ->join($this->db_prefix."promotion_plan pp", "pd.promotion_plan_id = pp.id", 'left')
+            ->field($_field)
+            ->order("pd.id desc")
+            ->paginate();
+        $_data = array();
+        if (!empty($_data_list)) {
+            $_data_array = $_data_list->toArray();
+            if (!empty($_data_array)) {
+                $_data = isset($_data_array['data']) ? $_data_array['data'] : array();
+            }
+            if (!empty($_data)) {
+                foreach ($_data as $_k => $_v) {
+                    $_ag_string = $this->getAgUrl($_v['agent_id'], $_v['app_id']);
+                    if ($_ag_string) {
+                        $_data[$_k]['url'] = $this->getBaseUrl($_v['id']).$_ag_string;
+                        $_data[$_k]['down_url'] = $this->getDownUrl($_v['agent_id'], $_v['app_id']);
+                    } else {
+                        $_data[$_k]['url'] = '';
+                        $_data[$_k]['down_url'] = '';
+                    }
+                    $_data[$_k]['image'] = STATICSITE.'/upload/'.$_v['image'];
+                }
+            }
+        }
+        $this->genUsers();
+        $this->genPlatforms();
+        $this->_games($_select_app_id);
+        $this->genStatus();
+        $this->getDomain();
+        $this->assign('Page', $_data_list->render());
+        $this->assign('plan_id', $_owner_platform_id);
+        $this->assign('data', $_data);
+        $this->assign('formget', $_formget);
+        $this->assign('sub_back', $_back_url);
+
+        return $this->fetch();
+    }
+
+    public function getDomain() {
+        $_cates = array(
+            "0" => "默认",
+        );
+        $_map['is_delete'] = 2;
+        //  $_map['status'] = 2;
+        $_domains = (new PromotiondomainModel())->getIdValues($_map, "domain");
+        if (!empty($_domains)) {
+            $domains = $_cates + $_domains;
+        } else {
+            $domains = $_cates;
+        }
+        $this->assign("domains", $domains);
+    }
+
+    public function getLandingPages() {
+        $_app_id = $this->request->param("appid/d", 0);
+        $_map['app_id'] = $_app_id;
+        $_map['is_delete'] = 2;
+        if ($this->not_admin) {
+            //$_map['ower_id'] = get_current_admin_id();
+            $_owner_id = $this->admin_id;
+            $_map['owner_id'] = array('in', [1, $_owner_id]);
+        }
+        $_landing_pages = (new GamelandingpageModel())->where($_map)->field('id,image')->select();
+        if (!empty($_landing_pages)) {
+            if (is_object($_landing_pages)) {
+                $_landing_pages = $_landing_pages->toArray();
+            }
+            foreach ($_landing_pages as $_k => $_v) {
+                $_landing_pages[$_k]['image'] = STATICSITE.'/upload/'.$_v['image'];
+            }
+
+            return $this->ajaxReturn(['error' => '0', 'data' => $_landing_pages]);
+        } else {
+            return $this->ajaxReturn(['error' => '1', 'msg' => "暂未添加落地页"]);
+        }
+    }
+
+    /**
+     * @return mixed
+     */
+    public function detailAdd() {
+        $_app_id = $this->request->param("app_id/d", 0);
+        $_numbers = $this->request->param("numbers/d", 1);
+        $_landing_page_id = $this->request->param("landing_page_id/d", 0);
+        $_plan_id = $this->request->param("plan_id/d", 0);
+        $_domain_id = $this->request->param("domain_id/d", 0);
+        if (empty($_plan_id)) {
+            return $this->ajaxReturn(['error' => '1', 'msg' => '参数错误']);
+        }
+        if (empty($_app_id)) {
+            return $this->ajaxReturn(['error' => '1', 'msg' => '请选择添加游戏']);
+        }
+        /*if (empty($_material_id)) {
+            return $this->ajaxReturn(['error' => '1', 'msg' => '请选择推广素材']);
+        }*/
+        if (empty($_landing_page_id)) {
+            return $this->ajaxReturn(['error' => '1', 'msg' => '请选择落地页']);
+        }
+        /*生成推广agent_id*/
+        $_pp_map['id'] = $_plan_id;
+        $_plan_data = (new PromotionplanModel())->getInfoById($_plan_id);
+        $_classify = (new GameModel())->where(['id' => $_app_id])->value('classify');
+        $_base_data['landing_page_id'] = $_landing_page_id;
+        $_base_data['classify'] = $_classify;
+        $_base_data['app_id'] = $_app_id;
+        $_base_data['promotion_plan_id'] = $_plan_id;
+        $_base_data['domain_id'] = $_domain_id;
+        $_x = 1;
+        $_owner_username = (new UserModel())->getNameById($_plan_data['owner_id']);
+        while ($_x <= $_numbers) {
+//            $this->genAgentPer($_base_data, $_plan_data['owner_id'], $_x);
+            $this->genAgentPer($_base_data, $_owner_username, $_plan_data['owner_id'], $_x);
+            $_x++;
+        }
+
+        return $this->ajaxReturn(['error' => '0', 'msg' => '添加成功']);
+    }
+
+    public function genAgentPer($base_data, $owner_username, $owner_id, $num) {
+        $_data['agent_id'] = 0;
+        $_data['app_id'] = $base_data['app_id'];
+        $_data['promotion_plan_id'] = $base_data['promotion_plan_id'];
+        $_data['landing_page_id'] = $base_data['landing_page_id'];
+        $_data['create_time'] = time();
+        $_data['update_time'] = $_data['create_time'];
+        $_data['access_url'] = $base_data['app_id']."/".$base_data['landing_page_id'];
+        $_data['status'] = 2;
+        $_data['domain_id'] = $base_data['domain_id'];
+        $_pd_id = (new PromotiondetailModel())->addData($_data);
+//        $_pd_id = M('promotion_detail')->data($_data)->add();
+        if (!$_pd_id) {
+            return $this->ajaxReturn(['error' => '1', 'msg' => '添加失败']);
+        }
+        $_agent_id = $this->genTagent($owner_username, $owner_id, $_pd_id, $num);
+        if (!$_agent_id) {
+            return $this->ajaxReturn(['error' => '1', 'msg' => '添加失败']);
+        }
+        /*插入agent_game表*/
+        if ($this->game_ios == substr($base_data['classify'], 0, 1)) {
+            $this->genAgentGame($_agent_id, $base_data['app_id']);
+        }
+        $_up = array();
+        $_up['agent_id'] = $_agent_id;
+        $_up['update_time'] = time();
+        $_re = (new PromotiondetailModel())->updateData($_up, ['id' => $_pd_id]);
+        if ($_re) {
+        }
+    }
+
+    public function genTagent($owner_username, $owner_id, $pd_id, $num) {
+        $_time = time();
+        $_agent_name = $owner_username.'_'.$pd_id.'_'.$_time.$num;
+        $_user_nice = $owner_username.'_'.$pd_id.'_'.$_time.$num;
+        $_role_id = $this->page_role_id;
+        $_user_pass = $this->default_pass;
+        $_data['user_login'] = $_agent_name;
+        $_data['user_pass'] = $_user_pass;
+        $_data['pay_pwd'] = $_user_pass;
+        $_data['user_nicename'] = $_user_nice;
+        $_data['user_email'] = '';
+        $_data['role_id'] = $_role_id;
+        $_data['parent_id'] = $owner_id;
+        $_agent_id = (new AgentLogic())->addAgent($_data);
+        if ($_agent_id) {
+            return $_agent_id;
+        } else {
+            return false;
+        }
+    }
+
+    public function genAgentGame($agent_id, $app_id) {
+        $_check_map = array();
+        $_check_map['agent_id'] = $agent_id;
+        $_check_map['app_id'] = $app_id;
+        $_ag_model = new AgentGameModel();
+        $_check = $_ag_model->getAgIdByAgentIdAppId($agent_id, $app_id);
+        if (!empty($_check)) {
+            return;
+        }
+        $_agent_game_class = new AgentGame();
+        $_re = $_agent_game_class->addGame($agent_id, $app_id);
+        if (!$_re) {
+            Log::write('添加渠道游戏失败:'.json_encode($_check_map), 'error');
+        }
+    }
+
+    public function editBudget() {
+        $_id = $this->request->param("id/d", 0);
+        $_budget = $this->request->param("budget/d", 0);
+        if (empty($_id) || empty($_budget)) {
+            $this->ajaxReturn(array("error" => "1", "msg" => "参数错误".$_id.'$$'.$_budget));
+            exit;
+        }
+        $_map['id'] = $_id;
+        $_data['budget'] = $_budget;
+        $_data['update_time'] = time();
+        $_rs = (new PromotiondetailModel())->updateData($_data, $_map);
+        if ($_rs) {
+            $this->ajaxReturn(array("error" => "0", "msg" => "修改成功"));
+            exit;
+        } else {
+            $this->ajaxReturn(array("error" => "1", "msg" => "修改失败"));
+            exit;
+        }
+    }
+
+    public function editTime() {
+        $_id = $this->request->param("id/d", 0);
+        $_edit_time = $this->request->param("edit_time", 0);
+        $_edit_type = $this->request->param("edit_type/d", 0);
+        if (empty($_id) || empty($_edit_time) || empty($_edit_type)) {
+            $this->ajaxReturn(array("error" => "1", "msg" => "参数错误"));
+            exit;
+        }
+        $_map = array();
+        $_map['id'] = $_id;
+        if (1 == $_edit_type) {
+            $_data['start_time'] = strtotime($_edit_time);
+        } else {
+            $_data['end_time'] = strtotime($_edit_time);
+        }
+        $_data['update_time'] = time();
+        $_rs = (new PromotiondetailModel())->updateData($_data, $_map);
+        if ($_rs) {
+            $this->ajaxReturn(array("error" => "0", "msg" => "修改成功"));
+            exit;
+        } else {
+            $this->ajaxReturn(array("error" => "1", "msg" => "修改失败"));
+            exit;
+        }
+    }
+
+    public function editStatus() {
+        $_id = $this->request->param("id/d", 0);
+        $_status = $this->request->param("status/d", 0);
+        $_up = array();
+        $_up['status'] = $_status;
+        $_up['update_time'] = time();
+        $_rs = (new PromotiondetailModel())->updateData($_up, array("id" => $_id));
+        if ($_rs) {
+            $this->ajaxReturn(array("error" => "0", "msg" => "修改成功"));
+            exit;
+        } else {
+            $this->ajaxReturn(array("error" => "1", "msg" => "修改失败"));
+            exit;
+        }
+    }
+
+    public function getMaterial() {
+        /* 素材表已废弃 */
+        return $this->ajaxReturn(['error' => '1', 'msg' => "素材表已废弃"]);
+    }
+}

+ 249 - 0
admin/admin/controller/distribution/PlatformController.php

@@ -0,0 +1,249 @@
+<?php
+/**
+ * 渠道分发中分发平台管理
+ * PlatformController.php UTF-8
+ *
+ *
+ * @date    : 2018/5/31 23:15
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : ouzhongfu <ozf@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\distribution;
+
+use huo\model\distribution\PlatformModel;
+use huo\model\distribution\PromotiondomainModel;
+use cmf\view\Filter;
+
+class PlatformController extends BaseController {
+    protected $platform;
+
+    function _initialize() {
+        parent::_initialize();
+    }
+
+    function index() {
+        $_param = $this->request->param();
+        $_map['is_delete'] = $this->request->param('is_delete/d', 2);
+        $_offset = $this->request->param('offset/d', 10);
+        $_map['name'] = $this->request->param('name', '');
+        $_data = (new PlatformModel())->getList($_map, $_offset);
+        $_page = $_data->render();
+        $_items_Arr = $_data->toArray();
+        $_items = isset($_items_Arr['data']) ? $_items_Arr['data'] : $_items_Arr;
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', 'uri' => url('admin/distribution.platform/index')]
+        );
+        $this->assign('data', $_param);
+        $this->assign('items', $_items);
+        $this->assign('page', $_page);
+        $this->assign('filter_button', $_filter_button);
+        $this->assign('filter_button_clear', $_filter_button_clear);
+
+        return $this->fetch();
+    }
+
+    function add() {
+        return $this->fetch();
+    }
+
+    /**
+     *处理添加
+     */
+    function addPost() {
+        $_data = [];
+        $_data['name'] = $this->request->param('platform_name/s', '');
+        $_data['create_time'] = time();
+        $_data['update_time'] = $_data['create_time'];
+        $_check_map['name'] = $_data['name'];
+        $_check_map['is_delete'] = 2;
+        $_check = (new PlatformModel())->where($_check_map)->find();
+        if (!empty($_check)) {
+            $this->adminError(lang('distribution platform name conflict'));
+        }
+        if (false != (new PlatformModel())->addData($_data)) {
+            $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/distribution.platform/index'));
+        } else {
+            $this->adminError(lang('ADD').lang('FAILURE'));
+        }
+    }
+
+    /**
+     *删除处理
+     */
+    function del() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError(lang('distribution parameter error'));
+        }
+        $_map['id'] = $_id;
+        $_data['is_delete'] = 1;
+        $_result = (new PlatformModel())->updateData($_data, $_map);
+        if (false != $_result) {
+            $this->adminSuccess(lang('distribution delete platform success'), url('admin/distribution.platform/index'));
+        }
+        $this->adminError(lang('distribution delete platform fall'), url('admin/distribution.platform/index'));
+    }
+
+    /**
+     * 修改页面
+     *
+     * @return mixed
+     */
+    function edit() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError(lang('distribution parameter error'));
+        }
+        $_map['id'] = $_id;
+        $_data = (new PlatformModel())->getInfoById($_id);
+        if (false != $_data) {
+            $this->assign('data', $_data);
+
+            return $this->fetch();
+        } else {
+            $this->adminError(lang('distribution parameter error'));
+        }
+    }
+
+    /*
+     * 修改处理
+     * */
+    function editPost() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError(lang('distribution parameter error'));
+        }
+        $_platform_name = $this->request->param('platform_name', '');
+        if (empty($_platform_name)) {
+            $this->adminError(lang('distribution platform name is null'));
+        } else {
+            $_map['id'] = ['neq', $_id];
+            $_map['is_delete'] = ['eq', 2];
+            $_map['name'] = ['eq', $_platform_name];
+            $_result = (new PlatformModel())->where($_map)->find();
+            if (!empty($_result)) {
+                $this->adminError(lang('distribution platform name conflict'));
+            }
+        }
+        $_data['update_time'] = time();
+        $_data['name'] = $_platform_name;
+        $_edit_map['id'] = $_id;
+        $_result = (new PlatformModel())->updateData($_data, $_edit_map);
+        if ($_result) {
+            $this->adminSuccess(lang('distribution edit platform success'), url('admin/distribution.platform/index'));
+        } else {
+            $this->adminError(lang('distribution edit platform fail'), url('admin/distribution.platform/index'));
+        }
+    }
+
+    /**
+     * 域名列表
+     */
+    public function domain() {
+        $_map = array();
+        $_map['is_delete'] = 2;
+        $_offset = $this->request->param('offset/d', 20);
+        $_data_list = (new PromotiondomainModel())
+            ->where($_map)
+            ->order('id desc')
+            ->paginate($_offset);
+        $_data = array();
+        if (!empty($_data_list)) {
+            $_data_arr = $_data_list->toArray();
+            $_data = isset($_data_arr['data']) ? $_data_arr['data'] : array();
+        }
+        $this->assign('Page', $_data_list->render());
+        $this->assign('data', $_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 域名添加
+     */
+    public function addDomain() {
+        $_domain = $this->request->param('domain', '');
+        if (empty($_domain)) {
+            $this->adminError('请填写域名!');
+        }
+        $_map['domain'] = $_domain;
+        $_map['is_delete'] = 2;
+        $_check = (new PromotiondomainModel())->where($_map)->find();
+        if (!empty($_check)) {
+            $this->adminSuccess('添加成功!');
+        }
+        $checkExpressions = '|^http://|';
+        $httpsExpressions = '|^https://|';
+        if (false == preg_match($checkExpressions, $_domain) && false == preg_match($httpsExpressions, $_domain)) {
+            $this->adminError('请输入正确的回调地址,以http://或者https://开头!');
+        }
+        $_data['domain'] = $_domain;
+        $_data['create_time'] = time();
+        $_data['update_time'] = $_data['create_time'];
+        $_data['status'] = 2;
+        $_rs = (new PromotiondomainModel())->addData($_data);
+        if ($_rs) {
+            $this->adminSuccess('添加成功');
+        } else {
+            $this->adminError('添加失败!');
+        }
+    }
+
+    /**
+     * 删除
+     */
+    public function delDomain() {
+        $_id = $this->request->param('id', 0);
+        if (empty($_id)) {
+            $this->error("参数错误!");
+            exit;
+        }
+        $_map = array();
+        $_map['id'] = $_id;
+        $_up = array();
+        $_up['delete_time'] = time();
+        $_up['update_time'] = $_up['delete_time'];
+        $_up['is_delete'] = 1;
+        $_rs = (new PromotiondomainModel())->updateData($_up, $_map);
+        if ($_rs) {
+            $this->adminSuccess("删除成功");
+        } else {
+            $this->adminError("删除失败");
+        }
+    }
+
+    /**
+     *修改
+     */
+    public function editDomain() {
+        $_id = $this->request->param('set_id/d', 0);
+        $_domain = $this->request->param('domain', '');
+        if (empty($_id)) {
+            $this->adminError('参数错误!');
+        }
+        if (empty($_domain)) {
+            $this->adminError('请输入域名!');
+        }
+        $_map = array();
+        $_map['id'] = $_id;
+        $checkExpressions = '|^http://|';
+        $httpsExpressions = '|^https://|';
+        if (false == preg_match($checkExpressions, $_domain) && false == preg_match($httpsExpressions, $_domain)) {
+            $this->adminError('请输入正确的回调地址,以http://或者https://开头!');
+        }
+        $_data = array();
+        $_data['domain'] = $_domain;
+        $_data['update_time'] = time();
+        $_rs = (new PromotiondomainModel())->updateData($_data, $_map);
+        if ($_rs) {
+            $this->adminSuccess("修改成功");
+        } else {
+            $this->adminError("修改失败!");
+        }
+    }
+}

+ 132 - 0
admin/admin/controller/distribution/PromotionWhitelistController.php

@@ -0,0 +1,132 @@
+<?php
+/**
+ * 渠道分发中分发平台管理
+ * PromotionWhitelistController.php UTF-8
+ *
+ *
+ * @date    : 2018/5/31 23:15
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : ouzhongfu <ozf@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\distribution;
+
+use huo\model\distribution\PlatformModel;
+use huo\model\distribution\PromotionwhitelistModel;
+use cmf\view\Filter;
+
+class PromotionWhitelistController extends BaseController {
+    protected $platform;
+
+    function _initialize() {
+        parent::_initialize();
+    }
+
+    function whitelist() {
+        $_id = $this->request->param('id/d', 0);
+        $_offset = $this->request->param('offset/d', 20);
+        if (empty($_id)) {
+            $this->adminError('参数错误');
+            exit;
+        }
+        $_map = array();
+        $_map['is_delete'] = 2;
+        $_map['platform_id'] = $_id;
+        $_data_list = (new PromotionwhitelistModel())
+            ->where($_map)
+            ->order('id desc')
+            ->paginate($_offset);
+        $this->genWlistStatus();
+        $_data = array();
+        if (!empty($_data_list)) {
+            $_data_arr = $_data_list->toArray();
+            if (!empty($_data_arr)) {
+                $_data = isset($_data_arr['data']) ? $_data_arr['data'] : array();
+            }
+        }
+        $this->assign('platform_id', $_id);
+        $this->assign('Page', $_data_list->render());
+        $this->assign('data', $_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 获取白名单状态列表
+     */
+    public function genWlistStatus() {
+        $_data = [
+            '1' => '未联调',
+            '2' => '联调中'
+        ];
+        $this->assign('wlist_status', $_data);
+    }
+
+    /**
+     *添加白名单
+     */
+    public function addWhilelist() {
+        $_device_id = $this->request->param('device_id', ''); //I('device_id', '');
+        $_platform_id = $this->request->param('platform_id', '');
+        if (empty($_device_id) || empty($_platform_id)) {
+            $this->adminError('参数错误!');
+        }
+        $_map['device_id'] = $_device_id;
+        $_map['platform_id'] = $_platform_id;
+        $_map['is_delete'] = 2;
+        $_check = (new PromotionwhitelistModel())->where($_map)->find();
+        if (!empty($_check)) {
+            $this->adminSuccess('添加成功!');
+        }
+        $_data['device_id'] = $_device_id;
+        $_data['platform_id'] = $_platform_id;
+        $_data['create_time'] = time();
+        $_data['update_time'] = $_data['create_time'];
+        $_data['status'] = 1;
+        $_rs = (new PromotionwhitelistModel())->addData($_data);
+        if ($_rs) {
+            $this->adminSuccess('添加成功!');
+        } else {
+            $this->adminError('添加失败!');
+        }
+    }
+
+    public function delWlist() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError('参数错误!');
+        }
+        $_map = array();
+        $_map['id'] = $_id;
+        $_up = array();
+        $_up['is_delete'] = 1;
+        $_up['delete_time'] = time();
+        $_rs = (new PromotionwhitelistModel())->updateData($_up, $_map);
+        if ($_rs) {
+            $this->success("删除成功");
+        } else {
+            $this->error("删除失败");
+        }
+    }
+
+    public function setTest() {
+        $_id = $this->request->param('id/d', 0);
+        $_status = $this->request->param('status/d', 0);
+        if (empty($_id)) {
+            $this->adminError('参数错误!');
+        }
+        $_map = array();
+        $_map['id'] = $_id;
+        $_data = array();
+        $_data['status'] = $_status;
+        $_data['update_time'] = time();
+        $_rs = (new PromotionwhitelistModel())->updateData($_data, $_map);
+        if ($_rs) {
+            $this->success("设定成功!");
+        } else {
+            $this->adminError('设定失败!');
+        }
+    }
+}

+ 50 - 0
admin/admin/controller/feedback/FeedbackController.php

@@ -0,0 +1,50 @@
+<?php
+/**
+ * FeedbackController.php UTF-8
+ * 意见反馈
+ *
+ * @date    : 2018/2/8 16:43
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : linjiebin <ljb@huosdk.com>
+ * @version : HUOSDK 7.2
+ */
+
+namespace admin\admin\controller\feedback;
+
+use cmf\controller\AdminBaseController;
+use huo\model\member\MemProblemModel;
+use think\Lang;
+
+class FeedbackController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_feedback'.EXT
+        );
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    public function index() {
+        $_param = $this->request->param();
+        $_list_rows = $this->request->param('list_rows', 10);
+        $_m = new MemProblemModel();
+        $_data = $_m->getProblem($_param, $_list_rows);
+        $_data->appends($_param);
+        $this->assign($_param);
+        $this->assign('data', $_data->items());
+        $this->assign('page', $_data->render());
+
+        return $this->fetch();
+    }
+
+    public function set_status() {
+        $_data = $this->request->param();
+        $_ids = $_data['ids'];
+        $_status = get_val($_data, 'status', 2);
+        $_m = new MemProblemModel();
+        $_m->editStatus($_ids, $_status);
+        $this->adminSuccess(lang('SAVE_SUCCESS'));
+    }
+}
+

+ 516 - 0
admin/admin/controller/financial/AgentController.php

@@ -0,0 +1,516 @@
+<?php
+/**
+ * AgentController.php UTF-8
+ * 渠道财务
+ *
+ * @date    : 2018/5/22 14:01
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : linjiebin <ljb@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\financial;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\agent\Agent;
+use huo\controller\finance\Settle;
+use huo\logic\agent\AgentListLogic;
+use huo\logic\finance\AgentOrderLogic;
+use huo\logic\finance\SettleHistoryLogic;
+use huo\logic\finance\SettleLogic;
+use huo\model\user\RoleModel;
+use huolib\constant\AgentConst;
+use huolib\constant\PaywayConst;
+use huolib\constant\SettleConst;
+use huolib\status\CommonStatus;
+use huolib\tool\Export;
+use think\Lang;
+
+class AgentController extends AdminBaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin'.EXT);
+    }
+
+    /**
+     * 渠道余额
+     * admin/financial.agent/remain
+     *
+     * @return mixed
+     */
+    public function remain() {
+        /* 搜索列表 */
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        $this->_agents($_param['agent_id'], false, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true);
+        $_roles = (new RoleModel())->getIdNames([], true);
+        $this->assign('roles', $_roles);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_data = (new AgentListLogic())->getRemainList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('financial/agent/remain');
+    }
+
+    /**
+     * 渠道收益
+     * admin/financial.agent/incomeIndex
+     *
+     * @return mixed
+     */
+    public function incomeIndex() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIncome();
+        }
+        $_agent_detail = $this->request->param('detail/d', 0);
+        if (1 == $_agent_detail) {
+            $_agent_id = $this->request->param('id/d', 0);
+            $_parent_id = 0;
+            $_role_type = (new Agent())->getRoleType($_agent_id);
+            if (AgentConst::isGroup($_role_type)) {
+                $_parent_id = $_agent_id;
+                $_agent_id = 0;
+                $this->income($_agent_id, $_parent_id);
+
+                return $this->fetch('financial/agent/income_parent');
+            }
+            $this->income($_agent_id, $_parent_id);
+
+            return $this->fetch('financial/agent/income_agent');
+        } else {
+            $this->income();
+
+            return $this->fetch('financial/agent/income');
+        }
+    }
+
+    private function income($agent_id = 0, $parent_id = 0) {
+        if ($this->isAgent()) {
+            $agent_id = $this->admin_id;
+        }
+        $_param['agent_id'] = $this->request->param('agent_id/d', $agent_id);
+        $this->_agents($_param['agent_id'], false, [AgentConst::ROLE_TYPE_AGENT], true);
+        $_param['parent_id'] = $this->request->param('parent_id/d', $parent_id);
+        $this->_agents($_param['parent_id'], false, [AgentConst::ROLE_TYPE_GROUP], true);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_param['order_id'] = $this->request->param('order_id/s', '');
+        $_order_text = Filter::text('order_id', $_param['order_id'], '请输入订单号');
+        $this->assign('order_text', $_order_text);
+        $_param['username'] = $this->request->param('username/s', '');
+        $_username_text = Filter::text('username', $_param['username'], '请输入玩家账号');
+        $this->assign('username_text', $_username_text);
+        $_ma = $this->request->param('ma/s', '');
+        $this->_memAgents($_ma);
+        if (AgentConst::IS_AGENT == $_ma) {
+            $_param['from_id'] = ['gt', 0];
+        } elseif (AgentConst::IS_AGENT == $_ma || !empty($_param['username'])) {
+            $_param['from_id'] = 0;
+        }
+        /*平台币、游戏币支付的不显示*/
+        $_param['pay_ignore'] = ['not in', [PaywayConst::PAYWAY_GAMEPAY, PaywayConst::PAYWAY_PTBPAY]];
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_data = (new AgentOrderLogic())->getIncomeList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('sum', $_data['sum']);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+    }
+
+    /**
+     * 渠道收益明细导出数据
+     *
+     */
+    public function exportIncome() {
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        $_param['parent_id'] = $this->request->param('parent_id/d', 0);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $_param['order_id'] = $this->request->param('order_id/s', '');
+        $_param['username'] = $this->request->param('username/s', '');
+        $_ma = $this->request->param('ma/s', '');
+        $_mas = $this->_memAgents($_ma);
+        if (AgentConst::IS_AGENT == $_ma) {
+            $_param['from_id'] = ['gt', 0];
+        } elseif (AgentConst::IS_AGENT == $_ma || !empty($_param['username'])) {
+            $_param['from_id'] = 0;
+        }
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new AgentOrderLogic())->getIncomeList($_param, $_page);
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+//            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '渠道收益明细';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '时间',
+                '订单',
+                '玩家账号',
+                '游戏',
+                '来源',
+                '来源渠道',
+                '支付金额',
+                '实付金额',
+                '二级渠道',
+                '二级收益',
+                '一级渠道',
+                '一级收益'
+            ];
+            $_export_datas = [];
+            if (1 == $_p) {
+                $_total = [
+                    '汇总',
+                    '--',
+                    '--',
+                    '--',
+                    '--',
+                    '--',
+                    $_data['sum']['amount'],
+                    $_data['sum']['real_amount'],
+                    '--',
+                    $_data['sum']['agent_gain'],
+                    '--',
+                    $_data['sum']['parent_gain'],
+                ];
+                $_export_datas[] = $_total;
+            }
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['username'] = $_val['username'];
+                $_export_data['gamename'] = $_val['gamename'];
+                if ($_val['from_id'] > 0) {
+                    $_export_data['from'] = $_mas[AgentConst::IS_AGENT];
+                } else {
+                    $_export_data['from'] = $_mas[AgentConst::IS_MEMBER];
+                }
+                $_export_data['from_name'] = $_val['from_name'];
+                $_export_data['amount'] = $_val['amount'];
+                $_export_data['real_amount'] = $_val['real_amount'];
+                $_export_data['agent_name'] = $_val['agent_name'];
+                $_export_data['agent_gain'] = $_val['agent_gain'];
+                $_export_data['parent_name'] = $_val['parent_name'];
+                $_export_data['parent_gain'] = $_val['parent_gain'];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new AgentOrderLogic())->getIncomeList($_param, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 玩家渠道来源选择器
+     *
+     * @param string $ma
+     *
+     * @return array
+     */
+    public function _memAgents($ma) {
+        $_mas = AgentConst::getMemAgents();
+        $this->assign('mas', $_mas);
+        $_mas_select = Filter::selectCommon($_mas, 'ma', $ma);
+        $this->assign('mas_select', $_mas_select);
+
+        return $_mas;
+    }
+
+    /**
+     * 提现运营审核
+     * admin/financial.agent/opCheck
+     *
+     * @return mixed
+     */
+    public function opCheck() {
+        $_status = SettleConst::SETTLE_STATUS_OP_CHECK;
+        $this->getSettleList($_status);
+
+        return $this->fetch('financial/agent/opcheck');
+    }
+
+    /**
+     * 渠道平台币收入记录导出数据
+     *
+     * @param array $status
+     */
+    public function exportWithdraw($status) {
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-3 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $_param['type'] = $this->request->param('type/s', '');
+        $_types = $this->_settle_type($_param['type']);
+        $_param['banknum'] = $this->request->param('banknum/s', '');
+        $_param['cardholder'] = $this->request->param('cardholder/s', '');
+        $_param['status'] = $status;
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new SettleLogic())->getSettleList(0, $_param, $_page);
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '渠道提现记录';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '申请时间',
+                '单号',
+                '渠道',
+                '提现金额',
+                '提现方式',
+                '提现人',
+                '账号(卡号)',
+                '开户行',
+                '开户支行'
+            ];
+            $_export_datas = [];
+            if (1 == $_p) {
+                $_total = [
+                    '汇总',
+                    '--',
+                    '--',
+                    $_data['sum']['amount'],
+                    '--',
+                    '--',
+                    '--',
+                    '--',
+                    '--'
+                ];
+                $_export_datas[] = $_total;
+            }
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['id'] = $_val['id'];
+                $_export_data['agent_name'] = $_val['agent_name'];
+                $_export_data['types'] = $_types[$_val['type']];
+                $_export_data['cardholder'] = $_val['cardholder'];
+                $_export_data['banknum'] = $_val['banknum'];
+                if ('bank' == $_val['type']) {
+                    $_export_data['bankname'] = $_val['bankname'];
+                    $_export_data['branchname'] = $_val['branchname'];
+                } else {
+                    $_export_data['bankname'] = '--';
+                    $_export_data['branchname'] = '--';
+                }
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new SettleLogic())->getSettleList(0, $_param, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 获取提现列表
+     *
+     * @param $status
+     */
+    public function getSettleList($status) {
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        $this->_agents($_param['agent_id'], false, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-3 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_param['type'] = $this->request->param('type/s', '');
+        $this->_settle_type($_param['type']);
+        $_param['banknum'] = $this->request->param('banknum/s', '');
+        $_banknum_text = Filter::text('banknum', $_param['banknum'], '请输入账号(卡号)');
+        $this->assign('banknum_text', $_banknum_text);
+        $_param['cardholder'] = $this->request->param('cardholder/s', '');
+        $_cardholder_text = Filter::text('cardholder', $_param['cardholder'], '请输入提现人');
+        $this->assign('cardholder_text', $_cardholder_text);
+        $_param['status'] = $status;
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_data = (new SettleLogic())->getSettleList(0, $_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('sum', $_data['sum']);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+    }
+
+    /**
+     * 提现类型选择器
+     *
+     * @param $type
+     *
+     * @return array
+     */
+    public function _settle_type($type) {
+        $_types = SettleConst::getTypes();
+        $this->assign('types', $_types);
+        $_types_select = Filter::selectCommon($_types, 'type', $type);
+        $this->assign('types_select', $_types_select);
+
+        return $_types;
+    }
+
+    /**
+     * 提现财务审核
+     * admin/financial.agent/finCheck
+     *
+     * @return mixed
+     */
+    public function finCheck() {
+        $_status = SettleConst::SETTLE_STATUS_FIN_CHECK;
+        $this->getSettleList($_status);
+
+        return $this->fetch('financial/agent/fincheck');
+    }
+
+    /**
+     * 提现记录
+     * admin/financial.agent/finCheck
+     *
+     * @return mixed
+     */
+    public function withdrawIndex() {
+        $_status = $this->request->param('status/d', SettleConst::SETTLE_STATUS_OK);
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportWithdraw($_status);
+        }
+        $this->_settle_status($_status);
+        $this->getSettleList($_status);
+
+        return $this->fetch('financial/agent/withdraw_index');
+    }
+
+    /**
+     * 提现状态选择器
+     *
+     * @param int $status
+     *
+     * @return array
+     */
+    public function _settle_status($status) {
+        $_statuses = SettleConst::getStatuses();
+        $this->assign('statuses', $_statuses);
+        $_statuses_select = Filter::selectCommon($_statuses, 'status', $status);
+        $this->assign('statuses_select', $_statuses_select);
+
+        return $_statuses;
+    }
+
+    /**
+     * 审核详情
+     * admin/financial.agent/edit
+     */
+    public function edit() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = (new SettleLogic())->getDetail($_id);
+        $this->assign('data', $_data);
+        $this->_settle_type(0);
+
+        return $this->fetch('financial/agent/edit');
+    }
+
+    /**
+     * 提现详情
+     *
+     * @return mixed
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function detail() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->_settle_type(0);
+        $_data = (new SettleLogic())->getDetail($_id);
+        $this->assign('data', $_data);
+        /*审核记录*/
+        $_map = ['s_id' => $_data['id']];
+        $_history = (new SettleHistoryLogic())->getList($_map);
+        $this->assign('history', $_history);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 设置提现状态
+     * admin/financial.agent/setStatus
+     */
+    public function setStatus() {
+        $_id = $this->request->param('id/d', 0);
+        $_status = $this->request->param('status/d', 0);
+        $_content = $this->request->param('content/s', '');
+        if (empty($_status)) {
+            $this->adminError('请审核');
+        }
+        if (empty($_id) || empty($_status) || $_status < 1 || $_status > 2) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = (new SettleLogic())->getDetail($_id);
+        switch ($_data['status']) {
+            case SettleConst::SETTLE_STATUS_OP_CHECK:
+                if (1 == $_status) {
+                    /* 运营审核不通过 */
+                    $_status = SettleConst::SETTLE_STATUS_OP_NO;
+                } elseif (2 == $_status) {
+                    /* 运营审核通过 */
+                    $_status = SettleConst::SETTLE_STATUS_FIN_CHECK;
+                }
+                break;
+            case SettleConst::SETTLE_STATUS_FIN_CHECK:
+                if (1 == $_status) {
+                    /* 财务审核不通过 */
+                    $_status = SettleConst::SETTLE_STATUS_FIN_NO;
+                } elseif (2 == $_status) {
+                    /* 财务审核通过 */
+                    $_status = SettleConst::SETTLE_STATUS_OK;
+                }
+                break;
+            default:
+                $this->adminError(lang('param error'));
+        }
+        $_rs = (new Settle())->setStatus($this->admin_id, $_id, $_status, $_content);
+        if (CommonStatus::NO_ERROR != $_rs['code']) {
+            $this->adminError($_rs['msg']);
+        }
+        $this->adminSuccess('设置成功');
+    }
+}

+ 129 - 0
admin/admin/controller/financial/AgentCpaLogController.php

@@ -0,0 +1,129 @@
+<?php
+/**
+ * AgentCpaLogController.php  UTF-8
+ * 渠道CPA记录
+ *
+ * @date    : 2020/3/7 18:22
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOOA 1.0
+ */
+
+namespace admin\admin\controller\financial;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\logic\agent\AgentCpaLogLogic;
+use huolib\constant\AgentConst;
+use huolib\tool\Export;
+
+class AgentCpaLogController extends AdminBaseController {
+    public function _initialize() {
+        parent::_initialize();
+    }
+
+    /**
+     * 列表
+     */
+    public function index() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->export();
+        }
+        $_param = $this->getSearchParam();
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_data = (new AgentCpaLogLogic())->getAdminList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('index');
+    }
+
+    /**
+     * 导出数据
+     *
+     */
+    public function export() {
+        $_param = $this->getSearchParam();
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new AgentCpaLogLogic())->getAdminList($_param, $_page);
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '渠道CPA明细';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '时间',
+                '记录号',
+                '玩家账号',
+                '注册IP',
+                '游戏',
+                '二级渠道',
+                '二级CPA',
+                '一级渠道',
+                '一级CPA'
+            ];
+            $_export_datas = [];
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['username'] = $_val['username'];
+                $_export_data['ip'] = $_val['ip'];
+                $_export_data['game_name'] = $_val['game_name'];
+                $_export_data['agent_name'] = $_val['agent_name'];
+                $_export_data['agent_cpa'] = $_val['agent_cpa'];
+                $_export_data['parent_name'] = $_val['parent_name'];
+                $_export_data['parent_cpa'] = $_val['parent_cpa'];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new AgentCpaLogLogic())->getAdminList($_param, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 获取请求参数
+     */
+    public function getSearchParam() {
+        $_param = [];
+        $agent_id = 0;
+        if ($this->isAgent()) {
+            $agent_id = $this->admin_id;
+        }
+        $_param['agent_id'] = $this->request->param('agent_id/d', $agent_id);
+        $this->_agents($_param['agent_id'], false, [AgentConst::ROLE_TYPE_AGENT], true);
+        $_param['parent_id'] = $this->request->param('parent_id/d', 0);
+        $this->_agents($_param['parent_id'], false, [AgentConst::ROLE_TYPE_GROUP], true);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_param['order_id'] = $this->request->param('order_id/s', '');
+        $_order_text = Filter::text('order_id', $_param['order_id'], '请输入订单号');
+        $this->assign('order_text', $_order_text);
+        $_param['username'] = $this->request->param('username/s', '');
+        $_username_text = Filter::text('username', $_param['username'], '请输入玩家账号');
+        $this->assign('username_text', $_username_text);
+
+        return $_param;
+    }
+}

+ 521 - 0
admin/admin/controller/financial/GamemoneyController.php

@@ -0,0 +1,521 @@
+<?php
+/**
+ * GmController.php UTF-8
+ *
+ *
+ * @date    : 2018/6/5 16:23
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\financial;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\member\MemWallet;
+use huo\controller\wallet\GmCache;
+use huo\logic\finance\GmBackLogic;
+use huo\logic\finance\GmChargeLogic;
+use huo\logic\finance\GmMemLogic;
+use huo\logic\finance\GmOrderLogic;
+use huo\logic\finance\PtbOrderLogic;
+use huo\model\finance\PtbBackModel;
+use huolib\constant\OrderConst;
+use huolib\constant\WalletConst;
+use huolib\status\MemberStatus;
+use huolib\tool\Export;
+use think\Lang;
+
+class GamemoneyController extends AdminBaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_ptb'.EXT);
+    }
+
+    /**
+     * 玩家游戏币收入记录导出数据
+     *
+     * @param array $map
+     */
+    public function exportPlayer($map = []) {
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new GmChargeLogic())->getIncomeList($map, $_page);
+        $agents = $this->_agents(0, true, [3, 4], true);
+        $wallet_froms = $this->_walletForms();
+        $pay_statuss = $this->_payStatuss();
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+//            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '玩家游戏币收入记录';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '时间',
+                '玩家账号',
+                '归属渠道',
+                '订单号',
+                '充值数量',
+                '充值方式',
+                '实际支付金额',
+                '状态'
+            ];
+            $_export_datas = [];
+            if (1 == $_p) {
+                $_total = [
+                    '汇总',
+                    '',
+                    '',
+                    '',
+                    $_data['sum']['sum_gm_cnt'],
+                    '',
+                    $_data['sum']['sum_real_amount'],
+                    ''
+                ];
+                $_export_datas[] = $_total;
+            }
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['agent'] = $_val['mem']['username'].'|'.$_val['mem']['nickname'];
+                $_export_data['agents'] = isset($agents[$_val['mem']['agent_id']]) ? $agents[$_val['mem']['agent_id']]
+                    : '官方渠道';
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['gm_cnt'] = $_val['gm_cnt'];
+                $_export_data['type'] = $wallet_froms[$_val['type']];
+                $_export_data['real_amount'] = $_val['real_amount'];
+                $_export_data['status'] = $pay_statuss[$_val['status']];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new GmChargeLogic())->getIncomeList($map, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 玩家平台币消费记录导出数据
+     *
+     * @param array $map
+     */
+    public function exportPlayerCost($map = []) {
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new GmOrderLogic())->getCostList($map, $_page);
+        $_agents = $this->_agents(0, true, [3, 4], true);
+        $_pay_statuss = $this->_payStatuss();
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+//            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '玩家游戏币消费记录';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '时间',
+                '玩家账号',
+                '归属渠道',
+                '订单号',
+                '消费数量',
+                '充值游戏',
+                '状态'
+            ];
+            $_export_datas = [];
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['agent'] = $_val['mem']['username'].'|'.$_val['mem']['nickname'];
+                $_export_data['agents'] = isset($_agents[$_val['mem']['agent_id']]) ? $_agents[$_val['mem']['agent_id']]
+                    : '官方渠道';
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['gm_cnt'] = $_val['gm_cnt'];
+                $_export_data['game'] = $_val['game']['name'];
+                $_export_data['status'] = $_pay_statuss[$_val['status']];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new PtbOrderLogic())->getCostList($map, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 玩家币收入记录
+     *
+     * @return mixed
+     */
+    public function index() {
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_username = $this->request->param('username', '');
+        $_order_id = $this->request->param('order_id');
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        $_from = $this->request->param('from/d');
+        $_status = $this->request->param('status/d');
+        $_start_time = $this->request->param('start_time');
+        $_end_time = $this->request->param('end_time');
+        $_map = [];
+        !empty($_username) && $_map['username'] = $_username;
+        !empty($_agent_id) && $_map['agent_id'] = $_agent_id;
+        !empty($_order_id) && $_map['order_id'] = $_order_id;
+        !empty($_from) && $_map['type'] = $_from;
+        !empty($_status) && $_map['status'] = $_status;
+        !empty($_start_time) && $_map['start_time'] = $_start_time;
+        !empty($_end_time) && $_map['end_time'] = $_end_time;
+        $this->_incomeFilterSelect($_agent_id, $_from, $_status);
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportPlayer($_map);
+        }
+        $template = 'player_income_index';
+        $_data = (new GmChargeLogic())->getIncomeList($_map, $_page.','.$_list_rows);
+        $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('username', $_username);
+        $this->assign('sum', $_data['sum']);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch($template);
+    }
+
+    /**
+     * 游戏币币消费记录
+     *
+     * @return mixed
+     */
+    public function costIndex() {
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_order_id = $this->request->param('order_id', '');
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        $_username = $this->request->param('username', '');
+        $_status = $this->request->param('status/d');
+        $_start_time = $this->request->param('start_time');
+        $_end_time = $this->request->param('end_time');
+        $_map = [];
+        !empty($_agent_id) && $_map['agent_id'] = $_agent_id;
+        !empty($_order_id) && $_map['order_id'] = $_order_id;
+        !empty($_username) && $_map['username'] = $_username;
+        !empty($_status) && $_map['status'] = $_status;
+        !empty($_start_time) && $_map['start_time'] = $_start_time;
+        !empty($_end_time) && $_map['end_time'] = $_end_time;
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportPlayerCost($_map);
+        }
+        $template = 'player_cost_index';
+        $this->_playerCostFilterSelect($_agent_id, $_status);
+        $_data = (new GmOrderLogic())->getCostList($_map, $_page.','.$_list_rows);
+        $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('start_time', $_start_time);
+        $this->assign('end_time', $_end_time);
+        $this->assign('username', $_username);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch($template);
+    }
+
+    /**
+     * 游戏币发放管理
+     *
+     * @return mixed
+     */
+    public function gainIndex() {
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_username = $this->request->param('username', '');
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_map = [];
+        !empty($_username) && $_map['username'] = $_username;
+        !empty($_app_id) && $_map['app_id'] = $_app_id;
+        $_map['type'] = WalletConst::WALLET_FROM_GIVE;
+        $this->_gainFilterSelect($_app_id);
+        $template = 'player_gain_index';
+        $_data = (new GmMemLogic())->getMemList($_map, $_page.','.$_list_rows);
+        $items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('username', $_username);
+        $this->assign('items', $items->items());
+        $this->assign('page', $items->render());
+
+        return $this->fetch($template);
+    }
+
+    /**
+     * 游戏币扣除管理
+     *
+     * @return mixed
+     */
+    public function deductIndex() {
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_order_id = $this->request->param('order_id', '');
+        $_app_id = $this->request->param('app_id', 0);
+        $_username = $this->request->param('username', '');
+        $_start_time = $this->request->param('start_time');
+        $_end_time = $this->request->param('end_time');
+        $_map = [];
+        !empty($_username) && $_map['username'] = $_username;
+        !empty($_app_id) && $_map['app_id'] = $_app_id;
+        !empty($_order_id) && $_map['back_order_id'] = $_order_id;
+        !empty($_start_time) && $_map['start_time'] = $_start_time;
+        !empty($_end_time) && $_map['end_time'] = $_end_time;
+        $this->_deductFilterSelect($_app_id);
+        $template = 'player_deduct_index';
+        $_map['user_type'] = PtbBackModel::USER_TYPE_MEM;
+        $_data = (new GmBackLogic())->getBackList($_map, $_page.','.$_list_rows);
+        $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('start_time', $_start_time);
+        $this->assign('end_time', $_end_time);
+        $this->assign('username', $_username);
+        $this->assign('sum', $_data['sum']);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch($template);
+    }
+
+    /**
+     * 给玩家发放游戏币页面
+     *
+     * @return mixed
+     */
+    public function playerGain() {
+        $_mem_id = $this->request->param('mem_id');
+        $_app_id = $this->request->param('app_id');
+        if (empty($_mem_id) || empty($_app_id)) {
+            return $this->adminError('非法请求');
+        }
+        $this->assign('mem_id', $_mem_id);
+        $this->assign('app_id', $_app_id);
+
+        return $this->fetch('player_gain');
+    }
+
+    /**
+     * 给玩家发放游戏币
+     */
+    public function doPlayerGain() {
+        $_param = $this->request->param();
+        $_result = $this->validate($_param, 'Gain.gm');
+        if (true !== $_result) {
+            return $this->adminError($_result);
+        }
+        $_mem_id = $this->request->param('mem_id');
+        $_app_id = $this->request->param('app_id');
+        $_gm_cnt = $this->request->param('gm_cnt');
+        $_remark = $this->request->param('remark');
+        $this->verifyPayPwd();
+        $_rs = (new MemWallet())->gainMemGm($_mem_id, $_app_id, $_gm_cnt, $_remark);
+        if ($this->hasError($_rs)) {
+            return $this->adminError($_rs['msg']);
+        }
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 扣除玩家游戏币页面
+     *
+     * @return mixed
+     */
+    public function playerDeduct() {
+        $_mem_id = $this->request->param('mem_id');
+        $_app_id = $this->request->param('app_id');
+        if (empty($_mem_id) || empty($_app_id)) {
+            return $this->adminError('非法请求');
+        }
+        $this->assign('mem_id', $_mem_id);
+        $this->assign('app_id', $_app_id);
+
+        return $this->fetch('player_deduct');
+    }
+
+    /**
+     * 扣除玩家游戏币
+     */
+    public function doPlayerDeduct() {
+        $_param = $this->request->param();
+        $_result = $this->validate($_param, 'Deduct.gm');
+        if (true !== $_result) {
+            return $this->adminError($_result);
+        }
+        $_mem_id = $this->request->param('mem_id');
+        $_app_id = $this->request->param('app_id');
+        $_gm_cnt = $this->request->param('gm_cnt');
+        $_remark = $this->request->param('remark');
+        $this->verifyPayPwd();
+        $_rs = (new MemWallet())->deductMemGm($_mem_id, $_app_id, $_gm_cnt, $_gm_cnt, $_remark);
+        if ($this->hasError($_rs)) {
+            return $this->adminError($_rs['msg']);
+        }
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 扣除发放订单中的平台币页面
+     *
+     * @return mixed
+     */
+    public function orderDeduct() {
+        $_order_id = $this->request->param('order_id');
+        $this->assign('order_id', $_order_id);
+
+        return $this->fetch('order_deduct');
+    }
+
+    /**
+     * 扣除发放订单中的游戏币
+     */
+    public function doOrderDeduct() {
+        $_order_id = $this->request->param('order_id');
+        if (empty($_order_id)) {
+            $this->adminError('订单号不能为空');
+        }
+        $this->verifyPayPwd();
+        $_gm_charge = (new GmChargeLogic())->getDetailByOrderId($_order_id);
+        if (empty($_gm_charge)) {
+            $this->adminError('订单错误');
+        }
+        if (WalletConst::WALLET_FROM_GIVE !== $_gm_charge->type) {
+            $this->adminError('只有后台发放的订单才能扣除');
+        }
+        if ($_gm_charge->back_status !== WalletConst::WALLET_BACK_STATUS_NO) {
+            $this->adminError('当前订单已经扣除过了,请勿重复扣除');
+        }
+        //查询玩家的当前游戏币余额
+        $_gmc_class = GmCache::ins();
+        $_gm_data = $_gmc_class->getInfoByMemGame($_gm_charge->mem_id, $_gm_charge->app_id);
+        if (empty($_gm_data)) {
+            $_code = MemberStatus::UID_INVALID;
+
+            return $this->adminError($_code, MemberStatus::getMsg($_code));
+        }
+        //标记扣回过
+        $_gm_charge->back_status = WalletConst::WALLET_BACK_STATUS_ALL;
+        //需扣回的游戏币数量
+        $_deduct_gm_cnt = $_gm_charge->gm_cnt;
+        if ($_gm_data['remain'] < $_gm_charge->gm_cnt) {
+            $_deduct_gm_cnt = $_gm_data['remain'];
+            $_gm_charge->back_status = WalletConst::WALLET_BACK_STATUS_PART;
+        }
+        $_mem_id = $_gm_charge->mem_id;
+        $_app_id = $_gm_charge->app_id;
+        $order_gm_cnt = $_gm_charge->gm_cnt;
+        $_gm_cnt = $_deduct_gm_cnt;
+        $_remark = '从发放订单中扣除游戏币';
+        $order_id = $_gm_charge->order_id;
+        $_rs = (new MemWallet())->deductMemGm($_mem_id, $_app_id, $order_gm_cnt, $_gm_cnt, $_remark, $order_id);
+        if ($this->hasError($_rs)) {
+            return $this->adminError($_rs['msg']);
+        }
+        $_gm_charge->save();
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 来源
+     *
+     * @param $from
+     */
+    protected function _walletForms($from = 0) {
+        $_wallet_froms = WalletConst::getFroms();
+        $_wallet_froms_select = Filter::selectCommon($_wallet_froms, 'from', $from);
+        $this->assign('wallet_froms', $_wallet_froms);
+        $this->assign('wallet_froms_select', $_wallet_froms_select);
+
+        return $_wallet_froms;
+    }
+
+    /**
+     * 支付状态
+     *
+     * @param $status
+     *
+     * @return array|bool|mixed
+     */
+    protected function _payStatuss($status = 0) {
+        $_pay_statuss = OrderConst::getPayStatuss();
+        $_pay_statuss_select = Filter::selectCommon($_pay_statuss, 'status', $status);
+        $this->assign('pay_statuss', $_pay_statuss);
+        $this->assign('pay_statuss_select', $_pay_statuss_select);
+
+        return $_pay_statuss;
+    }
+
+    /**
+     * 收入记录选项
+     *
+     * @param int $agent_id
+     * @param int $from
+     * @param int $status
+     */
+    protected function _incomeFilterSelect($agent_id = 0, $from = 0, $status = 0) {
+        $this->_agents($agent_id, true, [3, 4], true);
+        $this->_walletForms($from);
+        $this->_payStatuss($status);
+        $this->_time();
+    }
+
+    /**
+     * 玩家消费记录选项
+     *
+     * @param int $agent_id
+     * @param int $status
+     */
+    protected function _playerCostFilterSelect($agent_id = 0, $status = 0) {
+        $this->_agents($agent_id, true, [3, 4], true);
+        $this->_time();
+        $this->_payStatuss($status);
+    }
+
+    /**
+     * 游戏币发放选项
+     *
+     * @param int $app_id
+     */
+    protected function _gainFilterSelect($app_id = 0) {
+        $this->_games($app_id);
+    }
+
+    /**
+     * 游戏币扣除选项
+     *
+     * @param int $app_id
+     */
+    protected function _deductFilterSelect($app_id = 0) {
+        $this->_games($app_id);
+        $this->_time();
+    }
+}

+ 488 - 0
admin/admin/controller/financial/OrderController.php

@@ -0,0 +1,488 @@
+<?php
+/**
+ * OrderController.php  UTF-8
+ * 游戏订单管理类
+ *
+ * @date    : 2018/5/11 10:51
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\financial;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\member\MemCache;
+use huo\controller\pay\Notify;
+use huo\controller\pay\Order;
+use huo\controller\pay\SdkOrderCache;
+use huo\logic\agent\AgentLogic;
+use huo\logic\data\SwitchDayDataLogic;
+use huo\logic\order\AppleOrderLogic;
+use huo\logic\order\OrderLogic;
+use huo\model\conf\PaywayModel;
+use huo\model\game\GameModel;
+use huo\model\user\UserModel;
+use huolib\constant\AgentConst;
+use huolib\constant\OrderConst;
+use huolib\status\OrderStatus;
+use huolib\tool\Export;
+use huolib\tool\Page;
+use huoMpay\Payments;
+use think\Lang;
+
+class OrderController extends AdminbaseController {
+    protected $map       = ['agent_id' => 0];
+    protected $is_switch = OrderConst::PAY_SWITCH_NO;
+
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.'financial'.EXT
+        );
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+        $_is_agent = false;
+        if (AgentConst::ROLE_TYPE_PC == $this->role_type
+            || AgentConst::ROLE_TYPE_AGENT == $this->role_type) {
+            /* 查找拥有的渠道ID */
+            $_agent_ids = (new AgentLogic())->getAgentIds($this->admin_id, true);
+            if (!empty($_agent_ids)) {
+                $this->map['agent_id'] = $_agent_ids[0];
+                $_GET['agent_id'] = $_agent_ids[0];
+                $_is_agent = true;
+            }
+        }
+        $this->assign('is_agent', $_is_agent);
+    }
+
+    /***
+     *  订单状态
+     */
+    protected function _allStatus() {
+        $_all_status = array(
+            "1" => lang('pending'),
+            "2" => lang('pay success'),
+            "3" => lang('pay fail')
+        );
+        $this->assign("all_status", $_all_status);
+
+        return $_all_status;
+    }
+
+    /**
+     * 导出订单数据
+     *
+     * @param int $is_handle
+     * @param int $cp_status
+     */
+    public function exportIndex($is_handle = 0, $cp_status = 0) {
+        set_time_limit(0);
+        ini_set("memory_limit", "1024M");
+        $_param = $this->request->param();
+        $_param['is_handle'] = $is_handle;
+        $_param['order_id'] = $this->request->param('order_id/s', '');
+        $_param['cp_order_id'] = $this->request->param('cp_order_id/s', '');
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_param['username'] = $this->request->param('username/s', '');
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        $_param['os'] = $this->request->param('os/s', '');
+        $this->_getOs($_param['os']);
+        if (!empty($this->map['agent_id'])) {
+            $_param['agent_id'] = $this->map['agent_id'];
+        }
+        $_param['parent_id'] = $this->request->param('parent_id/d', 0);
+        $_param['payway'] = $this->request->param('payway/s', '');
+        if (empty($cp_status)) {
+            $_param['cp_status'] = $this->request->param('cp_status/d', 0);
+        } else {
+            $_param['cp_status'] = $cp_status;
+        }
+        if ($this->isAgent()) {
+            if ($this->role_type == AgentConst::AGENT_ROLE_MP_AGENT) {
+                $_param['agent_id'] = $this->admin_id;
+            } else {
+                $_agent_ids = (new AgentLogic())->getAgentIds($this->admin_id, true);
+                $_param['agent_id'] = ['in', $_agent_ids];
+            }
+        }
+        $_param['status'] = $this->request->param('status/d', 0);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $_param['is_switch'] = $this->is_switch;
+        $_cp_statuses = OrderConst::getCpStatuses();
+        $_pay_statuses = OrderConst::getPayStatuss();
+        $_payways = (new PaywayModel())->getPayWaysByPayName();
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new OrderLogic())->getOrderList($_param, $_page);
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+//            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '订单号',
+                'CP订单号',
+                '时间',
+                '账号',
+                '游戏',
+                '金额',
+                '实收金额',
+                '游戏区服',
+                '游戏角色',
+                '充值方式',
+                '归属渠道',
+                '支付状态',
+                '回调状态',
+            ];
+            $_export_datas = [];
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['cp_order_id'] = $_val['cp_order_id'];
+                $_export_data['create_time'] = date('Y-m-d H:i', $_val['create_time']);
+                $_export_data['username'] = $_val['username'];
+                $_export_data['gamename'] = $_val['gamename'];
+                $_export_data['amount'] = $_val['amount'];
+                $_export_data['real_amount'] = $_val['real_amount'];
+                $_export_data['server_name'] = $_val['leftpayext']['server_name'];
+                $_export_data['role_name'] = $_val['leftpayext']['role_name'];
+                $_export_data['payway'] = get_val($_payways, 'payway', $_val['payway']);
+                $_export_data['agent_name'] = $_val['agent_name'];
+                $_export_data['status'] = $_pay_statuses[$_val['status']];
+                $_export_data['cp_status'] = $_cp_statuses[$_val['cp_status']];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '游戏订单', '.csv', true);
+                break;
+            } else {
+                $_file_name = '游戏订单'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new OrderLogic())->getOrderList($_param, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '游戏订单');
+    }
+
+    /**
+     * 游戏订单列表
+     * admin/financial.order/index
+     *
+     */
+    public function index() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIndex();
+        }
+        $this->is_switch = $this->request->param('is_switch/d', 0);
+        $this->_paySwitch($this->is_switch);
+        $this->orderList();
+
+        return $this->fetch('financial/order/index');
+    }
+
+    /**
+     * 切量游戏订单列表
+     * admin/financial.order/isSwitch
+     *
+     */
+    public function isSwitch() {
+        $this->is_switch = OrderConst::PAY_SWITCH_YES;
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIndex();
+        }
+        $this->orderList();
+
+        return $this->fetch('financial/order/is_switch');
+    }
+
+    /**
+     * 补单列表
+     * admin/financial.order/repairIndex
+     */
+    public function repairIndex() {
+        $is_handle = OrderConst::ORDER_IS_HANDLE;
+        $_cp_status = $this->request->param('cp_status/d', OrderConst::CP_STATUS_FAIL);
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIndex($is_handle, $_cp_status);
+        }
+        $this->orderList($is_handle, $_cp_status);
+
+        return $this->fetch('financial/order/repairindex');
+    }
+
+    /**
+     *  订单列表
+     *
+     * @param int $is_handle
+     * @param int $cp_status
+     */
+    protected function orderList($is_handle = 0, $cp_status = 0) {
+        if (!empty($is_handle)) {
+            $_param['is_handle'] = $is_handle;
+        }
+        $_param['os'] = $this->request->param('os/s', '');
+        $this->_getOs($_param['os']);
+        $_param['order_id'] = $this->request->param('order_id/s', '');
+        $_order_text = Filter::text('order_id', $_param['order_id'], '请输入订单号');
+        $this->assign('order_input', $_order_text);
+        $_param['cp_order_id'] = $this->request->param('cp_order_id/s', '');
+        $_cp_order_text = Filter::text('cp_order_id', $_param['cp_order_id'], '请输入CP订单号');
+        $this->assign('cp_order_input', $_cp_order_text);
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $this->_games($_param['app_id']);
+        $_param['mem_id'] = $this->request->param('mem_id/d', '');
+        $_mem_id_text = Filter::text('mem_id', $_param['mem_id'], '请输入玩家ID');
+        $this->assign('mem_id_text', $_mem_id_text);
+        $_param['username'] = $this->request->param('username/s', '');
+        $_username_text = Filter::text('username', $_param['username'], '请输入玩家账号');
+        $this->assign('username_input', $_username_text);
+        $_param['role_name'] = $this->request->param('role_name/s', '');
+        $_role_name_text = Filter::text('role_name', $_param['role_name'], '请输入角色名称');
+        $this->assign('role_name_input', $_role_name_text);
+        $_param['status'] = $this->request->param('status/d', OrderConst::PAY_STATUS_SUC);
+        $_param['agent_id'] = $this->request->param('agent_id/d', $this->map['agent_id']);
+        if ($this->isAgent()) {
+            if ($this->role_type == AgentConst::AGENT_ROLE_MP_AGENT) {
+                $_param['agent_id'] = $this->admin_id;
+            } else {
+                $_agent_ids = (new AgentLogic())->getAgentIds($this->admin_id, true);
+                $_param['agent_id'] = ['in', $_agent_ids];
+            }
+            $_param['status'] = OrderConst::PAY_STATUS_SUC;
+        }
+        $this->_pay_statuses($_param['status']);
+        $this->_agents($_param['agent_id'], true, [3, 4], true);
+        $_param['parent_id'] = $this->request->param('parent_id/d', 0);
+        $this->_agents($_param['parent_id'], true, [3], true);
+        $_param['payway'] = $this->request->param('payway/s', '');
+        $this->_payways($_param['payway']);
+        if (empty($cp_status)) {
+            $_param['cp_status'] = $this->request->param('cp_status/d', 0);
+        } else {
+            $_param['cp_status'] = $cp_status;
+        }
+        $this->_cp_statuses($_param['cp_status']);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 week')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_param['is_switch'] = $this->is_switch;
+        if ($this->isAgent()) {
+            $_param['is_switch'] = OrderConst::PAY_SWITCH_NO;
+        }
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_data = (new OrderLogic())->getOrderList($_param, $_page.','.$_list_rows);
+        foreach ($_data['list'] as $_k => $_v) {
+            if (empty($_v['agent_name'])) {
+                $_data['list'][$_k]['agent_name'] = '官方渠道';
+            }
+        }
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('sum', $_data['sum']);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+    }
+
+    /**
+     * CP发货状态
+     *
+     * @param $cp_status
+     */
+    public function _cp_statuses($cp_status) {
+        $_cp_statuses = OrderConst::getCpStatuses();
+        $this->assign('cp_statuses', $_cp_statuses);
+        $this->assign('cp_statuses_select', Filter::selectCommon($_cp_statuses, 'cp_status', $cp_status));
+    }
+
+    /**
+     * CP发货状态
+     *
+     * @param $os
+     */
+    public function _getOs($os) {
+        $_array = [
+            'devtools' => '调试工具',
+            'android'  => 'android',
+            'ios'      => 'ios',
+            'windows'  => 'windows',
+        ];
+        $this->assign('os_select', Filter::selectCommon($_array, 'os', $os));
+    }
+
+    /**
+     *  订单详情
+     * admin/financial.order/detail
+     */
+    public function detail() {
+        $_order_id = $this->request->param('order_id/s', '');
+        if (empty($_order_id)) {
+            $this->error(lang('REQUEST_ERROR'));
+        }
+        $_order_data = SdkOrderCache::ins()->getInfoByOrderId($_order_id);
+        $_order_data['gamename'] = (new GameModel())->getNameById($_order_data['app_id']);
+        $_order_data['agent_name'] = (new UserModel())->getNameById($_order_data['agent_id']);
+        if (0 == $_order_data['agent_id']) {
+            $_order_data['agent_name'] = '官方渠道';
+        }
+        $this->_payways($_order_data['payway']);
+        $this->_cp_statuses($_order_data['cp_status']);
+        $this->_pay_statuses($_order_data['status']);
+        $this->assign('order', $_order_data);
+
+        $_cp_notify_log_data = (new Order())->getCpNotifyLogData($_order_id);
+        $this->assign('cp_notify_log_data', $_cp_notify_log_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 查单
+     */
+    public function query() {
+        $_order_id = $this->request->param('order_id/s', '');
+        if (empty($_order_id)) {
+            $this->error(lang('REQUEST_ERROR'));
+        }
+        $_order_data = SdkOrderCache::ins()->getInfoByOrderId($_order_id);
+        /* 未支付 查询米大师余额 并扣除米大师余额 */
+        if (OrderConst::PAY_STATUS_SUC != $_order_data['status']) {
+            $_rs = (new Payments())->getBalanceAndPay($_order_data['mem_id'], $_order_id);
+            if (OrderStatus::NO_ERROR != $_rs['code']) {
+                $this->adminError($_rs['msg'], $_rs['code']);
+            }
+            $this->adminSuccess('操作成功!');
+        }
+    }
+
+    /**
+     *  补单
+     * admin/financial.order/repair
+     */
+    public function repair() {
+        $_order_id = $this->request->param('order_id/s', '');
+        if (empty($_order_id)) {
+            $this->error(lang('REQUEST_ERROR'));
+        }
+        $_notify_class = new Notify();
+        $_rs = $_notify_class->notify($_order_id);
+        if (OrderStatus::NO_ERROR == $_rs['code']) {
+            $this->adminSuccess($_rs['msg']);
+        } else {
+            $this->adminError($_rs['msg']);
+        }
+    }
+
+    /***
+     *  苹果订单列表
+     *  admin/financial.order/apple
+     */
+    public function apple() {
+        $_param['order_id'] = $this->request->param('order_id/s', '');
+        $_param['trans_id'] = $this->request->param('trans_id/s', '');
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $this->_games($_param['app_id'], 0, 0, 0, 4);
+        $_param['username'] = $this->request->param('username/s', '');
+        $_param['payway'] = $this->request->param('payway/s', '');
+        $this->_payways($_param['payway']);
+        $_param['status'] = $this->request->param('status/d', 0);
+        $this->_pay_statuses($_param['status']);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_datas = (new AppleOrderLogic())->getOrderList($_param, $this->page.','.$this->list_rows);
+        $_page_data = Page::paginate($_datas['count'], $_datas['list'], $this->page, $this->list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('financial/order/apple');
+    }
+
+    /**
+     * 角色订单明细
+     * admin/financial.order/roleOrder
+     */
+    public function roleOrder() {
+        $_server_id = $this->request->param('server_id/s', '');
+        $_role_id = $this->request->param('role_id/s', '');
+        if (empty($_server_id) || empty($_role_id)) {
+            $this->adminError('参数错误!');
+        }
+        $_param['order_id'] = $this->request->param('order_id/s', '');
+        $_order_text = Filter::text('order_id', $_param['order_id'], '请输入订单号');
+        $this->assign('order_input', $_order_text);
+        $_param['cp_order_id'] = $this->request->param('cp_order_id/s', '');
+        $_cp_order_text = Filter::text('cp_order_id', $_param['cp_order_id'], '请输入CP订单号');
+        $this->assign('cp_order_input', $_cp_order_text);
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $this->_games($_param['app_id']);
+        $_param['payway'] = $this->request->param('payway/s', '');
+        $this->_payways($_param['payway']);
+        if (empty($cp_status)) {
+            $_param['cp_status'] = $this->request->param('cp_status/d', 0);
+        } else {
+            $_param['cp_status'] = $cp_status;
+        }
+        $this->_cp_statuses($_param['cp_status']);
+        $_param['status'] = $this->request->param('status/d', 0);
+        $this->_pay_statuses($_param['status']);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_data = (new OrderLogic())->getOrderExtList($_server_id, $_role_id, $_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch();
+    }
+
+    /**
+     * 切量订单回退
+     * admin/financial.order/setSwitch
+     */
+    public function setSwitch() {
+        $_order_id = $this->request->param('order_id/s', '');
+        if (empty($_order_id)) {
+            $this->adminError('参数错误!');
+        }
+        $_order_data = SdkOrderCache::ins()->getInfoByOrderId($_order_id);
+        $_mem_data = MemCache::ins()->getInfoById($_order_data['mem_id']);
+        /* 目前是切换玩家不可回退 */
+        if (OrderConst::PAY_SWITCH_YES == $_mem_data['is_switch']) {
+            $this->adminError('玩家处于切换状态,不可回退订单!');
+        }
+        $_rs = (new SwitchDayDataLogic())->returnOrdData($_order_id);
+        if (false == $_rs) {
+            $this->adminError('恢复失败!');
+        }
+        $this->adminSuccess('恢复成功!');
+    }
+
+    /**
+     * 支付切换选择器
+     *
+     * @param int $is_switch
+     */
+    protected function _paySwitch($is_switch = 0) {
+        $_pay_switch_arr = [
+            OrderConst::PAY_SWITCH_YES => lang('SWITCH'),
+            OrderConst::PAY_SWITCH_NO  => lang('NOT_SWITCH'),
+        ];
+        $_is_switch_select = Filter::selectCommon($_pay_switch_arr, 'is_switch', $is_switch);
+        $this->assign('is_switch_select', $_is_switch_select);
+    }
+}

+ 1015 - 0
admin/admin/controller/financial/PtbController.php

@@ -0,0 +1,1015 @@
+<?php
+/**
+ * PtbController.php UTF-8
+ *
+ *
+ * @date    : 5/18/2018 2:50 PM
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\financial;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\agent\AgentCache;
+use huo\controller\member\MemCache;
+use huo\controller\member\MemWallet;
+use huo\controller\rate\PtbRate;
+use huo\controller\wallet\PtbAgent;
+use huo\logic\agent\AgentListLogic;
+use huo\logic\agent\AgentRateLogic;
+use huo\logic\finance\PtbAgentChargeLogic;
+use huo\logic\finance\PtbAgentOrder;
+use huo\logic\finance\PtbBackLogic;
+use huo\logic\finance\PtbChargeLogic;
+use huo\logic\finance\PtbOrderLogic;
+use huo\logic\member\MemberLogic;
+use huo\model\finance\PtbBackModel;
+use huo\model\user\RoleModel;
+use huolib\constant\AgentConst;
+use huolib\constant\OrderConst;
+use huolib\constant\WalletConst;
+use huolib\status\MemberStatus;
+use huolib\tool\Export;
+use think\Lang;
+use think\Validate;
+
+class PtbController extends AdminBaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_ptb'.EXT);
+    }
+
+    /**
+     * 渠道平台币收入记录导出数据
+     *
+     * @param array $map
+     */
+    public function exportAgent($map = []) {
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new PtbAgentChargeLogic())->getIncomeList($map, $_page);
+        $parents = $this->_agents(0, true, [3], true);
+        $wallet_froms = $this->_walletForms();
+        $pay_statuss = $this->_payStatuss();
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+//            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '渠道平台币收入记录';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '时间',
+                '渠道账号',
+                '父渠道',
+                '订单号',
+                '充值数量',
+                '充值方式',
+                '实际支付金额',
+                '状态'
+            ];
+            $_export_datas = [];
+            if (1 == $_p) {
+                $_total = [
+                    '汇总',
+                    '',
+                    '',
+                    '',
+                    $_data['sum']['sum_ptb_cnt'],
+                    '',
+                    $_data['sum']['sum_real_amount'],
+                    ''
+                ];
+                $_export_datas[] = $_total;
+            }
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['agent'] = $_val['agent']['user_login'];
+                $_export_data['parent_id'] = isset($parents[$_val['agent']['parent_id']])
+                    ? $parents[$_val['agent']['parent_id']] : '官方渠道';
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['ptb_cnt'] = $_val['ptb_cnt'];
+                $_export_data['type'] = $wallet_froms[$_val['type']];
+                $_export_data['real_amount'] = $_val['real_amount'];
+                $_export_data['status'] = $pay_statuss[$_val['status']];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new PtbAgentChargeLogic())->getIncomeList($map, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 玩家平台币收入记录导出数据
+     *
+     * @param array $map
+     */
+    public function exportPlayer($map = []) {
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new PtbChargeLogic())->getIncomeList($map, $_page);
+        $agents = $this->_agents(0, true, [3, 4], true);
+        $wallet_froms = $this->_walletForms();
+        $pay_statuss = $this->_payStatuss();
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '玩家平台币收入记录';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '时间',
+                '玩家账号',
+                '归属渠道',
+                '订单号',
+                '充值数量',
+                '充值方式',
+                '实际支付金额',
+                '状态'
+            ];
+            $_export_datas = [];
+            if (1 == $_p) {
+                $_total = [
+                    '汇总',
+                    '',
+                    '',
+                    '',
+                    $_data['sum']['sum_ptb_cnt'],
+                    '',
+                    $_data['sum']['sum_real_amount'],
+                    ''
+                ];
+                $_export_datas[] = $_total;
+            }
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['agent'] = $_val['mem']['username'].'|'.$_val['mem']['nickname'];
+                $_export_data['agents'] = isset($agents[$_val['mem']['agent_id']]) ? $agents[$_val['mem']['agent_id']]
+                    : '官方渠道';
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['ptb_cnt'] = $_val['ptb_cnt'];
+                $_export_data['type'] = $wallet_froms[$_val['type']];
+                $_export_data['real_amount'] = $_val['real_amount'];
+                $_export_data['status'] = $pay_statuss[$_val['status']];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new PtbChargeLogic())->getIncomeList($map, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 渠道平台币消费记录导出数据
+     *
+     * @param array $map
+     */
+    public function exportAgentCost($map = []) {
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new PtbAgentOrder())->getCostList($map, $_page);
+        $_parents = $this->_agents(0, true, [3], true);
+        $_mas = AgentConst::getMemAgents();
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '渠道平台币消费记录';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '时间',
+                '渠道账号',
+                '归属渠道',
+                '订单号',
+                '转移数量',
+                '消费方式',
+                '接收渠道',
+                '接收玩家'
+            ];
+            $_export_datas = [];
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['agent'] = $_val['agent']['user_login'].'|'.$_val['agent']['user_nicename'];
+                $_export_data['parent_id'] = isset($_parents[$_val['agent']['parent_id']])
+                    ? $_parents[$_val['agent']['parent_id']] : '官方渠道';
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['ptb_cnt'] = $_val['ptb_cnt'];
+                $_export_data['to_mem_id'] = !empty($_val['to_mem_id']) ? $_mas['mem'] : $_mas['agent'];
+                $_export_data['toagent'] = !empty($_val['toagent']) ? $_val['toagent']['user_login'] : "--";
+                $_export_data['mem'] = !empty($_val['mem']) ? $_val['mem']['username'] : "--";
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new PtbAgentOrder())->getCostList($map, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 玩家平台币消费记录导出数据
+     *
+     * @param array $map
+     */
+    public function exportPlayerCost($map = []) {
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new PtbOrderLogic())->getCostList($map, $_page);
+        $_agents = $this->_agents(0, true, [3, 4], true);
+        $_pay_statuss = $this->_payStatuss();
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '玩家平台币消费记录';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '时间',
+                '玩家账号',
+                '归属渠道',
+                '订单号',
+                '消费数量',
+                '充值游戏',
+                '状态'
+            ];
+            $_export_datas = [];
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['agent'] = $_val['mem']['username'].'|'.$_val['mem']['nickname'];
+                $_export_data['agents'] = isset($_agents[$_val['mem']['agent_id']]) ? $_agents[$_val['mem']['agent_id']]
+                    : '官方渠道';
+                $_export_data['order_id'] = $_val['order_id'];
+                $_export_data['ptb_cnt'] = $_val['ptb_cnt'];
+                $_export_data['game'] = $_val['game']['name'];
+                $_export_data['status'] = $_pay_statuss[$_val['status']];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new PtbOrderLogic())->getCostList($map, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 平台币收入记录
+     *
+     * @return mixed
+     */
+    public function index() {
+        $_user_type = $this->request->param('user_type', 'mem'); //用户类型 agent:渠道  mem:玩家
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_username = $this->request->param('username', '');
+        $_order_id = $this->request->param('order_id');
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        $_parent_id = $this->request->param('parent_id/d', 0);
+        $_from = $this->request->param('from/d');
+        $_status = $this->request->param('status/d');
+        $_start_time = $this->request->param('start_time');
+        $_end_time = $this->request->param('end_time');
+        $_hide_tag = $this->request->param('hide_tag/s');
+        $_map = [];
+        if (!empty($_username)) {
+            $_map['username'] = $_username;
+        }
+        if (!empty($_agent_id)) {
+            if ('agent' == $_user_type) {
+                $_map['agent_id'] = $_agent_id;
+            } else {
+                $_map['from_id'] = $_agent_id;
+            }
+        }
+        if (!empty($_order_id)) {
+            $_map['order_id'] = $_order_id;
+        }
+        if (!empty($_parent_id)) {
+            $_map['parent_id'] = $_parent_id;
+        }
+        if (!empty($_from)) {
+            $_map['type'] = $_from;
+        }
+        if (!empty($_status)) {
+            $_map['status'] = $_status;
+        }
+        if (!empty($_start_time)) {
+            $_map['start_time'] = $_start_time;
+        }
+        if (!empty($_end_time)) {
+            $_map['end_time'] = $_end_time;
+        }
+        $this->_incomeFilterSelect($_agent_id, $_parent_id, $_from, $_status);
+        if ('agent' == $_user_type) {
+            if ('1' == $this->request->param('export/d', 0)) {
+                return $this->exportAgent($_map);
+            }
+            $template = 'agent_income_index';
+            $_data = (new PtbAgentChargeLogic())->getIncomeList($_map, $_page.','.$_list_rows);
+            $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        } else {
+            if ('1' == $this->request->param('export/d', 0)) {
+                return $this->exportPlayer($_map);
+            }
+            $template = 'player_income_index';
+            $_data = (new PtbChargeLogic())->getIncomeList($_map, $_page.','.$_list_rows);
+            $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        }
+        $this->assign('hide_tag', $_hide_tag);
+        $this->assign('start_time', $_start_time);
+        $this->assign('end_time', $_end_time);
+        $this->assign('username', $_username);
+        $this->assign('sum', $_data['sum']);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch($template);
+    }
+
+    /**
+     * 平台币消费记录
+     *
+     * @return mixed
+     */
+    public function costIndex() {
+        $_user_type = $this->request->param('user_type', 'mem'); //用户类型 agent:渠道  mem:玩家
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10); //
+        $_order_id = $this->request->param('order_id', '');
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        $_parent_id = $this->request->param('parent_id/d', 0);
+        $_username = $this->request->param('username', '');
+        $_cost_type = $this->request->param('ma/s', '');        //消费方式
+        $_from = $this->request->param('from/d', 0);
+        $_status = $this->request->param('status/d');
+        $_start_time = $this->request->param('start_time');
+        $_end_time = $this->request->param('end_time');
+        $_hide_tag = $this->request->param('hide_tag/s');
+        $_map = [];
+        if (!empty($_agent_id)) {
+            $_map['agent_id'] = $_agent_id;
+        }
+        if (!empty($_order_id)) {
+            $_map['order_id'] = $_order_id;
+        }
+        if (!empty($_parent_id)) {
+            $_map['parent_id'] = $_parent_id;
+        }
+        if (!empty($_username)) {
+            $_map['username'] = $_username;
+        }
+        if (!empty($_from)) {
+            $_map['type'] = $_from;
+        }
+        if (!empty($_status)) {
+            $_map['status'] = $_status;
+        }
+        if (!empty($_start_time)) {
+            $_map['start_time'] = $_start_time;
+        }
+        if (!empty($_end_time)) {
+            $_map['end_time'] = $_end_time;
+        }
+        if (!empty($_cost_type)) {
+            $_map['cost_type'] = $_cost_type;
+        }
+        if ('agent' == $_user_type) {
+            if ('1' == $this->request->param('export/d', 0)) {
+                return $this->exportAgentCost($_map);
+            }
+            $template = 'agent_cost_index';
+            $this->_agentCostFilterSelect($_agent_id, $_parent_id, $_status, $_cost_type);
+            $_data = (new PtbAgentOrder())->getCostList($_map, $_page.','.$_list_rows);
+            $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        } else {
+            if ('1' == $this->request->param('export/d', 0)) {
+                return $this->exportPlayerCost($_map);
+            }
+            $template = 'player_cost_index';
+            $this->_playerCostFilterSelect($_agent_id, $_from, $_status);
+            $_data = (new PtbOrderLogic())->getCostList($_map, $_page.','.$_list_rows);
+            $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        }
+        $this->assign('hide_tag', $_hide_tag);
+        $this->assign('start_time', $_start_time);
+        $this->assign('end_time', $_end_time);
+        $this->assign('username', $_username);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch($template);
+    }
+
+    /**
+     * 平台币发放管理
+     *
+     * @return mixed
+     */
+    public function gainIndex() {
+        $_user_type = $this->request->param('user_type', 'mem'); //用户类型 agent:渠道  mem:玩家
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_order_id = $this->request->param('order_id', '');
+        $_username = $this->request->param('username', '');
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        $_status = $this->request->param('status/d');
+        $_start_time = $this->request->param('start_time');
+        $_end_time = $this->request->param('end_time');
+        $_map = [];
+        if (!empty($_agent_id)) {
+            $_map['agent_id'] = $_agent_id;
+        }
+        if (!empty($_order_id)) {
+            $_map['order_id'] = $_order_id;
+        }
+        if (!empty($_username)) {
+            $_map['username'] = $_username;
+        }
+        if (!empty($_status)) {
+            $_map['status'] = $_status;
+        }
+        if (!empty($_start_time)) {
+            $_map['start_time'] = $_start_time;
+        }
+        if (!empty($_end_time)) {
+            $_map['end_time'] = $_end_time;
+        }
+        $_map['type'] = WalletConst::WALLET_FROM_GIVE;
+        $this->_gainFilterSelect($_agent_id, $_status);
+        if ('agent' == $_user_type) {
+            $template = 'agent_gain_index';
+            $_data = (new AgentListLogic())->getRemainList($_map, $_page.','.$_list_rows);
+            $items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        } else {
+            $template = 'player_gain_index';
+            $_data = (new MemberLogic())->getRemainList($_map, $_page.','.$_list_rows);
+            $items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        }
+        $this->assign('start_time', $_start_time);
+        $this->assign('end_time', $_end_time);
+        $this->assign('username', $_username);
+        $this->assign('items', $items->items());
+        $this->assign('page', $items->render());
+
+        return $this->fetch($template);
+    }
+
+    /**
+     * 平台币扣除管理
+     *
+     * @return mixed
+     */
+    public function deductIndex() {
+        $_user_type = $this->request->param('user_type', 'mem');
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_order_id = $this->request->param('order_id', '');
+        $_username = $this->request->param('username', '');
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        $_parent_id = $this->request->param('parent_id/d', 0);
+        $_start_time = $this->request->param('start_time');
+        $_end_time = $this->request->param('end_time');
+        $_map = [];
+        if (!empty($_agent_id)) {
+            if ('agent' == $_user_type) {
+                $_map['agent_id'] = $_agent_id;
+            } else {
+                $_map['belong_agent_id'] = $_agent_id;
+            }
+        }
+        if (!empty($_parent_id)) {
+            $_map['parent_id'] = $_parent_id;
+        }
+        if (!empty($_order_id)) {
+            $_map['back_order_id'] = $_order_id;
+        }
+        if (!empty($_username)) {
+            $_map['username'] = $_username;
+        }
+        if (!empty($_start_time)) {
+            $_map['start_time'] = $_start_time;
+        }
+        if (!empty($_end_time)) {
+            $_map['end_time'] = $_end_time;
+        }
+        if (!empty($_user_type)) {
+            $_map['user_type'] = $_user_type;
+        }
+        $this->_deductFilterSelect($_agent_id, $_parent_id);
+        if ('agent' == $_user_type) {
+            $template = 'agent_deduct_index';
+            $_map['user_type'] = PtbBackModel::USER_TYPE_AGENT;
+            $_data = (new PtbBackLogic())->getBackList($_map, $_page.','.$_list_rows);
+            $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        } else {
+            $template = 'player_deduct_index';
+            $_map['user_type'] = PtbBackModel::USER_TYPE_MEM;
+            $_data = (new PtbBackLogic())->getBackList($_map, $_page.','.$_list_rows);
+            $_items = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        }
+        $this->assign('start_time', $_start_time);
+        $this->assign('end_time', $_end_time);
+        $this->assign('username', $_username);
+        $this->assign('sum', $_data['sum']);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch($template);
+    }
+
+    /**
+     * 给渠道发放平台币页面
+     *
+     * @return mixed
+     */
+    public function agentGain() {
+        $_agent_id = $this->request->param('agent_id');
+        if (empty($_agent_id)) {
+            return $this->adminError('非法请求');
+        }
+        $this->assign('agent_id', $_agent_id);
+
+        return $this->fetch('agent_gain');
+    }
+
+    /**
+     * 给渠道发放平台币
+     */
+    public function doAgentGain() {
+        $_param = $this->request->param();
+        $_result = $this->validate($_param, 'Gain.agent');
+        if (true !== $_result) {
+            return $this->adminError($_result);
+        }
+        $_agent_id = $this->request->param('agent_id');
+        $_ptb_cnt = $this->request->param('ptb_cnt');
+        $_remark = $this->request->param('remark');
+        $this->verifyPayPwd();
+        $_ptb_agent = new PtbAgent();
+        $_rs = $_ptb_agent->gainAgentPtb($this->admin_id, $_agent_id, $_ptb_cnt, $_remark);
+        if ($this->hasError($_rs)) {
+            return $this->adminError($_rs['msg']);
+        }
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 给玩家发放平台币页面
+     *
+     * @return mixed
+     */
+    public function playerGain() {
+        $_mem_id = $this->request->param('mem_id');
+        if (empty($_mem_id)) {
+            return $this->adminError('非法请求');
+        }
+        $this->assign('mem_id', $_mem_id);
+
+        return $this->fetch('player_gain');
+    }
+
+    /**
+     * 给玩家发放平台币
+     */
+    public function doPlayerGain() {
+        $_param = $this->request->param();
+        $_result = $this->validate($_param, 'Gain.player');
+        if (true !== $_result) {
+            return $this->adminError($_result);
+        }
+        $_mem_id = $this->request->param('mem_id');
+        $_ptb_cnt = $this->request->param('ptb_cnt');
+        $_remark = $this->request->param('remark');
+        $this->verifyPayPwd();
+        $_rs = (new MemWallet())->gainMemPtb($_mem_id, $_ptb_cnt, $_remark);
+        if ($this->hasError($_rs)) {
+            return $this->adminError($_rs['msg']);
+        }
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 扣除渠道平台币页面
+     *
+     * @return mixed
+     */
+    public function agentDeduct() {
+        $_agent_id = $this->request->param('agent_id');
+        if (empty($_agent_id)) {
+            return $this->adminError('非法请求');
+        }
+        $this->assign('agent_id', $_agent_id);
+
+        return $this->fetch('agent_deduct');
+    }
+
+    /**
+     * 扣除渠道平台币
+     */
+    public function doAgentDeduct() {
+        $_param = $this->request->param();
+        $_result = $this->validate($_param, 'Deduct.agent');
+        if (true !== $_result) {
+            return $this->adminError($_result);
+        }
+        $_agent_id = $this->request->param('agent_id');
+        $_ptb_cnt = $this->request->param('ptb_cnt');
+        $_remark = $this->request->param('remark');
+        $this->verifyPayPwd();
+        $_ptb_agent = new PtbAgent();
+        $_rs = $_ptb_agent->deductAgentPtb($this->admin_id, $_agent_id, $_ptb_cnt, $_ptb_cnt, $_remark);
+        if ($this->hasError($_rs)) {
+            return $this->adminError($_rs['msg']);
+        }
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 扣除玩家平台币页面
+     *
+     * @return mixed
+     */
+    public function playerDeduct() {
+        $_mem_id = $this->request->param('mem_id');
+        if (empty($_mem_id)) {
+            return $this->adminError('非法请求');
+        }
+        $this->assign('mem_id', $_mem_id);
+
+        return $this->fetch('player_deduct');
+    }
+
+    /**
+     * 扣除玩家平台币
+     */
+    public function doPlayerDeduct() {
+        $_param = $this->request->param();
+        $_result = $this->validate($_param, 'Deduct.player');
+        if (true !== $_result) {
+            return $this->adminError($_result);
+        }
+        $_mem_id = $this->request->param('mem_id');
+        $_ptb_cnt = $this->request->param('ptb_cnt');
+        $_remark = $this->request->param('remark');
+        $this->verifyPayPwd();
+        $_rs = (new MemWallet())->deductMemPtb($_mem_id, $_ptb_cnt, $_ptb_cnt, $_remark);
+        if ($this->hasError($_rs)) {
+            return $this->adminError($_rs['msg']);
+        }
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 扣除发放订单中的平台币页面
+     *
+     * @return mixed
+     */
+    public function orderDeduct() {
+        $_order_id = $this->request->param('order_id');
+        $_user_type = $this->request->param('user_type'); //用户类型 agent:渠道  mem:玩家
+        $this->assign('order_id', $_order_id);
+        $this->assign('user_type', $_user_type);
+
+        return $this->fetch('order_deduct');
+    }
+
+    /**
+     * 扣除发放订单中的平台币
+     */
+    public function doOrderDeduct() {
+        $_order_id = $this->request->param('order_id');
+        $_user_type = $this->request->param('user_type'); //用户类型 agent:渠道  mem:玩家
+        if (empty($_order_id)) {
+            $this->adminError('订单号不能为空');
+        }
+        if (empty($_user_type)) {
+            $this->adminError('用户类型不能为空');
+        }
+        $this->verifyPayPwd();
+        if ('agent' == $_user_type) {
+            $_ptb_agent_charge = (new PtbAgentChargeLogic())->getDetailByOrderId($_order_id);
+            if (empty($_ptb_agent_charge)) {
+                $this->adminError('订单错误不能为空');
+            }
+            if (WalletConst::WALLET_FROM_GIVE !== $_ptb_agent_charge->type) {
+                $this->adminError('只有后台发放的订单才能扣除');
+            }
+            if ($_ptb_agent_charge->back_status !== WalletConst::WALLET_BACK_STATUS_NO) {
+                $this->adminError('当前订单已经扣除过了,请勿重复扣除');
+            }
+            //查询渠道当前平台币余额
+            $_ac_class = AgentCache::ins();
+            $_ae_data = $_ac_class->getAgentExtByAgentId($_ptb_agent_charge->agent_id);
+            //标记扣回过
+            $_ptb_agent_charge->back_status = WalletConst::WALLET_BACK_STATUS_ALL;
+            //需扣回的平台币数量
+            $_deduct_ptb_cnt = $_ptb_agent_charge->ptb_cnt;
+            if ($_ae_data['ptb_remain'] < $_ptb_agent_charge->ptb_cnt) {
+                $_deduct_ptb_cnt = $_ae_data['ptb_remain'];
+                $_ptb_agent_charge->back_status = WalletConst::WALLET_BACK_STATUS_PART;
+            }
+            $_cur_admin_id = $this->admin_id;
+            $_agent_id = $_ptb_agent_charge->agent_id;
+            $_order_ptb_cnt = $_ptb_agent_charge->ptb_cnt;
+            $_ptb_cnt = $_deduct_ptb_cnt;
+            $_remark = '从发放订单中扣除平台币';
+            $_order_id = $_ptb_agent_charge->order_id;
+            $_ptb_agent = new PtbAgent();
+            $_rs = $_ptb_agent->deductAgentPtb(
+                $_cur_admin_id, $_agent_id, $_order_ptb_cnt, $_ptb_cnt, $_remark, $_order_id
+            );
+            if ($this->hasError($_rs)) {
+                return $this->adminError($_rs['msg']);
+            }
+            $_ptb_agent_charge->save();
+        } else {
+            $_ptb_charge = (new PtbChargeLogic())->getDetailByOrderId($_order_id);
+            if (empty($_ptb_charge)) {
+                $this->adminError('订单错误不能为空');
+            }
+            if (WalletConst::WALLET_FROM_GIVE !== $_ptb_charge->type) {
+                $this->adminError('只有后台发放的订单才能扣除');
+            }
+            if ($_ptb_charge->back_status !== WalletConst::WALLET_BACK_STATUS_NO) {
+                $this->adminError('当前订单已经扣除过了,请勿重复扣除');
+            }
+            //查询玩家的当前平台币余额
+            $_mc_class = MemCache::ins();
+            $_me_data = $_mc_class->getMeInfoById($_ptb_charge->mem_id);
+            if (empty($_me_data)) {
+                $_code = MemberStatus::UID_INVALID;
+
+                return $this->adminError($_code, MemberStatus::getMsg($_code));
+            }
+            //标记扣回过
+            $_ptb_charge->back_status = WalletConst::WALLET_BACK_STATUS_ALL;
+            //需扣回的平台币数量
+            $_deduct_ptb_cnt = $_ptb_charge->ptb_cnt;
+            if ($_me_data['ptb_cnt'] < $_ptb_charge->ptb_cnt) {
+                $_deduct_ptb_cnt = $_me_data['ptb_cnt'];
+                $_ptb_charge->back_status = WalletConst::WALLET_BACK_STATUS_PART;
+            }
+            $_mem_id = $_ptb_charge->mem_id;
+            $_order_ptb_cnt = $_ptb_charge->ptb_cnt;
+            $_ptb_cnt = $_deduct_ptb_cnt;
+            $_remark = '从发放订单中扣除平台币';
+            $order_id = $_ptb_charge->order_id;
+            $_rs = (new MemWallet())->deductMemPtb($_mem_id, $_order_ptb_cnt, $_ptb_cnt, $_remark, $order_id);
+            if ($this->hasError($_rs)) {
+                return $this->adminError($_rs['msg']);
+            }
+            $_ptb_charge->save();
+        }
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 来源
+     *
+     * @param $from
+     */
+    protected function _walletForms($from = 0) {
+        $_wallet_froms = WalletConst::getFroms();
+        $_wallet_froms_select = Filter::selectCommon($_wallet_froms, 'from', $from);
+        $this->assign('wallet_froms', $_wallet_froms);
+        $this->assign('wallet_froms_select', $_wallet_froms_select);
+
+        return $_wallet_froms;
+    }
+
+    /**
+     * 支付状态
+     *
+     * @param $status
+     *
+     * @return array|bool|mixed
+     */
+    protected function _payStatuss($status = 0) {
+        $_pay_statuss = OrderConst::getPayStatuss();
+        $_pay_statuss_select = Filter::selectCommon($_pay_statuss, 'status', $status);
+        $this->assign('pay_statuss', $_pay_statuss);
+        $this->assign('pay_statuss_select', $_pay_statuss_select);
+
+        return $_pay_statuss;
+    }
+
+    /**
+     * 收入记录选项
+     *
+     * @param int $agent_id
+     * @param int $_parent_id
+     * @param int $from
+     * @param int $status
+     */
+    protected function _incomeFilterSelect($agent_id = 0, $_parent_id = 0, $from = 0, $status = 0) {
+        //渠道
+        $this->_agents($agent_id, true, [3, 4], true);
+        //父渠道
+        $this->_agents($_parent_id, true, [3], true);
+        $this->_time();
+        $this->_walletForms($from);
+        $this->_payStatuss($status);
+    }
+
+    /**
+     * 渠道消费记录选项
+     *
+     * @param int $agent_id
+     * @param int $_parent_id
+     * @param int $status
+     * @param int $cost_type
+     */
+    protected function _agentCostFilterSelect($agent_id = 0, $_parent_id = 0, $status = 0, $cost_type = '') {
+        $this->_agents($agent_id, true, [3, 4], true);
+        //父渠道
+        $this->_agents($_parent_id, true, [3], true);
+        $this->_time();
+        $this->_payStatuss($status);
+        $_mas = AgentConst::getMemAgents();
+        $this->assign('mas', $_mas);
+        $_mas_select = Filter::selectCommon($_mas, 'ma', $cost_type);
+        $this->assign('mas_select', $_mas_select);
+    }
+
+    /**
+     * 玩家消费记录选项
+     *
+     * @param int $agent_id
+     * @param int $from
+     * @param int $status
+     */
+    protected function _playerCostFilterSelect($agent_id = 0, $from = 0, $status = 0) {
+        $this->_agents($agent_id, true, [3, 4], true);
+        $this->_time();
+        $this->_walletForms($from);
+        $this->_payStatuss($status);
+    }
+
+    /**
+     * 平台币发放选项
+     *
+     * @param int $agent_id
+     * @param int $status
+     */
+    protected function _gainFilterSelect($agent_id = 0, $status = 0) {
+        $this->_agents($agent_id, true, [3, 4], true);
+        $this->_time();
+        $this->_payStatuss($status);
+    }
+
+    /**
+     * 平台币扣除选项
+     *
+     * @param int $agent_id
+     * @param int $parent_id
+     * @param int $status
+     */
+    protected function _deductFilterSelect($agent_id = 0, $parent_id = 0) {
+        $this->_agents($agent_id, true, [3, 4], true);
+        //父渠道
+        $this->_agents($parent_id, true, [3], true);
+        $this->_time();
+    }
+
+    /**
+     * 平台币折扣设置列表
+     */
+    public function rate() {
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        $this->_agents($_param['agent_id'], false, [3, 4], true);
+        $_roles = (new RoleModel())->getIdNames([], true);
+        $this->assign('roles', $_roles);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        //默认折扣
+        $_default_rate = (new AgentRateLogic())->getDefaultInfo();
+        $this->assign('default_rate', $_default_rate);
+        $_data = (new AgentListLogic())->getAgentRateList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('agent_rate');
+    }
+
+    /**
+     * 平台币折扣设置页面
+     */
+    public function editRate() {
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        $_role_type = $this->request->param('role_type/d', 0);
+        $_rate = (new AgentRateLogic())->getInfoByAgentId($_agent_id);
+        if (empty($_rate)) {
+            $_rate = (new AgentRateLogic())->getDefaultInfo();
+        }
+        $this->assign('agent_id', $_agent_id);
+        $this->assign('rate', $_rate);
+        $this->assign('role_type', $_role_type);
+
+        return $this->fetch('edit_rate');
+    }
+
+    /**
+     * 平台币折扣设置
+     */
+    public function doEditRate() {
+        $_param = $this->request->param();
+        $validate = new Validate(
+            [
+                'agent_id'       => 'require',
+                'agent_rate'     => 'require|number|between:0.1,10',
+                'sub_agent_rate' => 'number|between:0.1,10',
+            ]
+        );
+        $validate->message(
+            [
+                'agent_id.require'       => '渠道不能为空',
+                'agent_rate.require'     => '一级折扣不能为空',
+                'agent_rate.number'      => '一级折扣只能为数字',
+                'agent_rate.between'     => '一级折扣只能在0.1~10范围内',
+                'sub_agent_rate.number'  => '二级折扣只能为数字',
+                'sub_agent_rate.between' => '二级折扣只能在0.1~10范围内',
+            ]
+        );
+        if (!$validate->check($_param)) {
+            $this->adminError($validate->getError());
+        }
+        $_agent_id = $this->request->param('agent_id/d');
+        $_agent_rate = $this->request->param('agent_rate/f');
+        $_sub_agent_rate = $this->request->param('sub_agent_rate/f', 10);
+        $_agent_rate = round($_agent_rate / 10, 4);
+        $_sub_agent_rate = round($_sub_agent_rate / 10, 4);
+        $_rs = (new PtbRate())->updateRate($_agent_id, $_agent_rate, $_sub_agent_rate);
+        if ($this->hasError($_rs)) {
+            $this->adminError($_rs['msg']);
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+}

+ 206 - 0
admin/admin/controller/game/AndroidGameController.php

@@ -0,0 +1,206 @@
+<?php
+/**
+ * AndroidGameController.php  UTF-8
+ * 安卓游戏管理类
+ *
+ * @date    : 2018/5/14 17:00
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use huo\controller\game\GameCache;
+use huo\controller\game\Gamepack;
+use huo\exception\HuoException;
+use huo\model\game\GamecategoryModel;
+use huo\model\game\GameextModel;
+use huo\model\game\GameModel;
+use huo\model\game\GameversionModel;
+use huolib\constant\GameConst;
+use think\Validate;
+
+class AndroidGameController extends GameController {
+    function _initialize() {
+        parent::_initialize();
+        $this->classify = GameConst::GAME_ANDROID;
+        $this->index_url = url('admin/Game.android_game/index');
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    /**
+     * 添加游戏母包
+     *
+     * @param      $classify
+     * @param bool $is_update
+     *
+     * @return mixed
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function addPackageUrl($classify = 0, $is_update = false) {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_update = $this->request->param('update/d', 0);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_game_data = $this->getDetail($_app_id);
+        if (empty($_game_data)) {
+            $this->adminError(lang('ERROR'));
+        }
+        if (empty($_update) && !empty($_game_data['gv'][0]['package_url'])) {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+        $this->assign($_game_data);
+        $_gp_class = new Gamepack($_app_id);
+        try {
+            $_gp_class->setPinyin($_game_data['en_abbr']);
+            $_gp_class->setAgentgame($_game_data['en_abbr']);
+            $_rs = $_gp_class->pack();
+            //$_data = $_gp_class->getData();
+            $_data = $_rs['data'];
+        } catch (HuoException $_he) {
+            $_data = $_he->getData();
+        }
+        if (empty($_data)) {
+            return $this->fetch('addpackageurl');
+        }
+        if (is_array($_data) && isset($_data['size'])) {
+            $_gv_model = new GameversionModel();
+            $_map['id'] = $_game_data['gv'][0]['id'];
+            $_gv_data['package_url'] = $_data['url'];
+            $_gv_data['size'] = $_data['size'];
+            $_gv_data['version'] = $_data['vername'];
+            $_rs = $_gv_model->save($_gv_data, $_map);
+            if (false !== $_rs) {
+                $_game_model = new GameModel();
+                $_g_data['package_name'] = $_data['pakagename'];
+                $_g_map['id'] = $_app_id;
+                $_game_model->save($_g_data, $_g_map);
+                $this->redirect($this->request->server('HTTP_REFERER'));
+            }
+        }
+
+        return $this->fetch('addpackageurl');
+    }
+
+    /**
+     * 编辑游戏处理函数
+     *
+     * @throws
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'id'          => 'require|number|token',
+                    'name'        => 'require',
+                    'package_url' => 'url',
+                    'down_cnt'    => 'number|max:100000000',
+                ]
+            );
+            $_param = $this->request->post();
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_app_id = $this->request->post('id/d', 0);
+            $_down_cnt = $this->request->post('down_cnt/d', 0);
+            $_g_all = $this->getDetail($_app_id);
+            $_rise_cnt = $_down_cnt - $_g_all['ext']['down_cnt'];
+            $_game_data['hot_order'] = $_g_all['hot_order'] + $_rise_cnt;
+            $_game_data['rise_order'] = $_g_all['rise_order'] + $_rise_cnt;
+            $_game_data['id'] = $_app_id;
+            $_game_data['icon'] = $this->request->post('icon/s', '');
+            $_game_data['name'] = $this->request->post('name/s', '');
+            $_game_data['cp_id'] = $this->request->post('cp_id/d', 0);
+            $_game_data['is_online'] = $this->request->post('is_online/d', 1);
+            $_game_data['publicity'] = $this->request->post('publicity/s', '');
+            $_game_data['description'] = $this->request->post('description/s', '');
+            $_game_data['hot_image'] = $this->request->post('hot_image/s', '');
+            $_game_data['fine_image'] = $this->request->post('fine_image/s', '');
+            $_category = $this->request->post('category/a');
+            if (is_array($_category)) {
+                $_game_data['category'] = implode(',', $_category);
+            }
+            if (!empty($_param['photo_names']) && !empty($_param['photo_urls'])) {
+                $_game_data['image'] = [];
+                foreach ($_param['photo_urls'] as $_key => $_url) {
+                    $_photo_url = cmf_asset_relative_url($_url);
+                    array_push(
+                        $_game_data['image'], ["url" => $_photo_url, "name" => $_param['photo_names'][$_key]]
+                    );
+                }
+            }
+            $_rs = GameCache::ins()->updateGame($_app_id, $_game_data, true);
+            if ($this->hasOa) {
+                $_game_model = new GameModel();
+                $_oa_data = $_game_data;
+            }
+            if (false !== $_rs) {
+                $_gv_data['package_url'] = $this->request->post('package_url/s', '');
+//                $_gv_data['size'] = $this->request->post('size/s', '');
+                $_gv_data['version'] = $this->request->post('version/s', '');
+                $_gv_map['id'] = $_g_all['gv'][0]['id'];
+                $_gv_model = new GameversionModel();
+                $_gv_model->save($_gv_data, $_gv_map);
+                if ($this->hasOa) {
+                    $_oa_data['standard_mem_cnt'] = $this->request->post('standard_mem_cnt/d', '');
+                    $_oa_data['standard_level'] = $this->request->post('standard_level/d', '');
+                    $_oa_game_data = array();
+                    $_oa_game_data['standard_mem_cnt'] = $_oa_data['standard_mem_cnt'];
+                    $_oa_game_data['standard_level'] = $_oa_data['standard_level'];
+                    $_oa_game_model = new \huo\model\oa\OaGameModel();
+                    \think\Log::write($_oa_data, 'debug');
+                    $_oa_game_model->save($_oa_game_data, ['app_id' => $_app_id]);
+                    $_oa_data['version'] = $_gv_data['version'];
+                }
+                $_ge_data['down_cnt'] = $_down_cnt;
+                GameextModel::update($_ge_data, ['app_id' => $_app_id]);
+                if (!empty($_category)) {
+                    /* 先删除所有类型 */
+                    $_gc_map['id'] = ['gt', 0];
+                    $_gc_map['app_id'] = $_app_id;
+                    $_gc_model = new GamecategoryModel();
+                    $_gc_rs = $_gc_model->where($_gc_map)->delete();
+                    if (false !== $_gc_rs) {
+                        $_gc_data = [];
+                        foreach ($_category as $_v) {
+                            $_gc_temp_data['app_id'] = $_app_id;
+                            $_gc_temp_data['cate_id'] = $_v;
+                            $_gc_data[] = $_gc_temp_data;
+                        }
+                        $_gc_model->insertAll($_gc_data);
+                    }
+                }
+                if ($this->hasOa) {
+                    $_re = $_game_model->updateOaGame($_app_id, $_oa_data);
+                    if ($_re) {
+                        \think\Log::write($_oa_data, 'debug');
+                    }
+                }
+                $this->adminSuccess(lang('SUCCESS'), url('admin/game.android_game/index'));
+            } else {
+                $this->adminError("ERROR");
+            }
+        } else {
+            $this->adminError("param error");
+        }
+    }
+
+    /**
+     * 删除游戏列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function deleteIndex() {
+        $this->delete_index_url = url('admin/Game.android_game/deleteIndex');
+
+        return parent::deleteIndex();
+    }
+}

+ 145 - 0
admin/admin/controller/game/ChannelController.php

@@ -0,0 +1,145 @@
+<?php
+/**
+ * ChannelController.php  UTF-8
+ * CPS平台管理
+ *
+ * @date    : 2018/7/27 14:17
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\logic\game\ChannelLogic;
+use huolib\constant\CommonConst;
+use think\Lang;
+
+class ChannelController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'cp'.EXT);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    /**
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function index() {
+        $_map = array();
+        $_id = $this->request->get('id');
+        if (isset($_id) && $_id > 0) {
+            $_map['id'] = $_id;
+        }
+        $_map['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_list_row = $this->request->get('list_rows');
+        $_offset = !empty($_list_row) ? $_list_row : 50;
+        $_order = 'id desc';
+        $_cps = (new ChannelLogic())->getChannelList($_map, $_order, $_offset);
+        $_cpnames = (new ChannelLogic())->getNamesById();
+        /*搜索*/
+        $_channel_select = Filter::selectCommon($_cpnames, 'id', $this->request->get('id/d', 0));
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', 'uri' => url('admin/Game.Channel/index')]
+        );
+        $this->assign('items', $_cps);
+        $this->assign('page', $_cps->render());
+        $this->assign('channel_select', $_channel_select);
+        $this->assign('filter_button', $_filter_button);
+        $this->assign('filter_button_clear', $_filter_button_clear);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加CP
+     */
+    public function add() {
+        return $this->fetch();
+    }
+
+    /**
+     * 添加CP处理函数
+     */
+    public function addPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $result = $this->validate($_param, 'Channel.add');  //add场景验证
+            if (true !== $result) {
+                $this->adminError($result);
+            }
+            $_param['is_delete'] = CommonConst::CONST_NOT_DELETE;
+            $_param['create_time'] = time();
+            $_rs = (new ChannelLogic())->addChannel($_param);
+            if ($_rs) {
+                $this->adminSuccess(lang('ADD_SUCCESS'));
+            } else {
+                $this->adminSuccess(lang('ADD_FAILED'), url('admin/game.channel/index'));
+            }
+        } else {
+            $this->adminError(lang('REQUEST_ERROR'));
+        }
+    }
+
+    /**
+     * 编辑CP
+     *
+     * @throws
+     */
+    public function edit() {
+        $_cp_id = $this->request->param('cp_id/d', 0);
+        $_cp_data = (new ChannelLogic())->getChannelById($_cp_id);
+        if (empty($_cp_data)) {
+            $this->adminError('param error');
+        }
+        $this->assign('cp', $_cp_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     *  编辑CP处理函数
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $result = $this->validate($_param, 'Channel.edit');  //edit场景验证
+            if (true !== $result) {
+                $this->adminError($result, $this->request->server('HTTP_REFERER'));
+            }
+            $_param['update_time'] = time();
+            $_rs = (new ChannelLogic())->updateChannel($_param['id'], $_param);
+            if ($_rs) {
+                $this->adminSuccess(lang('EDIT_SUCCESS'), url('admin/game.channel/index'));
+            } else {
+                $this->adminSuccess(lang('EDIT_FAILED'));
+            }
+        } else {
+            $this->adminError(lang('REQUEST_ERROR'));
+        }
+    }
+
+    /**
+     * 删除
+     */
+    public function delete() {
+        $_cp_id = $this->request->param('cp_id/d', 0);
+        if (empty($_cp_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data['is_delete'] = 1;
+        $_data['delete_time'] = time();
+        $_rs = (new ChannelLogic())->updateChannel($_cp_id, $_data);;
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            $this->adminSuccess(lang('DELETE').lang('SUCCESS'));
+        }
+    }
+}

+ 170 - 0
admin/admin/controller/game/CpController.php

@@ -0,0 +1,170 @@
+<?php
+/**
+ * CpController.php  UTF-8
+ * CP管理类
+ *
+ * @date    : 2018/5/3 10:17
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\logic\member\CpLogic;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use think\Lang;
+
+class CpController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'cp'.EXT);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    /**
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function index() {
+        $_map = array();
+        $_id = $this->request->get('id');
+        if (isset($_id) && $_id > 0) {
+            $_map['id'] = $_id;
+        }
+        $_map['is_delete'] = 2;
+        $_map['type'] = GameConst::CP_TYPE_CP;
+        $_list_row = $this->request->get('list_rows');
+        $_offset = !empty($_list_row) ? $_list_row : 10;
+        $_order = 'id desc';
+        $_cps = (new CpLogic())->getCpList($_map, $_order, $_offset);
+        $_cpnames = (new CpLogic())->getNamesById();
+        $_cp_select = Filter::selectCommon($_cpnames, 'id', $this->request->get('id/d', 0));
+        $this->assign('items', $_cps);
+        $this->assign('page', $_cps->render());
+        $this->assign('cp_select', $_cp_select);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 媒体列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function media() {
+        $_map = array();
+        $_id = $this->request->get('id');
+        if (isset($_id) && $_id > 0) {
+            $_map['id'] = $_id;
+        }
+        $_map['is_delete'] = 2;
+        $_map['type'] = GameConst::CP_TYPE_MEDIA;
+        $_list_row = $this->request->get('list_rows');
+        $_offset = !empty($_list_row) ? $_list_row : 10;
+        $_order = 'id desc';
+        $_cps = (new CpLogic())->getCpList($_map, $_order, $_offset);
+        $_cpnames = (new CpLogic())->getNamesById($_map['type']);
+        /*搜索*/
+        $_cp_select = Filter::selectCommon($_cpnames, 'id', $this->request->get('id/d', 0));
+        $this->assign('items', $_cps);
+        $this->assign('page', $_cps->render());
+        $this->assign('cp_select', $_cp_select);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加CP
+     */
+    public function add() {
+        $_type = $this->request->param('type/d', GameConst::CP_TYPE_CP);
+        $this->assign('type', $_type);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加CP处理函数
+     */
+    public function addPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $result = $this->validate($_param, 'Cp.add');  //add场景验证
+            if (true !== $result) {
+                $this->adminError($result);
+            }
+            $_param['is_delete'] = CommonConst::CONST_NOT_DELETE;
+            $_param['create_time'] = time();
+            $_rs = (new CpLogic())->addCp($_param);
+            if ($_rs) {
+                $this->adminSuccess(lang('ADD_SUCCESS'));
+            } else {
+                $this->adminSuccess(lang('ADD_FAILED'));
+            }
+        } else {
+            $this->adminError(lang('REQUEST_ERROR'));
+        }
+    }
+
+    /**
+     * 编辑CP
+     *
+     * @throws
+     */
+    public function edit() {
+        $_cp_id = $this->request->param('id/d', 0);
+        $_cp_data = (new CpLogic())->getCpById($_cp_id);
+        if (empty($_cp_data)) {
+            $this->adminError('param error');
+        }
+        $this->assign('cp', $_cp_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     *  编辑CP处理函数
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $result = $this->validate($_param, 'Cp.edit');  //edit场景验证
+            if (true !== $result) {
+                $this->adminError($result, $this->request->server('HTTP_REFERER'));
+            }
+            $_param['update_time'] = time();
+            $_rs = (new CpLogic())->updateCp($_param['id'], $_param);
+            if ($_rs) {
+                $this->adminSuccess(lang('EDIT_SUCCESS'));
+            } else {
+                $this->adminSuccess(lang('EDIT_FAILED'));
+            }
+        } else {
+            $this->adminError(lang('REQUEST_ERROR'));
+        }
+    }
+
+    /**
+     * 删除
+     */
+    public function delete() {
+        $_cp_id = $this->request->param('id/d', 0);
+        if (empty($_cp_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data['is_delete'] = 1;
+        $_data['delete_time'] = time();
+        $_rs = (new CpLogic())->updateCp($_cp_id, $_data);;
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            $this->adminSuccess(lang('DELETE').lang('SUCCESS'));
+        }
+    }
+}

+ 399 - 0
admin/admin/controller/game/CpsGameController.php

@@ -0,0 +1,399 @@
+<?php
+/**
+ * CpsGameController.php  UTF-8
+ * CPS 游戏管理
+ *
+ * @date    : 2018/7/20 10:44
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : Beibao 1.0
+ */
+
+namespace admin\admin\controller\game;
+
+use cmf\view\Filter;
+use huo\controller\game\GameCache;
+use huo\logic\game\ChannelLogic;
+use huo\model\game\GamecategoryModel;
+use huo\model\game\GameModel;
+use huo\model\game\GameversionModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\tool\StrUtils;
+use think\Validate;
+
+class CpsGameController extends GameController {
+    function _initialize() {
+        parent::_initialize();
+        $this->sdk = GameConst::GAME_IS_NOT_SDK;
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    /**
+     * H5游戏列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function index() {
+        $this->classify = GameConst::GAME_H5;
+        $this->index_url = url('admin/Game.cps_game/index');
+
+        return parent::index();
+    }
+
+    /**
+     * 安卓游戏列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function andindex() {
+        $this->classify = GameConst::GAME_ANDROID;
+        $this->index_url = url('admin/Game.cps_game/andindex');
+
+        return parent::index();
+    }
+
+    /**
+     * IOS游戏列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function iosindex() {
+        $this->classify = GameConst::GAME_IOS;
+        $this->index_url = url('admin/Game.cps_game/iosindex');
+
+        return parent::index();
+    }
+
+    /**
+     * CPS已删除游戏列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function deleteindex() {
+        $this->index_url = url('admin/Game.cps_game/deleteindex');
+        $_cps_name_select = Filter::selectCommon((new ChannelLogic())->getNamesById(), 'cp_id', 0);
+        $this->assign('cps_name_select', $_cps_name_select);
+        $this->_gameClassifies(0);
+
+        return parent::deleteindex();
+    }
+
+    /**
+     * 添加游戏处理函数
+     *
+     * @param int $classify
+     *
+     * @return void
+     */
+    public function addPost($classify = GameConst::GAME_ANDROID) {
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'name|游戏名称'    => 'require|token',
+                    'cp_id'        => 'require|number',
+                    'en_name|英文名称' => 'require',
+                    'classify'     => 'require|number',
+                ]
+            );
+            $_param = $this->request->param();
+            $_param['is_sdk'] = $this->sdk;
+            $_param['classify'] = $classify;
+            if (GameConst::GAME_H5 == $classify) {   //h5 游戏只有在线游戏
+                $_param['is_online'] = GameConst::GAME_IS_ON_LINE;
+            }
+            if (isset($_param['cp_id']) && !empty($_param['cp_id'])) {
+                $_param['add_cp_time'] = time();
+            }
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_game_model = new GameModel();
+            $_rs = $_game_model->addGames($_param);
+            if ($_rs) {
+                switch ($classify) {
+                    case GameConst::GAME_ANDROID:
+                        $_url = url('admin/game.cps_game/andindex');
+                        break;
+                    case GameConst::GAME_IOS:
+                        $_url = url('admin/game.cps_game/iosindex');
+                        break;
+                    default:
+                        $_url = url('admin/game.cps_game/index');
+                }
+                $this->adminSuccess(lang('ADD_SUCCESS'), $_url);
+            } else {
+                $this->adminError(lang('ADD_FAILED'));
+            }
+        } else {
+            $this->adminError(lang('ADD_FAILED'));
+        }
+    }
+
+    /**
+     * 编辑游戏处理函数
+     *
+     * @throws
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'id'               => 'require|number|token',
+                    'name|游戏名称'        => 'require',
+                    'cp_id'            => 'require|number',
+                    'en_name|英文名称'     => 'require',
+                    'package_url|游戏地址' => 'url',
+                ]
+            );
+            $_param = $this->request->post();
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_app_id = $this->request->post('id/d', 0);
+            $_g_all = $this->getDetail($_app_id);
+            $_game_data['icon'] = $this->request->post('icon/s', '');
+            $_game_data['name'] = $this->request->post('name/s', '');
+            $_game_data['publicity'] = $this->request->post('publicity/s', '');
+            $_game_data['description'] = $this->request->post('description/s', '');
+            $_game_data['cp_id'] = $this->request->post('cp_id/s', 0);
+            $_game_data['hot_image'] = $this->request->post('hot_image/s', '');
+            $_game_data['fine_image'] = $this->request->post('fine_image/s', '');
+            $_category = $this->request->post('category/a');
+            if (is_array($_category)) {
+                $_game_data['category'] = implode(',', $_category);
+            }
+            if (!empty($_param['photo_names']) && !empty($_param['photo_urls'])) {
+                $_game_data['image'] = [];
+                foreach ($_param['photo_urls'] as $_key => $_url) {
+                    $_photo_url = cmf_asset_relative_url($_url);
+                    array_push(
+                        $_game_data['image'], ["url" => $_photo_url, "name" => $_param['photo_names'][$_key]]
+                    );
+                }
+            }
+            $_rs = GameModel::update($_game_data, ['id' => $_app_id]);
+            if (false !== $_rs) {
+                $_gv_data['package_url'] = $this->request->post('package_url/s', '');
+                $_gv_data['size'] = $this->request->post('size/s', '');
+                $_gv_data['size'] = $this->format_size($_gv_data['size']);
+                $_gv_data['version'] = $this->request->post('version/s', '');
+                $_gv_map['id'] = $_g_all['gv'][0]['id'];
+                $_gv_model = new GameversionModel();
+                $_gv_model->save($_gv_data, $_gv_map);
+                if (!empty($_category)) {
+                    /* 先删除所有类型 */
+                    $_gc_map['id'] = ['gt', 0];
+                    $_gc_map['app_id'] = $_app_id;
+                    $_gc_model = new GamecategoryModel();
+                    $_gc_rs = $_gc_model->where($_gc_map)->delete();
+                    if (false !== $_gc_rs) {
+                        $_gc_data = [];
+                        foreach ($_category as $_v) {
+                            $_gc_temp_data['app_id'] = $_app_id;
+                            $_gc_temp_data['cate_id'] = $_v;
+                            $_gc_data[] = $_gc_temp_data;
+                        }
+                        $_gc_model->insertAll($_gc_data);
+                    }
+                }
+                switch ($_param['classify']) {
+                    case GameConst::GAME_ANDROID:
+                        $_url = url('admin/game.cps_game/andindex');
+                        break;
+                    case GameConst::GAME_IOS:
+                        $_url = url('admin/game.cps_game/iosindex');
+                        break;
+                    default:
+                        $_url = url('admin/game.cps_game/index');
+                }
+                $this->adminSuccess(lang('edit success'), $_url);
+            } else {
+                $this->adminError("edit failure");
+            }
+        } else {
+            $this->adminError("param error");
+        }
+    }
+
+    /**
+     * 游戏地址
+     *
+     * @return mixed
+     */
+    public function gameurl() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = GameCache::ins()->getInfoByAppId($_app_id);
+        if (empty($_data['gv'][0])) {
+            $this->adminError('param error');
+        }
+        $_package_url = isset($_data['gv'][0]['package_url']) ? $_data['gv'][0]['package_url'] : '';
+        $this->assign($_data);
+        $this->assign('package_url', $_package_url);
+
+        return $this->fetch('game/cps_game/game');
+    }
+
+    /**
+     * 游戏地址
+     *
+     * @return mixed
+     */
+    public function editPackageUrl() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_gc_class = GameCache::ins();
+        $_game_data = $_gc_class->getInfoByAppId($_app_id);
+        if (empty($_game_data)) {
+            $this->adminError(lang('ERROR'));
+        }
+        $_gv_data['package_url'] = $this->request->param('package_url/s', '');
+        if (empty($_gv_data['package_url'])) {
+            $this->adminError(lang('param error'));
+        }
+        $_gv_model = new GameversionModel();
+        $_map['id'] = $_game_data['gv'][0]['id'];
+        $_rs = $_gv_model->save($_gv_data, $_map);
+        if (false !== $_rs) {
+            $_gc_class->updateGame($_app_id, $_game_data, true);
+            $this->assign($_game_data);
+            $this->adminSuccess(lang('SUCCESS'));
+        } else {
+            $this->adminError('服务器内部错误');
+        }
+    }
+
+    /**
+     * 添加CP
+     */
+    public function cpsAdd() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->assign('app_id', $_app_id);
+
+        return $this->fetch();
+    }
+
+    public function cpsAddPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $_app_id = $_param['app_id'];
+            $result = $this->validate($_param, 'Channel.add');  //add场景验证
+            if (true !== $result) {
+                $this->adminError($result);
+            }
+            $_param['is_delete'] = CommonConst::CONST_NOT_DELETE;
+            $_param['create_time'] = time();
+            $_rs = (new ChannelLogic())->addChannel($_param, true);
+            if ($_rs) {
+                $_gc_class = GameCache::ins();
+                $_game_data = $_gc_class->getInfoByAppId($_app_id);
+                $_game_data['cp_id'] = $_rs;
+                $_rs = $_gc_class->updateGame($_app_id, $_game_data);
+            }
+        } else {
+            $_rs = false;
+        }
+        if ($_rs) {
+            $this->adminSuccess(lang('ADD_SUCCESS'), $this->index_url);
+        } else {
+            $this->adminSuccess(lang('ADD_FAILED'));
+        }
+    }
+
+    /**
+     * 编辑CP处理
+     *
+     * @return mixed
+     */
+    public function cps() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $_cps_name_select = Filter::selectCommon((new ChannelLogic())->getNamesById(), 'cp_id', 0);
+        $this->assign('cps_name_select', $_cps_name_select);
+        $this->assign($_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     * app_id
+     * 编辑CP提交
+     */
+    public function cpsPost() {
+        $_validate = new Validate(
+            [
+                'app_id' => 'require|number|token',
+                'cp_id'  => 'require',
+            ]
+        );
+        $_param = $this->request->param();
+        if (!$_validate->check($_param)) {
+            $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+        }
+        $_app_id = $_param['app_id'];
+        $_gc_class = GameCache::ins();
+        $_game_data = $_gc_class->getInfoByAppId($_app_id);
+        $_game_data['cp_id'] = $_param['cp_id'];
+        $_rs = $_gc_class->updateGame($_app_id, $_game_data);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'), $this->request->server('HTTP_REFERER'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+
+    /**
+     * 格式话文件大小 将大小转为B单位 如 1KB => 1024
+     *
+     * @param $size
+     *
+     * @return bool|string
+     */
+    public function format_size($size) {
+        $size = strtoupper($size);  //转大写
+        $size = StrUtils::trimAll($size);
+        $_unit = substr($size, -2);  //获取单位
+        $_size = substr($size, 0, -2);
+        switch ($_unit) {
+            case 'KB':
+                $_size = $_size * 1024;
+                break;
+            case 'MB':
+                $_size = $_size * pow(1024, 2);
+                break;
+            case 'GB':
+                $_size = $_size * pow(1024, 3);
+                break;
+            case 'TB':
+                $_size = $_size * pow(1024, 4);
+                break;
+            case 'PB':
+                $_size = $_size * pow(1024, 5);
+                break;
+            case 'EB':
+                $_size = $_size * pow(1024, 6);
+                break;
+            default:
+                $_size = substr($size, 0, -1);
+        }
+
+        return $_size;
+    }
+}

+ 233 - 0
admin/admin/controller/game/GameCategoryController.php

@@ -0,0 +1,233 @@
+<?php
+/**
+ * GameCategoryController.php UTF-8
+ * 游戏类型管理
+ *
+ * @date    : 2017/11/18 10:48
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\game\CategoryCache;
+use huo\model\game\CategoryModel;
+use huolib\constant\CacheConst;
+use huolib\constant\GameConst;
+use think\Cache;
+use think\Lang;
+use think\Validate;
+
+class GameCategoryController extends AdminbaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(
+            [
+                APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'game_category'.EXT,
+            ]
+        );
+        parent::_initialize();
+    }
+
+    /**
+     * 类型列表
+     * admin/game.game_category/index
+     */
+    public function index() {
+        $_categoryTree = (new CategoryModel())->adminCategoryTableTree(0, '', false);
+        $this->assign('category', $_categoryTree);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 标签列表
+     * admin/game.game_category/tagindex
+     */
+    public function tagindex() {
+        $_field = ['id', 'name', 'bg_color', 'font_color', 'status', 'list_order'];
+        $_tags = (new CategoryModel())->getList(0, '-list_order', GameConst::CATEGORY_TYPE_TAG, $_field, false);
+        $this->assign('list', $_tags);
+        $this->assign('type', GameConst::CATEGORY_TYPE_TAG);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加游戏类型
+     * admin/game.game_category/add
+     */
+    public function add() {
+        $type = $this->request->param('type/d', GameConst::CATEGORY_TYPE_CATE);
+        $this->assign('type', $type);
+        $_status_radio = Filter::radioCommon($this->_category_status(), 'status', GameConst::CATEGORY_TYPE_DISPLAY);
+        $this->assign('status_radio', $_status_radio);
+        if (GameConst::CATEGORY_TYPE_TAG == $type) {
+            return $this->fetch('tagadd');
+        }
+        $parentId = $this->request->param('parent/d', 0);
+        $_cate_model = new CategoryModel();
+        $_cate_tree = $_cate_model->adminCategoryTree($parentId);
+        $this->assign('categories_tree', $_cate_tree);
+
+        return $this->fetch();
+    }
+
+    public function _category_status() {
+        $_status = [
+            '1' => lang('HIDDEN'),
+            '2' => lang('DISPLAY'),
+        ];
+        $this->assign('category_status', $_status);
+
+        return $_status;
+    }
+
+    public function _category_type() {
+        $_type = [
+            '1' => lang('label'),
+            '2' => lang('features'),
+        ];
+        $this->assign('category_type', $_type);
+
+        return $_type;
+    }
+
+    /**
+     * 添加游戏类型处理函数
+     * admin/game.game_category/addPost
+     */
+    public function addPost() {
+        $_param = $this->request->param();
+        $_url = url('Game.gameCategory/index');
+        if (GameConst::CATEGORY_TYPE_CATE == $_param['type']) {
+            $_rute = ['name' => 'require'];
+            $_msg = ['name.require' => '类型名称不能为空'];
+        } else {
+            $_rute = ['name' => 'require'];
+            $_msg = ['name.require' => '标签名称不能为空'];
+            $_url = url('Game.gameCategory/tagindex');
+        }
+        $_validate = new Validate($_rute, $_msg);
+        if (!$_validate->check($_param)) {
+            $this->adminError($_validate->getError());
+        }
+        $_rs = (new CategoryCache())->addCategory($_param['type'], $_param);
+        if ($_rs === false) {
+            $this->adminError(lang('add failure'));
+        }
+        $this->adminSuccess(lang('add success'), $_url);
+    }
+
+    /**
+     * 编辑游戏类型
+     * admin/game.game_category/edit
+     */
+    public function edit() {
+        $_id = $this->request->param('id/d', 0);
+        if ($_id > 0) {
+            $_cate_model = new CategoryModel();
+            $_cate = $_cate_model->getInfoById($_id);
+            if (empty($_cate)) {
+                return $this->adminError('参数错误');
+            }
+            $this->assign($_cate);
+            $_status_radio = Filter::radioCommon($this->_category_status(), 'status', $_cate['status']);
+            $this->assign('status_radio', $_status_radio);
+            if (GameConst::CATEGORY_TYPE_TAG == $_cate['type']) {
+                return $this->fetch('tagedit');
+            }
+            $_cate_tree = $_cate_model->adminCategoryTree($_cate['parent_id'], $_id);
+            $this->assign('categories_tree', $_cate_tree);
+
+            return $this->fetch();
+        } else {
+            return $this->adminError(lang('edit failure'));
+        }
+    }
+
+    /**
+     * 编辑游戏类型处理函数
+     * admin/game.game_category/editPost
+     */
+    public function editPost() {
+        $id = $this->request->param('id/d', 0);
+        if ($id > 0) {
+            $_param = $this->request->param();
+            $_url = url('Game.gameCategory/index');
+            if (GameConst::CATEGORY_TYPE_CATE == $_param['type']) {
+                $_rute = ['name' => 'require'];
+                $_msg = ['name.require' => '类型名称不能为空'];
+            } else {
+                $_rute = ['name' => 'require'];
+                $_msg = ['name.require' => '标签名称不能为空'];
+                $_url = url('Game.gameCategory/tagindex');
+            }
+            $_validate = new Validate($_rute, $_msg);
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError());
+            }
+            $_rs = (new CategoryCache())->updateCategory($_param['type'], $_param);
+            if ($_rs === false) {
+                $this->adminError(lang('edit failure'));
+            }
+            $this->adminSuccess(lang('edit success'), $_url, 0, 1);
+        }
+    }
+
+    /**
+     * 删除
+     * admin/game.game_category/delete
+     */
+    public function delete() {
+        $id = $this->request->param('id/d', 0);
+        if ($id > 0) {
+            $_id = (new Categorycache())->deleteCategory($id);
+            if (false === $_id) {
+                $this->adminError(lang('please delete subcategories'));
+            }
+            $this->adminSuccess(lang('delete success'));
+        } else {
+            $this->adminError(lang('delete failure'));
+        }
+    }
+
+    /**
+     * 排序
+     * admin/game.game_category/listOrder
+     */
+    public function listOrder() {
+        $_type = $this->request->param('type/d', GameConst::CATEGORY_TYPE_CATE);
+        $_r = parent::listOrders(new CategoryModel());
+        if (GameConst::CATEGORY_TYPE_CATE == $_type) {
+            Cache::rm(CacheConst::KEY_CACHE_GAME_CATEGORY);//清除缓存
+        } else {
+            Cache::rm(CacheConst::KEY_CACHE_GAME_TAG);//清除缓存
+        }
+        $this->adminSuccess("排序更新成功!");
+    }
+
+    /**
+     * 设置状态
+     * admin/game.game_category/setStatus
+     */
+    public function setStatus() {
+        $_id = $this->request->param('id/d', 0);
+        $_data = (new CategoryModel())->getInfoById($_id);
+        $_status = $this->request->param('status/d', GameConst::CATEGORY_TYPE_DISPLAY);
+        if (empty($_data)) {
+            $this->adminError('参数错误');
+        }
+        $_data['status'] = $_status;
+        $_rs = (new CategoryCache())->updateCategory($_data['type'], $_data);
+        if (false == $_rs) {
+            $this->adminError('修改失败!');
+        }
+        $this->adminSuccess('修改成功!');
+    }
+}
+

+ 1354 - 0
admin/admin/controller/game/GameController.php

@@ -0,0 +1,1354 @@
+<?php
+/**
+ * GameController.php UTF-8
+ * 游戏管理类
+ *
+ * @date    : 2017/11/29 14:34
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use admin\admin\validate\GameValidate;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\game\CategoryCache;
+use huo\controller\game\GameCache;
+use huo\controller\game\GameList;
+use huo\controller\game\Gamepack;
+use huo\logic\agent\AgentGameLogic;
+use huo\logic\game\ChannelLogic;
+use huo\logic\game\GameLogic;
+use huo\logic\member\CpLogic;
+use huo\model\game\CategoryModel;
+use huo\model\game\GamecategoryModel;
+use huo\model\game\GameextModel;
+use huo\model\game\GameModel;
+use huo\model\game\GameversionModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\MpConfConst;
+use huolib\constant\OrderConst;
+use huomp\model\game\GameMiniModel;
+use huomp\model\weixin\MpConfModel;
+use huomp\model\weixin\OaMpModel;
+use think\Lang;
+use think\Loader;
+use think\Validate;
+
+class GameController extends AdminbaseController {
+    protected $hasOa;
+    protected $sdk              = GameConst::GAME_IS_SDK;
+    protected $classify         = 0;
+    protected $is_delete        = CommonConst::CONST_NOT_DELETE;
+    protected $index_url        = '';
+    protected $delete_index_url = '';
+    protected $mp_classify
+                                = [GameConst::GAME_MP, GameConst::GAME_MP_BOX, GameConst::GAME_MP_RPBOX,
+                                   GameConst::GAME_MP_PERSONAL,GameConst::GAME_IOS_SWITCH_H5];
+
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'game'.EXT);
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'cp'.EXT);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+        $this->hasOa = \huolib\oa\Oa::hasOa();
+        $this->assign('hasOa', $this->hasOa);
+    }
+
+    /**
+     * 游戏状态
+     */
+    public function _gameStatus() {
+        $_game_status = [
+            GameConst::GAME_STATUS_ACCESS => lang('in access'),
+            GameConst::GAME_STATUS_ON     => lang('online'),
+            GameConst::GAME_STATUS_OFF    => lang('offline'),
+        ];
+        $this->assign('game_status', $_game_status);
+        $_game_status_select = Filter::selectCommon($_game_status, 'status', $this->request->get('status/d', 0));
+        $this->assign('game_status_select', $_game_status_select);
+
+        return $_game_status;
+    }
+
+    /**
+     * 网游单机函数
+     *
+     * @return array
+     */
+    private function _isOnline() {
+        $_is_on_arr = [
+            GameConst::GAME_IS_SINGLE  => lang('single_game'),
+            GameConst::GAME_IS_ON_LINE => lang('online_game')
+        ];
+        $this->assign('is_online', $_is_on_arr);
+
+        return $_is_on_arr;
+    }
+
+    /**
+     * 支付切换函数
+     *
+     * @return array
+     */
+    protected function _need_popup() {
+        $_need_popup_arr = [
+            GameConst::RATE_MP_NEED_POPUP_NOT => '否',
+            GameConst::RATE_MP_NEED_POPUP     => '是'
+        ];
+        $this->assign('need_popup', $_need_popup_arr);
+
+        return $_need_popup_arr;
+    }
+
+    /**
+     * 入口图片打开
+     *
+     * @return array
+     */
+    protected function _paySwitch() {
+        $_pay_switch_arr = [
+            OrderConst::PAY_SWITCH_YES => '切换',
+            OrderConst::PAY_SWITCH_NO  => '不切换'
+        ];
+        $this->assign('pay_switch', $_pay_switch_arr);
+
+        return $_pay_switch_arr;
+    }
+
+    /**
+     * 支付显示控制
+     *
+     * @return array
+     */
+    protected function _payShow() {
+        $_pay_show_arr = [
+            CommonConst::STATUS_NO  => '不显示',
+            CommonConst::STATUS_YES => '显示'
+        ];
+        $this->assign('pay_show', $_pay_show_arr);
+
+        return $_pay_show_arr;
+    }
+
+    /**
+     * 浮点显示函数
+     *
+     * @return array
+     */
+    private function _floatIsShow() {
+        $_float_is_show_arr = [
+            GameConst::GAME_FLOAT_IS_HIDDEN => lang('not show'),
+            GameConst::GAME_FLOAT_IS_SHOW   => lang('show')
+        ];
+        $this->assign('float_is_show', $_float_is_show_arr);
+
+        return $_float_is_show_arr;
+    }
+
+    /**
+     * 是否可推广游戏函数
+     *
+     * @return array
+     */
+    private function _promoteSwitch() {
+        $_promote_switch_arr = [
+            GameConst::GAME_PROMOTE_SWITCH_NO    => lang('do not promote'),
+            GameConst::GAME_PROMOTE_SWITCH_CAN   => lang('promote'),
+            GameConst::GAME_PROMOTE_SWITCH_CHECK => lang('need check')
+        ];
+        $this->assign('promote_switch', $_promote_switch_arr);
+
+        return $_promote_switch_arr;
+    }
+
+    /**
+     * 游戏列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function index() {
+        $_app_id = $this->request->get('app_id/d', 0);
+        $classify = $this->request->get('classify/d', $this->classify);
+        if (!empty($classify)) {
+            if (3 == substr($classify, 0, 1)) {
+                $_map['classify'] = [
+                    ['eq', 3],
+                    ['between', [300, 399]],
+                    'or'
+                ];
+            } elseif (4 == substr($classify, 0, 1) && 401 != $classify) {
+                $_map['classify'] = [
+                    ['eq', 4],
+                    ['between', [400, 499]],
+                    'or'
+                ];
+            } elseif (in_array($classify, [601, 602])) {
+                $_map['classify'] = ['in', [601, 602]];
+            } elseif (6 == substr($classify, 0, 1) && !in_array($classify, [601, 602, 603])) {
+                $_map['classify'] = [
+                    ['eq', 6],
+                    ['between', [604, 699]],
+                    'or'
+                ];
+            } else {
+                $_map['classify'] = $classify;
+            }
+        }
+        $_map['is_delete'] = $this->is_delete;
+        $_map['is_sdk'] = $this->request->get('is_sdk/d', $this->sdk);
+        $_map['apple_id'] = $this->request->get('vset_re_app_id/d', 0);
+        $this->getList($_map);
+        $this->_games($_app_id, 0, $this->is_delete, $this->sdk, $classify, false, true);
+        $this->_mp_games($_map['apple_id']);
+        if (GameConst::GAME_IS_SDK == $this->sdk) {
+            $_cps = (new CpLogic())->getNamesById();
+        } else {
+            $_cps = (new ChannelLogic())->getNamesById();
+        }
+        $_cp_name_select = Filter::selectCommon($_cps, 'cp_id', 0);
+        $this->assign('cp_name_select', $_cp_name_select);
+        $this->assign('cps', $_cps);
+        $_pay_switch_game_classify = [GameConst::GAME_IOS, GameConst::GAME_MP, GameConst::GAME_MP_PERSONAL];
+        if (in_array($this->classify, $_pay_switch_game_classify)) {
+            $_pay_check = $this->_paySwitch();
+            $_pay_check = Filter::selectCommon($_pay_check, 'pay_switch', $this->request->param('pay_switch/d', 0));
+            $this->assign('pay_check', $_pay_check);
+            $_pay_show = $this->_payShow();
+            $_pay_show = Filter::selectCommon($_pay_show, 'pay_show', $this->request->param('pay_show/d', 0));
+            $this->assign('pay_show_select', $_pay_show);
+        }
+        /*搜索*/
+        $_game_status = $this->_gameStatus();
+        $_game_status_select = Filter::selectCommon($_game_status, 'status', $this->request->get('status/d', 0));
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $this->assign('game_status_select', $_game_status_select);
+        $this->assign('classify', $classify);
+        $this->assign('is_sdk', $this->sdk);
+        $this->assign('filter_button', $_filter_button);
+        $this->assign('total_div', $this->total_div);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', 'uri' => $this->index_url]
+        );
+        $this->assign('filter_button_clear', $_filter_button_clear);
+        if (GameConst::GAME_MP == $this->classify || GameConst::GAME_MP_BOX == $this->classify) {
+            return $this->fetch('box/game/index');
+        }
+        if (GameConst::GAME_MP_PERSONAL == $this->classify) {
+            return $this->fetch('box/game/personal');
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * @param        $where
+     * @param string $field
+     * @param string $order
+     *
+     * @return \think\Paginator
+     * @throws \think\exception\DbException
+     */
+    public function getList($where, $field = '', $order = '') {
+        $_get = $this->request->param('', '', 'trim');
+        $_param = array_merge($_get, $where);
+        $_map = [];
+        $_key_arr
+            = ['id', 'name', 'en_name', 'category', 'classify', 'cp_id', 'parent_id',
+               'status', 'is_delete',
+               'is_online', 'delete_time', 'icon',
+               'is_sdk', 'fine_order', 'hot_order', 'pay_switch'];
+        foreach ($_param as $_k => $_v) {
+            if (in_array($_k, $_key_arr) && !empty($_v)) {
+                $_map[$_k] = $_v;
+            }
+        }
+        if (isset($_get['app_id']) && !empty($_get['app_id'])) {
+            $_map['id'] = $_get['app_id'];
+        } else {
+            $_map['id'] = ['not in', ['100']];
+        }
+        $_order = 'id desc';
+        if (!empty($order)) {
+            $_order = $order;
+        }
+        $_game_model = new GameModel();
+        if (!empty($field)) {
+            if ($this->hasOa) {
+                $_items = $_game_model->useGlobalScope(false)->with('oa')->where($_map)->field($field)->order(
+                    $_order
+                )->paginate();
+            } else {
+                $_items = $_game_model->useGlobalScope(false)->where($_map)->field($field)->order($_order)
+                                      ->paginate();
+            }
+        } else {
+            $_game_field
+                = 'id,name,pay_switch,pay_show,cp_id,status,run_time,cp_payback_url,is_online,icon,delete_time,down_cnt,classify, classify as classify_label ,parent_id';
+            $_gv_field = "id,app_id,version_key,package_url";
+            if ($this->hasOa) {
+                $_items = $_game_model->useGlobalScope(false)->with('mini,linkgame')->with(
+                    ['gv' => function ($query) use ($_gv_field) {
+                        $query->field($_gv_field);
+                    }]
+                )->with('oa')->field($_game_field)->where($_map)->order('id desc')->paginate();
+            } elseif (in_array($this->classify, $this->mp_classify)) {
+                $_items = $_game_model->useGlobalScope(false)->with('mini,linkgame,ext')->with(
+                    ['gv' => function ($query) use ($_gv_field) {
+                        $query->field($_gv_field);
+                    }]
+                )->field($_game_field)->where($_map)->order('id desc')->paginate();
+            } else {
+                $_items = $_game_model->useGlobalScope(false)->with('linkgame,ext')->with(
+                    ['gv' => function ($query) use ($_gv_field) {
+                        $query->field($_gv_field);
+                    }]
+                )->field($_game_field)->where($_map)->order('id desc')->paginate();
+            }
+        }
+        $_re_data = $_items->toArray();
+        $_list = [];
+        foreach ($_re_data['data'] as $_k => $_v) {
+            $_v['parent_game']['game_id'] = 0;
+            $_v['parent_game']['game_name'] = '';
+            // 有关联游戏的
+            if (!empty($_v['parent_id'])) {
+                if (GameConst::GAME_MP == $_v['classify']) {
+                    $_link_game_id = $_game_model->getLinkAppId($_v['id']);
+                    if (!empty($_link_game_id)) {
+                        $_v['parent_game']['game_id'] = $_link_game_id;
+                        $_v['parent_game']['game_name'] = $_game_model->getNameById($_link_game_id);
+                    }
+                } elseif (GameConst::GAME_H5 == $_v['classify']) {
+                    if ($_v['parent_id'] != $_v['id']) {
+                        $_v['parent_game']['game_id'] = $_v['parent_id'];
+                        $_v['parent_game']['game_name'] = $_game_model->getNameById($_v['parent_id']);
+                    }
+                }
+            }
+            $_v['game_url'] = MOBILESITE .'/sdk.php/game?game_id=' . $_v['id'] . '&agent_id=0';;
+            $_list[] = $_v;
+        }
+        $this->assign('page', $_items->render());
+        $this->assign('items', $_list);
+
+        return $_items;
+    }
+
+    /**
+     * 关联游戏
+     * admin/game.game/linkGame
+     */
+    public function linkGame() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        switch ($this->classify) {
+            /*小游戏游戏则显示H5游戏列表*/
+            case GameConst::GAME_MP:
+                $_map_classify = [GameConst::GAME_H5];
+                break;
+            /*H5游戏则显示小游戏列表*/
+            case GameConst::GAME_H5:
+                $_map_classify = [GameConst::GAME_MP];
+                break;
+            default:
+                return false;
+                break;
+        }
+        /*GET请求则渲染游戏选择框*/
+        if ($this->request->isGet()) {
+            $_game_logic = new GameLogic();
+            $_game_data = $_game_logic->getInfoByAppId($_app_id);
+            if (empty($_game_data)) {
+                return $this->adminError(lang('MSG_GAME_SELECT_ERROR'));
+            }
+            if ($this->classify == GameConst::GAME_ANDROID) {
+                // 获取当前安卓游戏关联的ios游戏id 为选中状态
+                $_map = [
+                    'parent_id' => $_app_id,
+                    'classify'  => ['neq', $this->classify]
+                ];
+                $_game_data['parent_id'] = (new GameModel())->getIdByWhere($_map);
+            }
+            $_game_where = [
+                'parent_id' => ['elt', 0],
+            ];
+            $this->_games(
+                $_game_data['parent_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0, $_map_classify,
+                false, true, $_game_where, '', '', 'parent_id'
+            );
+        }
+
+        return true;
+    }
+
+    /**
+     * 设置关联游戏
+     * admin/game.game/linkGamePost
+     */
+    public function linkGamePost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            /*校验参数*/
+            $_validate = new GameValidate('linkGame');
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError());
+            }
+            $_app_id = $this->request->post('app_id/d', 0);
+            $_parent_id = $this->request->post('parent_id/d', 0);
+            $_game_logic = new GameLogic();
+            $_game_cache = GameCache::ins();
+            $_game_data = $_game_logic->getInfoByAppId($_app_id);
+            $_parent_game_data = $_game_logic->getInfoByAppId($_parent_id);
+            if ($this->classify == GameConst::GAME_MP) {
+                $_old_map = [
+                    'parent_id' => $_app_id,
+                    'classify'  => ['neq', $this->classify]
+                ];
+                $_old_parent_id = (new GameModel())->getIdByWhere($_old_map);
+                $_old_parent_game_data = $_game_logic->getInfoByAppId($_old_parent_id);
+            } else {
+                $_old_parent_game_data = $_game_logic->getInfoByAppId($_game_data['parent_id']);
+            }
+            /* 1.取消当前游戏的相关联的游戏的parent_id*/
+            if (0 < $_game_data['parent_id'] && !empty($_old_parent_game_data)
+                && ($_old_parent_game_data['id'] != $_parent_id)) {
+                $_rs1 = $_game_cache->updateGame($_old_parent_game_data['id'], ['parent_id' => 0], true);
+            } else {
+                $_rs1 = true;
+            }
+            /* 2.关联当前游戏的parent_id */
+            if (0 == $_parent_id) {
+                $_game_data['parent_id'] = 0;
+            } else {
+                $_game_data['parent_id'] = $this->classify == GameConst::GAME_MP ? $_app_id : $_parent_id;
+            }
+            $_rs2 = $_game_cache->updateGame($_app_id, ['parent_id' => $_game_data['parent_id']], true);
+            /*3. 设置关联的游戏也关联当前游戏 */
+            if (0 < $_parent_id) {
+                $_parent_game_data['parent_id'] = $_parent_game_data['classify'] == GameConst::GAME_MP
+                    ? $_parent_id : $_app_id;
+                $_rs3 = $_game_cache->updateGame($_parent_id, ['parent_id' => $_parent_game_data['parent_id']], true);
+            } else {
+                $_rs3 = true;
+            }
+            if ($_rs1 && $_rs2 && $_rs3) {
+                $this->adminSuccess(lang('CHANGE_SUCCESS'));
+            }
+        }
+        $this->adminError(lang('CHANGE_FAILED'), '', ['token' => token()]);
+    }
+
+    /**
+     * 添加游戏
+     */
+    public function add() {
+        $_classify = $this->request->param('classify/d', $this->classify);
+        $this->assign('classify', $_classify);
+        $_is_sdk = $this->request->param('is_sdk/d', $this->sdk);
+        $this->assign('is_sdk', $_is_sdk);
+        $_is_online_radio = Filter::radioCommon($this->_isOnline(), 'is_online', GameConst::GAME_IS_ON_LINE);
+        $this->assign('is_online_radio', $_is_online_radio);
+        $_is_pay_switch = Filter::radioCommon($this->_paySwitch(), 'pay_switch', OrderConst::PAY_SWITCH_NO);
+        $this->assign('is_pay_switch', $_is_pay_switch);
+        if (GameConst::GAME_IS_SDK == $this->sdk) {
+            $_cp_name_select = Filter::selectCommon((new CpLogic())->getNamesById(), 'cp_id', 0);
+            $this->assign('cp_name_select', $_cp_name_select);
+        } else {
+            $_cp_name_select = Filter::selectCommon((new ChannelLogic())->getNamesById(), 'cp_id', 0);
+            $this->assign('cp_name_select', $_cp_name_select);
+        }
+        if (GameConst::GAME_MP_BOX == $this->classify) {
+            $_box_type = [
+                GameConst::GAME_MP_BOX   => '金币盒子',
+                GameConst::GAME_MP_RPBOX => '红包盒子'
+            ];
+            $_box_type = Filter::radioCommon($_box_type, 'classify', GameConst::GAME_MP_BOX);
+            $this->assign('box_type', $_box_type);
+        }
+        $_cate_model = new CategoryModel();
+        $_cates = $_cate_model->getIdNames();
+        $this->assign('cates', $_cates);
+        $_cates_box_check = Filter::checkCommon($_cates, 'category[]', '');
+        $this->assign('cates_box_check', $_cates_box_check);
+        $_float_is_show = Filter::radioCommon($this->_floatIsShow(), 'float_is_show', GameConst::GAME_FLOAT_IS_HIDDEN);
+        $this->assign('float_is_show', $_float_is_show);
+        if (in_array($this->classify, $this->mp_classify)) {
+            return $this->fetch('box/game/add');
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加游戏处理函数
+     *
+     * @return bool|mixed
+     */
+    public function addPost() {
+        $classify = $this->request->param('classify/d', $this->classify);
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'name|游戏名称' => 'require|token',
+                    'cp_id'     => 'require|number',
+                    'classify'  => 'require|number',
+                ]
+            );
+            $_param = $this->request->param();
+            $_param['is_sdk'] = get_val($_param, 'is_sdk', $this->sdk);
+            $_param['promote_switch'] = get_val($_param, 'promote_switch', 2);
+            $_param['classify'] = $classify;
+            if (GameConst::GAME_H5 == $classify) {   //h5 游戏只有在线游戏
+                $_param['is_online'] = GameConst::GAME_IS_ON_LINE;
+            }
+            if (isset($_param['cp_id']) && !empty($_param['cp_id'])) {
+                $_param['add_cp_time'] = time();
+            }
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_game_model = new GameModel();
+            Loader::import('pinyin/Pin', '', '.class.php');
+            $_pin_class = new \Pin();
+            $_param['en_name'] = $_pin_class->pinyin($_param['name']);
+            $_rs = $_game_model->addGames($_param);
+        } else {
+            $_rs = false;
+        }
+        if ($_rs) {
+            $this->adminSuccess(lang('ADD_SUCCESS'), $this->index_url);
+        } else {
+            $this->adminSuccess(lang('ADD_FAILED'));
+        }
+    }
+
+    /**
+     * 删除游戏
+     */
+    public function delete() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data['id'] = $_app_id;
+        $_data['is_delete'] = CommonConst::CONST_DELETED;
+        $_data['delete_time'] = time();
+        $_game_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $_rs = GameCache::ins()->updateGame($_app_id, $_data, true);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            //小程序处理
+            if (GameConst::GAME_MP_BOX == $_game_data['classify'] || GameConst::GAME_MP == $_game_data['classify']) {
+                /* 删除游戏关联公众号 */
+                (new OaMpModel())->deleteDataByAppId($_app_id);
+            }
+            if ($this->hasOa) {
+                $_game_model = new GameModel();
+                $_game_model->deleteOaGame($_app_id);
+            }
+            /* 删除游戏关联 Gamecategory表 数据*/
+            (new GamecategoryModel())->deleteDataByWhere(['app_id' => $_app_id]);
+            /*删除渠道游戏*/
+            unset($_data['id']);  //app_id 在后续不需要
+            (new AgentGameLogic())->UpdateAgentGameByAppId($_app_id, $_data);
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+
+    /**
+     * 设置状态 上线 下线
+     *
+     * @throws
+     */
+    public function setStatus() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_status = $this->request->param('status/d', GameConst::GAME_STATUS_ACCESS);
+        if (empty($_app_id) || empty($_status)) {
+            $this->adminError(lang('param error'));
+        }
+        if (2 == $_status) {
+            $_data['run_time'] = time();
+            $_msg = lang('online');
+        } else {
+            $_msg = lang('offline');
+        }
+        $_data['status'] = $_status;
+        $_data['id'] = $_app_id;
+        $_rs = GameCache::ins()->updateGame($_app_id, $_data);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+
+    /**
+     * CP回调地址处理
+     *
+     * @return mixed
+     */
+    public function cpurl() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $this->assign($_data);
+        if (GameConst::GAME_MP == $this->classify) {
+            return $this->fetch('box/game/cpurl');
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * app_id
+     * cp_payback_url
+     * 编辑回调
+     */
+    public function editCpUrl() {
+        $_validate = new Validate(
+            [
+                'app_id'         => 'require|number|token',
+                'cp_payback_url' => 'require|url',
+            ]
+        );
+        $_param = $this->request->param();
+        if (!$_validate->check($_param)) {
+            $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+        }
+        $_app_id = $_param['app_id'];
+        $_gc_class = GameCache::ins();
+        $_game_data = $_gc_class->getInfoByAppId($_app_id);
+        $_game_data['cp_payback_url'] = $_param['cp_payback_url'];
+        $_rs = $_gc_class->updateGame($_app_id, $_game_data);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'), $this->request->server('HTTP_REFERER'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+
+    /**
+     * 添加CP
+     */
+    public function cpAdd() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->assign('app_id', $_app_id);
+        if (GameConst::GAME_MP == $this->classify) {
+            return $this->fetch('box/game/cp_add');
+        }
+
+        return $this->fetch();
+    }
+
+    public function cpAddPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $_app_id = $_param['app_id'];
+            $result = $this->validate($_param, 'Cp.add');  //add场景验证
+            if (true !== $result) {
+                $this->adminError($result);
+            }
+            $_param['is_delete'] = CommonConst::CONST_NOT_DELETE;
+            $_param['create_time'] = time();
+            $_rs = (new CpLogic())->addCp($_param, true);
+            if ($_rs) {
+                $_gc_class = GameCache::ins();
+                $_game_data = $_gc_class->getInfoByAppId($_app_id);
+                $_game_data['cp_id'] = $_rs;
+                $_rs = $_gc_class->updateGame($_app_id, $_game_data);
+            }
+        } else {
+            $_rs = false;
+        }
+        if ($_rs) {
+            $this->adminSuccess(lang('ADD_SUCCESS'), $this->index_url);
+        } else {
+            $this->adminSuccess(lang('ADD_FAILED'));
+        }
+    }
+
+    /**
+     * 编辑CP处理
+     *
+     * @return mixed
+     */
+    public function cp() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $_cp_name_select = Filter::selectCommon((new CpLogic())->getNamesById(), 'cp_id', $_data['cp_id']);
+        $this->assign('cp_name_select', $_cp_name_select);
+        $this->assign($_data);
+        if (GameConst::GAME_MP == $this->classify) {
+            return $this->fetch('box/game/cp');
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * app_id
+     * 编辑CP提交
+     */
+    public function cpPost() {
+        $_validate = new Validate(
+            [
+                'app_id' => 'require|number|token',
+                'cp_id'  => 'require',
+            ]
+        );
+        $_param = $this->request->param();
+        if (!$_validate->check($_param)) {
+            $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+        }
+        $_app_id = $_param['app_id'];
+        $_gc_class = GameCache::ins();
+        $_game_data = $_gc_class->getInfoByAppId($_app_id);
+        $_game_data['cp_id'] = $_param['cp_id'];
+        $_rs = $_gc_class->updateGame($_app_id, $_game_data);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'), $this->request->server('HTTP_REFERER'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+
+    /**
+     * 添加游戏母包
+     *
+     * @param      $classify
+     * @param bool $is_update
+     *
+     * @return void
+     */
+    public function addPackageUrl($classify, $is_update = false) {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_update = $this->request->param('update/d', 0);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_gc_class = GameCache::ins();
+        $_game_data = $_gc_class->getInfoByAppId($_app_id);
+        if (empty($_game_data)) {
+            $this->adminError(lang('ERROR'));
+        }
+        if (empty($_update) && !empty($_game_data['gv'][0]['package_url']) && false == $is_update) {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+        if (GameConst::GAME_ANDROID == $classify || GameConst::GAME_IOS_SWITCH == $classify) {
+            $_gp_class = new Gamepack($_app_id);
+            $_gp_class->setPinyin($_game_data['en_abbr']);
+            $_gp_class->setAgentgame($_game_data['en_abbr']);
+            $_gp_class->pack();
+            $_data = $_gp_class->getData();
+            if (empty($_data) || !is_array($_data) || !isset($_data['size'])) {
+                $this->adminError(lang('ERROR'));
+            }
+            $_gv_data['package_url'] = $_data['url'];
+            $_gv_data['size'] = $_data['size'];;
+            $_gv_data['version'] = $_data['vername'];
+        } else {
+            $_gv_data['package_url'] = $this->request->param('package_url/s', '');
+            if (empty($_gv_data['package_url'])) {
+                $this->adminError(lang('param error'));
+            }
+        }
+        $_gv_model = new GameversionModel();
+        $_map['id'] = $_game_data['gv'][0]['id'];
+        $_rs = $_gv_model->save($_gv_data, $_map);
+        if (false !== $_rs) {
+            $_game_data['package_name'] = isset($_data['pakagename']) ? $_data['pakagename']
+                : $_game_data['package_name'];
+            $_gc_class->updateGame($_app_id, $_game_data, true);
+            $this->assign($_game_data);
+            $this->adminSuccess(lang('SUCCESS'));
+        } else {
+            $this->adminError('服务器内部错误');
+        }
+    }
+
+    /**
+     * 获取对接参数
+     *
+     * @throws
+     */
+    public function param() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->assign($this->getDetail($_app_id));
+        if (in_array($this->classify, $this->mp_classify)) {
+            return $this->fetch('box/game/param');
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * @param $app_id
+     *
+     * @return array
+     */
+    public function getDetail($app_id) {
+        $_data = (new GameModel())->with('ext')->with('gv')->where('id', $app_id)->find()->toArray();
+        if (empty($_data['gv'][0])) {
+            $this->adminError(lang('param error'));
+        }
+        /*苹果游戏加协议*/
+        if (GameConst::GAME_IOS_SWITCH == $_data['classify'] || GameConst::GAME_IOS == $_data['classify']) {
+            $_data['protocol'] = 'h'.DOCDOMAIN.$_data['apple_id'].'://';
+        }
+        /*小程序添加小程序参数*/
+        if (in_array($_data['classify'], $this->mp_classify)) {
+            $_data['mp'] = (new GameMiniModel())->getDataByAppId($app_id);
+        }
+
+        return $_data;
+    }
+
+    /**
+     * 编辑游戏
+     *
+     * @param bool $fetch
+     *
+     */
+    public function edit() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_game_data = $this->getDetail($_app_id);
+        if (empty($_game_data['gv'][0])) {
+            $this->adminError('param error');
+        }
+        if ($this->hasOa) {
+            $_oa_game_model = new \huo\model\oa\OaGameModel();
+            $_oa_game = $_oa_game_model->where(array('app_id' => $_app_id))->find();
+            if (is_object($_oa_game)) {
+                $_oa_game = $_oa_game->toArray();
+            }
+            if (empty($_oa_game)) {
+                $_oa_game = [
+                    'standard_mem_cnt' => 0,
+                    'standard_level'   => 0
+                ];
+            }
+            $_game_data = $_game_data + $_oa_game;
+        }
+        $this->assign($_game_data);
+        $_cate_model = new CategoryModel();
+        $_cates = $_cate_model->getIdNames();
+        $this->assign('cates', $_cates);
+        $_cates_box_check = Filter::checkCommon($_cates, 'category[]', $_game_data['category']);
+        $this->assign('cates_box_check', $_cates_box_check);
+        $_is_pay_switch = Filter::radioCommon($this->_paySwitch(), 'pay_switch', $_game_data['pay_switch']);
+        $this->assign('is_pay_switch', $_is_pay_switch);
+        $_float_is_show = Filter::radioCommon($this->_floatIsShow(), 'float_is_show', $_game_data['float_is_show']);
+        $this->assign('float_is_show', $_float_is_show);
+        $_promote_switch = Filter::radioCommon(
+            $this->_promoteSwitch(), 'promote_switch', $_game_data['promote_switch']
+        );
+        $_tags = (new CategoryCache())->getIdNames(GameConst::CATEGORY_TYPE_TAG);
+        $this->assign('tags', $_tags);
+        $_tag_box_check = Filter::checkCommon($_tags, 'tag[]', $_game_data['tags']);
+        $this->assign('tag_box_check', $_tag_box_check);
+        $this->assign('promote_switch', $_promote_switch);
+        if (GameConst::GAME_IS_SDK == $_game_data['is_sdk']) {
+            $_cp_name_select = Filter::selectCommon((new CpLogic())->getNamesById(), 'cp_id', $_game_data['cp_id']);
+            $this->assign('cp_name_select', $_cp_name_select);
+        } else {
+            $_cp_name_select = Filter::selectCommon(
+                (new ChannelLogic())->getNamesById(), 'cp_id', $_game_data['cp_id']
+            );
+            $this->assign('cp_name_select', $_cp_name_select);
+        }
+        $_is_online_radio = Filter::radioCommon($this->_isOnline(), 'is_online', $_game_data['is_online']);
+        $this->assign('is_online_radio', $_is_online_radio);
+        if (!in_array($this->classify, $this->mp_classify)) {
+            return $this->fetch();
+        }
+    }
+
+    /**
+     * 编辑游戏处理函数
+     *
+     * @throws
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'id'             => 'require|number|token',
+                    'name'           => 'require',
+                    'package_url'    => 'url',
+                    'down_cnt'       => 'number|max:100000000',
+                    'float_is_show'  => 'require|in:1,2',
+                    'promote_switch' => 'require|in:1,2',
+                ]
+            );
+            $_param = $this->request->post();
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_app_id = $this->request->post('id/d', 0);
+            $_down_cnt = $this->request->post('down_cnt/d', 0);
+            $_g_all = $this->getDetail($_app_id);
+            $_rise_cnt = $_down_cnt - $_g_all['ext']['down_cnt'];
+            $_game_data['hot_order'] = $_g_all['hot_order'] + $_rise_cnt;
+            $_game_data['rise_order'] = $_g_all['rise_order'] + $_rise_cnt;
+            $_game_data['rise_order'] = $_g_all['rise_order'] + $_rise_cnt;
+            $_game_data['icon'] = $this->request->post('icon/s', '');
+            $_game_data['name'] = $this->request->post('name/s', '');
+            $_game_data['publicity'] = $this->request->post('publicity/s', '');
+            $_game_data['description'] = $this->request->post('description/s', '');
+            $_game_data['hot_image'] = $this->request->post('hot_image/s', '');
+            $_game_data['fine_image'] = $this->request->post('fine_image/s', '');
+            $_game_data['pay_switch'] = $this->request->post('pay_switch/d', OrderConst::PAY_SWITCH_NO);
+            $_game_data['float_is_show'] = $this->request->post('float_is_show/d', GameConst::GAME_FLOAT_IS_HIDDEN);
+            $_game_data['promote_switch'] = $this->request->post('promote_switch/d', GameConst::GAME_PROMOTE_SWITCH_NO);
+            $_category = $this->request->post('category/a');
+            if (is_array($_category)) {
+                $_game_data['category'] = implode(',', $_category);
+            }
+            if (!empty($_param['photo_names']) && !empty($_param['photo_urls'])) {
+                $_game_data['image'] = [];
+                foreach ($_param['photo_urls'] as $_key => $_url) {
+                    $_photo_url = cmf_asset_relative_url($_url);
+                    array_push(
+                        $_game_data['image'], ["url" => $_photo_url, "name" => $_param['photo_names'][$_key]]
+                    );
+                }
+            }
+            $_rs = GameModel::update($_game_data, ['id' => $_app_id]);
+            if ($this->hasOa) {
+                $_game_model = new GameModel();
+                $_oa_data = $_game_data;
+            }
+            if (false !== $_rs) {
+                $_gv_data['package_url'] = $this->request->post('package_url/s', '');
+//                $_gv_data['size'] = $this->request->post('size/s', '');
+                $_gv_data['version'] = $this->request->post('version/s', '');
+                if ($this->hasOa) {
+                    $_oa_data['standard_mem_cnt'] = $this->request->post('standard_mem_cnt/d', '');
+                    $_oa_data['standard_level'] = $this->request->post('standard_level/d', '');
+                    $_oa_game_data = array();
+                    $_oa_game_data['standard_mem_cnt'] = $_oa_data['standard_mem_cnt'];
+                    $_oa_game_data['standard_level'] = $_oa_data['standard_level'];
+                    $_oa_game_model = new \huo\model\oa\OaGameModel();
+                    \think\Log::write($_oa_data, 'debug');
+                    $_oa_game_model->save($_oa_game_data, ['app_id' => $_app_id]);
+                    $_oa_data['version'] = $_gv_data['version'];
+                }
+                $_gv_map['id'] = $_g_all['gv'][0]['id'];
+                $_gv_model = new GameversionModel();
+                $_gv_model->save($_gv_data, $_gv_map);
+                $_ge_data['down_cnt'] = $_down_cnt;
+                GameextModel::update($_ge_data, ['app_id' => $_app_id]);
+                if (!empty($_category)) {
+                    /* 先删除所有类型 */
+                    $_gc_map['id'] = ['gt', 0];
+                    $_gc_map['app_id'] = $_app_id;
+                    $_gc_model = new GamecategoryModel();
+                    $_gc_rs = $_gc_model->where($_gc_map)->delete();
+                    if (false !== $_gc_rs) {
+                        $_gc_data = [];
+                        foreach ($_category as $_v) {
+                            $_gc_temp_data['app_id'] = $_app_id;
+                            $_gc_temp_data['cate_id'] = $_v;
+                            $_gc_data[] = $_gc_temp_data;
+                        }
+                        $_gc_model->insertAll($_gc_data);
+                    }
+                }
+                if ($this->hasOa) {
+                    $_re = $_game_model->updateOaGame($_app_id, $_oa_data);
+                    if ($_re) {
+                        \think\Log::write($_oa_data, 'debug');
+                    }
+                }
+                $this->adminSuccess(lang('edit success'), url('game.game/index'));
+            } else {
+                $this->adminError("edit failure");
+            }
+        } else {
+            $this->adminError("param error");
+        }
+    }
+
+    /**
+     * 还原已删除游戏
+     */
+    public function resetPost() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data['id'] = $_app_id;
+        $_data['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_data['delete_time'] = 0;
+        $_data['update_time'] = time();
+        $_rs = GameCache::ins()->updateGame($_app_id, $_data, true);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            if ($this->hasOa) {
+                $_game_model = new GameModel();
+                $_game_model->restoreOaGame($_app_id);
+            }
+            unset($_data['id']); //app_id 在后续操作不需要
+            (new AgentGameLogic())->UpdateAgentGameByAppId($_app_id, $_data);
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+
+    /**
+     *排序处理
+     */
+    public function listOrder() {
+        $ids = $this->request->post("list_orders/a");
+        if (!empty($ids)) {
+            foreach ($ids as $key => $r) {
+                $data['id'] = $key;
+                $data['list_order'] = $r;
+                GameCache::ins()->updateGame($key, $data);
+            }
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 新游列表
+     *
+     * @throws \think\exception\DbException
+     */
+    public function newIndex() {
+        $_map['classify'] = $this->classify;
+        $_map['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_map['is_sdk'] = GameConst::GAME_IS_SDK;
+        $_map['status'] = GameConst::GAME_STATUS_ON;
+        $_field = 'id,hot_order,name,status,run_time';
+        $order = 'run_time desc';
+        $this->getList($_map, $_field, $order);
+        $_games = (new GameModel())->getIdNames(
+            0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, $this->classify, false, true
+        );
+        $_app_select = Filter::selectCommon($_games, 'id', $this->request->get('id/d', 0));
+        $this->assign('app_select', $_app_select);
+        $_game_status = $this->_gameStatus();
+        $_game_status_select = Filter::selectCommon($_game_status, 'status', $this->request->get('status/d', 0));
+        $this->assign('game_status_select', $_game_status_select);
+        $this->assign('cps', (new CpLogic())->getNamesById());
+
+        return $this->fetch();
+    }
+
+    /**
+     * 删除游戏列表
+     *
+     * @throws \think\exception\DbException
+     */
+    public function deleteIndex() {
+        $_app_id = $this->request->get('app_id/d', 0);
+        $classify = $this->classify;
+        if (!empty($classify)) {
+            if (3 == substr($classify, 0, 1)) {
+                $_map['classify'] = [
+                    ['eq', 3],
+                    ['between', [300, 399]],
+                    'or'
+                ];
+            } elseif (4 == substr($classify, 0, 1) && 401 != $classify) {
+                $_map['classify'] = [
+                    ['eq', 4],
+                    ['between', [400, 499]],
+                    'or'
+                ];
+            } elseif (6 == substr($classify, 0, 1) && 601 != $classify) {
+                $_map['classify'] = [
+                    ['eq', 6],
+                    ['between', [600, 699]],
+                    'or'
+                ];
+            } else {
+                $_map['classify'] = $classify;
+            }
+        }
+        $_map['is_delete'] = CommonConst::CONST_DELETED;
+        $this->getList($_map);
+        $this->_games($_app_id, 0, CommonConst::CONST_DELETED, $this->sdk, $classify, false, true);
+        $this->assign('cps', (new CpLogic())->getNamesById());
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $this->assign('filter_button', $_filter_button);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', $this->delete_index_url]
+        );
+        $this->assign('filter_button_clear', $_filter_button_clear);
+        $this->assign('total_div', $this->total_div);
+        if (GameConst::GAME_MP == $this->classify) {
+            return $this->fetch('box/game/deleteindex');
+        }
+
+        return $this->fetch('deleteindex');
+    }
+
+    /**
+     * 热门列表
+     *
+     * @param $classify
+     *
+     * @return mixed
+     */
+    public function hotIndex($classify) {
+        $_get = $this->request->param('', '', 'trim');
+        $_map['classify'] = $classify;
+        $_map['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        //$_map['is_sdk'] = GameConst::GAME_IS_SDK;
+        if (isset($_get['app_id']) && !empty($_get['app_id'])) {
+            $_map['id'] = $_get['app_id'];
+        }
+        $_field = [
+            'is_online' => 'is_online',
+            'hot_order' => 'hot_order',
+            'status'    => 'status'
+        ];
+        $order = '+hot_order';
+        $_data = (new GameList())->getGameListDetail($_map, '', $order, $_field);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], 1, 30);
+        $this->_games(
+            $this->request->param('app_id/d', 0), GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0, $classify
+        );
+        $this->_gameStatus();
+        $this->_isOnline();
+        $this->assign('items', $_page_data->items());
+        $this->assign('page', $_page_data->render());
+        $this->assign('cps', (new CpLogic())->getNamesById());
+    }
+
+    /**
+     * 喜爱排序
+     *
+     * @param $classify
+     */
+    public function likeIndex($classify) {
+        $_get = $this->request->param('', '', 'trim');
+        $_map['classify'] = $classify;
+        $_map['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_map['is_sdk'] = GameConst::GAME_IS_SDK;
+        if (isset($_get['app_id']) && !empty($_get['app_id'])) {
+            $_map['id'] = $_get['app_id'];
+        }
+        $_field = [
+            'is_online'  => 'is_online',
+            'like_order' => 'like_order',
+            'status'     => 'status'
+        ];
+        $order = '-like_order';
+        $_data = (new GameList())->getGameListDetail($_map, '', $order, $_field);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], 1, 30);
+        $this->_games(
+            $this->request->param('app_id/d', 0), GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0, $classify
+        );
+        $this->_gameStatus();
+        $this->_isOnline();
+        $this->assign('items', $_page_data->items());
+        $this->assign('page', $_page_data->render());
+        $this->assign('cps', (new CpLogic())->getNamesById());
+    }
+
+    /**
+     * 增长最快列表
+     *
+     * @param $classify
+     *
+     * @return mixed
+     */
+    public function rankIndex($classify) {
+        $_get = $this->request->param('', '', 'trim');
+        $_map['classify'] = $classify;
+        $_map['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        //$_map['is_sdk'] = GameConst::GAME_IS_SDK;
+        if (isset($_get['app_id']) && !empty($_get['app_id'])) {
+            $_map['id'] = $_get['app_id'];
+        }
+        $_field = [
+            'is_online'  => 'is_online',
+            'list_order' => 'list_order',
+            'status'     => 'status'
+        ];
+        $order = '-list_order';
+        //$this->getList($_map, $_field, $order);
+        $_data = (new GameList())->getGameListDetail($_map, '', $order, $_field);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], 1, 30);
+        $this->_games(
+            $this->request->param('app_id/d', 0), GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0, $classify
+        );
+        $this->_gameStatus();
+        $this->_isOnline();
+        $this->assign('items', $_page_data->items());
+        $this->assign('page', $_page_data->render());
+        $this->assign('cps', (new CpLogic())->getNamesById());
+    }
+
+    /**
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function fine() {
+        $_app_id = $this->request->get('id/d', 0);
+        $this->_games($_app_id, GameConst::GAME_STATUS_ON, $this->is_delete, 0, $this->classify);
+        $_map['is_delete'] = $this->is_delete;
+        $_map['classify'] = $this->classify;
+        $_map['fine_order'] = ['neq', 0];
+        $_field
+            = "id,CONCAT(name,'-',CASE classify WHEN 3 THEN '安卓' WHEN 4 THEN 'IOS'  WHEN 5 THEN 'H5' WHEN 6 THEN '小游戏' WHEN 601 THEN '盒子' ELSE 'APPSTORE' END,CASE is_sdk WHEN 1 THEN '-CPS游戏' ELSE '' END) as name,fine_order";
+        $order = 'fine_order desc';
+        $_list = $this->getList($_map, $_field, $order);
+        $this->assign('list', $_list);
+        if (GameConst::GAME_MP == $this->classify) {
+            return $this->fetch('box/game/fine');
+        }
+
+        return $this->fetch();
+    }
+
+    public function set_fine() {
+        $_app_id = $_POST['app_id'];
+        $_list_order = $_POST['list_orders'];
+        $_map['id'] = ['neq', 0];
+        $_data['fine_order'] = 0;
+        $_game_model = new GameModel();
+        $_game_model->allowField(true)->isUpdate(true)->save($_data, $_map);
+        if (empty($_app_id)) {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+        $_map['id'] = ['in', $_app_id];
+        $_game_model = new GameModel();
+        foreach ($_app_id as $_key => $_value) {
+            $_map['id'] = $_value;
+            $_data['fine_order'] = $_list_order[$_key] ? $_list_order[$_key] : 0;
+            $_game_model->where($_map)->update($_data);
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function hot() {
+        $_app_id = $this->request->get('id/d', 0);
+        $this->_games(
+            $_app_id, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0,
+            [GameConst::GAME_ANDROID, GameConst::GAME_IOS, GameConst::GAME_IOS_SWITCH]
+        );
+        $_map['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_map['hot_order'] = ['neq', 0];
+        $_field
+            = "id,CONCAT(name,'-',CASE classify WHEN 3 THEN '安卓' WHEN 4 THEN 'IOS'  WHEN 5 THEN 'H5' ELSE 'APPSTORE' END,CASE is_sdk WHEN 1 THEN '-CPS游戏' ELSE '' END) as name,hot_order";
+        $order = 'hot_order desc';
+        $_list = $this->getList($_map, $_field, $order);
+        $this->assign('list', $_list);
+
+        return $this->fetch();
+    }
+
+    public function set_hot() {
+        $_app_id = $_POST['app_id'];
+        $_list_order = $_POST['list_orders'];
+        $_map['id'] = ['neq', 0];
+        $_data['hot_order'] = 0;
+        $_game_model = new GameModel();
+        $_game_model->allowField(true)->isUpdate(true)->save($_data, $_map);
+        if (empty($_app_id)) {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+        foreach ($_app_id as $_key => $_value) {
+            $_map['id'] = $_value;
+            $_data['hot_order'] = $_list_order[$_key] ? $_list_order[$_key] : 0;
+            $_game_model->where($_map)->update($_data);
+        }
+//        $_map['id'] = ['in', $_app_id];
+//        $_data['hot_order'] = 1;
+//        $_game_model = new GameModel();
+//        $_game_model->allowField(true)->isUpdate(true)->save($_data, $_map);
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 编辑字段值
+     */
+    public function editField() {
+        $_field = $this->request->param('field/s', '');
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_field) || empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $this->assign($_data);
+        $this->assign('field', $_field);
+        if (GameConst::GAME_MP == $this->classify) {
+            $_game_mini = (new GameMiniModel())->getDataByAppId($_app_id);
+            $this->assign($_game_mini);
+
+            return $this->fetch('box/game/edit_field');
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑字段值提交
+     */
+    public function editFieldPost() {
+        $_param = $this->request->param();
+        $_app_id = $_param['app_id'];
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        if (isset($_param['mini_app_id'])) {
+            $_gm_mini_model = new GameMiniModel();
+            $_mini_data = $_gm_mini_model->getDataByMpAppId($_param['mini_app_id']);
+            if (!empty($_mini_data) && $_mini_data['app_id'] != $_app_id) {
+                $this->adminError('该小程序ID已存在');
+            } else {
+                $_rs = $_gm_mini_model->updateData($_param, $_app_id);
+            }
+        } else {
+            if (!empty($_param['app_key']) && strlen($_param['app_key']) != 32) {
+                $this->adminError('app_key字符长度必须是32位');
+            }
+            $_gc_class = GameCache::ins();
+            $_rs = $_gc_class->updateGame($_app_id, $_param);
+        }
+        $_mp_conf_data = [];
+        if (isset($_param['mini_app_id'])) {
+            $_mp_conf_data['mp_id'] = $_param['mini_app_id'];
+        }
+        if (isset($_param['name'])) {
+            $_mp_conf_data['wx_name'] = $_param['name'];
+        }
+        if (!empty($_mp_conf_data)) {
+            (new MpConfModel())->updateGameMpConf($_app_id, MpConfConst::MP_CONF_TYPE_6, $_mp_conf_data);
+        }
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+}
+

+ 424 - 0
admin/admin/controller/game/H5gameController.php

@@ -0,0 +1,424 @@
+<?php
+/**
+ * H5gameController.php UTF-8
+ *
+ *
+ * @date    : 2018/5/8 11:17
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use cmf\view\Filter;
+use huo\controller\game\GameCache;
+use huo\logic\member\CpLogic;
+use huo\model\conf\PaywayModel;
+use huo\model\game\CategoryModel;
+use huo\model\game\GamecategoryModel;
+use huo\model\game\GameextModel;
+use huo\model\game\GameModel;
+use huo\model\game\GameversionModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use think\Validate;
+
+class H5gameController extends GameController {
+    function _initialize() {
+        parent::_initialize();
+        $this->classify = GameConst::GAME_H5;
+        $this->index_url = url('admin/Game.h5game/index');
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    /**
+     * 游戏地址
+     *
+     * @return mixed
+     */
+    public function gameurl() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = GameCache::ins()->getInfoByAppId($_app_id);
+
+        if (empty($_data['gv'][0])) {
+            $this->adminError('param error');
+        }
+        $_package_url = isset($_data['gv'][0]['package_url']) ? $_data['gv'][0]['package_url'] : '';
+        $_data['game_url'] = MOBILESITE .'/sdk.php/game?game_id=' . $_data['id'] . '&agent_id=0';
+        $this->assign($_data);
+        $this->assign('package_url', $_package_url);
+
+        return $this->fetch('game/h5game/game');
+    }
+
+    /**
+     * 游戏地址
+     *
+     * @return mixed
+     */
+    public function editPackageUrl() {
+        $classify = GameConst::GAME_H5;
+        parent::addPackageUrl($classify, true);
+
+        return;
+    }
+
+    public function edit() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_game_data = $this->getDetail($_app_id);
+        if (empty($_game_data['gv'][0])) {
+            $this->adminError('param error');
+        }
+        $this->assign($_game_data);
+        $_cate_model = new CategoryModel();
+        $_cates = $_cate_model->getIdNames();
+        $this->assign('cates', $_cates);
+        $_cates_box_check = Filter::checkCommon($_cates, 'category[]', $_game_data['category']);
+        $this->assign('cates_box_check', $_cates_box_check);
+        $_cp_name_select = Filter::selectCommon((new CpLogic())->getNamesById(), 'cp_id', $_game_data['cp_id']);
+        $this->assign('cp_name_select', $_cp_name_select);
+        /* 绑定支付主体配置 */
+        $_ext_info = get_val($_game_data, 'ext_info', []);
+        $_alipay = get_val($_ext_info, 'alipay', '');
+        $this->getPayway('alipay', $_alipay);
+        $_wxpay = get_val($_ext_info, 'wxpay', '');
+        $this->getPayway('wxpay', $_wxpay);
+
+        return $this->fetch();
+    }
+
+    /***
+     * 获取可切换支付方式
+     *
+     * @param        $code
+     *
+     * @param string $current
+     *
+     * @return array
+     */
+    public function getPayway($code, $current = '') {
+        $_array = (new PaywayModel())->getPayWaysByPayName(2, 2, $code);
+        $_select = Filter::radioCommon($_array, $code, $current);
+        $this->assign($code.'_select', $_select);
+
+        return $_array;
+    }
+
+    /**
+     * 编辑游戏处理函数
+     *
+     * @throws
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'id'          => 'require|number|token',
+                    'name'        => 'require',
+                    'package_url' => 'url',
+                    'down_cnt'    => 'number|max:100000000',
+                ]
+            );
+            $_param = $this->request->post();
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_app_id = $this->request->post('id/d', 0);
+            $_down_cnt = $this->request->post('down_cnt/d', 0);
+            $_g_all = $this->getDetail($_app_id);
+            $_rise_cnt = $_down_cnt - $_g_all['ext']['down_cnt'];
+            $_game_data['hot_order'] = $_g_all['hot_order'] + $_rise_cnt;
+            $_game_data['rise_order'] = $_g_all['rise_order'] + $_rise_cnt;
+            $_game_data['id'] = $_app_id;
+            $_game_data['icon'] = $this->request->post('icon/s', '');
+            $_game_data['name'] = $this->request->post('name/s', '');
+            $_game_data['is_auth'] = $this->request->post('is_auth/d', GameConst::GAME_IDENTIFY_IS_NO);
+            $_game_data['cp_id'] = $this->request->post('cp_id/d', 0);
+            $_game_data['publicity'] = $this->request->post('publicity/s', '');
+            $_game_data['description'] = $this->request->post('description/s', '');
+            $_game_data['hot_image'] = $this->request->post('hot_image/s', '');
+            $_game_data['fine_image'] = $this->request->post('fine_image/s', '');
+            $_ext_info['login_back_img'] = $this->request->post('login_back_img/s', '');
+            $_ext_info['wxpay'] = $this->request->post('wxpay/s', '');
+            $_ext_info['alipay'] = $this->request->post('alipay/s', '');
+            $_game_data['ext_info'] = $_ext_info;
+            $_category = $this->request->post('category/a');
+            if (is_array($_category)) {
+                $_game_data['category'] = implode(',', $_category);
+            }
+            if (!empty($_param['photo_names']) && !empty($_param['photo_urls'])) {
+                $_game_data['image'] = [];
+                foreach ($_param['photo_urls'] as $_key => $_url) {
+                    $_photo_url = cmf_asset_relative_url($_url);
+                    array_push(
+                        $_game_data['image'], ["url" => $_photo_url, "name" => $_param['photo_names'][$_key]]
+                    );
+                }
+            }
+            $_rs = GameCache::ins()->updateGame($_app_id, $_game_data, true);
+            if ($this->hasOa) {
+                $_game_model = new GameModel();
+                $_oa_data = $_game_data;
+            }
+            if (false !== $_rs) {
+                $_gv_data['package_url'] = $this->request->post('package_url/s', '');
+//                $_gv_data['size'] = $this->request->post('size/s', '');
+                $_gv_data['version'] = $this->request->post('version/s', '');
+                $_gv_map['id'] = $_g_all['gv'][0]['id'];
+                $_gv_model = new GameversionModel();
+                $_gv_model->save($_gv_data, $_gv_map);
+                if ($this->hasOa) {
+                    $_oa_data['standard_mem_cnt'] = $this->request->post('standard_mem_cnt/d', '');
+                    $_oa_data['standard_level'] = $this->request->post('standard_level/d', '');
+                    $_oa_game_data = array();
+                    $_oa_game_data['standard_mem_cnt'] = $_oa_data['standard_mem_cnt'];
+                    $_oa_game_data['standard_level'] = $_oa_data['standard_level'];
+                    $_oa_game_model = new \huo\model\oa\OaGameModel();
+                    \think\Log::write($_oa_game_data, 'debug');
+                    $_oa_game_model->save($_oa_game_data, ['app_id' => $_app_id]);
+                    $_oa_data['version'] = $_gv_data['version'];
+                }
+                $_ge_data['down_cnt'] = $_down_cnt;
+                GameextModel::update($_ge_data, ['app_id' => $_app_id]);
+                if (!empty($_category)) {
+                    /* 先删除所有类型 */
+                    $_gc_map['id'] = ['gt', 0];
+                    $_gc_map['app_id'] = $_app_id;
+                    $_gc_model = new GamecategoryModel();
+                    $_gc_rs = $_gc_model->where($_gc_map)->delete();
+                    if (false !== $_gc_rs) {
+                        $_gc_data = [];
+                        foreach ($_category as $_v) {
+                            $_gc_temp_data['app_id'] = $_app_id;
+                            $_gc_temp_data['cate_id'] = $_v;
+                            $_gc_data[] = $_gc_temp_data;
+                        }
+                        $_gc_model->insertAll($_gc_data);
+                    }
+                }
+                if ($this->hasOa) {
+                    $_re = $_game_model->updateOaGame($_app_id, $_oa_data);
+                    if ($_re) {
+                        \think\Log::write($_oa_data, 'debug');
+                    }
+                }
+                $this->adminSuccess(lang('SUCCESS'), url('admin/game.h5game/index'));
+            } else {
+                $this->adminError("ERROR");
+            }
+        } else {
+            $this->adminError("param error");
+        }
+    }
+
+    /**
+     *排序处理
+     */
+    public function listOrder() {
+        $ids = $this->request->post("list_orders/a");
+        if (!empty($ids)) {
+            foreach ($ids as $key => $r) {
+                $data['id'] = $key;
+                $data['list_order'] = $r;
+                GameCache::ins()->updateGame($key, $data);
+            }
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    public function hotOrder() {
+        $ids = $this->request->post("hot_orders/a");
+        if (!empty($ids)) {
+            foreach ($ids as $key => $r) {
+                $data['id'] = $key;
+                $data['hot_order'] = $r;
+                GameCache::ins()->updateGame($key, $data);
+            }
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    public function likeOrder() {
+        $ids = $this->request->post("like_orders/a");
+        if (!empty($ids)) {
+            foreach ($ids as $key => $r) {
+                $data['id'] = $key;
+                $data['like_order'] = $r;
+                GameCache::ins()->updateGame($key, $data);
+            }
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 新游列表
+     *
+     * @throws \think\exception\DbException
+     */
+    public function newIndex() {
+        $_map['classify'] = GameConst::GAME_H5;
+        $_map['is_delete'] = 2;
+        $_map['is_sdk'] = 2;
+        $_map['status'] = 2;
+        $_field = 'id,hot_order,name,status,run_time';
+        $order = 'run_time desc';
+        $this->getList($_map, $_field, $order);
+        $_game_status = $this->_gameStatus();
+        $_game_status_select = Filter::selectCommon($_game_status, 'status', $this->request->get('status/d', 0));
+        $this->assign('game_status_select', $_game_status_select);
+        $this->assign('cps', (new CpLogic())->getNamesById());
+
+        return $this->fetch();
+    }
+
+    /**
+     * 删除游戏列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function deleteIndex() {
+        $this->delete_index_url = url('admin/Game.h5game/deleteIndex');
+
+        return parent::deleteIndex();
+    }
+
+    /**
+     * 热门列表
+     *
+     * @param int $classify
+     *
+     * @return mixed
+     */
+    public function hotIndex($classify = GameConst::GAME_H5) {
+        $classify = GameConst::GAME_H5;
+        parent::hotIndex($classify);
+
+        return $this->fetch('hotindex');
+    }
+
+    /**
+     * 喜爱列表
+     *
+     * @param int $classify
+     *
+     * @return mixed
+     */
+    public function likeIndex($classify = GameConst::GAME_H5) {
+        $classify = GameConst::GAME_H5;
+        parent::likeIndex($classify);
+
+        return $this->fetch('likeindex');
+    }
+
+    /**
+     * 增长最快列表
+     *
+     * @param int $classify
+     *
+     * @return mixed
+     */
+    public function rankIndex($classify = GameConst::GAME_H5) {
+        $classify = GameConst::GAME_H5;
+        parent::rankIndex($classify);
+
+        return $this->fetch('rankindex');
+    }
+
+    /**
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function fine() {
+//        $_map['classify'] = 3;
+        $_map['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_map['fine_order'] = ['neq', 0];
+        $_field = 'id,name,fine_order';
+        $order = 'fine_order desc';
+        $_list = $this->getList($_map, $_field, $order);
+        $this->assign('list', $_list);
+
+        return $this->fetch();
+    }
+
+    public function set_fine() {
+        $_app_id = $_POST['app_id'];
+        $_list_order = $_POST['list_orders'];
+        $_map['id'] = ['neq', 0];
+        $_data['fine_order'] = 0;
+        $_game_model = new GameModel();
+        $_game_model->allowField(true)->isUpdate(true)->save($_data, $_map);
+        if (empty($_app_id)) {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+        $_map['id'] = ['in', $_app_id];
+        $_game_model = new GameModel();
+        foreach ($_app_id as $_key => $_value) {
+            $_map['id'] = $_value;
+            $_data['fine_order'] = $_list_order[$_key] ? $_list_order[$_key] : 0;
+            $_game_model->where($_map)->update($_data);
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function hot() {
+        $_map['is_delete'] = 2;
+        $_map['hot_order'] = ['neq', 0];
+        $_field = 'id,name,hot_order';
+        $order = 'hot_order desc';
+        $_list = $this->getList($_map, $_field, $order);
+        $this->assign('list', $_list);
+
+        return $this->fetch();
+    }
+
+    public function set_hot() {
+        $_app_id = $_POST['app_id'];
+        $_list_order = $_POST['list_orders'];
+        $_map['id'] = ['neq', 0];
+        $_data['hot_order'] = 0;
+        $_game_model = new GameModel();
+        $_game_model->allowField(true)->isUpdate(true)->save($_data, $_map);
+        if (empty($_app_id)) {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+        foreach ($_app_id as $_key => $_value) {
+            $_map['id'] = $_value;
+            $_data['hot_order'] = $_list_order[$_key] ? $_list_order[$_key] : 0;
+            $_game_model->where($_map)->update($_data);
+        }
+//        $_map['id'] = ['in', $_app_id];
+//        $_data['hot_order'] = 1;
+//        $_game_model = new GameModel();
+//        $_game_model->allowField(true)->isUpdate(true)->save($_data, $_map);
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 关联游戏
+     * admin/game.game/linkGame
+     */
+    public function linkGame() {
+        parent::linkGame();
+
+        return $this->fetch();
+    }
+
+    /**
+     * 设置关联游戏
+     * admin/game.game/linkGamePost
+     */
+    public function linkGamePost() {
+        return parent::linkGamePost();
+    }
+}
+

+ 222 - 0
admin/admin/controller/game/HelpController.php

@@ -0,0 +1,222 @@
+<?php
+/**
+ * HelpController.php  UTF-8
+ * 游戏客服管理
+ *
+ * @date    : 2018/7/12 22:17
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\help\GameHelpCache;
+use huo\controller\help\QqCache;
+use huo\logic\game\GameHelpLogic;
+use huo\logic\qq\QqConfLogic;
+use huo\model\conf\QqConfModel;
+use huo\model\game\GameHelpModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\tool\Page;
+use think\Lang;
+
+class HelpController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'game_help'.EXT);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    /**
+     * 获取列表
+     * /admin/game.help/index
+     *
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function index() {
+        $_param = [];
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_param['start_time'] = $this->request->param('start_time/s', '');
+        $_param['end_time'] = $this->request->param('end_time/s', '');
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_page = $this->request->param('page/d', 1);
+        /*搜索*/
+        $this->_games(
+            $_param['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK
+        );
+        $this->_time($_param['start_time'], $_param['end_time']);
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', 'uri' => url('admin/Game.help/index')]
+        );
+        $_data = (new GameHelpLogic())->getAdminList($_param, $_page.','.$_list_rows);
+        $_page_data = Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        $this->assign('filter_button', $_filter_button);
+        $this->assign('filter_button_clear', $_filter_button_clear);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加客服
+     * /admin/game.help/add
+     */
+    public function add() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $this->_games(
+            $_app_id, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK
+        );
+        $this->_getQqs();
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加客服提交
+     * /admin/game.help/addPost
+     */
+    public function addPost() {
+        $_param = $this->request->param();
+        $_param['qq_ids'] = $_param['qq_id'];
+        $_result = $this->validate($_param, 'GameHelp');
+        if ($_result !== true) {
+            $this->adminError($_result);
+        }
+        $_gmh_model = new GameHelpModel();
+        $_gmh_data = $_gmh_model->getInfoByAppId($_param['app_id'], false);
+        $_param['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_param['delete_time'] = 0;
+        if (!empty($_gmh_data)) {  //存在
+            if (CommonConst::CONST_NOT_DELETE == $_gmh_data['is_delete']) { //非删除状态提示存在
+                $this->adminError(lang('app_exist'));
+            }
+            $_rs = (new GameHelpCache())->updateGmh($_param['app_id'], $_param);  //删除状态更新
+        } else {
+            $_rs = $_gmh_model->addGmh($_param);
+        }
+        if (false == $_rs) {
+            $this->adminError(lang('ADD_FAILED'));
+        }
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/game.help/index'));
+    }
+
+    /**
+     * 编辑客服
+     * /admin/game.help/edit
+     */
+    public function edit() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_gmh_data = (new GameHelpModel())->getInfoByAppId($_app_id);
+        if (empty($_gmh_data)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->_games(
+            $_gmh_data['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, 0,
+            true, true, [], '', 'disabled'
+        );
+        $this->_getQqs($_gmh_data['qq_ids']);
+        $this->assign($_gmh_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑客服提交
+     * /admin/game.help/editPost
+     */
+    public function editPost() {
+        $_param = $this->request->param();
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_param['qq_ids'] = $_param['qq_id'];
+        $_result = $this->validate($_param, 'GameHelp');
+        if ($_result !== true) {
+            $this->adminError($_result);
+        }
+        $_rs = (new GameHelpCache())->updateGmh($_param['app_id'], $_param);
+        if (false == $_rs) {
+            $this->adminError(lang('EDIT_FAILED'));
+        }
+        $this->adminSuccess(lang('EDIT_SUCCESS'), url('admin/game.help/index'));
+    }
+
+    /**
+     * 删除客服
+     * /admin/game.help/delete
+     */
+    public function delete() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = [];
+        $_data['is_delete'] = CommonConst::CONST_DELETED;
+        $_data['delete_time'] = time();
+        $_rs = (new GameHelpCache())->updateGmh($_app_id, $_data);
+        if (false == $_rs) {
+            $this->adminError(lang('DELETE_FAILED'));
+        }
+        $this->adminSuccess(lang('DELETE_SUCCESS'), url('admin/game.help/index'));
+    }
+
+    /**
+     * 添加QQ群
+     */
+    public function qqAdd() {
+        $_app_id = $this->request->param('app_id', '-1');
+        $this->assign('app_id', $_app_id);
+
+        return $this->fetch();
+    }
+
+    /***
+     * 添加QQ群提交处理
+     *
+     * @throws
+     */
+    public function qqAddPost() {
+        $_qq_id = 0;
+        $_params = $this->request->param();
+        $_app_id = $_params['app_id'];
+        $_params['type'] = GameConst::QQ_TYPE_QQ;
+        $_params['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_validate = validate('Qq');
+        if (!$_validate->scene('qq')->check($_params)) {
+            $this->adminError($_validate->getError());
+        }
+        $_res = (new QqConfLogic())->isUnique($_params);
+        if (!empty($_res)) {
+            if (!empty($_res['id']) && CommonConst::CONST_NOT_DELETE != $_res['is_delete']) {  //存在记录但是已经删除,更新记录
+                $_params['is_delete'] = CommonConst::CONST_NOT_DELETE;
+                $_params['delete_time'] = 0;
+                $_result = (new QqCache())->updateQq($_res['id'], $_params);
+                if (false == $_result) {
+                    $this->adminError(lang('ADD_FAILED'));
+                }
+                $_qq_id = $_res['id'];
+            } else {
+                $this->adminError(lang('QQ').lang('existed'));
+            }
+        }
+        if (empty($_qq_id)) {
+            $_qq_id = (new QqConfModel())->addQqs($_params);
+        }
+        if (empty($_qq_id)) {
+            $this->adminError(lang('ADD_FAILED'));
+        }
+        if ($_app_id != '-1') {
+            $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/game.help/edit', ['app_id' => $_app_id]));
+        }
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/game.help/index'));
+    }
+}

+ 265 - 0
admin/admin/controller/game/IosGameController.php

@@ -0,0 +1,265 @@
+<?php
+/**
+ * AndroidGameController.php  UTF-8
+ * 安卓游戏管理类
+ *
+ * @date    : 2018/5/14 17:00
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use huo\controller\game\GameCache;
+use huo\controller\game\GamePaySwitchCache;
+use huo\logic\game\GamePaySwitchLogic;
+use huo\model\game\GamecategoryModel;
+use huo\model\game\GameextModel;
+use huo\model\game\GameModel;
+use huo\model\game\GameversionModel;
+use huolib\constant\GameConst;
+use huolib\constant\OrderConst;
+use think\Lang;
+use think\Validate;
+
+class IosGameController extends GameController {
+    function _initialize() {
+        parent::_initialize();
+        $this->classify = GameConst::GAME_IOS;
+        $this->index_url = url('admin/Game.ios_game/index');
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    /**
+     * 添加游戏处理函数
+     */
+    public function addPost() {
+        if (OrderConst::PAY_SWITCH_YES == $this->request->param('pay_switch/d')) {  //支付切换的 放到支付切换类
+            $this->classify = GameConst::GAME_IOS_SWITCH;
+        } else {
+            $this->classify = GameConst::GAME_IOS;
+        }
+        parent::addPost();
+    }
+
+    /**
+     * 游戏地址
+     *
+     * @return mixed
+     */
+    public function gameurl() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = GameCache::ins()->getInfoByAppId($_app_id);
+        if (empty($_data['gv'][0])) {
+            $this->adminError('param error');
+        }
+        $_package_url = isset($_data['gv'][0]['package_url']) ? $_data['gv'][0]['package_url'] : '';
+        $this->assign($_data);
+        $this->assign('package_url', $_package_url);
+
+        return $this->fetch('game/ios_game/game');
+    }
+
+    /**
+     * 游戏地址
+     *
+     * @return mixed
+     */
+    public function editPackageUrl() {
+        $classify = GameConst::GAME_IOS;
+        parent::addPackageUrl($classify, true);
+
+        return;
+    }
+
+    /**
+     * 编辑游戏处理函数
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'id'          => 'require|number|token',
+                    'name'        => 'require',
+                    'package_url' => 'url',
+                    'down_cnt'    => 'number|max:100000000',
+                    'apple_id'    => 'number',
+                ]
+            );
+            $_param = $this->request->post();
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_app_id = $this->request->post('id/d', 0);
+            $_down_cnt = $this->request->post('down_cnt/d', 0);
+            $_g_all = $this->getDetail($_app_id);
+            $_rise_cnt = $_down_cnt - $_g_all['ext']['down_cnt'];
+            $_game_data['hot_order'] = $_g_all['hot_order'] + $_rise_cnt;
+            $_game_data['rise_order'] = $_g_all['rise_order'] + $_rise_cnt;
+            $_game_data['id'] = $_app_id;
+            $_game_data['icon'] = $this->request->post('icon/s', '');
+            $_game_data['name'] = $this->request->post('name/s', '');
+            $_game_data['cp_id'] = $this->request->post('cp_id/d', 0);
+            $_game_data['is_online'] = $this->request->post('is_online/d', GameConst::GAME_IS_ON_LINE);
+            $_game_data['pay_switch'] = $this->request->post('pay_switch/d', OrderConst::PAY_SWITCH_NO);
+            if (OrderConst::PAY_SWITCH_YES == $_game_data['pay_switch']) {  //支付切换的 放到支付切换类
+                $_game_data['classify'] = GameConst::GAME_IOS_SWITCH;
+            } else {
+                $_game_data['classify'] = GameConst::GAME_IOS;
+            }
+            $_game_data['publicity'] = $this->request->post('publicity/s', '');
+            $_game_data['description'] = $this->request->post('description/s', '');
+            $_game_data['hot_image'] = $this->request->post('hot_image/s', '');
+            $_game_data['fine_image'] = $this->request->post('fine_image/s', '');
+            $_game_data['apple_id'] = $this->request->post('apple_id/d', 0);
+            $_category = $this->request->post('category/a');
+            if (is_array($_category)) {
+                $_game_data['category'] = implode(',', $_category);
+            }
+            if (!empty($_param['photo_names']) && !empty($_param['photo_urls'])) {
+                $_game_data['image'] = [];
+                foreach ($_param['photo_urls'] as $_key => $_url) {
+                    $_photo_url = cmf_asset_relative_url($_url);
+                    array_push(
+                        $_game_data['image'], ["url" => $_photo_url, "name" => $_param['photo_names'][$_key]]
+                    );
+                }
+            }
+            $_rs = GameCache::ins()->updateGame($_app_id, $_game_data, true);
+            if ($this->hasOa) {
+                $_game_model = new GameModel();
+                $_oa_data = $_game_data;
+            }
+            if (false !== $_rs) {
+                $_gv_data['package_url'] = $this->request->post('package_url/s', '');
+//                $_gv_data['size'] = $this->request->post('size/s', '');
+                $_gv_data['version'] = $this->request->post('version/s', '');
+                $_gv_map['id'] = $_g_all['gv'][0]['id'];
+                $_gv_model = new GameversionModel();
+                $_gv_model->save($_gv_data, $_gv_map);
+                if ($this->hasOa) {
+                    $_oa_data['standard_mem_cnt'] = $this->request->post('standard_mem_cnt/d', '');
+                    $_oa_data['standard_level'] = $this->request->post('standard_level/d', '');
+                    $_oa_game_data = array();
+                    $_oa_game_data['standard_mem_cnt'] = $_oa_data['standard_mem_cnt'];
+                    $_oa_game_data['standard_level'] = $_oa_data['standard_level'];
+                    $_oa_game_model = new \huo\model\oa\OaGameModel();
+                    \think\Log::write($_oa_data, 'debug');
+                    $_oa_game_model->save($_oa_game_data, ['app_id' => $_app_id]);
+                    $_oa_data['version'] = $_gv_data['version'];
+                }
+                $_ge_data['down_cnt'] = $_down_cnt;
+                GameextModel::update($_ge_data, ['app_id' => $_app_id]);
+                if (!empty($_category)) {
+                    /* 先删除所有类型 */
+                    $_gc_map['id'] = ['gt', 0];
+                    $_gc_map['app_id'] = $_app_id;
+                    $_gc_model = new GamecategoryModel();
+                    $_gc_rs = $_gc_model->where($_gc_map)->delete();
+                    if (false !== $_gc_rs) {
+                        $_gc_data = [];
+                        foreach ($_category as $_v) {
+                            $_gc_temp_data['app_id'] = $_app_id;
+                            $_gc_temp_data['cate_id'] = $_v;
+                            $_gc_data[] = $_gc_temp_data;
+                        }
+                        $_gc_model->insertAll($_gc_data);
+                    }
+                }
+                if ($this->hasOa) {
+                    $_re = $_game_model->updateOaGame($_app_id, $_oa_data);
+                    if ($_re) {
+                        \think\Log::write($_oa_data, 'debug');
+                    }
+                }
+                $this->adminSuccess(lang('SUCCESS'), url('admin/game.iosGame/index'));
+            } else {
+                $this->adminError("ERROR");
+            }
+        } else {
+            $this->adminError("param error");
+        }
+    }
+
+    /***
+     * 编辑切换规则
+     */
+    public function paySwitch() {
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_pay_switch'.EXT);
+        $_app_id = $this->request->param('app_id/d', 0);
+        $this->_games($_app_id, 0, 2, 2, GameConst::GAME_IOS_SWITCH, false, true, [], '', 'disabled');
+        if (empty($_app_id)) {
+            $this->adminError(lang('param_error'));
+        }
+        $_data = GamePaySwitchCache::ins()->getInfoByAppId($_app_id);
+        $this->assign('data', $_data);
+        $this->assign('app_id', $_app_id);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑切换规则提交
+     *
+     * @throws
+     */
+    public function paySwitchPost() {
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_pay_switch'.EXT);
+        $_params = $this->request->param();
+        $_params['is_domestic'] = isset($_params['is_domestic']) ? $_params['is_domestic'] : 2;
+        $_params['is_overseas'] = isset($_params['is_overseas']) ? $_params['is_overseas'] : 2;
+        $_params['is_first'] = isset($_params['is_first']) ? $_params['is_first'] : 1;
+        $_model = new GamePaySwitchLogic();
+        if (empty($_params['app_id'])) {
+            $this->adminError(lang('please select a game'));
+        }
+        if (!$_model->checkGame($_params['app_id'])) {
+            $_result = $_model->addPaySwitch($_params);
+            if (false == $_result) {
+                $this->adminError(lang('add').lang('failure'));
+            }
+            $this->adminSuccess(lang('add').lang('success'), url('admin/game.iosGame/index'));
+        }
+        $_result = GamePaySwitchCache::ins()->updatePaySwitch($_params['app_id'], $_params);
+        if (false == $_result) {
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/game.iosGame/index'));
+    }
+
+    /**
+     * 删除游戏列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function deleteIndex() {
+        $this->delete_index_url = url('admin/Game.iosGame/deleteIndex');
+
+        return parent::deleteIndex();
+    }
+
+    /**
+     * 点击切换不切换
+     * */
+    public function setSwitch() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_pay_switch = $this->request->param('pay_switch/d', 1);
+        if (empty($_app_id) || empty($_pay_switch)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data['pay_switch'] = $_pay_switch;
+        $_data['id'] = $_app_id;
+        $_rs = GameCache::ins()->updateGame($_app_id, $_data);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+}

+ 147 - 0
admin/admin/controller/game/PaySwitchController.php

@@ -0,0 +1,147 @@
+<?php
+/**
+ * paySwitchController.php  UTF-8
+ * 支付切换规则
+ *
+ * @date    : 2018/6/6 21:27
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\game\GamePaySwitchCache;
+use huo\logic\game\GamePaySwitchLogic;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\OrderConst;
+use huolib\tool\Page;
+use think\Lang;
+
+class PaySwitchController extends AdminBaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_pay_switch'.EXT);
+        parent::_initialize();
+    }
+
+    /**
+     * 切换规则列表
+     * admin/game.pay_switch/index
+     *
+     * @throws
+     */
+    public function index() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $this->_games(
+            $_app_id, 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, GameConst::GAME_IOS_SWITCH, false, true
+        );
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_list = (new GamePaySwitchLogic())->getLists($_app_id, $_page.','.$_list_rows);
+        $_page_data = Page::paginate($_list['count'], $_list['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加切换规则
+     * admin/game.pay_switch/add
+     *
+     * @throws
+     */
+    public function add() {
+        $this->_games(
+            0, 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, GameConst::GAME_IOS_SWITCH, false, true
+        );
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加切换规则提交
+     * admin/game.pay_switch/addPost
+     *
+     * @throws
+     */
+    public function addPost() {
+        $_params = $this->request->param();
+        $_params['is_domestic'] = isset($_params['is_domestic']) ? $_params['is_domestic'] : 2;
+        $_params['is_overseas'] = isset($_params['is_overseas']) ? $_params['is_overseas'] : 2;
+        $_params['is_first'] = isset($_params['is_first']) ? $_params['is_first'] : 1;
+        $_model = new GamePaySwitchLogic();
+        if (empty($_params['app_id'])) {
+            $this->adminError(lang('please select a game'));
+        } elseif ($_model->checkGame($_params['app_id'])) {
+            $this->adminError(lang('game_existed'));
+        }
+        $_result = $_model->addPaySwitch($_params);
+        if (false == $_result) {
+            $this->adminError(lang('add').lang('failure'));
+        }
+        $this->adminSuccess(lang('add').lang('success'), url('admin/game.paySwitch/index'));
+    }
+
+    /**
+     * 编辑切换规则
+     * admin/game.pay_switch/edit
+     *
+     * @throws
+     */
+    public function edit() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $this->_games(
+            $_app_id, 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, GameConst::GAME_IOS_SWITCH, false, true,
+            [], '', 'disabled'
+        );
+        if (empty($_app_id)) {
+            $this->adminError(lang('param_error'));
+        }
+        $_data = GamePaySwitchCache::ins()->getInfoByAppId($_app_id);
+        $this->assign('data', $_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 编辑切换规则提交
+     * admin/game.pay_switch/editPost
+     *
+     * @throws
+     */
+    public function editPost() {
+        $_params = $this->request->param();
+        if (empty($_params['app_id'])) {
+            $this->adminError(lang('please select a game'));
+        }
+        $_params['is_domestic'] = isset($_params['is_domestic']) ? $_params['is_domestic'] : OrderConst::PAY_SWITCH_NO;
+        $_params['is_overseas'] = isset($_params['is_overseas']) ? $_params['is_overseas'] : OrderConst::PAY_SWITCH_NO;
+        $_params['is_first'] = isset($_params['is_first']) ? $_params['is_first'] : OrderConst::PAY_SWITCH_YES;
+        $_result = GamePaySwitchCache::ins()->updatePaySwitch($_params['app_id'], $_params);
+        if (false == $_result) {
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/game.paySwitch/index'));
+    }
+
+    public function setSwitch() {
+        $_data = [];
+        $_data['app_id'] = $this->request->param('app_id/d', 0);
+        $_field = $this->request->param('field/s', '');
+        $_status = $this->request->param('status/d', 1);
+        if (empty($_data['app_id']) || empty($_field)) {
+            $this->adminError(lang('param_error'));
+        }
+        $_data[$_field] = $_status;
+        $_result = GamePaySwitchCache::ins()->updatePaySwitch($_data['app_id'], $_data);
+        if (false == $_result) {
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/game.paySwitch/index'));
+    }
+}

+ 271 - 0
admin/admin/controller/game/QqController.php

@@ -0,0 +1,271 @@
+<?php
+/**
+ * QqController.php  UTF-8
+ * WWW
+ *
+ * @date    : 2018/7/13 22:58
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\game\GameQqCache;
+use huo\controller\help\QqCache;
+use huo\logic\game\GameQqLogic;
+use huo\logic\qq\QqConfLogic;
+use huo\model\conf\QqConfModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\tool\Page;
+use think\Lang;
+
+class QqController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'game_help'.EXT);
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    protected function _status($status = 0) {
+        $_status = GameConst::getQqStatusMsg($status, true);
+        $_status_select = Filter::selectCommon($_status, 'status', $status);
+        $this->assign('status_select', $_status_select);
+    }
+
+    /**
+     * 获取列表
+     * /admin/game.help/index
+     *
+     * @return mixed
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function index() {
+        $_param = [];
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_param['status'] = $this->request->param('status/d', 0);
+        $_param['start_time'] = $this->request->param('start_time/s', '');
+        $_param['end_time'] = $this->request->param('end_time/s', '');
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_page = $this->request->param('page/d', 1);
+        /*搜索*/
+        $this->_status($_param['status']);
+        $this->_games(
+            $_param['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK
+        );
+        $this->_time($_param['start_time'], $_param['end_time']);
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', 'uri' => url('admin/Game.help/index')]
+        );
+        $_data = (new GameQqLogic())->getAdminList($_param, $_page.','.$_list_rows);
+        $_page_data = Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        $this->assign('filter_button', $_filter_button);
+        $this->assign('filter_button_clear', $_filter_button_clear);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加页面
+     * /admin/game.help/add
+     */
+    public function add() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $this->_games(
+            $_app_id, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK
+        );
+        $this->_getQqGroups();
+        $this->_status();
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加页面
+     * /admin/game.help/addPost
+     */
+    public function addPost() {
+        $_param = $this->request->param();
+        $_gmq_data = (new GameQqLogic())->getGameQqDetail($_param);
+        if (false === $_gmq_data) {
+            $this->adminError(lang('ADD_FAILED'));
+        }
+        if (!empty($_gmq_data)) { //存在记录
+            if (CommonConst::CONST_NOT_DELETE == $_gmq_data['is_delete']) {  //存在未删除记录
+                $this->adminError(lang('QQ').lang('existed'));
+            } else {
+                $_gmq_data['is_delete'] = CommonConst::CONST_NOT_DELETE;
+                $_gmq_data['delete_time'] = 0;
+                $_rs = (new GameQqCache())->updateGame($_gmq_data);
+                if (false == $_rs) {
+                    $this->adminError(lang('ADD_FAILED'));
+                }
+                $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/game.qq/index'));
+            }
+        }
+        $_param['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_rs = (new GameQqCache())->addGame($_param);
+        if (false == $_rs) {
+            $this->adminError(lang('ADD_FAILED'));
+        }
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/game.qq/index'));
+    }
+
+    /**
+     * 添加页面
+     * /admin/game.help/edit
+     */
+    public function edit() {
+        $_id = $this->request->param('id/d', 0);
+        $_gmq_data = (new GameQqLogic())->getGameQqInfoById($_id);
+        if (empty($_gmq_data)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->_games(
+            $_gmq_data['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, 0,
+            true, true, [], '', 'disabled'
+        );
+        $this->_getQqGroups($_gmq_data['qq_id']);
+        $this->_status($_gmq_data['status']);
+        $this->assign($_gmq_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加页面
+     * /admin/game.help/editPost
+     */
+    public function editPost() {
+        $_param = $this->request->param();
+        if (empty($_param['id'])) {
+            $this->adminError(lang('param error'));
+        }
+        $_gmq_data = (new GameQqLogic())->getGameQqDetail($_param);
+        if (false === $_gmq_data) {
+            $this->adminError(lang('ADD_FAILED'));
+        }
+        if (!empty($_gmq_data)) { //存在记录
+            if (CommonConst::CONST_NOT_DELETE == $_gmq_data['is_delete']) {  //存在未删除记录
+                $this->adminError(lang('QQ').lang('existed'));
+            } else {
+                $_gmq_data['is_delete'] = CommonConst::CONST_NOT_DELETE;
+                $_gmq_data['delete_time'] = 0;
+                $_rs = (new GameQqCache())->updateGame($_gmq_data);
+                if (false == $_rs) {
+                    $this->adminError(lang('ADD_FAILED'));
+                }
+                /*修改则删除当前*/
+                $_data = [];
+                $_data['is_delete'] = CommonConst::CONST_DELETED;
+                $_data['delete_time'] = time();
+                $_data['id'] = $_param['id'];
+                (new GameQqCache())->updateGame($_data);
+                $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/game.qq/index'));
+            }
+        }
+        $_rs = (new GameQqCache())->updateGame($_param);
+        if (false == $_rs) {
+            $this->adminError(lang('ADD_FAILED'));
+        }
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/game.qq/index'));
+    }
+
+    /**
+     * 添加QQ群
+     */
+    public function qqAdd() {
+        $_id = $this->request->param('id', '-1');
+        $this->assign('id', $_id);
+
+        return $this->fetch();
+    }
+
+    /***
+     * 添加QQ群提交处理
+     *
+     * @throws
+     */
+    public function qqAddPost() {
+        $_qq_id = 0;
+        $_params = $this->request->param();
+        $_id = $_params['gqid'];
+        $_params['type'] = GameConst::QQ_TYPE_QQ_GROUP;
+        $_params['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_validate = validate('Qq');
+        if (!$_validate->scene('qq_group')->check($_params)) {
+            $this->adminError($_validate->getError());
+        }
+        $_res = (new QqConfLogic())->isUnique($_params);
+        if (!empty($_res)) {
+            if (!empty($_res['id']) && CommonConst::CONST_NOT_DELETE != $_res['is_delete']) {  //存在记录但是已经删除,更新记录
+                $_params['is_delete'] = CommonConst::CONST_NOT_DELETE;
+                $_params['delete_time'] = 0;
+                $_result = (new QqCache())->updateQq($_res['id'], $_params);
+                if (false == $_result) {
+                    $this->adminError(lang('ADD_FAILED'));
+                }
+                $_qq_id = $_res['id'];
+            } else {
+                $this->adminError(lang('QQ').lang('existed'));
+            }
+        }
+        if (empty($_qq_id)) {
+            $_qq_id = (new QqConfModel())->addQqs($_params);
+        }
+        if (empty($_qq_id)) {
+            $this->adminError(lang('ADD_FAILED'));
+        }
+        if ($_id != '-1') {
+            $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/game.qq/edit', ['id' => $_id]));
+        }
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/game.qq/index'));
+    }
+
+    /**
+     * 删除QQ
+     * /admin/game.help/delete
+     */
+    public function delete() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = [];
+        $_data['is_delete'] = CommonConst::CONST_DELETED;
+        $_data['delete_time'] = time();
+        $_data['id'] = $_id;
+        $_rs = (new GameQqCache())->updateGame($_data);
+        if (false == $_rs) {
+            $this->adminError(lang('DELETE_FAILED'));
+        }
+        $this->adminSuccess(lang('DELETE_SUCCESS'), url('admin/game.qq/index'));
+    }
+
+    /**
+     * 设置状态
+     */
+    public function setStatus() {
+        $_data = [];
+        $_data['id'] = $this->request->param('id/d', 0);
+        if (empty($_data['id'])) {
+            $this->adminError(lang('param error'));
+        }
+        $_data['status'] = $this->request->param('status/d', 2);
+        $_rs = (new GameQqCache())->updateGame($_data);
+        if (false == $_rs) {
+            $this->adminError(lang('EDIT_FAILED'));
+        }
+        $this->adminSuccess(lang('EDIT_SUCCESS'), url('admin/game.qq/index'));
+    }
+}

+ 132 - 0
admin/admin/controller/game/ServerController.php

@@ -0,0 +1,132 @@
+<?php
+/**
+ * ServerController.php UTF-8
+ * 开服管理
+ *
+ * @date    : 2018/1/24 20:24
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : linjiebin <ljb@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\game;
+
+use admin\admin\service\TimeService;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\model\game\GameserverModel;
+use think\Lang;
+
+class ServerController extends AdminBaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_server'.EXT
+        );
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    /**
+     * 开服列表
+     */
+    public function index() {
+        $_param = $this->request->param();
+        $_server_class = new GameserverModel();
+        $_server_obj = $_server_class->getList($_param);
+        $_server_obj->appends($_param);
+        $_page = $_server_obj->render();
+        $_items = $_server_obj->toArray()['data'];
+        $status_data = array("1" => lang('trailer'), "2" => lang('already_begun'));
+        foreach ($_items as $key => $value) {
+//            $_items[$key]['start_time'] = date("Y-m-d H:i:s", $value['start_time']);
+            $_items[$key]['ser_desc_striped'] = mb_substr(($value['ser_desc']), 0, 50);
+            $_items[$key]['status_txt'] = $status_data[$value['status']];
+        }
+        $_app_id = $this->request->param('app_id', 0);
+        $this->_games($_app_id, 2, 2);
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', 'uri' => url('admin/Game.server/index')]
+        );
+        $this->assign('filter_button', $_filter_button);
+        $this->assign('filter_button_clear', $_filter_button_clear);
+        $this->assign('data', $_param);
+        $this->assign('items', $_items);
+        $this->assign('page', $_page);
+
+        return $this->fetch();
+    }
+
+    public function add() {
+        $_games = $this->_games(0, 2, 2);
+        $_app_select = Filter::selectCommon($_games, 'app_id', $this->request->get('app_id/d', 0));
+        $this->assign('app_select', $_app_select);
+
+        return $this->fetch();
+    }
+
+    public function edit() {
+        $id = $this->request->param('id/d', 0);
+        $_server_class = new GameserverModel();
+        $_server_obj = $_server_class->getList(array("id" => $id), 1);
+        $_items = $_server_obj->items();
+        $_games = $this->_games(0, 2, 2);
+        $_app_select = Filter::selectCommon($_games, 'app_id', $_items[0]['app_id']);
+        $this->assign('app_select', $_app_select);
+        $this->assign("data", $_items[0]);
+        $status_choose_txt = $this->statusInput($_items[0]['status']);
+        $this->assign("status_choose_txt", $status_choose_txt);
+
+        return $this->fetch();
+    }
+
+    public function add_post() {
+        $_server_class = new GameserverModel();
+        $_param = $this->request->param();
+        $_param['start_time'] = strtotime($_param['start_time']);
+        $_res = $_server_class->addServer($_param);
+        if ($_res === false) {
+            $this->adminError(lang('ADD').lang('FAILURE'));
+        }
+        $this->adminSuccess(lang('ADD').lang('SUCCESS'), url('Game.server/index'));
+    }
+
+    public function edit_post() {
+        $_server_class = new GameserverModel();
+        $_param = $this->request->param();
+        $_param['start_time'] = strtotime($_param['start_time']);
+        $_res = $_server_class->updateServer($_param, $_param['id']);
+        if ($_res === false) {
+            $this->adminError(lang('EDIT').lang('FAILURE'));
+        }
+        $this->adminSuccess(lang('EDIT').lang('SUCCESS'), url('Game.server/index'));
+    }
+
+    public function delete() {
+        $id = $this->request->param('id/d', 0);
+        $_server_class = new GameserverModel();
+        $_res = $_server_class->deleteServer($id);
+        if ($_res === false) {
+            $this->adminError(lang('DELETE').lang('FAILURE'));
+        }
+        $this->adminSuccess(lang('DELETE').lang('SUCCESS'), url('Game.server/index'));
+    }
+
+    public function statusInput($status) {
+        $status_data = array("1" => lang('trailer'), "2" => lang('already_begun'));
+        $txt = '';
+        foreach ($status_data as $key => $value) {
+            $checked = '';
+            if ($status == $key) {
+                $checked = "checked='checked'";
+            }
+            $txt .= " <label class='radio-inline'><input type='radio' name='status' $checked value='$key' />".$value
+                    ."</label>";
+        }
+
+        return $txt;
+    }
+}
+

+ 235 - 0
admin/admin/controller/gift/GiftController.php

@@ -0,0 +1,235 @@
+<?php
+/**
+ * GiftController.php UTF-8
+ *
+ * @date    : 2017-11-22 17:24
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wangchuang <wangchuang@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\gift;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\gift\GiftCache;
+use huo\controller\help\QqCache;
+use huo\logic\game\GiftLogic;
+use huo\logic\qq\QqConfLogic;
+use huo\model\conf\QqConfModel;
+use huo\model\game\GiftModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use think\Lang;
+
+class GiftController extends AdminBaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_gift'.EXT);
+        parent::_initialize();
+    }
+
+    /**
+     * 游戏礼包列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function index() {
+        $_param = $this->request->param();
+        $_gift_model = new GiftModel();
+        $_gift_obj = $_gift_model->getGiftList($_param);
+        $_gift_obj->appends($_param);
+        $_page = $_gift_obj->render();
+        $_items = $_gift_obj->items();
+        $_app_id = $this->request->param('app_id', 0);
+        $this->_games($_app_id, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE);
+        $this->_getQqGroups($this->request->get('app_id/d', 0));
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', 'uri' => url('admin/Gift.gift/index')]
+        );
+        $this->assign('filter_button_clear', $_filter_button_clear);
+        $this->assign('filter_button', $_filter_button);
+        $this->assign('data', $_param);
+        $this->assign('items', $_items);
+        $this->assign('page', $_page);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加礼包
+     *
+     * @return mixed
+     */
+    public function add() {
+        $this->_games(0, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE);
+        $this->_getQqGroups();
+        $this->_time(date('Y-m-d'), date('Y-m-d', strtotime('1 month')));
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加礼包数据
+     */
+    public function addPost() {
+        $_param = $this->request->param();
+        // 验证参数
+        $_v_res = $this->validate($_param, 'Gift.add');
+        if ($_v_res !== true) {
+            $this->adminError($_v_res);
+        }
+        $_gift_model = new GiftModel();
+        $_res = $_gift_model->addNewGift($_param);
+        if ($_res === false) {
+            $this->adminError(lang('add failure'));
+        }
+        (new GiftLogic())->checkGameGift($_res);
+        $this->adminSuccess(lang('add success'), url('Gift.gift/index'));
+    }
+
+    /**
+     * 编辑礼包
+     */
+    public function edit() {
+        $_gift_id = $this->request->param('id', 0, 'intval');
+        $_gift_data = GiftCache::ins()->getInfoByGiftId($_gift_id);
+        $this->_games($_gift_data['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE);
+        $this->_time(date('Y-m-d', $_gift_data['start_time']), date('Y-m-d', $_gift_data['end_time']));
+        $this->assign('data', $_gift_data);
+        $this->_getQqGroups($_gift_data['qq_id']);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 修改礼包的信息
+     */
+    public function editPost() {
+        $_gift_data = $this->request->param();
+        // 验证参数
+        $_v_res = $this->validate($_gift_data, 'Gift.edit');
+        if ($_v_res !== true) {
+            $this->adminError($_v_res);
+        }
+        $_gift_data['start_time'] = strtotime($_gift_data['start_time']);
+        $_gift_data['end_time'] = strtotime($_gift_data['end_time']);
+        $gift_id = $_gift_data['id'];
+        $_res = GiftCache::ins()->updateGift($gift_id, $_gift_data);
+        if ($_res === false) {
+            $this->adminError(lang('edit failure'));
+        }
+        $this->adminSuccess(lang('edit success'), url('Gift.gift/index'));
+    }
+
+    /**
+     * 删除礼包
+     */
+    public function delete() {
+        $_gift_id = $this->request->param('id', 0, 'intval');
+        $_g_data['is_delete'] = 1;
+        $_g_data['delete_time'] = time();
+        $_res = GiftCache::ins()->updateGift($_gift_id, $_g_data);
+        if ($_res === false) {
+            $this->adminError(lang('delete failure'));
+        }
+        $this->adminSuccess(lang('delete success'), url('Gift.gift/index'));
+    }
+
+    /**
+     * 设置礼包状态
+     */
+    public function status() {
+        $_param = $this->request->param();
+        $_gift_model = new GiftModel();
+        $_res = $_gift_model->editStatus($_param);
+        if ($_res) {
+            $this->adminSuccess(lang('edit success'));
+        } else {
+            $this->adminError(lang('edit failure'));
+        }
+    }
+
+    /**
+     *  编辑加群礼包
+     */
+    public function qqGift() {
+        $_gift_id = $this->request->param('id', 0, 'intval');
+        $_gift_data = GiftCache::ins()->getInfoByGiftId($_gift_id);
+        $this->_getQqGroups($_gift_data['qq_id']);
+        $this->assign('data', $_gift_data);
+
+        return $this->fetch();
+    }
+
+    /**
+     *  保存加群礼包
+     */
+    public function qqGiftPost() {
+        $_gift_data = $this->request->param();
+        $_gift_id = $_gift_data['id'];
+        $_gift_data['update_time'] = time();
+        $_res = GiftCache::ins()->updateGift($_gift_id, $_gift_data);
+        if ($_res === false) {
+            $this->adminError(lang('edit failure'));
+        }
+        $this->adminSuccess(lang('edit success'));
+    }
+
+    /**
+     * 添加QQ群
+     */
+    public function qqAdd() {
+        $_gift_id = $this->request->param('gift_id/d', 0);
+        if (empty($_gift_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->assign('gift_id', $_gift_id);
+
+        return $this->fetch();
+    }
+
+    /***
+     * 添加QQ群提交处理
+     *
+     * @throws
+     */
+    public function qqAddPost() {
+        $_qq_id = 0;
+        $_params = $this->request->param();
+        $_gift_id = $_params['gift_id'];
+        $_params['type'] = 2;
+        $_params['is_delete'] = 2;
+        $_validate = validate('Qq');
+        if (!$_validate->scene('qq_group')->check($_params)) {
+            $this->adminError($_validate->getError());
+        }
+        $_res = (new QqConfLogic())->isUnique($_params);
+        if (!empty($_res)) {
+            if (!empty($_res['id']) && CommonConst::CONST_NOT_DELETE != $_res['is_delete']) {  //存在记录但是已经删除,更新记录
+                $_params['is_delete'] = 2;
+                $_params['delete_time'] = 0;
+                $_result = (new QqCache())->updateQq($_res['id'], $_params);
+                if (false == $_result) {
+                    $this->adminError(lang('add_failure'));
+                }
+                $_qq_id = $_res['id'];
+            } else {
+                $this->adminError(lang('qq_group_num').lang('existed'));
+            }
+        }
+        if (empty($_qq_id)) {
+            $_qq_id = (new QqConfModel())->addQqs($_params);
+        }
+        $_gift_data['qq_id'] = $_qq_id;
+        $_gift_data['update_time'] = time();
+        $_res = GiftCache::ins()->updateGift($_gift_id, $_gift_data);
+        if ($_res === false) {
+            $this->adminError(lang('edit failure'));
+        }
+        $this->adminSuccess(lang('edit success'), url('admin/gift.gift/index'));
+    }
+}

+ 189 - 0
admin/admin/controller/identify/HolidaySetController.php

@@ -0,0 +1,189 @@
+<?php
+/**
+ * HolidaySetController.php  UTF-8
+ * 节假日配置
+ *
+ * @date    : 2019/12/4 16:36
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.5
+ */
+
+namespace admin\admin\controller\identify;
+
+use cmf\controller\AdminBaseController;
+use huoIdentify\model\IdentifyHolidaySetModel;
+use huolib\constant\CommonConst;
+use huolib\status\CommonStatus;
+use huolib\tool\Page;
+use menu\controller\Menu;
+use think\Model;
+
+class HolidaySetController extends AdminBaseController {
+    /***
+     * 节假日配置
+     * admin/identify.holiday_set/index
+     * admin/identify.holidaySet/index
+     */
+    public function index() {
+        $_param = $this->request->param();
+        $_page = $this->page;
+        $_list_rows = $this->list_rows;
+        $_data = (new IdentifyHolidaySetModel())->getList($_param, $_page.','.$_list_rows);
+        $_page_data = Page::paginate($_data['count'], $_data['list'], $this->page, $this->list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('index');
+    }
+
+    /**
+     * 添加节假日配置
+     * admin/identify.holiday_set/add
+     * admin/identify.holidaySet/add
+     */
+    public function add() {
+        $this->_time();
+
+        return $this->fetch('add');
+    }
+
+    /**
+     * 添加节假日配置提交
+     * admin/identify.holiday_set/addPost
+     * admin/identify.holidaySet/addPost
+     */
+    public function addPost() {
+        $_holiday_arr = $this->request->param('holiday/a', []);
+        if (empty($_holiday_arr)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+            $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_year = date('Y', strtotime($_holiday_arr[0]));
+        /* 校验是否含非同年日期 */
+        foreach ($_holiday_arr as $_day) {
+            $_day_year = date('Y', strtotime($_day));
+            if ($_day_year != $_year) {
+                $this->adminError(lang('MUST_SAME_YEAR'));
+            }
+        }
+        $_ihs_model = new IdentifyHolidaySetModel();
+        /* 校验配置是否存在 */
+        $_id = $_ihs_model->getIdByYear($_year);
+        if (!empty($_id)) {
+            $this->adminError(lang('HOLIDAY_SET_EXISTED'));
+        }
+        $_holiday_arr = array_unique($_holiday_arr);
+        asort($_holiday_arr);
+        $_data = [
+            'year'    => $_year,
+            'holiday' => $_holiday_arr
+        ];
+        $_rs = $_ihs_model->addData($_data);
+        if (!$_rs) {
+            $this->adminError(lang('ADD_ERROR'));
+        }
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('index'));
+    }
+
+    /**
+     * 编辑节假日配置
+     * admin/identify.holiday_set/edit
+     * admin/identify.holidaySet/edit
+     */
+    public function edit() {
+        $_id = $this->request->param('id/d', CommonConst::CONST_ZERO);
+        $_data = (new IdentifyHolidaySetModel())->getInfoById($_id);
+        $this->assign($_data);
+
+        return $this->fetch('edit');
+    }
+
+    /**
+     * 编辑节假日配置提交
+     * admin/identify.holiday_set/editPost
+     * admin/identify.holidaySet/editPost
+     */
+    public function editPost() {
+        $_id = $this->request->param('id/d', CommonConst::CONST_ZERO);
+        $_year = $this->request->param('year/d', CommonConst::CONST_ZERO);
+        $_holiday_arr = $this->request->param('holiday/a', []);
+        if ((empty($_holiday_arr)) || empty($_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+            $this->adminError(CommonStatus::getMsg($_code));
+        }
+        /* 校验是否含非同年日期 */
+        foreach ($_holiday_arr as $_day) {
+            $_day_year = date('Y', strtotime($_day));
+            if ($_day_year != $_year) {
+                $this->adminError(lang('MUST_SAME_YEAR'));
+            }
+        }
+        $_ihs_model = new IdentifyHolidaySetModel();
+        $_holiday_arr = array_unique($_holiday_arr);
+        asort($_holiday_arr);
+        $_data = [
+            'holiday' => $_holiday_arr,
+        ];
+        $_rs = $_ihs_model->updateData($_data, $_id);
+        if (!$_rs) {
+            $this->adminError(lang('EDIT_ERROR'));
+        }
+        $this->adminSuccess(lang('EDIT_SUCCESS'));
+    }
+
+    /**
+     * 删除配置
+     * admin/identify.holiday_set/delete
+     * admin/identify.holidaySet/delete
+     */
+    public function delete() {
+        $_id = $this->request->param('id/d', CommonConst::CONST_ZERO);
+        if (empty($_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+            $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_ihs_model = new IdentifyHolidaySetModel();
+        $_rs = $_ihs_model->deleteData($_id);
+        if (!$_rs) {
+            $this->adminError(lang('DELETE_ERROR'));
+        }
+        $this->adminSuccess(lang('DELETE_SUCCESS'), url('index'));
+    }
+
+    /**
+     * 添加菜单
+     *
+     * admin/identify.holiday_set/addMenu
+     * admin/identify.holidaySet/addMenu
+     *
+     * @param int $parent_id
+     * @param int $list_order
+     *
+     * @return mixed
+     */
+    public function addMenu($parent_id = 494, $list_order = 900) {
+        $_controller = 'identify.holidaySet';/* 控制器名 */
+        $_name = '节假日配置'; /* 菜单名称 */
+        $_en_name = 'Holiday Set'; /* 菜单英文名称 */
+        $_icon = 'fa-id-card '; /* 菜单图标 */
+        $_menu_class = new Menu();
+        $_app = 'admin';
+        $_menu_class->setApp($_app);
+        /* 删除原有菜单 */
+        $_menu_class->deleteMenu('identify.holidaySet', $_app);
+        if (empty($_parent_id)) {
+            $_parent_id = $this->request->param('parent_id/d', $parent_id);
+        }
+        if (empty($_list_order)) {
+            $_list_order = $this->request->param('list_order/d', $list_order);
+        }
+        /* 实名认证配置 */
+        $_index_parent_id = $_menu_class->addDefaultMenu(
+            $_controller, $_parent_id, $_list_order, $_name, $_en_name, $_icon, 1, 1, ['add', 'edit', 'delete']
+        );
+
+        return $_index_parent_id;
+    }
+}

+ 203 - 0
admin/admin/controller/identify/IdentifyConfController.php

@@ -0,0 +1,203 @@
+<?php
+/**
+ * IdentifyConfController.php  UTF-8
+ * 实名认证配置
+ *
+ * @date    : 2019/12/3 14:28
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.5
+ */
+
+namespace admin\admin\controller\identify;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\wap\Option;
+use huoIdentify\controller\IdentifyConf;
+use huolib\constant\CommonConst;
+use huolib\constant\OptionConst;
+use menu\controller\Menu;
+
+class IdentifyConfController extends AdminBaseController {
+    function _initialize() {
+        parent::_initialize();
+    }
+
+    /**
+     * 通用配置首页
+     *
+     * admin/identify.identify_conf/index
+     * admin/identify.identifyConf/index
+     *
+     * @return mixed
+     */
+    public function index() {
+        $_setting_name = OptionConst::IDENTIFY_CONF_OPTION;
+        $_data = (new IdentifyConf())->getConf(true);
+        /* 未实名是否允许充值 1不允许 2允许 */
+        $_is_allow_charge = !empty($_data['unnamed']['is_allow_charge']) ? $_data['unnamed']['is_allow_charge']
+            : CommonConst::STATUS_NO;
+        $this->_isAllowCharge($_is_allow_charge);
+        /* 是否开启第三方api校验 */
+        $_other_api_check = !empty($_data['unnamed']['other_api_check']) ? $_data['unnamed']['other_api_check']
+            : CommonConst::STATUS_NO;
+        $this->_isOtherApiCheck($_other_api_check);
+        $this->assign('option_name', $_setting_name);
+        $this->assign('data', $_data);
+        $_charge_limit_cnt = count($_data['underage']['charge_limit']);
+        $this->assign('charge_limit_cnt', $_charge_limit_cnt);
+        $this->assign('no_frame', 1);
+        $this->assign('allow_start_time', get_val($_data['underage'], 'allow_start_time', '20'));
+        $_allow_start_time_minute = get_val($_data['underage'], 'allow_start_time_minute', '00');
+        $_allow_start_time_minute = mktime(
+            0, $_allow_start_time_minute, 0, date('m'), date('d'), date('Y')
+        );
+        $_allow_start_time_minute = date('i', $_allow_start_time_minute);
+        $this->assign('allow_start_time_minute', $_allow_start_time_minute);
+        $this->assign('allow_end_time', get_val($_data['underage'], 'allow_end_time', '20'));
+        $_allow_end_time_minute = get_val($_data['underage'], 'allow_end_time_minute', '00');
+        $_allow_end_time_minute = mktime(
+            0, $_allow_end_time_minute, 0, date('m'), date('d'), date('Y')
+        );
+        $_allow_end_time_minute = date('i', $_allow_end_time_minute);
+        $this->assign('allow_end_time_minute', $_allow_end_time_minute);
+
+        return $this->fetch('index');
+    }
+
+    /**
+     * 通用配置首页
+     *
+     * admin/identify.identify_conf/post
+     * admin/identify.identifyConf/post
+     *
+     * @return mixed
+     */
+    public function post() {
+        $_m = new Option();
+        $_setting_name = OptionConst::IDENTIFY_CONF_OPTION;
+        $_param = $this->request->param();
+        $_param = $this->trimAll($_param); //移除空格
+        /* 未实名配置 */
+        $_data['unnamed']['limit_time'] = get_val($_param, 'limit_time', CommonConst::CONST_ZERO);
+        $_data['unnamed']['id_card_bind_cnt'] = get_val($_param, 'id_card_bind_cnt', CommonConst::CONST_ZERO);
+        /* 转为秒 */
+        $_data['unnamed']['limit_time'] = $_data['unnamed']['limit_time'] * CommonConst::CONST_MINUTE_SECONDS;
+        $_data['unnamed']['expired_day'] = get_val($_param, 'expired_day', CommonConst::CONST_ZERO);
+        /* radio */
+        $_data['unnamed']['is_allow_charge'] = get_val($_param, 'is_allow_charge', CommonConst::CONST_ZERO);
+        $_data['unnamed']['other_api_check'] = get_val($_param, 'other_api_check', CommonConst::CONST_ZERO);
+        /* 未成年配置 */
+        $_data['underage']['limit_today_time'] = get_val($_param, 'limit_today_time', CommonConst::CONST_ZERO);
+        $_data['underage']['limit_next_day_time'] = get_val($_param, 'limit_next_day_time', CommonConst::CONST_ZERO);
+        $_data['underage']['day_limit_time'] = get_val($_param, 'day_limit_time', CommonConst::CONST_ZERO);
+        /* 允许登陆开始时间 */
+        $_data['underage']['allow_start_time'] = get_val($_param, 'allow_start_time', CommonConst::CONST_ZERO);
+        $_data['underage']['allow_start_time_minute'] = get_val(
+            $_param, 'allow_start_time_minute', CommonConst::CONST_ZERO
+        );
+        /* 允许登陆结束时间 */
+        $_data['underage']['allow_end_time'] = get_val($_param, 'allow_end_time', CommonConst::CONST_ZERO);
+        $_data['underage']['allow_end_time_minute'] = get_val(
+            $_param, 'allow_end_time_minute', CommonConst::CONST_ZERO
+        );
+        /* 转为秒 */
+        $_data['underage']['day_limit_time'] = $_data['underage']['day_limit_time'] * CommonConst::CONST_MINUTE_SECONDS;
+        $_data['underage']['holiday_limit_time'] = get_val($_param, 'holiday_limit_time', CommonConst::CONST_ZERO);
+        /* 转为秒 */
+        $_data['underage']['holiday_limit_time'] = $_data['underage']['holiday_limit_time']
+                                                   * CommonConst::CONST_MINUTE_SECONDS;
+        $_charge_limit = [];
+        foreach ($_param['min_age'] as $_k => $_v) {
+            $_charge_limit[$_k]['min_age'] = $_v;
+            $_charge_limit[$_k]['max_age'] = get_val($_param['max_age'], $_k, CommonConst::CONST_ZERO);
+            $_charge_limit[$_k]['week_money'] = get_val($_param['week_money'], $_k, CommonConst::CONST_ZERO);
+            $_charge_limit[$_k]['month_money'] = get_val($_param['month_money'], $_k, CommonConst::CONST_ZERO);
+        }
+        $_data['underage']['charge_limit'] = $_charge_limit;
+        $_res = $_m->saveOptionData($_setting_name, json_encode($_data));
+        if (!$_res) {
+            $this->adminError(lang('ERROR'), url('index'));
+        }
+        $this->adminSuccess(lang('SUCCESS'), url('index'));
+    }
+
+    /**
+     * 是否允许充值
+     *
+     * @param int $is_allow_charge
+     *
+     * @return array
+     */
+    public function _isAllowCharge($is_allow_charge = CommonConst::CONST_ZERO) {
+        $_arr = [
+            CommonConst::STATUS_NO  => lang('NOT_ALLOW'),
+            CommonConst::STATUS_YES => lang('ALLOW')
+        ];
+        $_is_allow_charge_radio = Filter::radioCommon($_arr, 'is_allow_charge', $is_allow_charge);
+        $this->assign('is_allow_charge_radio', $_is_allow_charge_radio);
+
+        return $_arr;
+    }
+
+    /**
+     * 是否第三方校验
+     *
+     * @param int $other_api_check
+     *
+     * @return array
+     */
+    public function _isOtherApiCheck($other_api_check = CommonConst::CONST_ZERO) {
+        $_arr = [
+            CommonConst::STATUS_NO  => lang('NAY'),
+            CommonConst::STATUS_YES => lang('YES')
+        ];
+        $_other_api_check_radio = Filter::radioCommon($_arr, 'other_api_check', $other_api_check);
+        $this->assign('other_api_check_radio', $_other_api_check_radio);
+
+        return $_arr;
+    }
+
+    /**
+     * 添加菜单
+     *
+     * admin/identify.identify_conf/addMenu
+     * admin/identify.identifyConf/addMenu
+     *
+     * @param int $parent_id
+     * @param int $list_order
+     *
+     * @return mixed
+     */
+    public function addMenu($parent_id = 494, $list_order = 900) {
+        $_controller = 'identify.identifyConf';/* 控制器名 */
+        $_name = '实名认证配置'; /* 菜单名称 */
+        $_en_name = 'Identify Conf'; /* 菜单英文名称 */
+        $_icon = 'fa-id-card '; /* 菜单图标 */
+        $_menu_class = new Menu();
+        $_app = 'admin';
+        $_menu_class->setApp($_app);
+        /* 删除原有菜单 */
+        $_menu_class->deleteMenu('identify.identifyConf', $_app);
+        if (empty($_parent_id)) {
+            $_parent_id = $this->request->param('parent_id/d', $parent_id);
+        }
+        if (empty($_list_order)) {
+            $_list_order = $this->request->param('list_order/d', $list_order);
+        }
+        /* 实名认证配置 */
+        $_index_parent_id = $_menu_class->addTop(
+            $_controller, $_parent_id, $_list_order, $_name, $_en_name, $_icon, 'index'
+        );
+        {
+            /* 实名认证配置提交 */
+            $_menu_class->addTop(
+                $_controller, $_index_parent_id, 1000, '实名认证配置提交', 'Identify Conf Post', $_icon, 'post'
+            );
+        }
+
+        return $_index_parent_id;
+    }
+}

+ 331 - 0
admin/admin/controller/identify/IdentifyGameController.php

@@ -0,0 +1,331 @@
+<?php
+/**
+ * IdentifyGameController.php UTF-8
+ *
+ *
+ * @date    : 2021-03-11 15:36
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : HUOSDK 9.0
+ */
+
+namespace admin\admin\controller\identify;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huoIdentify\identifyDriver\driver\Fcmgame;
+use huoIdentify\logic\IdentifyGameLogic;
+use huoIdentify\model\GameModel;
+use huoIdentify\model\IdentifyGameModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\IdentifyConst;
+use huolib\status\CommonStatus;
+use huolib\tool\Page;
+use menu\controller\Menu;
+use think\Model;
+
+class IdentifyGameController extends AdminBaseController {
+    function _initialize() {
+        parent::_initialize();
+    }
+
+    /**
+     * 列表
+     * admin/identify.identify_game/index
+     */
+    public function index() {
+        if (CommonConst::CONST_EXPORT == $this->request->param('export/d', 0)) {
+            return $this->exportIndex();
+        }
+        $_param = $this->getSearchParam();
+        $_param = $this->trimAll($_param);  //移除所有空格
+        /*获取列表数据与分页*/
+        $_datas = (new IdentifyGameLogic())->getAdminList($_param, $this->page.','.$this->list_rows, '-id');
+        $_page_data = Page::paginate($_datas['count'], $_datas['list'], $this->page, $this->list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('index');
+    }
+
+    /**
+     * 编辑
+     * admin/identify.identify_game/edit
+     */
+    public function edit() {
+        $_app_id = $this->request->param('app_id/d');
+        if (empty($_app_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+
+            return $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_game_info = (new GameModel())->getInfoById($_app_id);
+        $_data = (new IdentifyGameModel())->getInfoByAppId($_app_id);
+        $this->assign('game_info', $_game_info);
+        $this->assign('data', $_data);
+        $_driver_key = get_val($_data, 'driver_key', '');
+        $this->_driver_key($_driver_key);
+
+        return $this->fetch('edit');
+    }
+
+    /**
+     * 编辑操作函数
+     * admin/identify.identify_game/editPost
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            /* 校验参数 */
+            $_param = $this->request->param();
+            /* 逻辑处理 */
+            $_identify_game_model = new IdentifyGameModel();
+            $_identify_game_info = $_identify_game_model->getInfoByAppId($_param['app_id']);
+            $_ext_info = [];
+            if (!empty($_identify_game_info['ext_info'])) {
+                $_ext_info = $_identify_game_info['ext_info'];
+            }
+            $_param['ext_info'] = $_ext_info;
+            if (!empty($_param['channel_code'])) {
+                $_param['ext_info']['channel_code'] = $_param['channel_code'];
+                $_param['ext_info']['require_url'] = $_param['require_url'];
+            }
+            if (!empty($_param['require_url'])) {
+                $_param['ext_info']['require_url'] = $_param['require_url'];
+            }
+            if (!empty($_param['server_key'])) {
+                $_param['ext_info']['server_key'] = $_param['server_key'];
+            }
+            if (!empty($_param['game_id'])) {
+                $_param['ext_info']['game_id'] = $_param['game_id'];
+            }
+            if (!empty($_param['moxing_app_key'])) {
+                $_param['ext_info']['app_key'] = $_param['moxing_app_key'];
+            }
+            if (!empty($_param['secret_key'])) {
+                $_param['ext_info']['secret_key'] = $_param['secret_key'];
+            }
+            if (!empty($_param['channel_id'])) {
+                $_param['ext_info']['channel_id'] = $_param['channel_id'];
+            }
+            if (empty($_identify_game_info)) {
+                $_rs = $_identify_game_model->addData($_param);
+            } else {
+                $_rs = $_identify_game_model->updateData($_param, $_identify_game_info['id']);
+            }
+            if (false === $_rs) {
+                return $this->adminError(lang('FAILED'));
+            }
+
+            return $this->adminSuccess(lang('SUCCESS'));
+        } else {
+            $_code = CommonStatus::INVALID_PARAMS;
+
+            return $this->adminError(CommonStatus::getMsg($_code));
+        }
+    }
+
+    /**
+     * 删除配置
+     * admin/identify.identify_game/delete
+     */
+    public function delete() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+
+            return $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_identify_game_model = new IdentifyGameModel();
+        $_identify_game_info = $_identify_game_model->getInfoByAppId($_app_id);
+        if (empty($_identify_game_info)) {
+            return $this->adminSuccess(lang('SUCCESS'));
+        }
+        $_rs = $_identify_game_model->deleteData($_identify_game_info['id']);
+        if (false === $_rs) {
+            return $this->adminError(lang('FAILED'));
+        }
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 防沉迷密钥更新
+     */
+    public function modifyAppSecret() {
+        $_app_secret = $this->request->param('app_secret/s');
+        if (empty($_app_secret)) {
+            $this->error('请输入新密钥!');
+        }
+        $_map = [];
+        $_update_data = [
+            'app_secret' => $_app_secret
+        ];
+        $_identify_game_model = new IdentifyGameModel();
+        $_ids = $_identify_game_model->where($_map)->column('id');
+        foreach ($_ids as $_id) {
+            $_rs = $_identify_game_model->updateData($_update_data, $_id);
+            if (false === $_rs) {
+                $this->adminError('修改失败');
+            }
+        }
+        $this->adminSuccess('修改成功');
+    }
+
+    /**
+     * 设置前置校验
+     * adminoauth/tc_game/setPreCheck
+     */
+    public function setPreCheck() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_data = (new IdentifyGameModel())->getInfoByAppId($_app_id);
+        $this->assign('data', $_data);
+        $this->assign('app_id', $_app_id);
+        $this->_games($_app_id, 0, 0, 0, 0, false, true, [], '', 'disabled');
+        $_driver_key = get_val($_data, 'driver_key', '');
+        $this->_driver_key($_driver_key);
+        $this->_preCheckType(get_val($_data, 'pre_check', IdentifyConst::IDENTITY_PRE_CHECK_REGULAR));
+
+        return $this->fetch('set_pre_check');
+    }
+
+    /**
+     * 设置前置校验
+     * adminoauth/tc_game/setPreCheckPost
+     */
+    public function setPreCheckPost() {
+        if ($this->request->isPost()) {
+            /* 校验参数 */
+            $_param = $this->request->param();
+            $_param = $this->trimAll($_param);
+            /* 逻辑处理 */
+            $_identify_game_model = new IdentifyGameModel();
+            $_identify_game_info = $_identify_game_model->getInfoByAppId($_param['app_id']);
+            if (empty($_identify_game_info)) {
+                $_rs = $_identify_game_model->addData($_param);
+            } else {
+                $_rs = $_identify_game_model->updateData($_param, $_identify_game_info['id']);
+            }
+            if (false === $_rs) {
+                return $this->adminError(lang('EDIT_FAILED'));
+            }
+
+            return $this->adminSuccess(lang('EDIT_SUCCESS'), url('index'));
+        } else {
+            $_code = CommonStatus::INVALID_PARAMS;
+
+            return $this->adminError(CommonStatus::getMsg($_code));
+        }
+    }
+
+    /**
+     * 导出数据
+     */
+    private function exportIndex() {
+    }
+
+    /**
+     * 关联获取器选择器
+     *
+     * @param int $pre_check
+     */
+    protected function _preCheckType($pre_check = 0) {
+        $_pre_check_type_list = IdentifyConst::getIdentityPreCheckType(0, true);
+        $_pre_check_type_select = Filter::selectCommon($_pre_check_type_list, 'pre_check', $pre_check);
+        $this->assign('pre_check_type_list', $_pre_check_type_list);
+        $this->assign('pre_check_type_select', $_pre_check_type_select);
+    }
+
+    /**
+     * 搜索参数
+     * return array
+     */
+    private function getSearchParam() {
+        /* 游戏搜索 */
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $this->_games(
+            $_param['app_id'],
+            0,
+            CommonConst::CONST_NOT_DELETE,
+            0,
+            GameConst::GAME_H5,
+            false,
+            true
+        );
+        /* app_key搜索 */
+        $_param['app_key'] = $this->request->param('app_key/s', '', 'trim');
+        $_app_key_input = Filter::text('app_key', $_param['app_key'], lang('IDENTIFY_GAME_APP_KEY'));
+        $this->assign('app_key_input', $_app_key_input);
+        /* biz_id搜索 */
+        $_param['biz_id'] = $this->request->param('biz_id/s', '', 'trim');
+        $_biz_id_input = Filter::text('biz_id', $_param['biz_id'], lang('IDENTIFY_GAME_BIZ_ID'));
+        $this->assign('biz_id_input', $_biz_id_input);
+        $_param['driver_key'] = $this->request->param('driver_key/s', '', 'trim');
+        $this->_driver_key($_param['driver_key']);
+        $_param = $this->trimAll($_param);
+        $_param['classify'] = GameConst::GAME_H5;
+
+        return $_param;
+    }
+
+    /**
+     *  获取驱动key
+     *
+     * @param string $driver_key
+     *
+     * @return array
+     */
+    public function _driver_key($driver_key = '') {
+        $_keys = IdentifyConst::getDriverKey();
+        $this->assign('driver_keys', $_keys);
+        $_driver_key_select = Filter::selectCommon($_keys, 'driver_key', $driver_key);
+        $this->assign('driver_key_select', $_driver_key_select);
+
+        return $_keys;
+    }
+
+    /**
+     * 添加菜单
+     *
+     * admin/identify.identify_game/addMenu?parent_id=[顶部游戏菜单ID]
+     *
+     * @param int $parent_id
+     * @param int $list_order
+     *
+     * @return mixed
+     */
+    public function addMenu($parent_id, $list_order = 0) {
+        $_controller = 'identify.identify_game';/* 控制器名 */
+        $_name = '游戏实名认证'; /* 菜单名称 */
+        $_en_name = 'Game Identify'; /* 菜单英文名称 */
+        $_icon = 'id-card'; /* 菜单图标 */
+        $_menu_class = new Menu();
+        $_app = 'admin';
+        $_menu_class->setApp($_app);
+        /* 删除原有菜单 */
+        $_menu_class->deleteMenu($_controller, $_app);
+        /* 添加菜单入口 */
+        $_manage_id = $_menu_class->addManage($_controller, $parent_id, $list_order, $_name, $_en_name, $_icon);
+        /* 实名认证配置 */
+        $_index_parent_id = $_menu_class->addDefaultMenu(
+            $_controller, $_manage_id, $list_order, $_name, $_en_name, $_icon
+        );
+
+        return $_index_parent_id;
+    }
+
+    /**
+     * 防沉迷测试用例
+     * admin/identify.identify_game/fcmTestCase
+     */
+    public function fcmTestCase() {
+        // 测试demo
+        $_app_id = 1;
+        $_identify_conf = \huoIdentify\controller\IdentifyDriverConf::getConfig('fcmgame', $_app_id);
+        $_class = new Fcmgame($_identify_conf);
+        $_class->testCaseCheck('oQNQcz', 'PMUwew', 'zstm3z');
+        $_class->testCaseQuery('v2wrfB', '8Dy8Xk', 'mzSJuf');
+        $_class->testCaseLoginOrOut('n9aMVh', 'Xb5rBK');
+    }
+}

+ 155 - 0
admin/admin/controller/identify/IdentifyMemController.php

@@ -0,0 +1,155 @@
+<?php
+/**
+ * IdentifyMemController.php UTF-8
+ *
+ * @date    : 2021/7/5 16:13
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK-IDENTITY 1.0
+ */
+
+namespace admin\admin\controller\identify;
+
+use admin\admin\controller\MenuController;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huoIdentify\logic\IdentifyMemLogic;
+use huoIdentify\model\IdentifyMemModel;
+use huoIdentify\model\IdentifyPlatformLogModel;
+use huolib\constant\IdentifyConst;
+use huolib\status\CommonStatus;
+use huolib\tool\Page;
+use menu\controller\Menu;
+
+class IdentifyMemController extends AdminBaseController {
+    function _initialize() {
+        parent::_initialize();
+    }
+
+    /**
+     * 列表
+     * admin/identify.identify_mem/index
+     * admin/identify.identifyMem/index
+     *
+     * @return mixed
+     */
+    public function index() {
+        $_param = $this->getSearchParam();
+        $_param = $this->trimAll($_param);  //移除所有空格
+        /*获取列表数据与分页*/
+        $_logic = new IdentifyMemLogic();
+        $_datas = $_logic->getAdminList($_param, $this->page.','.$this->list_rows);
+        $_page_data = Page::paginate($_datas['count'], $_datas['list'], $this->page, $this->list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('index');
+    }
+
+    /**
+     * 删除配置
+     * adminidentity/identify_game/delete
+     * adminidentity/identifyGame/delete
+     */
+    public function delete() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+
+            return $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_model = new IdentifyMemModel();
+        $_info = $_model->getInfoById($_id);
+        $_rs = $_model->deleteData($_id);
+        if (false === $_rs) {
+            return $this->adminError(lang('FAILED'));
+        }
+        /* 删除小号关联的实名信息,否则不会重新上报实名信息给上游CP */
+        (new IdentifyPlatformLogModel())->deleteDataByMemId($_info['mem_id']);
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 搜索参数
+     * return array
+     */
+    public function getSearchParam() {
+        $_param = $this->request->param();
+        $_param['mem_id'] = $this->request->param('mem_id/d', '', 'trim');
+        $_mem_id_input = Filter::text('mem_id', $_param['mem_id'], lang('MEM_ID'));
+        $this->assign('mem_id_input', $_mem_id_input);
+        $_param['username'] = $this->request->param('username/s', '', 'trim');
+        $_username_input = Filter::text('username', $_param['username'], lang('USERNAME'));
+        $this->assign('username_input', $_username_input);
+        $_param['id_card'] = $this->request->param('id_card/s', '', 'trim');
+        $_id_card_input = Filter::text('id_card', $_param['id_card'], lang('ID_CARD'));
+        $this->assign('id_card_input', $_id_card_input);
+        $_param['real_name'] = $this->request->param('real_name/s', '', 'trim');
+        $_real_name_input = Filter::text('real_name', $_param['real_name'], lang('REAL_NAME'));
+        $this->assign('real_name_input', $_real_name_input);
+        $_param['identify_pi'] = $this->request->param('identify_pi/s', '', 'trim');
+        $_identify_pi_input = Filter::text('identify_pi', $_param['identify_pi'], lang('PI'));
+        $this->assign('identify_pi_input', $_identify_pi_input);
+        $_param['identify_from'] = $this->request->param('driver_key/s', '', 'trim');
+        $this->_driver_key($_param['identify_from']);
+        $_param = $this->trimAll($_param);
+
+        return $_param;
+    }
+
+    /**
+     *  获取驱动key
+     *
+     * @param string $driver_key
+     *
+     * @return array
+     */
+    public function _driver_key($driver_key = '') {
+        $_keys = IdentifyConst::getDriverKey();
+        $_keys['weixin'] = '腾讯云';
+        $this->assign('driver_keys', $_keys);
+        $_driver_key_select = Filter::selectCommon($_keys, 'driver_key', $driver_key);
+        $this->assign('driver_key_select', $_driver_key_select);
+
+        return $_keys;
+    }
+
+    /**
+     * 添加菜单
+     *
+     * admin/identify.identify_mem/addMenu?parent_id=[顶部游戏菜单ID]
+     * admin/identify.identifyMem/addMenu?parent_id=[顶部游戏菜单ID]
+     *
+     * @param int $parent_id
+     * @param int $list_order
+     *
+     * @return mixed
+     */
+    public function addMenu($parent_id = 0, $list_order = 0) {
+        $_controller = 'identify.identifyMem';/* 控制器名 */
+        $_name = '玩家实名认证'; /* 菜单名称 */
+        $_en_name = 'identifyMem'; /* 菜单英文名称 */
+        $_icon = 'id-card'; /* 菜单图标 */
+        $_app = 'admin'; /* 应用名 */
+        $_menu_class = new Menu();
+        $_menu_class->setApp($_app);
+        /* 删除原有菜单 */
+        $_menu_class->deleteMenu($_controller);
+        $_menu_class->deleteMenu($_controller, $_app);
+        $_parent_id = $parent_id;
+        if (empty($parent_id)) {
+            $_parent_id = $this->request->param('parent_id/d', $parent_id);
+        }
+        $_list_order = $list_order;
+        if (empty($list_order)) {
+            $_list_order = $this->request->param('list_order/d', $list_order);
+        }
+        /* 添加默认菜单 */
+        $_parent_id = $_menu_class->addDefaultMenu($_controller, $_parent_id, $_list_order, $_name, $_en_name, $_icon);
+        (new MenuController())->exportMenuLang();
+
+        return $_parent_id;
+    }
+}

+ 156 - 0
admin/admin/controller/identify/IdentifyPlatformLogController.php

@@ -0,0 +1,156 @@
+<?php
+/**
+ * IdentifyPlatformLogController.php UTF-8
+ *
+ * @date    : 2021/7/8 14:38
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK-IDENTITY 1.0
+ */
+
+namespace admin\admin\controller\identify;
+
+use admin\admin\controller\MenuController;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huoIdentify\logic\IdentifyPlatformLogLogic;
+use huoIdentify\model\IdentifyPlatformLogModel;
+use huolib\constant\CommonConst;
+use huolib\constant\IdentifyConst;
+use huolib\tool\Page;
+use huolib\status\CommonStatus;
+use menu\controller\Menu;
+
+class IdentifyPlatformLogController extends AdminBaseController {
+    function _initialize() {
+        parent::_initialize();
+    }
+
+    /**
+     * 列表
+     * admin/identify.identify_platform_log/index
+     * admin/identify.identifyPlatformLog/index
+     *
+     * @return mixed
+     */
+    public function index() {
+        $_param = $this->getSearchParam();
+        $_param = $this->trimAll($_param);  //移除所有空格
+        /*获取列表数据与分页*/
+        $_logic = new IdentifyPlatformLogLogic();
+        $_datas = $_logic->getAdminList($_param, $this->page.','.$this->list_rows);
+        $_page_data = Page::paginate($_datas['count'], $_datas['list'], $this->page, $this->list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('index');
+    }
+
+    /**
+     * 删除
+     * adminidentity/identify_game/delete
+     * adminidentity/identifyGame/delete
+     */
+    public function delete() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+
+            return $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_rs = (new IdentifyPlatformLogModel())->deleteData($_id);
+        if (false === $_rs) {
+            return $this->adminError(lang('FAILED'));
+        }
+
+        return $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 搜索参数
+     * return array
+     */
+    public function getSearchParam() {
+        $_param = $this->request->param();
+        $_param['mem_id'] = $this->request->param('mem_id/d', '', 'trim');
+        $_mem_id_input = Filter::text('mem_id', $_param['mem_id'], lang('MEM_ID'));
+        $this->assign('mem_id_input', $_mem_id_input);
+        $_param['mg_mem_id'] = $this->request->param('mg_mem_id/d', '', 'trim');
+        $_mg_mem_id_input = Filter::text('mg_mem_id', $_param['mg_mem_id'], lang('MG_MEM_ID'));
+        $this->assign('mg_mem_id_input', $_mg_mem_id_input);
+        $_param['username'] = $this->request->param('username/s', '', 'trim');
+        $_username_input = Filter::text('username', $_param['username'], lang('USERNAME'));
+        $this->assign('username_input', $_username_input);
+        $_param['id_card'] = $this->request->param('id_card/s', '', 'trim');
+        $_id_card_input = Filter::text('id_card', $_param['id_card'], lang('ID_CARD'));
+        $this->assign('id_card_input', $_id_card_input);
+        $_param['real_name'] = $this->request->param('real_name/s', '', 'trim');
+        $_real_name_input = Filter::text('real_name', $_param['real_name'], lang('REAL_NAME'));
+        $this->assign('real_name_input', $_real_name_input);
+        $_param['identify_pi'] = $this->request->param('identify_pi/s', '', 'trim');
+        $_identify_pi_input = Filter::text('identify_pi', $_param['identify_pi'], lang('PI'));
+        $this->assign('identify_pi_input', $_identify_pi_input);
+        $_param['identify_from'] = $this->request->param('driver_key/s', '', 'trim');
+        $this->_driver_key($_param['identify_from']);
+        $_param['app_id'] = $this->request->param('app_id/d', '', 'trim');
+        $this->_games($_param['app_id'], 0, CommonConst::CONST_NOT_DELETE);
+        $_param = $this->trimAll($_param);
+
+        return $_param;
+    }
+
+    /**
+     *  获取驱动key
+     *
+     * @param string $driver_key
+     *
+     * @return array
+     */
+    public function _driver_key($driver_key = '') {
+        $_keys = IdentifyConst::getDriverKey();
+        $_keys['alipay'] = lang('DRIVER_KEY_ALIPAY');
+        $this->assign('driver_keys', $_keys);
+        $_driver_key_select = Filter::selectCommon($_keys, 'driver_key', $driver_key);
+        $this->assign('driver_key_select', $_driver_key_select);
+
+        return $_keys;
+    }
+
+    /**
+     * 添加菜单
+     *
+     * admin/identify.identify_platform_log/addMenu?parent_id=[顶部游戏菜单ID]
+     * admin/identify.identifyPlatformLog/addMenu?parent_id=[顶部游戏菜单ID]
+     *
+     * @param int $parent_id
+     * @param int $list_order
+     *
+     * @return mixed
+     */
+    public function addMenu($parent_id = 0, $list_order = 0) {
+        $_controller = 'identify.identifyPlatformLog';/* 控制器名 */
+        $_name = '小号实名认证'; /* 菜单名称 */
+        $_en_name = 'identifyPlatformLog'; /* 菜单英文名称 */
+        $_icon = 'id-card'; /* 菜单图标 */
+        $_app = 'admin'; /* 应用名 */
+        $_menu_class = new Menu();
+        $_menu_class->setApp($_app);
+        /* 删除原有菜单 */
+        $_menu_class->deleteMenu($_controller);
+        $_menu_class->deleteMenu($_controller, $_app);
+        $_parent_id = $parent_id;
+        if (empty($parent_id)) {
+            $_parent_id = $this->request->param('parent_id/d', $parent_id);
+        }
+        $_list_order = $list_order;
+        if (empty($list_order)) {
+            $_list_order = $this->request->param('list_order/d', $list_order);
+        }
+        /* 添加默认菜单 */
+        $_parent_id = $_menu_class->addDefaultMenu($_controller, $_parent_id, $_list_order, $_name, $_en_name, $_icon);
+        (new MenuController())->exportMenuLang();
+
+        return $_parent_id;
+    }
+}

+ 427 - 0
admin/admin/controller/lottery/LotteryController.php

@@ -0,0 +1,427 @@
+<?php
+/**
+ * AwardsController.php  UTF-8
+ * WWW
+ *
+ * @date    : 2018/5/17 11:20
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\lottery;
+
+use admin\admin\controller\shop\GoodsController;
+use cmf\controller\ArticleBaseController;
+use huo\controller\shop\Award;
+use huo\controller\shop\GoodsCache;
+use huo\model\integral\AwardsModel;
+use huo\model\posts\PostsModel;
+use huo\model\shop\GoodsModel;
+use huolib\constant\CommonConst;
+use huolib\constant\MemItgConst;
+use huolib\constant\NewsConst;
+use think\Lang;
+use think\Request;
+
+class LotteryController extends ArticleBaseController {
+    public function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_news'.EXT);
+    }
+
+    /**
+     *  活动列表
+     */
+    public function index() {
+        $this->param['post_type'] = MemItgConst::SHOP_FLAG_LOTTERY;
+        $this->param['except_id'] = NewsConst::SHOP_DRAW_ACT_ID;
+        parent::index();
+        $this->assign('hide', false);
+
+        return $this->fetch();
+    }
+
+    /**
+     *  积分商城默认首页抽奖活动
+     */
+    public function shopIndex() {
+        $this->param['post_type'] = MemItgConst::SHOP_FLAG_LOTTERY;
+        $this->param['id'] = NewsConst::SHOP_DRAW_ACT_ID;
+        parent::index();
+        $this->assign('hide', true);
+
+        return $this->fetch('index');
+    }
+
+    /**
+     *  小程序金币抽奖
+     * admin/lottery.lottery/goldindex
+     */
+    public function goldIndex() {
+        $this->param['post_type'] = MemItgConst::SHOP_FLAG_LOTTERY;
+        $this->param['id'] = NewsConst::MP_DRAW_ACT_ID;
+        parent::index();
+        $this->assign('hide', true);
+
+        return $this->fetch('index');
+    }
+
+    /**
+     * 添加活动页面
+     */
+    public function add() {
+        $this->param['post_type'] = MemItgConst::SHOP_FLAG_LOTTERY;
+        parent::add();
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加活动提交
+     */
+    public function addPost() {
+        parent::addPost();
+        $this->adminSuccess(lang('ADD_SUCCESS'), url('admin/lottery.lottery/index'));
+    }
+
+    /**
+     * 修改活动页面
+     */
+    public function edit() {
+        $this->id = $this->request->param('id/d', 0);
+        if (NewsConst::SHOP_DRAW_ACT_ID == $this->id) {
+            $this->assign('isShopIndex', true);
+        } else {
+            $this->assign('isShopIndex', false);
+        }
+        parent::edit();
+
+        return $this->fetch();
+    }
+
+    /**
+     * 修改活动提交
+     */
+    public function editPost() {
+        parent::editPost();
+        $_return_url = url('admin/lottery.lottery/index');
+        $_data = $this->param;
+        if (NewsConst::SHOP_DRAW_ACT_ID == $_data['post']['id']) {
+            $_return_url = url('admin/lottery.lottery/shopIndex');
+        }
+        $this->adminSuccess(lang('EDIT_SUCCESS'), $_return_url);
+    }
+
+    /**
+     * 奖品列表
+     */
+    public function awardsList() {
+        $_id = $this->request->param('id/d');
+        if (NewsConst::SHOP_DRAW_ACT_ID == $_id) {
+            $this->assign('isShopIndex', true);
+        } else {
+            $this->assign('isShopIndex', false);
+        }
+        $post = (new PostsModel())->field('more')->where('id', $_id)->find();
+        $_awards = (new AwardsModel)->getAwards($_id);
+        $_map = array(
+            'act_id'    => $_id,
+            'is_delete' => CommonConst::CONST_NOT_DELETE
+        );
+        $_count_rate = (new AwardsModel)->where($_map)->sum('rate');
+        $_list_order = 1;
+        foreach ($_awards as $_k => $_v) {
+            $_awards[$_k]['goods_name'] = (new GoodsModel())->where('id', $_v['goods_id'])->value('goods_name');
+            if (empty($_count_rate)) {
+                $_awards[$_k]['rate_count'] = 0;
+            } else {
+                $_awards[$_k]['rate_count'] = round($_v['rate'] / $_count_rate, 4) * 100;
+            }
+            $_list_order++;
+        }
+        $this->assign('post', $post);
+        $this->assign('count_rate', $_count_rate);
+        $this->assign('act_id', $_id);
+        $this->assign('awards', $_awards);
+        $this->assign('list_order', $_list_order);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加奖品页面
+     */
+    public function addAward() {
+        $_act_id = $this->request->param('act_id/d');
+        $_list_order = $this->request->param('list_order/d');
+        $this->assign('list_order', $_list_order);
+        $this->assign('act_id', $_act_id);
+        if (NewsConst::SHOP_DRAW_ACT_ID == $_act_id) {
+            $this->assign('isShopIndex', true);
+        } else {
+            $this->assign('isShopIndex', false);
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * 添加奖品提交
+     */
+    public function addAwardPost() {
+        $_act_id = $this->request->param('act_id/d');
+        $_award_data = $this->request->param();
+        $_award_data['total_cnt'] = MemItgConst::AWARDS_SUM_UNLIMIT;
+        $_award_data['remain_cnt'] = MemItgConst::AWARDS_SUM_UNLIMIT;
+        $_result = (new Award())->addAward($_award_data);
+        if (false === $_result) {
+            $this->adminError(lang('add failure'));
+        }
+        $this->adminSuccess(
+            lang('add success').lang('goto').lang('add_goods'),
+            url('admin/lottery.lottery/addGoods', array('act_id' => $_act_id, 'aid' => $_result))
+        );
+    }
+
+    /**
+     * 修改奖品页面
+     */
+    public function editAward() {
+        $_act_id = $this->request->param('act_id/d');
+        $_aid = $this->request->param('aid/d');
+        $_field = 'id,award_name, rate, total_cnt, remain_cnt, limit_cnt, list_order';
+        $_map = array(
+            'id'     => $_aid,
+            'act_id' => $_act_id
+        );
+        $_award_data = (new AwardsModel())->field($_field)->where($_map)->find();
+        $this->assign('act_id', $_act_id);
+        $this->assign('data', $_award_data);
+        if (NewsConst::SHOP_DRAW_ACT_ID == $_act_id) {
+            $this->assign('isShopIndex', true);
+        } else {
+            $this->assign('isShopIndex', false);
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * 修改奖品提交
+     */
+    public function editAwardPost() {
+        $_params = $this->request->param();
+        $_params['total_cnt'] = MemItgConst::AWARDS_SUM_UNLIMIT;
+        $_params['remain_cnt'] = MemItgConst::AWARDS_SUM_UNLIMIT;
+        $_result = (new Award())->updateAward($_params['id'], $_params);
+        if (false === $_result) {
+            $this->adminError(lang('edit failure'));
+        }
+        $this->adminSuccess(
+            lang('edit success'), url('admin/lottery.lottery/awardsList', array('id' => $_params['act_id']))
+        );
+    }
+
+    /***
+     * 删除奖品
+     */
+    public function deleteAward() {
+        $_act_id = $this->request->param('act_id/d');
+        $_aid = $this->request->param('aid/d');
+        $_data = array(
+            'is_delete'   => 1,
+            'act_id'      => $_act_id,
+            'delete_time' => time()
+        );
+        $_result = (new Award())->updateAward($_aid, $_data);
+        if (false === $_result) {
+            $this->adminError(lang('delete failure'));
+        }
+        $this->adminSuccess(lang('delete success'), url('admin/lottery.lottery/awardsList', array('id' => $_act_id)));
+    }
+
+    /**
+     * 奖品排序
+     */
+    public function listOrder() {
+        $_act_id = $this->request->param('act_id/d');
+        $_ids = $this->request->post("list_orders/a");
+        $_result = (new Award())->listOrders($_act_id, $_ids);
+        if (false === $_result) {
+            $this->adminError(lang('listOrder failure'));
+        }
+        $this->adminSuccess(
+            lang('listOrder success'), url('admin/lottery.lottery/awardsList', array('id' => $_act_id))
+        );
+    }
+
+    /**
+     * 修改概率
+     */
+    public function setRate() {
+        $_params = $this->request->param();
+        $_data = array(
+            'act_id' => $_params['act_id'],
+            'rate'   => $_params['rate']
+        );
+        $_result = (new Award())->updateAward($_params['aid'], $_data);
+        if (false === $_result) {
+            $this->error(lang('setRate failure'));
+        }
+        $this->success(
+            lang('setRate success'), '', 1, array(),
+            url('admin/lottery.lottery/awardsList', ['id' => $_params['act_id']])
+        );
+    }
+
+    /**
+     * 添加为谢谢参与
+     */
+    public function addLoseAwards() {
+        $_act_id = $this->request->param('act_id/d');
+        $_list_order = $this->request->param('list_order/d');
+        $_award_data = array(
+            'act_id'     => $_act_id,
+            'award_name' => lang('lose_good'),
+            'rate'       => 100,
+            'total_cnt'  => MemItgConst::AWARDS_SUM_UNLIMIT,
+            'remain_cnt' => MemItgConst::AWARDS_SUM_UNLIMIT,
+            'list_order' => $_list_order,
+            'goods_id'   => MemItgConst::AWARD_LOSE_GOODS_ID
+        );
+        $_result = (new Award())->addAward($_award_data);
+        if (false === $_result) {
+            $this->adminError(lang('add failure'));
+        }
+        $this->adminSuccess(
+            lang('add success'), url('admin/lottery.lottery/awardsList', array('id' => $_act_id))
+        );
+    }
+
+    /**
+     * 添加商品页面
+     */
+    public function addGoods() {
+        $_act_id = $this->request->param('act_id/d');
+        $_aid = $this->request->param('aid/d');
+        $this->assign('act_id', $_act_id);
+        $this->assign('aid', $_aid);
+        $_name = (new AwardsModel())->where('id', $_aid)->value('award_name');
+        $this->assign('name', $_name);
+        if (NewsConst::SHOP_DRAW_ACT_ID == $_act_id) {
+            $this->assign('isShopIndex', true);
+        } else {
+            $this->assign('isShopIndex', false);
+        }
+
+        return (new GoodsController())->add();
+    }
+
+    /**
+     * 添加商品提交
+     */
+    public function addGoodsPost() {
+        $_data = $this->request->post();
+        $_act_id = $_data['act_id'];
+        $_aid = $_data['aid'];
+        unset($_data['act_id']);
+        $_data ['on_time'] = time();
+        $_data ['is_on_sale'] = 2;
+        $_data ['flag'] = 5;
+        if ($_data['is_real'] == MemItgConst::GOODS_IS_VIRTUAL
+            && $_data['object_type'] == MemItgConst::GOODS_IS_GIFT) {
+            if ($_data['object_id'] < 1) {
+                $this->adminError(lang('gift must'));
+            }
+            $_data['market_price'] = 0;
+            $_data['store_cnt'] = 0;
+            $_data['remain_cnt'] = 0;
+            $_data['gain_integral'] = 0;
+        }
+        if ($_data['is_real'] == MemItgConst::GOODS_IS_VIRTUAL
+            && $_data['object_type'] == MemItgConst::GOODS_IS_INTEGRAL) {
+            $_data['market_price'] = 0;
+        }
+        if ($_data['is_real'] == MemItgConst::GOODS_IS_VIRTUAL
+            && $_data['object_type'] == MemItgConst::GOODS_IS_REDPACKET) {
+            $_data['gain_integral'] = 0;
+        }
+        if ($_data['is_real'] == MemItgConst::GOODS_IS_REAL) {
+            $_data['object_type'] = 'dasf';
+        }
+        $_result_gid = (new GoodsModel())->addGoods($_data);
+        if (false === $_result_gid) {
+            $this->adminError(lang('add failure'));
+        }
+        $_data_award = array(
+            'act_id'   => $_act_id,
+            'goods_id' => $_result_gid
+        );
+        $_result = (new Award())->updateAward($_aid, $_data_award);
+        if (false === $_result) {
+            $this->adminError(lang('add to award failure'));
+        }
+        $this->adminSuccess(
+            lang('add success'), url('admin/lottery.lottery/awardsList', array('id' => $_act_id))
+        );
+    }
+
+    /**
+     * 修改商品页面
+     */
+    public function editGoods() {
+        $_act_id = $this->request->param('act_id/d');
+        $_aid = $this->request->param('aid/d');
+        $_gid = $this->request->param('gid/d');
+        Request::instance()->get(['id' => $_gid]);
+        $this->assign('act_id', $_act_id);
+        $this->assign('aid', $_aid);
+        $this->assign('gid', $_gid);
+        if (NewsConst::SHOP_DRAW_ACT_ID == $_act_id || NewsConst::MP_DRAW_ACT_ID == $_act_id) {
+            $this->assign('isShopIndex', 1);
+        } else {
+            $this->assign('isShopIndex', 0);
+        }
+
+        return (new GoodsController())->edit();
+    }
+
+    /**
+     * 修改商品提交
+     */
+    public function editGoodsPost() {
+        $_data = $this->request->post();
+        $_act_id = $_data['act_id'];
+        unset($_data['act_id']);
+        $_data ['on_time'] = strtotime($_data ['on_time']);
+        if ($_data['is_real'] == 1 && $_data['object_type'] == MemItgConst::GOODS_IS_GIFT) {
+            if ($_data['object_id'] < 1) {
+                $this->adminError(lang('gift must'));
+            }
+            $_data['market_price'] = 0;
+            $_data['store_cnt'] = MemItgConst::GOODS_SUM_UNLIMIT;
+            $_data['remain_cnt'] = MemItgConst::GOODS_SUM_UNLIMIT;
+            $_data['integral'] = 0;
+            $_data['gain_integral'] = 0;
+        }
+        if ($_data['is_real'] == 1 && $_data['object_type'] == MemItgConst::GOODS_IS_INTEGRAL) {
+            $_data['market_price'] = 0;
+            $_data['integral'] = 0;
+        }
+        if ($_data['is_real'] == MemItgConst::GOODS_IS_VIRTUAL
+            && $_data['object_type'] == MemItgConst::GOODS_IS_REDPACKET) {
+            $_data['gain_integral'] = 0;
+        }
+        if ($_data['is_real'] == 2) {
+            $_data['object_type'] = '';
+            $_data['gain_integral'] = 0;
+        }
+        $_res = (new GoodsCache())->updateGoods($_data['goods_id'], $_data);
+        if (false === $_res) {
+            $this->adminError(lang('edit failure'));
+        }
+        $this->adminSuccess(lang('edit success'), url('lottery.lottery/awardslist', array('id' => $_act_id)));
+    }
+}

+ 120 - 0
admin/admin/controller/member/BanController.php

@@ -0,0 +1,120 @@
+<?php
+/**
+ * BanController.php  UTF-8
+ * 封禁管理
+ *
+ * @date    : 2018/9/7 17:02
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\member;
+
+use ban\Ban;
+use ban\BanConst;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huolib\tool\Page;
+
+class BanController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+    }
+
+    /**
+     * IP封禁列表
+     * /admin/member.ban/ipBan
+     */
+    public function ipBan() {
+        $_param = $this->request->param();
+        /* 搜索条件 */
+        $_ip_input = Filter::text('ip', get_val($_param, 'ip'), '输入IP地址查找');
+        $this->assign('ip_input', $_ip_input);
+        $this->_time();
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 10);
+        $_param['type'] = BanConst::BAN_TYPE_IP;
+        $_data = (new Ban())->getBanList($_param, $_page.','.$_list_rows);
+        $_page_data = Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        $this->assign('type', BanConst::BAN_TYPE_IP);
+
+        return $this->fetch();
+    }
+
+    /**
+     * IP封禁列表
+     * /admin/member.ban/deviceBan
+     */
+    public function deviceBan() {
+        $_param = $this->request->param();
+        /* 搜索条件 */
+        $_device_input = Filter::text('device_id', get_val($_param, 'device_id'), '输入设备号查找');
+        $this->assign('device_input', $_device_input);
+        $this->_time();
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 10);
+        $_param['type'] = BanConst::BAN_TYPE_DEVICE;
+        $_data = (new Ban())->getBanList($_param, $_page.','.$_list_rows);
+        $_page_data = Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        $this->assign('type', BanConst::BAN_TYPE_DEVICE);
+
+        return $this->fetch();
+    }
+
+    /**
+     * IP封禁列表
+     * /admin/member.ban/udidBan
+     */
+    public function udidBan() {
+        $_param = $this->request->param();
+        /* 搜索条件 */
+        $_udid_input = Filter::text('udid', get_val($_param, 'udid'), '输入UDID地址查找');
+        $this->assign('udid_input', $_udid_input);
+        $this->_time();
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 10);
+        $_param['type'] = BanConst::BAN_TYPE_UDID;
+        $_data = (new Ban())->getBanList($_param, $_page.','.$_list_rows);
+        $_page_data = Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        $this->assign('type', BanConst::BAN_TYPE_UDID);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 新增封禁
+     * admin/member.ban/addBan
+     */
+    public function addBan() {
+        $_type = $this->request->param('type/s', '');
+        switch ($_type) {
+            case BanConst::BAN_TYPE_IP:
+                $_title = 'IP:';
+                $_input = Filter::text2('value', '', '请输入要封禁的IP地址', 'required');
+                break;
+            case BanConst::BAN_TYPE_DEVICE:
+                $_title = '设备号:';
+                $_input = Filter::text2('value', '', '请输入要封禁的设备号', 'required');
+                break;
+            case BanConst::BAN_TYPE_UDID:
+                $_title = 'UDID:';
+                $_input = Filter::text2('value', '', '请输入要封禁的UDID', 'required');
+                break;
+            default:
+                return $this->adminError('参数错误!');
+        }
+        $this->assign('input', $_input);
+        $this->assign('type', $_type);
+        $this->assign('title', $_title);
+
+        return $this->fetch();
+    }
+}

+ 55 - 0
admin/admin/controller/member/MemGameController.php

@@ -0,0 +1,55 @@
+<?php
+/**
+ * MemGameController.php  UTF-8
+ * 536_9_mph5_milaila_top
+ *
+ * @date    : 2021-07-23 16:20
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : huosdk 9.0
+ */
+
+namespace admin\admin\controller\member;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\logic\member\MemGameLogic;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\tool\Page;
+
+class MemGameController extends AdminbaseController {
+    /**
+     *  玩家游戏列表
+     **
+     * admin/member.mem_game/index
+     *
+     * @return mixed
+     */
+    public function index() {
+        $_param = $this->request->param();
+        // 搜索参数 start
+        $this->_games(
+            $this->request->get('app_id/d', 0), GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE,
+            GameConst::GAME_IS_SDK
+        );
+        $this->_time();
+        $_mg_mem_id_input = Filter::text('id', trim($this->request->param('id/s', '')), '请输入小号');
+        $this->assign('mg_mem_id_input', $_mg_mem_id_input);
+        $_username_input = Filter::text('username', trim($this->request->param('username/s', '')), '请输入玩家账号');
+        $this->assign('username_input', $_username_input);
+        // 搜索参数 end
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_param = $this->trimAll($_param);  //移除所有空格
+        $_field = [];
+        $_mem_game_logic = new MemGameLogic();
+        $_data = $_mem_game_logic->getAdminList($_param, $_page.','.$_list_rows, '-create_time', $_field);
+        $_page_data = Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch();
+    }
+}

+ 746 - 0
admin/admin/controller/member/MemberController.php

@@ -0,0 +1,746 @@
+<?php
+/**
+ * MemberController.class.php UTF-8
+ * 玩家管理
+ *
+ * @date    : 2017/11/17 11:55
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\member;
+
+use ban\BanConst;
+use ban\model\IpBanModel;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\address\Address;
+use huo\controller\agent\AgentGame;
+use huo\controller\member\Member;
+use huo\controller\member\MemCache;
+use huo\logic\agent\AgentLogic;
+use huo\logic\member\MemberLogic;
+use huo\logic\member\MemListLogic;
+use huo\logic\order\OrderLogic;
+use huo\model\game\GameModel;
+use huo\model\log\MemLoginLogModel;
+use huo\model\user\UserModel;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\IdentifyConst;
+use huolib\constant\MemConst;
+use huolib\constant\OrderConst;
+use huolib\status\CommonStatus;
+use huolib\tool\Export;
+use huolib\tool\Page;
+use think\Lang;
+
+class MemberController extends AdminbaseController {
+    protected $from_device     = ''; //空则所有玩家
+    protected $is_switch       = OrderConst::PAY_SWITCH_NO;
+    protected $agent_role_type = [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT]; //默认为一级渠道二级渠道
+
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(
+            [
+                APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_members'.EXT,
+            ]
+        );
+        parent::_initialize();
+    }
+
+    public function _getVipStatus() {
+        $_vip_status = [
+            '1' => lang('daily vip'),
+            '2' => lang('weekly vip'),
+            '3' => lang('month vip'),
+        ];
+        $this->assign('vipstatus', $_vip_status);
+    }
+
+    /**
+     * 状态组合 选择器
+     *
+     * @param int  $status
+     * @param bool $inc_select
+     *
+     * @return array|mixed
+     */
+    public function _getStatuses($status = 0, $inc_select = false) {
+        $_statuses = [
+            MemConst::STATUS_TRY    => lang('TRY'),
+            MemConst::STATUS_NORMAL => lang('NORMAL'),
+            MemConst::STATUS_FORBID => lang('FREEZE'),
+            MemConst::STATUS_RESET  => lang('RESET'),
+        ];
+        $this->assign('status', $_statuses);
+        if (true == $inc_select) {
+            $_statuses_select = Filter::selectCommon($_statuses, 'status', $status);
+            $this->assign('statuses_select', $_statuses_select);
+        }
+        if (empty($status)) {
+            return $_statuses;
+        } else {
+            return $_statuses[$status];
+        }
+    }
+
+    /**
+     * 实名状态组合 选择器
+     *
+     * @param int  $status
+     * @param bool $inc_select
+     *
+     * @return array|mixed
+     */
+    public function _RealNameStatuses($status = 0, $inc_select = false) {
+        $_statuses = [
+            MemConst::REAL_NAME_N => lang('real_name_n'),
+            MemConst::REAL_NAME_Y => lang('real_name_y')
+        ];
+        $this->assign('is_real_name', $_statuses);
+        if (true == $inc_select) {
+            $_statuses_select = Filter::selectCommon($_statuses, 'is_real_name', $status);
+            $this->assign('irn_statuses_select', $_statuses_select);
+        }
+        if (empty($status)) {
+            return $_statuses;
+        } else {
+            return $_statuses[$status];
+        }
+    }
+
+    /**
+     * 绑定手机状态组合 选择器
+     *
+     * @param int  $status
+     * @param bool $inc_select
+     *
+     * @return array|mixed
+     */
+    public function _BindMobileStatuses($status = 0, $inc_select = false) {
+        $_statuses = [
+            MemConst::BIND_MOBILE_N => lang('bind_mobile_n'),
+            MemConst::BIND_MOBILE_Y => lang('bind_mobile_y')
+        ];
+        $this->assign('is_bind_mobile', $_statuses);
+        if (true == $inc_select) {
+            $_statuses_select = Filter::selectCommon($_statuses, 'is_bind_mobile', $status);
+            $this->assign('ibm_statuses_select', $_statuses_select);
+        }
+        if (empty($status)) {
+            return $_statuses;
+        } else {
+            return $_statuses[$status];
+        }
+    }
+
+    /**
+     * 支付状态组合 选择器
+     *
+     * @param int  $status
+     * @param bool $inc_select
+     *
+     * @return array|mixed
+     */
+    public function _getPayStatus($status = 0, $inc_select = false) {
+        $_pay_statuses = [
+            OrderConst::PAY_STATUS_NOT  => lang('pending'),
+            OrderConst::PAY_STATUS_SUC  => lang('pay success'),
+            OrderConst::PAY_STATUS_FAIL => lang('pay fail')
+        ];
+        $this->assign('pay_status', $_pay_statuses);
+        if (true == $inc_select) {
+            $_statuses_select = Filter::selectCommon($_pay_statuses, 'status', $status);
+            $this->assign('pay_statuses_select', $_statuses_select);
+        }
+        if (empty($status)) {
+            return $_pay_statuses;
+        } else {
+            return $_pay_statuses[$status];
+        }
+    }
+
+    /**
+     * 玩家数据导出
+     *
+     * @throws
+     */
+    public function exportIndex() {
+        $_member_logic = new MemberLogic();
+        $_field = ['status', 'device_id', 'op_id'];
+        $_param = $this->request->param();
+        if ($this->isAgent()) {
+            $_agent_ids = (new AgentLogic())->getAgentIds($this->admin_id, true);
+            $_param['agent_id'] = ['in', $_agent_ids];
+        }
+        $_param['switch_time'] = $this->request->param('switch_time/d', 0);
+        $_param['switch_money'] = $this->request->param('switch_money/f', 0);
+        $this->_switchTime($_param['switch_time']);
+        $this->_switchMoney($_param['switch_money']);
+        $status = $this->_getStatuses(get_val($_param, 'status'), true);
+        $_param['is_switch'] = $this->is_switch;  //切量玩家不导出
+        $_param = $this->trimAll($_param);  //移除所有空格
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = $_member_logic->getList($_param, $_page, '-create_time', $_field, true);
+        $_total_cnt = $_data['count'];
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        if ($_total_cnt <= 0) {
+            $this->adminError(CommonStatus::getMsg(CommonStatus::CNT_IS_ZERO), 'admin/member.member/index');
+        }
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            if (!$this->isAgent()) {
+                $_head = [
+                    'ID',
+                    '账号',
+                    '昵称',
+                    '真实姓名',
+                    '注册IP',
+                    '注册渠道',
+                    '注册游戏',
+                    '注册来源',
+                    '绑定手机',
+                    '绑定支付宝',
+                    '注册时间',
+                    '状态'
+                ];
+            } else {
+                $_head = [
+                    'ID',
+                    '账号',
+                    '昵称',
+                    '真实姓名',
+                    '注册IP',
+                    '注册渠道',
+                    '注册游戏',
+                    '注册来源',
+                    '注册时间',
+                    '状态'
+                ];
+            }
+            $_export_datas = [];
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['id'] = $_val['id'];
+                $_export_data['username'] = $_val['username'];
+                $_export_data['nickname'] = $_val['nickname'];
+                $_export_data['real_name'] = $_val['real_name'];
+                $_export_data['reg_ip'] = $_val['reg_ip'];
+                $_export_data['agent_name'] = $_val['agent_name'];
+                $_export_data['agent_name'] = $_val['agent_name'];
+                $_export_data['gamename'] = $_val['gamename'];
+                $_export_data['from_device'] = $_val['from_device'];
+                if (!$this->isAgent()) {
+                    $_export_data['mobile'] = $_val['mobile'];
+                    $_export_data['alipay_account'] = $_val['alipay_account'];
+                }
+                $_export_data['create_time'] = date('Y-m-d H:i', $_val['create_time']);
+                $_export_data['status'] = $status[$_val['status']];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, 'mem_list', '.csv', true);
+                break;
+            } else {
+                $_file_name = 'mem_list'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = $_member_logic->getList($_param, $_page, '-create_time', $_field, true);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, 'mem_list');
+    }
+
+    /**
+     * 玩家列表
+     * admin/member.member/index
+     *
+     * @throws
+     */
+    public function index() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIndex();
+        }
+        //$_param['ig_from_device'] = $this->from_device;
+        // 获取玩家信息
+        $_member_logic = new MemberLogic();
+        $_field = ['status', 'device_id', 'op_id'];
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_game_where = [];
+        if ($this->isAgent()) {
+            $_agent_ids = (new AgentLogic())->getAgentIds($this->admin_id, true);
+            $_param['agent_id'] = ['in', $_agent_ids];
+            $_app_ids = (new AgentGame())->getGameIds($this->admin_id);
+            $_game_where = ['id' => ['in', $_app_ids]];
+            $this->_agents(
+                $_param['agent_id'], false, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true
+            );
+        } else {
+            $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+            $this->_agents(
+                $_param['agent_id'], false, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true
+            );
+            if (!empty($_param['agent_id'])) {
+                $_agent_ids = (new AgentLogic())->getAgentIds($_param['agent_id'], true);
+                $_param['agent_id'] = ['in', $_agent_ids];
+            }
+        }
+        $this->_games(
+            $_param['app_id'], 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, 0, false, true,
+            $_game_where
+        );
+        $_param['switch_time'] = $this->request->param('switch_time/d', 0);
+        $_param['switch_money'] = $this->request->param('switch_money/d', 0);
+        $this->_switchTime($_param['switch_time']);
+        $this->_switchMoney($_param['switch_money']);
+        $_param['mem_id'] = $this->request->param('mem_id/d', '');
+        $_memid_input = Filter::text('mem_id', $_param['mem_id'], '请输入玩家ID');
+        $this->assign('memid_input', $_memid_input);
+        $_param['username'] = $this->request->param('username/s', '');
+        $_username_input = Filter::text('username', $_param['username'], '请输入玩家账号');
+        $this->assign('username_input', $_username_input);
+        $_param['nickname'] = $this->request->param('nickname/s', '');
+        $_nickname_input = Filter::text('nickname', $_param['nickname'], '请输入玩家昵称');
+        $this->assign('nickname_input', $_nickname_input);
+        $_param['parent'] = $this->request->param('parent/s', '');
+        $_parent_input = Filter::text('parent', $_param['parent'], '请输入邀请人账号');
+        $this->assign('parent_input', $_parent_input);
+        $_param['mobile'] = $this->request->param('mobile/s', '');
+        $_mobile_input = Filter::text('mobile', $_param['mobile'], '请输入绑定手机号');
+        $this->assign('mobile_input', $_mobile_input);
+        $_param['device_id'] = $this->request->param('device_id/s', '');
+        $_device_input = Filter::text('device_id', $_param['device_id'], '请输入设备码');
+        $this->assign('device_input', $_device_input);
+        $_param['ip'] = $this->request->param('ip/s', '');
+        $_reg_ip_input = Filter::text('ip', $_param['ip'], '请输入IP地址');
+        $this->assign('reg_ip_input', $_reg_ip_input);
+        $_param['mem_agent_id'] = $this->request->param('mem_agent_id/d', '');
+        $_mem_agent_input = Filter::text('mem_agent_id', $_param['mem_agent_id'], '请输入玩家即渠道ID');
+        $this->assign('mem_agent_input', $_mem_agent_input);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 week')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_param['status'] = $this->request->param('status/d', 0);
+        $this->_getStatuses($_param['status'], true);
+        $_param['is_real_name'] = $this->request->param('is_real_name/d', 0);
+        $this->_RealNameStatuses($_param['is_real_name'], true);
+        $_param['is_bind_mobile'] = $this->request->param('is_bind_mobile/d', 0);
+        $this->_BindMobileStatuses($_param['is_bind_mobile'], true);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_param['is_recharged'] = $this->request->param('is_recharged/d', 0);
+        $this->_is_recharged($_param['is_recharged']);
+        $_param['is_agent'] = $this->isAgent();  //是否渠道登陆
+        if ($_param['is_agent']) {
+            $_param['is_switch'] = OrderConst::PAY_SWITCH_NO;  //切量不显示
+        }
+        $_param = $this->trimAll($_param);  //移除所有空格
+        $_data = $_member_logic->getList($_param, $_page.','.$_list_rows, '-create_time', $_field, true);
+        $_page_data = Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        if (MemConst::FROM_DEVICE_MP == $this->from_device) {
+            return $this->fetch('box/member/index');
+        }
+
+        return $this->fetch();
+    }
+
+    protected function _is_recharged($is_recharged = 0) {
+        $_is_recharged_list = [
+            CommonConst::STATUS_NO  => '否',
+            CommonConst::STATUS_YES => '是'
+        ];
+        $_is_recharged_list_select = Filter::selectCommon($_is_recharged_list, 'is_recharged', $is_recharged);
+        $this->assign('is_recharged_list', $_is_recharged_list);
+        $this->assign('is_recharged_list_select', $_is_recharged_list_select);
+
+        return $_is_recharged_list;
+    }
+
+    /**
+     * 玩家编辑
+     */
+    public function detail() {
+        $_mem_id = $this->request->param('id/d', 0);
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        if (!empty($_agent_id)) {
+            $_mem_id = (new UserModel())->getMemIdById($_agent_id);
+        }
+        if (!isset($_mem_id) || empty($_mem_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_mc_class = MemCache::ins();
+        $_mem_data = $_mc_class->getInfoById($_mem_id);
+        if (empty($_mem_data)) {
+            $this->adminError(lang('param error'));
+        }
+        $_me_data = $_mc_class->getMeInfoById($_mem_id);
+        $_data = array_merge($_mem_data, $_me_data);
+        $_data['status_text'] = $this->_getStatuses($_data['status']);
+        $_data['identify_type'] = (new IdentifyConst())->getMsg($_data['identify_type']);
+        $this->assign('data', $_data);
+        $_agent_name = (new UserModel())->getNameById($_mem_data['agent_id']);
+        $this->assign('agent_name', $_agent_name);
+        $_game_name = (new GameModel())->getNameById($_mem_data['app_id']);
+        $this->assign('game_name', $_game_name);
+        $_tag = $this->request->param('tag/s', 'role'); //默认选择角列表
+        $this->assign('tag', $_tag);
+        // 获取玩家的角色信息
+        $_role_page = 1;
+        $_role_list_rows = 50;
+        if ('role' == $_tag) {
+            $_role_page = $this->page;
+            $_role_list_rows = $this->list_rows;
+        }
+        $_mg_roles = (new MemListLogic())->getRoleList(['mem_id' => $_mem_id], $_role_page.','.$_role_list_rows);
+        $rp_conf = [
+            'path'     => url('admin/mp.member.member/detail', ['id' => $_mem_id, 'tag' => 'role']),
+            'fragment' => 'role',
+        ];
+        $_page_data = Page::paginate($_mg_roles['count'], $_mg_roles['list'], $_role_page, $_role_list_rows, $rp_conf);
+        $this->assign('role_records', $_mg_roles['list']);
+        $this->assign('role_page', $_page_data->render());
+        // 获取玩家登录记录
+        $_ml_page = 1;
+        $_ml_list_rows = 50;
+        if ('login' == $_tag) {
+            $_ml_page = $this->page;
+            $_ml_list_rows = $this->list_rows;
+        }
+        $_mem_login_obj = (new MemLoginLogModel)->memLoginInfo(['mem_id' => $_mem_id], $_ml_list_rows);
+        $_mem_login_obj = $_mem_login_obj->toArray();
+        $mlp_conf = [
+            'path'     => url('admin/mp.member.member/detail', ['d' => $_mem_id, 'tag' => 'login']),
+            'fragment' => 'login',
+        ];
+        $_page_data = Page::paginate(
+            $_mem_login_obj['total'], $_mem_login_obj['data'], $_ml_page, $_ml_list_rows, $mlp_conf
+        );
+        $this->assign('login_records', $_mem_login_obj['data']);
+        $this->assign('login_page', $_page_data->render());
+        // 获取充值记录 getMemPayInfo
+        $_pay_page = 1;
+        $_pay_list_rows = 50;
+        if ('charge' == $_tag) {
+            $_pay_page = $this->page;
+            $_pay_list_rows = $this->list_rows;
+        }
+        $_pay_conf = [
+            'path'     => url('admin/mp.member.member/detail', ['id' => $_mem_id, 'tag' => 'charge']),
+            'fragment' => 'charge',
+        ];
+        $_pay_data = (new OrderLogic())->getList([], ['mem_id' => $_mem_id], $_pay_page.','.$_pay_list_rows);
+        $_page_data = Page::paginate($_pay_data['count'], $_pay_data['list'], $_pay_page, $_pay_list_rows, $_pay_conf);
+        $this->assign('charge_records', $_pay_data['list']);
+        $this->assign('charge_page', $_page_data->render());
+        $this->_getPayStatus();
+        //$_role_records = [];
+        //$_role_page = '';
+        //$this->assign('role_records', $_role_records);
+        //$this->assign('login_records', $_login_records);
+        //$this->assign('charge_records', $_charge_records);
+        //$this->assign('role_page', $_role_page);
+        //$this->assign('login_page', $_login_page);
+        //$this->assign('charge_page', $_charge_page);
+        /* Modified by ouzhongfu BEGIN 2020/4/9 ISSUES:11805 获取玩家收货地址 */
+        $_address_list = (new Address())->getMemAddress($_mem_id);
+        if (!empty($_address_list['count'])) {
+            $_address = $_address_list['list'];
+        } else {
+            $_address = [];
+        }
+        $this->assign('address', $_address);
+        /* END 2020/4/9 ISSUES:11805 */
+        if (MemConst::FROM_DEVICE_MP == $this->from_device) {
+            /* 获取风险数据 */
+            /* 数据报表 */
+            /*$_agent_id = (new UserModel())->getIdByMemId($_data['mem_id']);
+            $_risk_analysis = new RiskAnalysis($_agent_id);
+            $_analysis_report = $_risk_analysis->getReport();*/
+            $_analysis_report = [];
+            $this->assign('analysis_report', $_analysis_report);
+
+            return $this->fetch('box/member/detail');
+        }
+
+        return $this->fetch();
+    }
+
+    /**
+     * 玩家删除与恢复
+     */
+    public function delete() {
+    }
+
+    /**
+     * 修改玩家信息
+     * admin/member.member/editPost
+     */
+    public function editPost() {
+        $_param = $this->request->param();
+        $_result = $this->validate($_param, 'Member.edit');
+        if (false === $_result) {
+            $this->adminError($_result);
+        }
+        $_mem_id = $_param['mem_id'];
+        $_data = [];
+        if (isset($_param['name']) && !empty($_param['name'])) {
+            $_name = $_param['name'];
+        } else {
+            $this->adminError(lang('edit').lang('fail'));
+        }
+        if (isset($_param['value'])) {
+            $_value = $_param['value'];
+        } else {
+            $this->adminError(lang('edit').lang('fail'));
+        }
+        /** @var string $_name */
+        switch ($_name) {
+            case 'password':
+                $_rs = (new Member())->updatePassword($_mem_id, $_value);
+                if (false == $_rs) {
+                    $this->adminError(lang('edit').lang('fail'));
+                }
+                $this->adminSuccess(lang('edit').lang('success'));
+                break;
+            case 'mobile':
+                $_data['mobile'] = $_value;
+                break;
+            case 'email':
+                $_data['email'] = $_value;
+                break;
+            case 'clearsecurity':
+                $_data['mobile'] = $_value;
+                $_data['email'] = $_value;
+                break;
+            case 'status':
+                $_data['status'] = $_value;
+                $_data['update_time'] = time();
+                break;
+            default :
+                break;
+        }
+        $_rs = MemCache::ins()->updateMem($_mem_id, $_data);
+        if (false == $_rs) {
+            $this->adminError(lang('edit').lang('fail'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'));
+    }
+
+    /**
+     * 冻结玩家账户
+     * admin/member.member/freeze
+     */
+    public function freeze() {
+        $_param = $this->request->param();
+        $_mem_id = $_param['id'];
+        $_data['status'] = MemConst::STATUS_FORBID;
+        $_rs = MemCache::ins()->updateMem($_mem_id, $_data);
+        if ($_rs) {
+            $this->adminSuccess('冻结成功');
+        } else {
+            $this->adminError('冻结失败');
+        }
+    }
+
+    /**
+     * 解冻玩家账户
+     * admin/member.member/thaw
+     */
+    public function thaw() {
+        $_param = $this->request->param();
+        $_mem_id = $_param['id'];
+        $_data['status'] = MemConst::STATUS_NORMAL;
+        $_rs = MemCache::ins()->updateMem($_mem_id, $_data);
+        if ($_rs) {
+            $this->adminSuccess('解冻成功');
+        } else {
+            $this->adminError('解冻失败');
+        }
+    }
+
+    /**
+     * ip 封禁
+     * admin/member.member/ban
+     */
+    public function ban() {
+        $_param = $this->request->param();
+        if (empty($_param['type']) || empty($_param['value'])) {
+            return $this->adminError('参数错误!');
+        }
+        $_param['value'] = trim($_param['value']);
+        $_data = [];
+        switch ($_param['type']) {
+            case BanConst::BAN_TYPE_IP:
+                $_model = (new IpBanModel());
+                $_data['ip'] = $_param['value'];
+                $_msg = 'IP';
+                break;
+            default:
+                return $this->adminError('参数错误!');
+        }
+        $_rs = $_model->getDetail($_param['value']);
+        if (!empty($_rs)) {
+            return $this->adminSuccess($_msg.'已被封禁!');
+        }
+        $_rs = $_model->addData($_data);
+        if (false == $_rs) {
+            return $this->adminError('封禁失败!');
+        }
+
+        return $this->adminSuccess('封禁成功!');
+    }
+
+    /**
+     * 设备号|udid|ip 解封
+     */
+    public function unban() {
+        $_param = $this->request->param();
+        if (empty($_param['type']) || empty($_param['value'])) {
+            return $this->adminError('参数错误!');
+        }
+        switch ($_param['type']) {
+            case BanConst::BAN_TYPE_IP:
+                $_model = (new IpBanModel());
+                $_msg = 'IP';
+                break;
+            default:
+                return $this->adminError('参数错误!');
+        }
+        $_rs = $_model->getDetail($_param['value']);
+        if (empty($_rs)) {
+            return $this->adminError($_msg.'未被封禁!');
+        }
+        $_rs = $_model->deleteData($_param['value']);
+        if (false == $_rs) {
+            return $this->adminError('解封失败!');
+        }
+
+        return $this->adminSuccess('解封成功!');
+    }
+
+    /***
+     *  玩家切量时间
+     *
+     * @param int $switch_time
+     *
+     * @return array
+     */
+    protected function _switchTime($switch_time = 0) {
+        $_switch_time = array(
+            OrderConst::PAY_SWITCH_YES => '已设置',
+            OrderConst::PAY_SWITCH_NO  => '未设置'
+        );
+        $_switch_time_select = Filter::selectCommon($_switch_time, 'switch_time', $switch_time);
+        $this->assign("switch_time", $_switch_time);
+        $this->assign("switch_time_select", $_switch_time_select);
+
+        return $_switch_time;
+    }
+
+    /**
+     * 清除切量时间
+     * admin/mp.member.member/emptySwitchTime
+     */
+    public function emptySwitchTime() {
+        $_mem_id = $this->request->param('mem_id/d', 0);
+        if (empty($_mem_id)) {
+            $this->adminError('缺少参数玩家ID');
+        }
+        $_mem_cache = MemCache::ins();
+        $_mem_data = $_mem_cache->getInfoById($_mem_id);
+        $_mem_data ['switch_time'] = 0;
+        $_rs = MemCache::ins()->updateMem($_mem_id, $_mem_data);
+        if (false == $_rs) {
+            $this->adminError('操作失败!');
+        }
+        $this->adminSuccess('操作成功!');
+    }
+
+    /**
+     * 修改切量时间
+     * admin/mp.member.member/setSwitchTime
+     */
+    public function setSwitchTime() {
+        $_mem_id = $this->request->param('mem_id/d', 0);
+        if (empty($_mem_id)) {
+            $this->adminError('缺少参数玩家ID');
+        }
+        $_mem_cache = MemCache::ins();
+        $_mem_data = $_mem_cache->getInfoById($_mem_id);
+        if ($this->request->isPost()) {
+            $_switch_time = $this->request->param('start_time', '');
+            if (empty($_switch_time)) {
+                $this->adminError('请选择切量时间!');
+            }
+            $_switch_time = strtotime($_switch_time);
+            if (empty($_switch_time) || $_switch_time < time()) {
+                $this->adminError('切量时间必须大于当前时间!');
+            }
+            $_mem_data['switch_time'] = $_switch_time;
+            $_mem_cache->updateMem($_mem_id, $_mem_data);
+            $this->adminSuccess('操作成功!');
+        } else {
+            $_switch_time_choose = Filter::timeChoose($_mem_data['switch_time']);
+            $this->assign('switch_time_choose', $_switch_time_choose);
+            $this->assign('mem_id', $_mem_id);
+
+            return $this->fetch('/box/member/set_switch_time');
+        }
+    }
+
+    /***
+     *  玩家切量金额
+     *
+     * @param int $switch_time
+     *
+     * @return array
+     */
+    protected function _switchMoney($switch_money = 0) {
+        $_switch_money = array(
+            OrderConst::PAY_SWITCH_YES => '已设置',
+            OrderConst::PAY_SWITCH_NO  => '未设置'
+        );
+        $_switch_money_select = Filter::selectCommon($_switch_money, 'switch_money', $switch_money);
+        $this->assign("switch_money", $_switch_money);
+        $this->assign("switch_money_select", $_switch_money_select);
+
+        return $_switch_money;
+    }
+
+    /**
+     * 修改切量时间
+     * admin/mp.member.member/setSwitchTime
+     */
+    public function setSwitchMoney() {
+        $_mem_id = $this->request->param('mem_id/d', 0);
+        if (empty($_mem_id)) {
+            $this->adminError('缺少参数玩家ID');
+        }
+        $_mem_cache = MemCache::ins();
+        $_mem_data = $_mem_cache->getInfoById($_mem_id);
+        if ($this->request->isPost()) {
+            $_mem_data['switch_money'] = $this->request->param('switch_money', 0);
+            $_mem_cache->updateMem($_mem_id, $_mem_data);
+            $this->adminSuccess('操作成功!');
+        } else {
+            $this->assign('switch_money', $_mem_data['switch_money']);
+            $this->assign('mem_id', $_mem_id);
+
+            return $this->fetch('/box/member/set_switch_money');
+        }
+    }
+}
+

+ 155 - 0
admin/admin/controller/member/RoleController.php

@@ -0,0 +1,155 @@
+<?php
+/**
+ * RoleController.php  UTF-8
+ * 玩家角色类
+ *
+ * @date    : 2018/5/10 10:07
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\member;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\game\GameCache;
+use huo\logic\agent\AgentLogic;
+use huo\logic\member\MemListLogic;
+use huo\model\game\GameModel;
+use huo\model\member\MemberModel;
+use huo\model\member\MemGameModel;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\OrderConst;
+use huolib\tool\Page;
+use think\Lang;
+
+class RoleController extends AdminBaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(
+            [
+                APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_members'.EXT,
+            ]
+        );
+        parent::_initialize();
+    }
+
+    /**
+     *  角色列表
+     **
+     * admin/member.role/index
+     *
+     * @return mixed
+     */
+    public function index() {
+        $_param = $this->request->param();
+        $this->_getOs(get_val($_param, 'os', ''));
+        /*搜索*/
+        $this->_games(
+            $this->request->get('app_id/d', 0), GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE,
+            GameConst::GAME_IS_SDK
+        );
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-1 week')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_mg_mem_id_input = Filter::text('mg_mem_id', trim($this->request->param('mg_mem_id/s', '')), '请输入mem_id');
+        $this->assign('mg_mem_id_input', $_mg_mem_id_input);
+        $_username_input = Filter::text('username', trim($this->request->param('username/s', '')), '请输入玩家账号');
+        $this->assign('username_input', $_username_input);
+        $_server_name_input = Filter::text('server_name', trim($this->request->param('server_name/s', '')), '请输入角色区服');
+        $this->assign('server_name_input', $_server_name_input);
+        $_role_name_input = Filter::text('role_name', trim($this->request->param('role_name/s', '')), '请输入角色名');
+        $this->assign('role_name_input', $_role_name_input);
+        /*分页*/
+        $_currentPage = $this->request->param('page/d', 1);  //当前页
+        $_listRows = $this->request->param('list_rows/d', 10);  //每页数量
+        $_page = $_currentPage.','.$_listRows;
+        $_mem_map = [];
+        $_mem_list_logic = new MemListLogic();
+        if (!empty($_param['username'])) {
+            $_mem_map['username'] = $_param['username'];
+        }
+        if ($this->isAgent()) {
+            $_agent_ids = (new AgentLogic())->getAgentIds($this->admin_id, true);
+            $_mem_map['agent_id'] = ['in', $_agent_ids];
+            $_mem_map['is_switch'] = OrderConst::PAY_SWITCH_NO;
+        } else {
+            $_mem_map['agent_id'] = $this->request->param('agent_id/d', 0);
+            $this->_agents(
+                $_mem_map['agent_id'], false, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true
+            );
+            if (empty($_mem_map['agent_id'])) {
+                unset($_mem_map['agent_id']);
+            }
+        }
+        if (!empty($_mem_map)) {
+            $_mem_ids = (new MemberModel())->getMemIds($_mem_map);
+            $_mem_ids = empty($_mem_ids) ? [-1] : $_mem_ids;
+        }
+        if (!empty($_mem_ids)) {
+            $_param['mem_id'] = ['in', $_mem_ids];
+        }
+        $_mg_roles = $_mem_list_logic->getRoleList($_param, $_page);
+        $_items = $_mg_roles['list'];
+        $_roles_obj = (new Page())->paginate($_mg_roles['count'], $_items, $_currentPage, $_listRows);
+        $_roles_obj->appends($this->request->param());
+        $_page = $_roles_obj->render();
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear', 'uri' => url('admin/member.member/index')]
+        );
+        $this->assign('filter_button_clear', $_filter_button_clear);
+        $this->assign('filter_button', $_filter_button);
+        $this->assign('page', $_page);
+        $this->assign('data', $this->request->param());
+        $this->assign('items', $_items);
+
+        return $this->fetch();
+    }
+
+    /**
+     * 获取角色操作系统
+     *
+     * @param $os
+     */
+    public function _getOs($os) {
+        $_array = [
+            'default' => '无',
+            'ios'     => 'IOS',
+            'android' => 'Android'
+        ];
+        $_os_select = Filter::selectCommon($_array, 'os', $os);
+        $this->assign('os_select', $_os_select);
+    }
+
+    public function setCurrentDefault() {
+        $_mg_mem_id = $this->request->param('mg_mem_id');
+        $_mem_game_model = new MemGameModel();
+        $_mem_game_info = $_mem_game_model->getInfoById($_mg_mem_id);
+        if (empty($_mem_game_info)) {
+            $this->adminError('参数非法');
+        }
+        $_game_info = GameCache::ins()->getInfoByAppId($_mem_game_info['app_id']);
+        if (empty($_game_info['parent_id'])) {
+            $_game_ids = [$_game_info['id']];
+        } else {
+            $_game_ids = (new GameModel())->getIdsByWhere(['parent_id' => $_game_info['id']]);
+        }
+        $_mem_game_ids = $_mem_game_model
+            ->where(['app_id' => ['in', $_game_ids], 'mem_id' => $_mem_game_info['mem_id']])
+            ->column('id');
+        foreach ($_mem_game_ids as $_mem_game_id) {
+            $_is_default = 1;
+            if ($_mem_game_id == $_mg_mem_id) {
+                $_is_default = 2;
+            }
+            $_mem_game_model->updateData(['is_default' => $_is_default], $_mem_game_id);
+        }
+        $this->adminSuccess('成功');
+    }
+}

+ 141 - 0
admin/admin/controller/member/VipController.php

@@ -0,0 +1,141 @@
+<?php
+/**
+ * VipController.php  UTF-8
+ * huosdk_mobi
+ *
+ * @date    : 2017-11-23 16:47
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wangchuang <wc@huosdk.com>
+ * @version : HUOOA 1.0
+ */
+
+namespace admin\admin\controller\member;
+
+use admin\admin\model\CountryConfModel;
+use admin\admin\model\OptionModel;
+use admin\admin\model\VipModel;
+use cmf\controller\AdminBaseController;
+use think\Lang;
+
+class VipController extends AdminbaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load([
+                       APP_PATH . 'admin' . DS . 'lang' . DS . $langSet . DS . 'admin_vip' . EXT,
+                   ]);
+        parent::_initialize();
+    }
+
+    /**
+     * 费率列表
+     */
+    public function feeRateList() {
+        $_param = $this->request->param();
+
+        $_vip_model = new VipModel();
+        $_vip_obj = $_vip_model->getVipList($_param, 10);
+
+        $_vip_obj->appends($_param);
+        $_items = $_vip_obj->items();
+        $_page = $_vip_obj->render();
+        $_items = $_vip_model->handleData($_items);
+
+        $this->assign('data', $_param);
+        $this->assign('items', $_items);
+        $this->assign('page', $_page);
+        return $this->fetch('feeRateList');
+    }
+
+    /**
+     * 添加国家费率
+     */
+    public function addFeeRate() {
+        $_c_conf_model = new CountryConfModel();
+        $_countries = $_c_conf_model->getAllCountry();
+
+        $this->assign('countries', $_countries);
+        return $this->fetch('addFeeRate');
+    }
+
+    /**
+     * 添加国家费率数据
+     */
+    public function addFeeRatePost() {
+        $_param = $this->request->param();
+
+        $_vip_model = new VipModel();
+        $_res = $_vip_model->addFeeRateData($_param);
+
+        if ($_res) {
+            $this->adminSuccess(lang('add success'), url('member.vip/feeRateList'));
+        } else {
+            $this->adminError(lang('add failure'));
+        }
+    }
+
+    /**
+     * 获取货币缩写
+     */
+    public function getCurrencyAbbr() {
+        $_param = $this->request->param();
+        $_c_conf_model = new CountryConfModel();
+
+        $_data = $_c_conf_model->getCountryAddr($_param);
+
+        $this->result($_data);
+    }
+
+    /**
+     * 编辑费率
+     */
+    public function editFeeRate() {
+        $_param = $this->request->param();
+
+        $_vip_model = new VipModel();
+        $_data = $_vip_model->getFeeRateInfo($_param);
+
+        $this->assign('data', $_data);
+        return $this->fetch('editFeeRate');
+    }
+
+    /**
+     * 编辑费率数据
+     */
+    public function editFeeRatePost() {
+        $_param = $this->request->param();
+
+        $_vip_model = new VipModel();
+        $_res = $_vip_model->editFeeRate($_param);
+
+        if ($_res) {
+            $this->adminSuccess(lang('edit success'), url('member.vip/feeRateList'));
+        } else {
+            $this->adminError(lang('edit failure'));
+        }
+    }
+
+    /**
+     * 设置试用期限、宽限期限页面
+     */
+    public function setPeriod() {
+        $_option_model = new OptionModel();
+        $_data = $_option_model->getVipPeriod();
+
+        $this->assign('data', $_data);
+
+        return $this->fetch('setPeriod');
+    }
+
+
+    /**
+     * 设置vip试用期限、宽限期限
+     */
+    public function setPeriodPost() {
+        $_param = $this->request->param();
+        $_option_model = new OptionModel();
+        $_option_model->setPeriod($_param);
+        $this->adminSuccess(lang('edit success'));
+    }
+
+}

+ 302 - 0
admin/admin/controller/mp/agent/AgBaseController.php

@@ -0,0 +1,302 @@
+<?php
+/**
+ * AgBaseController.php  UTF-8
+ * 渠道游戏基类
+ *
+ * @date    : 2020/3/7 11:52
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOOA 1.0
+ */
+
+namespace admin\admin\controller\mp\agent;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\agent\Agent;
+use huo\controller\agent\AgentCache;
+use huo\controller\agent\AgentGame;
+use huo\controller\game\GameCache;
+use huo\controller\rate\RateCache;
+use huo\logic\agent\AgentGameLogic;
+use huo\model\user\RoleModel;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\status\CommonStatus;
+use huolib\status\RateStatus;
+use huomp\model\agent\AgentAdsCfgModel;
+
+class AgBaseController extends AdminBaseController {
+    protected $id       = 0;
+    protected $classify = 0;
+    protected $role_id  = 0;
+
+    function _initialize() {
+        parent::_initialize();
+        $this->role_id = [AgentConst::AGENT_ROLE_MP_AGENT, AgentConst::AGENT_ROLE_MP_GROUP];
+    }
+
+    /**
+     * 列表
+     */
+    public function index() {
+        $_param = $this->request->param();
+        $_game_where = [];
+        if ($this->isAgent()) {
+            $_param['agent_id'] = $this->admin_id;
+            $_app_ids = (new AgentGame())->getGameIds($this->admin_id);
+            $_game_where = ['id' => ['in', $_app_ids]];
+        } else {
+            $_agent_id = $this->request->param('agent_id');
+            $this->_agents($_agent_id, true, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true);
+            $_param['parent_id'] = $this->request->param('parent_id/d', '');
+            $this->_agents($_param['parent_id'], false, [AgentConst::ROLE_TYPE_GROUP], true);
+            $_agent_input = Filter::text('agent_name', get_val($_param, 'agent_name', ''), '请输入渠道账号');
+            $this->assign('agent_input', $_agent_input);
+            $_roles = (new RoleModel())->getIdNames(['id' => ['in', $this->role_id]], true);
+            $this->assign('roles', $_roles);
+            $_role_array = [];
+            if (!empty($_roles)) {
+                foreach ($_roles as $_k => $_v) {
+                    $_role_array[$_k] = $_v['name'];
+                }
+            }
+            $_role_select = Filter::selectCommon($_role_array, 'role_id', get_val($_param, 'role_id', 0));
+            $this->assign('roles_select', $_role_select);
+            if (empty($_param['role_id'])) {
+                $_param['role_id'] = $this->role_id;
+            }
+        }
+        /*过滤 只显示小游戏*/
+        $_classify = $this->classify;
+        $this->_games(
+            get_val($_param, 'app_id', 0), 0, CommonConst::CONST_NOT_DELETE,
+            GameConst::GAME_IS_SDK, $_classify, false, true, $_game_where
+        );
+        $this->_time();
+        $_param['agent_benefit_type'] = get_val($_param, 'agent_benefit_type', 0);
+        $this->_agentBenefitType($_param['agent_benefit_type']);
+        $_param['status'] = get_val($_param, 'status', 0);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 50);
+        $_ag_logic = new AgentGameLogic();
+        $_param['classify'] = $this->classify;
+        $_data = $_ag_logic->getAgentGames($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return true;
+    }
+
+    /**
+     * 添加
+     * admin/mp.agent.agBase/add
+     */
+    public function add() {
+        $this->_games(
+            0, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK,
+            $this->classify
+        );
+        $this->_agents(0);
+
+        return true;
+    }
+
+    /**
+     * 添加操作函数
+     * admin/mp.agent.agBase/addPost
+     *
+     * @return void
+     */
+    public function addPost() {
+        if ($this->request->isPost()) {
+            $_app_id = $this->request->param('app_id/d', 0);
+            $_agent_id = $this->request->param('agent_id/d', 0);
+            $_set_qr_code = false;
+            if (GameConst::GAME_MP == $this->classify) {
+                $_set_qr_code = true;
+            }
+            $_rs = (new AgentGame())->addGame($_agent_id, $_app_id, $_set_qr_code);
+            if (false == $_rs) {
+                $this->adminError('添加失败');
+            }
+            $this->adminSuccess('添加成功');
+        } else {
+            $_code = CommonStatus::INVALID_PARAMS;
+            $this->adminError(CommonStatus::getMsg($_code));
+        }
+    }
+
+    /**
+     * 推广游戏列表
+     * admin/mp.agent.agBase/edit
+     */
+    public function edit() {
+        $_ag_id = $this->request->param('ag_id/d', 0);
+        if (empty($_ag_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+            $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_ac_class = new AgentCache();
+        $_ag_data = $_ac_class->getAgInfoByAgId($_ag_id);
+        $_app_id = $_ac_class->getAppIdByAgId($_ag_id);
+        $_agent_id = $_ac_class->getAgentIdByAgId($_ag_id);
+        $_rc_class = RateCache::ins();
+        $_game_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $_rate_data = $_rc_class->getInfoByAppIdAgentId($_app_id, $_agent_id);
+        $_gr_data = $_rc_class->getInfoByAppId($_app_id);
+        $_agent_data = $_ac_class->getInfoByAgentId($_agent_id);
+        $_role_type = (new Agent())->getRoleType($_agent_id);
+        $this->assign('ag_data', $_ag_data);
+        $this->assign('gr_data', $_gr_data);
+        $this->assign('agent', $_agent_data);
+        $this->assign('ag_id', $_ag_id);
+        $this->assign('game', $_game_data);
+        $this->assign('data', $_rate_data);
+        $this->assign('role_type', $_role_type);
+
+        return true;
+    }
+
+    /**
+     * 游戏折扣编辑
+     * admin/mp.agent.agBase/editPost
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $_ag_id = $_param['ag_id'];
+            $_data = [];
+            $_ac_class = AgentCache::ins();
+            $_ag_data = $_ac_class->getAgInfoByAgId($_ag_id);
+            $_ag_data['status'] = get_val($_param, 'status', 0);
+            $_ac_class->updateAg($_ag_id, $_ag_data);
+            $_data['agent_rebate'] = get_val($_param, 'agent_rebate', 0);
+            $_data['sub_agent_rebate'] = get_val($_param, 'sub_agent_rebate', 0);
+            $_data['agent_reward'] = get_val($_param, 'agent_reward', 0);
+            $_data['sub_agent_reward'] = get_val($_param, 'sub_agent_reward', 0);
+            $_gr_class = new AgentGame();
+            $_rs = $_gr_class->setGameRate($_ag_id, $_data);
+            if (RateStatus::NO_ERROR != $_rs['code']) {
+                $this->adminError($_rs['msg']);
+            }
+            $this->adminSuccess($_rs['msg']);
+        } else {
+            $this->adminError('请求类型错误');
+        }
+    }
+
+    /**
+     * 添加渠道推广码
+     * admin/mp.agent.agBase/addQrcode
+     */
+    public function addQrcode() {
+        $_ag_id = $this->request->param('ag_id/d', 0);
+        if (empty($_ag_id)) {
+            $this->adminError('缺少参数Ag_id');
+        }
+        $_rs = (new \huomp\controller\agent\AgentGame())->setQrUrl($_ag_id);
+        if (CommonStatus::NO_ERROR != $_rs) {
+            $this->adminError('添加失败!');
+        }
+        $this->adminSuccess('添加成功!');
+    }
+
+    /***
+     * 获取渠道二维码推广配置
+     * admin/agent.AgentGame/editAdsCfg
+     */
+    public function editAdsCfg() {
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        if (empty($_agent_id)) {
+            $this->adminError('参数错误');
+        }
+        $_cfg = (new AgentAdsCfgModel())->getInfoByAgentId($_agent_id);
+        $this->assign($_cfg);
+        $this->assign('agent_id', $_agent_id);
+
+        return $this->fetch('box/agent/ads_cfg');
+    }
+
+    /**
+     * 渠道二维码推广配置提交
+     * admin/agent.AgentGame/editAdsCfgPost
+     */
+    public function editAdsCfgPost() {
+        $_param = $this->request->param();
+        $_param = $this->trimAll($_param);
+        if (empty($_param['agent_id'])) {
+            $this->adminError('参数错误');
+        }
+        $_agent_ads = new AgentAdsCfgModel();
+        $_cfg = $_agent_ads->getInfoByAgentId($_param['agent_id']);
+        if (empty($_cfg)) {
+            $_rs = $_agent_ads->addData($_param);
+        } else {
+            $_rs = $_agent_ads->updateData($_param, $_cfg['id']);
+        }
+        if (true == $_rs) {
+            $this->adminSuccess('修改成功');
+        } else {
+            $this->adminError('修改失败');
+        }
+    }
+
+    /**
+     * 推广状态选择器
+     *
+     * @param $promote_switch
+     */
+    public function _promotes($promote_switch = 0) {
+        $_promotes = GameConst::getPromotes();
+        $this->assign('promotes', $_promotes);
+        $this->assign('promotes_select', Filter::selectCommon($_promotes, 'promote_switch', $promote_switch));
+        $_promote_switch_radio = Filter::radioCommon($_promotes, 'promote_switch', $promote_switch);
+        $this->assign('promote_switch_radio', $_promote_switch_radio);
+    }
+
+    /**
+     * 玩家优惠选择器
+     *
+     * @param int  $benefit_type
+     * @param bool $read_only 是否只读
+     */
+    public function _benefitType($benefit_type = 0, $read_only = false) {
+        $_benefit_type_arr = GameConst::getRateMsg(0, true);
+        $_disable = '';
+        if (true == $read_only) {
+            $_disable = 'disabled';
+        }
+        $this->assign('benefit_type_arr', $_benefit_type_arr);
+        $this->assign(
+            'benefit_type_select',
+            Filter::selectCommon($_benefit_type_arr, 'benefit_type', $benefit_type, '', $_disable)
+        );
+        $_benefit_type_radio = Filter::radioCommon($_benefit_type_arr, 'benefit_type', $benefit_type);
+        $this->assign('benefit_type_radio', $_benefit_type_radio);
+    }
+
+    /**
+     * 渠道推广模式选择器
+     *
+     * @param int  $benefit_type
+     * @param bool $read_only 是否只读
+     */
+    public function _agentBenefitType($benefit_type = 0, $read_only = false) {
+        $_agent_benefit_type_arr = GameConst::getAgentBenefitTypeMsg(0, true);
+        $_disable = '';
+        if (true == $read_only) {
+            $_disable = 'disabled';
+        }
+        $this->assign('agent_benefit_type_arr', $_agent_benefit_type_arr);
+        $this->assign(
+            'agent_benefit_type_select',
+            Filter::selectCommon($_agent_benefit_type_arr, 'agent_benefit_type', $benefit_type, '', $_disable)
+        );
+        $_agent_benefit_type_radio = Filter::radioCommon($_agent_benefit_type_arr, 'agent_benefit_type', $benefit_type);
+        $this->assign('agent_benefit_type_radio', $_agent_benefit_type_radio);
+    }
+}

+ 119 - 0
admin/admin/controller/mp/agent/AgentController.php

@@ -0,0 +1,119 @@
+<?php
+/**
+ * AgentController.php  UTF-8
+ * 推广渠道
+ *
+ * @date    : 2018/8/14 17:26
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\mp\agent;
+
+use admin\admin\controller\agent\AgentController as BaseAgent;
+use cmf\view\Filter;
+use huo\controller\agent\Agent;
+use huo\logic\agent\AgentListLogic;
+use huo\model\user\RoleModel;
+use huolib\constant\AgentConst;
+use huolib\constant\MemConst;
+use huolib\status\CommonStatus;
+
+class AgentController extends BaseAgent {
+    function _initialize() {
+        parent::_initialize();
+        $this->from_device = MemConst::FROM_DEVICE_MP;
+        $this->agent_role_type = [AgentConst::ROLE_TYPE_AGENT, AgentConst::AGENT_ROLE_MP_AGENT];
+        $this->role_id = [AgentConst::AGENT_ROLE_MP_AGENT, AgentConst::AGENT_ROLE_MP_GROUP];
+    }
+
+    /**
+     * 渠道列表
+     * admin/mp.agent.agent/index
+     *
+     * @return mixed
+     */
+    public function index() {
+        /* 搜索列表 */
+        $_param = $this->request->param();
+        $_user_login = Filter::text('user_login', get_val($_param, 'user_login', ''), '请输入渠道账号');
+        $this->assign('user_login', $_user_login);
+        $_agent_name = Filter::text('agent_name', get_val($_param, 'agent_name', ''), '请输入渠道昵称');
+        $this->assign('agent_name', $_agent_name);
+        $_roles = (new RoleModel())->getIdNames(['id' => ['in', $this->role_id]], true);
+        $this->assign('roles', $_roles);
+        $_role_array = [];
+        if (!empty($_roles)) {
+            foreach ($_roles as $_k => $_v) {
+                $_role_array[$_k] = $_v['name'];
+            }
+        }
+        $_role_select = Filter::selectCommon($_role_array, 'role_id', get_val($_param, 'role_id', 0));
+        $this->assign('role_select', $_role_select);
+        if (empty($_param['role_id'])) {
+            $_param['role_id'] = ['in', $this->role_id];
+        }
+        if ($this->isAgent()) {
+            $_param['parent_id'] = ['in', [$this->admin_id]];
+        }
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 50);
+        $_data = (new AgentListLogic())->getAgentList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        $this->assign('is_agent', $this->isAgent());
+
+        return $this->fetch('box/agent/index');
+    }
+
+    /**
+     * 添加渠道
+     * admin/agent.agent/add
+     *
+     * @return mixed
+     */
+    public function add() {
+        $_array = (new Agent())->getCpsIdName(AgentConst::AGENT_ROLE_MP_GROUP);
+        $_agent_select = Filter::selectCommon($_array, 'p_id', 0);
+        $this->assign('agent_select', $_agent_select);
+        $_array = [
+            AgentConst::AGENT_ROLE_MP_GROUP => '一级渠道',
+            AgentConst::AGENT_ROLE_MP_AGENT => '二级渠道',
+        ];
+        $_level_select = Filter::selectCommon($_array, 'role_id', 0);
+        $this->assign('level_select', $_level_select);
+        $this->assign('is_agent', $this->isAgent());
+
+        return $this->fetch('box/agent/add');
+    }
+
+    /**
+     * 添加渠道操作
+     * admin/mp.agent.agent/addPost
+     *
+     */
+    public function addPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $_user_login = $_param['user_login'];
+            $_user_nicename = $_param['user_nicename'];
+            $_user_pass = $_param['user_pass'];
+            $_role_id = $this->request->param('role_id/d', AgentConst::AGENT_ROLE_MP_AGENT);
+            $_parent_id = $this->request->param('p_id/d', $this->admin_id);
+            if ($_role_id == AgentConst::AGENT_ROLE_MP_GROUP) {
+                $_parent_id = 1;
+            }
+            $_rs = (new Agent())->addAgent($_user_login, $_user_nicename, $_user_pass, $_parent_id, $_role_id);
+            if (CommonStatus::NO_ERROR == $_rs['code']) {
+                $this->adminSuccess(lang('add').lang('success'));
+            } else {
+                $this->adminError($_rs['msg']);
+            }
+        } else {
+            return $this->adminError(lang('param error'));
+        }
+    }
+}

+ 102 - 0
admin/admin/controller/mp/agent/GameController.php

@@ -0,0 +1,102 @@
+<?php
+/**
+ * AgentController.php  UTF-8
+ * 推广游戏管理
+ *
+ * @date    : 2018/8/14 17:26
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\mp\agent;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\game\GameCache;
+use huo\controller\rate\GameRate;
+use huo\controller\rate\RateCache;
+use huo\logic\game\GamRateLogic;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\status\CommonStatus;
+use huolib\status\RateStatus;
+
+class GameController extends AdminBaseController {
+    protected $role_id;
+
+    function _initialize() {
+        parent::_initialize();
+        $this->role_id = [AgentConst::AGENT_ROLE_MP_AGENT, AgentConst::AGENT_ROLE_MP_GROUP];
+    }
+
+    /**
+     * 推广游戏
+     * admin/mp.agent.game/index
+     *
+     * @return mixed
+     */
+    public function index() {
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        /*过滤 只显示小游戏和H5游戏*/
+        $_classify = [GameConst::GAME_MP, GameConst::GAME_H5];
+        $this->_games(
+            $_param['app_id'], GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK,
+            $_classify
+        );
+        $_game_model = new GamRateLogic();
+        $_param['classify'] = ['in', $_classify];
+        $_obj = $_game_model->getAgentGameList($_param);
+        $this->assign('page', $_obj->render());
+        $this->assign('items', $_obj);
+
+        return $this->fetch('box/agent/game');
+    }
+
+    /**
+     * 编辑推广游戏
+     * admin/mp.agent.game/edit
+     */
+    public function edit() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $_code = CommonStatus::INVALID_PARAMS;
+            $this->adminError(CommonStatus::getMsg($_code));
+        }
+        $_game_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $_rate_data = RateCache::ins()->getInfoByAppId($_app_id);
+        $this->assign('app_id', $_app_id);
+        $this->assign('game', $_game_data);
+        $this->assign('data', $_rate_data);
+        $this->assign('benefit_type', GameConst::RATE_BENEFIT_REWARD);
+
+        return $this->fetch('box/agent/gameedit');
+    }
+
+    /**
+     * 游戏折扣编辑
+     * admin/mp.agent.game/editPost
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $_app_id = $_param['app_id'];
+            $_promote_switch = get_val($_param, 'promote_switch', 2);
+            $_data = [];
+            $_data['agent_benefit_type'] = get_val($_param, 'agent_benefit_type', 0);
+            $_data['agent_rebate'] = get_val($_param, 'agent_rebate', 0);
+            $_data['sub_agent_rebate'] = get_val($_param, 'sub_agent_rebate', 0);
+            $_data['agent_reward'] = get_val($_param, 'agent_reward', 0);
+            $_data['sub_agent_reward'] = get_val($_param, 'sub_agent_reward', 0);
+            $_gr_class = new GameRate();
+            $_rs = $_gr_class->setGameRate($_app_id, $_promote_switch, $_data);
+            if (RateStatus::NO_ERROR != $_rs['code']) {
+                $this->adminError($_rs['msg']);
+            }
+            $this->adminSuccess($_rs['msg']);
+        } else {
+            $this->adminError('请求类型错误');
+        }
+    }
+}

+ 70 - 0
admin/admin/controller/mp/agent/H5AgentGameController.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * h5AgentGameController.php  UTF-8
+ * H5游戏推广管理
+ *
+ * @date    : 2020/3/7 13:46
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOOA 1.0
+ */
+
+namespace admin\admin\controller\mp\agent;
+
+use huolib\constant\AgentConst;
+use huolib\constant\GameConst;
+
+class H5AgentGameController extends AgBaseController {
+    function _initialize() {
+        parent::_initialize();
+        $this->role_id = [AgentConst::AGENT_ROLE_MP_AGENT, AgentConst::AGENT_ROLE_MP_GROUP];
+        $this->classify = GameConst::GAME_H5;
+    }
+
+    /**
+     * 游戏列表
+     * admin/mp.agent.h5AgentGame/index
+     */
+    public function index() {
+        parent::index();
+
+        return $this->fetch('box/agent/h5_agent_game');
+    }
+
+    /**
+     * 添加渠道游戏
+     * admin/mp.agent.h5AgentGame/add
+     */
+    public function add() {
+        parent::add();
+
+        return $this->fetch('box/agent/agent_game_add');
+    }
+
+    /**
+     * 添加渠道游戏提交
+     * admin/mp.agent.h5AgentGame/addPost
+     */
+    public function addPost() {
+        parent::addPost();
+    }
+
+    /**
+     * 编辑渠道游戏
+     * admin/mp.agent.h5AgentGame/edit
+     */
+    public function edit() {
+        parent::edit();
+
+        return $this->fetch('box/agent/agent_game_edit');
+    }
+
+    /**
+     * 编辑渠道游戏提交
+     * admin/mp.agent.h5AgentGame/editPost
+     */
+    public function editPost() {
+        parent::editPost();
+    }
+}

+ 70 - 0
admin/admin/controller/mp/agent/MpAgentGameController.php

@@ -0,0 +1,70 @@
+<?php
+/**
+ * MpAgentGameController.php  UTF-8
+ * 小游戏推广管理
+ *
+ * @date    : 2020/3/7 13:46
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : wuyonghong <wyh@huosdk.com>
+ * @version : HUOOA 1.0
+ */
+
+namespace admin\admin\controller\mp\agent;
+
+use huolib\constant\AgentConst;
+use huolib\constant\GameConst;
+
+class MpAgentGameController extends AgBaseController {
+    function _initialize() {
+        parent::_initialize();
+        $this->role_id = [AgentConst::AGENT_ROLE_MP_AGENT, AgentConst::AGENT_ROLE_MP_GROUP];
+        $this->classify = GameConst::GAME_MP;
+    }
+
+    /**
+     * 游戏列表
+     * admin/mp.agent.mpAgentGame/index
+     */
+    public function index() {
+        parent::index();
+
+        return $this->fetch('box/agent/mp_agent_game');
+    }
+
+    /**
+     * 添加渠道游戏
+     * admin/mp.agent.mpAgentGame/add
+     */
+    public function add() {
+        parent::add();
+
+        return $this->fetch('box/agent/agent_game_add');
+    }
+
+    /**
+     * 添加渠道游戏提交
+     * admin/mp.agent.mpAgentGame/addPost
+     */
+    public function addPost() {
+        parent::addPost();
+    }
+
+    /**
+     * 编辑渠道游戏
+     * admin/mp.agent.mpAgentGame/edit
+     */
+    public function edit() {
+        parent::edit();
+
+        return $this->fetch('box/agent/agent_game_edit');
+    }
+
+    /**
+     * 编辑渠道游戏提交
+     * admin/mp.agent.mpAgentGame/editPost
+     */
+    public function editPost() {
+        parent::editPost();
+    }
+}

+ 861 - 0
admin/admin/controller/mp/data/DataController.php

@@ -0,0 +1,861 @@
+<?php
+/**
+ * DataController.php  UTF-8
+ * huosdk_mini_program
+ *
+ * @date    : 2018/8/16 17:38
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\mp\data;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\agent\AgentGame;
+use huo\logic\agent\AgentLogic;
+use huo\logic\data\DataLogic;
+use huo\logic\data\DayDataLogic;
+use huo\logic\data\RemainDataLogic;
+use huo\logic\data\SwitchDayDataLogic;
+use huo\logic\data\SwitchRemainDataLogic;
+use huo\model\agent\AgentOrderModel;
+use huo\model\data\DayAgentModel;
+use huo\model\data\DayAgentSwitchModel;
+use huo\model\data\DayGameSwitchModel;
+use huo\model\data\DayModel;
+use huo\model\data\DaySwitchModel;
+use huo\model\data\DgaSwitchModel;
+use huo\model\game\GameModel;
+use huo\model\member\MemberModel;
+use huo\model\user\AgentExtModel;
+use huo\model\user\UserModel;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use huolib\constant\DataConst;
+use huolib\constant\GameConst;
+use huolib\constant\MemConst;
+use huolib\constant\OrderConst;
+use huolib\tool\Export;
+use huolib\tool\Page;
+use huomp\logic\agent\AgentExtLogic;
+use huomp\logic\game\GameMiniListLogic;
+use think\Lang;
+use think\Request;
+
+class DataController extends AdminbaseController {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'statics'.EXT);
+    }
+
+    /**
+     * admin/mp.data.data/index
+     * 数据列表 数据列表 数据总览
+     */
+    public function index() {
+        $_mem_model = new MemberModel();
+        $_order_model = new AgentOrderModel();
+        $_user_model = new UserModel();
+        $_ae_model = new AgentExtModel();
+        $_game_model = new GameModel();
+        $_map = ['status' => MemConst::STATUS_NORMAL];
+        if ($this->isAgent()) {
+            $_map['agent_id'] = $this->map['agent_id'];
+            $_map['is_switch'] = OrderConst::PAY_SWITCH_NO;
+        }
+        $_user_total = format_ten_thousand($_mem_model->total($_map));
+        /*自然注册玩家*/
+        $_map['agent_id'] = 0;
+        $_total_register = format_ten_thousand($_mem_model->nonAgentUserCount($_map));
+        $_today_register = format_ten_thousand($_mem_model->todayCount($_map));
+        $_week_register = format_ten_thousand($_mem_model->thisWeekCount($_map));
+        $_month_register = format_ten_thousand($_mem_model->thisMonthCount($_map));
+        /*邀请注册玩家*/
+        if ($this->isAgent()) {
+            $_map['agent_id'] = $this->map['agent_id'];
+            $_map['is_switch'] = OrderConst::PAY_SWITCH_NO;
+        } else {
+            $_map['agent_id'] = ['neq', 0];
+        }
+        $_total_agentuser = format_ten_thousand($_mem_model->agentUserCount($_map));
+        $_today_agentuser = format_ten_thousand($_mem_model->todayCount($_map));
+        $_week_agentuser = format_ten_thousand($_mem_model->thisWeekCount($_map));
+        $_month_agentuser = format_ten_thousand($_mem_model->thisMonthCount($_map));
+        /* 活跃玩家 */
+        UNSET($_map['agent_id']);
+        if ($this->isAgent()) {
+            $_map['agent_id'] = $this->map['agent_id'];
+            $_map['is_switch'] = OrderConst::PAY_SWITCH_NO;
+        }
+        $_active_today = format_ten_thousand($_mem_model->todayActive($_map));
+        $_active_this_week = format_ten_thousand($_mem_model->thisWeekActive($_map));
+        $_active_this_month = format_ten_thousand($_mem_model->thisMonthActive($_map));
+        /* 渠道数 */
+        $_user_map['role_id'] = ['in', AgentConst::AGENT_ROLE_MP_AGENT];
+        $_online_agent = format_ten_thousand($_user_model->onlineCount($_user_map));
+        /* 渠道总流水 */
+        $_agent_sum_money = format_ten_thousand($_ae_model->sumMpMoney($_user_map));
+        /* 上线游戏 */
+        $_g_map = ['classify' => GameConst::GAME_MP];
+        $_online_game = format_ten_thousand($_game_model->onlineCount($_g_map));
+        /* 流水 */
+        $_o_map = [];
+        $_money_today = format_ten_thousand($_order_model->todayMoney($_o_map));
+        $_money_this_week = format_ten_thousand($_order_model->thisWeekMoney($_o_map));
+        $_money_this_month = format_ten_thousand($_order_model->thisMonthMoney($_o_map));
+        $_assign = [
+            'user_total'        => $_user_total,
+            'today_register'    => $_today_register,
+            'today_agentuser'   => $_today_agentuser,
+            'week_register'     => $_week_register,
+            'week_agentuser'    => $_week_agentuser,
+            'month_register'    => $_month_register,
+            'month_agentuser'   => $_month_agentuser,
+            'total_register'    => $_total_register,
+            'total_agentuser'   => $_total_agentuser,
+            'active_today'      => $_active_today,
+            'active_this_week'  => $_active_this_week,
+            'active_this_month' => $_active_this_month,
+            'online_agent'      => $_online_agent,
+            'online_game'       => $_online_game,
+            'agent_sum_money'   => $_agent_sum_money,
+            'money_today'       => $_money_today,
+            'money_this_week'   => $_money_this_week,
+            'money_this_month'  => $_money_this_month
+        ];
+        $this->assign('data', $_assign);
+
+        return $this->fetch('box/data/index');
+    }
+
+    /**
+     * 获取图标数据
+     *
+     * @return \think\response\Json
+     * @throws \Exception
+     */
+    public function chartData() {
+        $_result = [];
+        $_model = new DayModel();
+        $_start_date = date('Y-m-01');
+        $_end_date = date('Y-m-d');
+        if ($this->isAgent()) {
+            $_model = new DayAgentModel();
+            $_model->map = ['agent_id' => $this->map['agent_id']];
+        }
+        switch ($this->request->request('type')) {
+            case 'active':
+                $_result['title'] = '活跃';
+                $_data = $_model->getByDate('user_cnt', $_start_date, $_end_date);
+                break;
+            case 'register':
+                $_result['title'] = '新增';
+                $_data = $_model->getByDate('reg_cnt', $_start_date, $_end_date);
+                break;
+            case 'money':
+                $_result['title'] = '单日流水';
+                $_data = $_model->getByDate('sum_money', $_start_date, $_end_date);
+                break;
+            default:
+                throw new \Exception('参数错误');
+        }
+        $_result['xData'] = array_keys($_data);
+        $_result['realxValue'] = array_values($_data);
+
+        return json($_result);
+    }
+
+    /**
+     * 每个自然日数据导出
+     */
+    public function exportIndex() {
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_param['agent_id'] = $this->request->param('agent_id/d', $this->map['agent_id']);
+        /* 是否显示切量 */
+        $_switch_show = $this->request->param('switch_show/d', DataConst::SWITCH_HIDDEN);
+        if (!empty($this->map['agent_id'])) {
+            $_param['agent_id'] = $this->map['agent_id'];
+        }
+        $_time_range = $this->request->param('time_range');
+        switch ($_time_range) {
+            case 'seven_days':
+                $_start_time = date('Y-m-d', strtotime('-6 days'));
+                $_end_time = date('Y-m-d', strtotime('-1 days'));
+                break;
+            case 'this_month':
+                $_start_time = date('Y-m-01', strtotime(date("Y-m-d")));
+                $_end_time = date('Y-m-d', strtotime('-1 days'));
+                break;
+            case 'thirty_days':
+            default:
+                $_start_time = $this->request->param('start_time/s', date('Y-m-d', strtotime('-1 month')));
+                $_end_time = $this->request->param('end_time/s', date('Y-m-d', strtotime('-1 days')));
+                break;
+        }
+        list($_param['start_time'], $_param['end_time']) = $this->_time($_start_time, $_end_time);
+        $_agents = $this->_agentsByRoleId(
+            $_param['agent_id'], [AgentConst::AGENT_ROLE_MP_MEMBER, AgentConst::AGENT_ROLE_MP_AGENT]
+        );
+        $_games = $this->_games($_param['app_id'], 0, 0, 0, GameConst::GAME_MP);
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        if (DataConst::SWITCH_SHOW == $_switch_show) {
+            $_data = (new SwitchDayDataLogic())->getList($_param, $_page);
+            $_today_data = (new SwitchDayDataLogic())->getTodayData($_param);
+        } else {
+            $_data = (new DayDataLogic())->getList($_param, $_page);
+            $_today_data = (new DayDataLogic())->getTodayData($_param);
+        }
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            $_head = ['日期'];
+            if (!empty($_param['app_id'])) {
+                array_push($_head, '游戏');
+            }
+            if (!empty($_param['agent_id'])) {
+                array_push($_head, '渠道');
+            }
+            $_head2 = [
+                '访问人数',
+                '新增用户',
+                '活跃用户',
+                '访问转化率',
+                '独立ip数',
+                '成功订单数',
+                '新增付费人数',
+                '新增付费金额',
+                '总付费人数',
+                '总付费金额',
+                '新增付费率',
+                '活跃付费率',
+                '访问付费率',
+                '新增注册ARPU',
+                '活跃ARPU',
+                '付费ARPU'
+            ];
+            $_head = array_merge($_head, $_head2);
+            $_export_datas = [];
+            if (1 == $_p) {
+                $_data_sum['total'] = '汇总';
+                if (!empty($_param['app_id'])) {
+                    $_data_sum['game'] = '--';
+                }
+                if (!empty($_param['agent_id'])) {
+                    $_data_sum['agent'] = '--';
+                }
+                $_data_sum['active_cnt'] = $_data['sum']['active_cnt'];
+                $_data_sum['reg_cnt'] = $_data['sum']['reg_cnt'];
+                $_data_sum['user_cnt'] = $_data['sum']['user_cnt'];
+                $_data_sum['acr'] = $_data['sum']['acr'];
+                $_data_sum['ip_cnt'] = $_data['sum']['ip_cnt'];
+                $_data_sum['order_cnt'] = $_data['sum']['order_cnt'];
+                $_data_sum['reg_pay_cnt'] = $_data['sum']['reg_pay_cnt'];
+                $_data_sum['reg_sum_money'] = $_data['sum']['reg_sum_money'];
+                $_data_sum['pay_user_cnt'] = $_data['sum']['pay_user_cnt'];
+                $_data_sum['sum_money'] = $_data['sum']['sum_money'];
+                $_data_sum['reg_pay_rate'] = $_data['sum']['reg_pay_rate'];
+                $_data_sum['user_pay_rate'] = $_data['sum']['user_pay_rate'];
+                $_data_sum['reg_arpu'] = $_data['sum']['reg_arpu'];
+                $_data_sum['act_pay_rate'] = $_data['sum']['act_pay_rate'];
+                $_data_sum['arpu'] = $_data['sum']['arpu'];
+                $_data_sum['arppu'] = $_data['sum']['arppu'];
+                $_export_datas[] = $_data_sum;
+            }
+            if (!empty($_today_data)) {
+                $_export_data = [];
+                $_export_data['date'] = $_today_data['date'];
+                if (!empty($_param['app_id'])) {
+                    $_export_data['game'] = $_games[$_today_data['app_id']];
+                }
+                if (!empty($_param['agent_id'])) {
+                    $_export_data['agent'] = $_agents[$_today_data['agent_id']];
+                }
+                $_export_data['active_cnt'] = $_today_data['active_cnt'];
+                $_export_data['reg_cnt'] = $_today_data['reg_cnt'];
+                $_export_data['user_cnt'] = $_today_data['user_cnt'];
+                $_export_data['acr'] = $_today_data['acr'];
+                $_export_data['ip_cnt'] = $_today_data['ip_cnt'];
+                $_export_data['order_cnt'] = $_today_data['order_cnt'];
+                $_export_data['reg_pay_cnt'] = $_today_data['reg_pay_cnt'];
+                $_export_data['reg_sum_money'] = $_today_data['reg_sum_money'];
+                $_export_data['pay_user_cnt'] = $_today_data['pay_user_cnt'];
+                $_export_data['sum_money'] = $_today_data['sum_money'];
+                $_export_data['reg_pay_rate'] = $_today_data['reg_pay_rate'];
+                $_export_data['user_pay_rate'] = $_today_data['user_pay_rate'];
+                $_export_data['reg_arpu'] = $_today_data['reg_arpu'];
+                $_export_data['act_pay_rate'] = $_today_data['act_pay_rate'];
+                $_export_data['arpu'] = $_today_data['arpu'];
+                $_export_data['arppu'] = $_today_data['arppu'];
+                $_export_datas[] = $_export_data;
+            }
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data = [];
+                $_export_data['date'] = $_val['date'];
+                if (!empty($_param['app_id'])) {
+                    $_export_data['game'] = $_games[$_val['app_id']];
+                }
+                if (!empty($_param['agent_id'])) {
+                    $_export_data['agent'] = $_agents[$_val['agent_id']];
+                }
+                $_export_data['active_cnt'] = $_val['active_cnt'];
+                $_export_data['reg_cnt'] = $_val['reg_cnt'];
+                $_export_data['user_cnt'] = $_val['user_cnt'];
+                $_export_data['acr'] = $_val['acr'];
+                $_export_data['ip_cnt'] = $_val['ip_cnt'];
+                $_export_data['order_cnt'] = $_val['order_cnt'];
+                $_export_data['reg_pay_cnt'] = $_val['reg_pay_cnt'];
+                $_export_data['reg_sum_money'] = $_val['reg_sum_money'];
+                $_export_data['pay_user_cnt'] = $_val['pay_user_cnt'];
+                $_export_data['sum_money'] = $_val['sum_money'];
+                $_export_data['reg_pay_rate'] = $_val['reg_pay_rate'];
+                $_export_data['user_pay_rate'] = $_val['user_pay_rate'];
+                $_export_data['reg_arpu'] = $_val['reg_arpu'];
+                $_export_data['act_pay_rate'] = $_val['act_pay_rate'];
+                $_export_data['arpu'] = $_val['arpu'];
+                $_export_data['arppu'] = $_val['arppu'];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '每日数据', '.csv', true);
+                break;
+            } else {
+                $_file_name = '每日数据'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    if (DataConst::SWITCH_SHOW == $_switch_show) {
+                        $_data = (new SwitchDayDataLogic())->getList($_param, $_page);
+                        $_today_data = (new SwitchDayDataLogic())->getTodayData($_param);
+                    } else {
+                        $_data = (new DayDataLogic())->getList($_param, $_page);
+                        $_today_data = (new DayDataLogic())->getTodayData($_param);
+                    }
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '每日数据');
+    }
+
+    /**
+     * 每日数据
+     * admin/mp.data.data/dataday
+     */
+    public function dataday() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIndex();
+        }
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        if (empty($_param['agent_id']) && !empty($this->map['agent_id'])) {
+            $_param['agent_id'] = $this->map['agent_id'];
+        }
+        $_switch_button = DataConst::SWITCH_BUTTON_HIDDEN;  //切量按钮隐藏
+        if ($this->isAgent()) {
+            $_app_ids = (new AgentGame())->getGameIds($this->map['agent_id']);
+            $this->_games(
+                $_param['app_id'], 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK,
+                [GameConst::GAME_MP, GameConst::GAME_MP_RPBOX, GameConst::GAME_MP_BOX], false, true,
+                ['id' => ['in', $_app_ids]]
+            );
+        } else {
+            $this->_games(
+                $_param['app_id'], 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK,
+                [GameConst::GAME_MP, GameConst::GAME_MP_RPBOX, GameConst::GAME_MP_BOX]
+            );
+            if (!empty($_param['agent_id']) && '-1' != $_param['agent_id']) {
+                $_switch_button = DataConst::SWITCH_BUTTON_SHOW;  //总后台数据选择了渠道筛选,显示切量按钮
+            }
+        }
+        $this->assign('switch_button', $_switch_button);
+        $_agents = $this->_agents(
+            $_param['agent_id'], true, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true
+        );
+        $_agents_select = Filter::selectCommon($_agents, 'agent_id', $this->request->param('agent_id/d', 0));
+        $this->assign('agents_select', $_agents_select);
+        //日期按钮
+        $_time_range = $this->request->param('time_range');
+        switch ($_time_range) {
+            case 'seven_days':
+                $_start_time = date('Y-m-d', strtotime('-6 days'));
+                $_end_time = date('Y-m-d');
+                break;
+            case 'this_month':
+                $_start_time = date('Y-m-01', strtotime(date("Y-m-d")));
+                $_end_time = date('Y-m-d');
+                break;
+            case 'thirty_days':
+            default:
+                $_start_time = $this->request->param('start_time/s', date('Y-m-d', strtotime('-1 month')));
+                $_end_time = $this->request->param('end_time/s', date('Y-m-d'));
+                break;
+        }
+        $this->assign('time_range', $_time_range);
+        list($_param['start_time'], $_param['end_time']) = $this->_time($_start_time, $_end_time);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 50);
+        /* 是否显示切量 */
+        $_switch_show = $this->request->param('switch_show/d', DataConst::SWITCH_HIDDEN);
+        $this->assign('switch_show', $_switch_show);
+        if ($this->isAgent()) {
+            $_data = (new SwitchDayDataLogic())->getList($_param, $_page.','.$_list_rows);
+        } else {
+            $_data = (new DayDataLogic())->getList($_param, $_page.','.$_list_rows);
+            if (DataConst::SWITCH_SHOW == $_switch_show) {
+                $_switch_data = (new SwitchDayDataLogic())->getList($_param, $_page.','.$_list_rows);
+                $this->assign('switch_sum', $_switch_data['sum']);
+                $this->assign('switch_items', $_switch_data['list']);
+            }
+        }
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $_time = time();
+        $_start = strtotime($_start_time);
+        $_end = strtotime($_end_time) + CommonConst::CONST_DAY_SECONDS;
+        $_today_data = [];
+        if ($_time < $_end && $_time > $_start && 1 == $_page) {
+            if ($this->isAgent()) {
+                $_today_data = (new SwitchDayDataLogic())->getTodayData($_param);
+            } else {
+                $_today_data = (new DayDataLogic())->getTodayData($_param);
+                if (DataConst::SWITCH_SHOW == $_switch_show) {
+                    $_switch_today_data = (new SwitchDayDataLogic())->getTodayData($_param);
+                    $this->assign('switch_today_data', $_switch_today_data);
+                }
+            }
+        }
+        $this->assign('today', $_today_data);
+        $this->assign('sum', $_data['sum']);
+        $this->assign('items', $_page_data);
+        unset($_param['start_time']);
+        unset($_param['end_time']);
+        $this->assign('param', $_param);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('box/data/dataday');
+    }
+
+    /**
+     * 留存数据导出
+     *
+     * @param $param
+     *
+     * @return mixed
+     */
+    public function analysisExportIndex($param) {
+        $_agents = $this->_agentsByRoleId(
+            $param['agent_id'], [AgentConst::AGENT_ROLE_MP_MEMBER, AgentConst::AGENT_ROLE_MP_AGENT]
+        );
+        $_games = $this->_games($param['app_id'], 0, 0, 0, GameConst::GAME_MP);
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        Request::instance()->get(['page' => 1]);
+        Request::instance()->get(['list_rows' => $_offset]);
+        if (!empty($param['app_id']) && !empty($param['agent_id'])) {
+            $_data = (new RemainDataLogic())->gameAgent($param)->toArray();
+        } else if (empty($param['app_id']) && !empty($param['agent_id'])) {
+            $_data = (new RemainDataLogic())->agent($param)->toArray();
+        } else if (!empty($param['app_id']) && empty($param['agent_id'])) {
+            $_data = (new RemainDataLogic())->game($param)->toArray();
+        } else {
+            $_data = (new RemainDataLogic())->main($param)->toArray();
+        }
+        $_total_cnt = $_data['total'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            $_head = ['时间'];
+            if (!empty($param['app_id'])) {
+                array_push($_head, '游戏');
+            }
+            if (!empty($param['agent_id'])) {
+                array_push($_head, '二级渠道');
+            }
+            $_head2 = [
+                '注册用户',
+                '2日',
+                '3日',
+                '4日',
+                '5日',
+                '6日',
+                '7日',
+                '15日',
+                '30日',
+            ];
+            $_head = array_merge($_head, $_head2);
+            $_export_datas = [];
+            foreach ($_data['data'] as $_key => $_val) {
+                if (!empty($_val['reg_cnt'])) {
+                    $_day2 = '('.round($_val['day2'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day3 = '('.round($_val['day3'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day4 = '('.round($_val['day4'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day5 = '('.round($_val['day5'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day6 = '('.round($_val['day6'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day7 = '('.round($_val['day7'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day15 = '('.round($_val['day15'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                    $_day30 = '('.round($_val['day30'] / $_val['reg_cnt'], 4) * 100 .'%)';
+                } else {
+                    $_day2 = '(0%)';
+                    $_day3 = '(0%)';
+                    $_day4 = '(0%)';
+                    $_day5 = '(0%)';
+                    $_day6 = '(0%)';
+                    $_day7 = '(0%)';
+                    $_day15 = '(0%)';
+                    $_day30 = '(0%)';
+                }
+                $_export_data['date'] = $_val['date'];
+                if (!empty($param['app_id'])) {
+                    $_export_data['game'] = $_games[$_val['app_id']];
+                }
+                if (!empty($param['agent_id'])) {
+                    $_export_data['agent'] = $_agents[$_val['agent_id']];
+                }
+                $_export_data['reg_cnt'] = $_val['reg_cnt'];
+                $_export_data['day2'] = $_val['day2'].$_day2;
+                $_export_data['day3'] = $_val['day3'].$_day3;
+                $_export_data['day4'] = $_val['day4'].$_day4;
+                $_export_data['day5'] = $_val['day5'].$_day5;
+                $_export_data['day6'] = $_val['day6'].$_day6;
+                $_export_data['day7'] = $_val['day7'].$_day7;
+                $_export_data['day15'] = $_val['day15'].$_day15;
+                $_export_data['day30'] = $_val['day30'].$_day30;
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '留存分析', '.csv', true);
+                break;
+            } else {
+                $_file_name = '留存分析'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    Request::instance()->get(['page' => $_p]);
+                    if ($this->isAgent()) {
+                        if (!empty($param['app_id']) && !empty($param['agent_id'])) {
+                            $_data = (new SwitchRemainDataLogic())->gameAgent($param)->toArray();
+                        } else if (empty($param['app_id']) && !empty($param['agent_id'])) {
+                            $_data = (new SwitchRemainDataLogic())->agent($param)->toArray();
+                        } else if (!empty($param['app_id']) && empty($param['agent_id'])) {
+                            $_data = (new SwitchRemainDataLogic())->game($param)->toArray();
+                        } else {
+                            $_data = (new SwitchRemainDataLogic())->main($param)->toArray();
+                        }
+                    } else {
+                        if (!empty($param['app_id']) && !empty($param['agent_id'])) {
+                            $_data = (new RemainDataLogic())->gameAgent($param)->toArray();
+                        } else if (empty($param['app_id']) && !empty($param['agent_id'])) {
+                            $_data = (new RemainDataLogic())->agent($param)->toArray();
+                        } else if (!empty($param['app_id']) && empty($param['agent_id'])) {
+                            $_data = (new RemainDataLogic())->game($param)->toArray();
+                        } else {
+                            $_data = (new RemainDataLogic())->main($param)->toArray();
+                        }
+                    }
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '留存分析');
+    }
+
+    /**
+     * 留存数据
+     * admin/mp.data.data/analysis
+     */
+    public function analysis() {
+        if (!input('?get.page')) {
+            Request::instance()->get(['page' => 1]);
+        }
+        if (!input('?get.list_rows')) {
+            Request::instance()->get(['list_rows' => 50]);
+        }
+        $_param['app_id'] = $this->request->param('app_id/d', 0);
+        $_game_where = [];
+        if ($this->isAgent()) {
+            $_app_ids = (new AgentGame())->getGameIds($this->admin_id);
+            $_game_where = ['id' => ['in', $_app_ids]];
+        }
+        $_param['agent_id'] = $this->request->param('agent_id/d', $this->map['agent_id']);
+        if (empty($_param['agent_id']) && !empty($this->map['agent_id'])) {
+            $_param['agent_id'] = $this->map['agent_id'];
+        }
+        list($_param['start_time'], $_param['end_time']) = $this->_time();
+        $this->_games(
+            $_param['app_id'], 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK,
+            [GameConst::GAME_MP, GameConst::GAME_MP_RPBOX, GameConst::GAME_MP_BOX], false, true, $_game_where
+        );
+        $this->_agents($_param['agent_id'], true, [AgentConst::ROLE_TYPE_GROUP, AgentConst::ROLE_TYPE_AGENT], true);
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->analysisExportIndex($_param);
+        }
+        if (!empty($_param['app_id']) && !empty($_param['agent_id'])) {
+            return $this->gameAgent($_param);
+        } else if (empty($_param['app_id']) && !empty($_param['agent_id'])) {
+            return $this->agent($_param);
+        } else if (!empty($_param['app_id']) && empty($_param['agent_id'])) {
+            return $this->game($_param);
+        }
+
+        return $this->main($_param);
+    }
+
+    /**
+     * 总体数据
+     *
+     * @param $_param
+     *
+     * @return mixed
+     */
+    public function main($_param) {
+        if ($this->isAgent()) {
+            $_data = (new SwitchRemainDataLogic())->main($_param);
+        } else {
+            $_data = (new RemainDataLogic())->main($_param);
+        }
+        $this->assign('items', $_data);
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('box/data/remain');
+    }
+
+    /**
+     * 游戏渠道
+     *
+     * @param $_param
+     *
+     * @return mixed
+     */
+    public function gameAgent($_param) {
+        if ($this->isAgent()) {
+            $_data = (new SwitchRemainDataLogic())->gameAgent($_param);
+        } else {
+            $_data = (new RemainDataLogic())->gameAgent($_param);
+        }
+        $this->assign('items', $_data);
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('box/data/remain');
+    }
+
+    /**
+     * 游戏
+     *
+     * @param $_param
+     *
+     * @return mixed
+     */
+    public function game($_param) {
+        if ($this->isAgent()) {
+            $_data = (new SwitchRemainDataLogic())->game($_param);
+        } else {
+            $_data = (new RemainDataLogic())->game($_param);
+        }
+        $this->assign('items', $_data);
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('box/data/remain');
+    }
+
+    /**
+     * 渠道
+     *
+     * @param $_param
+     *
+     * @return mixed
+     */
+    public function agent($_param) {
+        if ($this->isAgent()) {
+            $_data = (new SwitchRemainDataLogic())->agent($_param);
+        } else {
+            $_data = (new RemainDataLogic())->agent($_param);
+        }
+        $this->assign('items', $_data);
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('box/data/remain');
+    }
+
+    /**
+     * 玩家收益排行
+     */
+    public function rank() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportAgent();
+        }
+        $_param = $this->request->param();
+        $_param['role_id'] = ['in', [AgentConst::AGENT_ROLE_MP_MEMBER, AgentConst::AGENT_ROLE_MP_AGENT]];
+        $_rank_by = get_val($_param, 'rank_by', 'share_total');
+        $this->assignRankBySelect($_rank_by);
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 50);
+        $_item = (new AgentExtLogic())->getRank($_rank_by, $_param, $_page.','.$_list_rows);
+        $_item = (new Page())->paginate($_item['count'], $_item['list'], $_page, $_list_rows);
+        $_offset = (($_item->currentPage() - 1) * $_list_rows);
+        $this->assign('offset', $_offset);
+        $this->assign('items', $_item);
+        $this->assign('page', $_item->render());
+
+        return $this->fetch('box/data/rank');
+    }
+
+    /**
+     * 渠道排行数据导出
+     *
+     * @throws
+     */
+    public function exportAgent() {
+        $_param = $this->request->param();
+        $_param['role_id'] = ['in', [AgentConst::AGENT_ROLE_MP_MEMBER, AgentConst::AGENT_ROLE_MP_AGENT]];
+        $_rank_by = get_val($_param, 'rank_by', 'share_total');
+        $this->assignRankBySelect($_rank_by);
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_data = (new AgentExtLogic())->getRank($_rank_by, $_param, $_p.','.$_offset);
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            $_head = ['排行', '渠道账号', '渠道昵称', '玩家账号', '玩家昵称', '邀请数量', '奖励收益'];
+            $_export_datas = [];
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['key'] = ($_p - 1) * $_offset + $_key + 1;
+                $_export_data['agent'] = $_val['user_login'];
+                $_export_data['user_nicename'] = $_val['user_nicename'];
+                $_export_data['mem'] = $_val['mem'];
+                $_export_data['mem_nickname'] = $_val['mem_nickname'];
+                $_export_data['reg_cnt'] = $_val['reg_cnt'];
+                $_export_data['share_total'] = $_val['share_total'];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '渠道排行', '.csv', true);
+                break;
+            } else {
+                $_file_name = '渠道排行'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_data = (new AgentExtLogic())->getRank($_rank_by, $_param, $_p.','.$_offset);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '渠道排行');
+    }
+
+    protected function assignRankBySelect($rank_by) {
+        $_rank_by_list = $this->getRankByList();
+        $_rank_by_select = Filter::selectCommon($_rank_by_list, 'rank_by', $rank_by);
+        $this->assign('rank_by_list', $_rank_by_list);
+        $this->assign('rank_by_select', $_rank_by_select);
+    }
+
+    protected function getRankByList() {
+        return [
+            'reg_cnt'     => '注册用户',
+            'share_total' => '渠道收益',
+        ];
+    }
+
+    /**
+     * 游戏热度
+     * admin/mp.data.data/hot
+     */
+    public function hot() {
+        $_page = $this->request->param('page/d', 1);
+        $_offset = $this->request->param('list_rows/d', 50);
+        $_param = [];
+        $_param['classify'] = GameConst::GAME_MP;
+        $_rdata = (new GameMiniListLogic())->getGameMiniList(
+            0, $_param, $_page.','.$_offset, GameConst::RANK_TYPE_DOWN
+        );
+        $_item = (new Page())->paginate($_rdata['count'], $_rdata['list'], $_page, $_offset);
+        $_offset = (($_item->currentPage() - 1) * $_offset);
+        $this->assign('offset', $_offset);
+        $this->assign('items', $_item);
+        $this->assign('page', $_item->render());
+
+        return $this->fetch('box/data/hot');
+    }
+
+    /**
+     * 修改数据
+     * admin/mp.data.data/editUserCnt
+     */
+    public function editUserCnt() {
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        $_reg_cnt = $this->request->param('reg_cnt/d', 0);
+        $_date = $this->request->param('date/s', date('Y-m-d'));
+        if (empty($_agent_id)) {
+            $this->adminError('参数错误!');
+        }
+        $_app_ids = (new AgentGame())->getGameIds($_agent_id);
+        $this->_games(
+            0, 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK,
+            [GameConst::GAME_MP, GameConst::GAME_MP_RPBOX, GameConst::GAME_MP_BOX], false, true,
+            ['id' => ['in', $_app_ids]]
+        );
+        $this->assign('date', $_date);
+        $this->assign('agent_id', $_agent_id);
+        $this->assign('reg_cnt', $_reg_cnt);
+
+        return $this->fetch('box/data/edit_reg_cnt');
+    }
+
+    /**
+     * 修改数据提交
+     * admin/mp.data.data/editUserCnt
+     */
+    public function editUserCntPost() {
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        if (empty($_agent_id)) {
+            $this->adminError('参数错误!');
+        }
+        $_date = $this->request->param('date/s', '');
+        if (empty($_date)) {
+            $this->adminError('请选择日期!');
+        }
+        $_date = date('Y-m-d', strtotime($_date));
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError('请选择游戏!');
+        }
+        $_reg_cnt = $this->request->param('reg_cnt/d', 0);
+        $_old_reg_cnt = $this->request->param('old_reg_cnt/d', 0);
+        $_cha = $_old_reg_cnt - $_reg_cnt;
+        $_data['reg_cnt_show'] = $_cha > 0 ? $_cha : 0;
+        $_data_logic = new DataLogic();
+        $_map = [];
+        $_map['date'] = $_date;
+        $_data_logic->updateOrInsert(new DaySwitchModel(), $_map, $_data);
+        $_map['app_id'] = $_app_id;
+        $_data_logic->updateOrInsert(new DayGameSwitchModel(), $_map, $_data);
+        $_map['agent_id'] = $_agent_id;
+        $_data_logic->updateOrInsert(new DgaSwitchModel(), $_map, $_data);
+        unset($_map['app_id']);
+        $_rs = $_data_logic->updateOrInsert(new DayAgentSwitchModel(), $_map, $_data);
+        if (false == $_rs) {
+            $this->adminError('修改失败!');
+        }
+        $this->adminSuccess('修改成功!');
+    }
+}

+ 191 - 0
admin/admin/controller/mp/data/RankController.php

@@ -0,0 +1,191 @@
+<?php
+/**
+ * RankController.php  UTF-8
+ * 小游戏排行
+ *
+ * @date    : 2018/11/5 14:24
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOMP 1.0
+ */
+
+namespace admin\admin\controller\mp\data;
+
+use admin\admin\controller\data\RankController as BaseController;
+use cmf\view\Filter;
+use huo\logic\data\DayDataLogic;
+use huo\logic\data\RankDataLogic;
+use huo\logic\member\MemListLogic;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\tool\Export;
+use huolib\tool\Page;
+use think\Request;
+
+class RankController extends BaseController {
+    /**
+     * 游戏排行数据导出
+     *
+     * @throws
+     */
+    public function exportGame() {
+        $_game_name = $this->request->param('game_name');
+        $_rank_by = $this->request->param('rank_by');
+        list($_start_time, $_end_time) = $this->resolveTimeRange();
+        $this->_time($_start_time, $_end_time);
+        $this->assignRankBySelect($_rank_by);
+        $_map = [
+            'start_time' => $_start_time,
+            'end_time'   => $_end_time,
+        ];
+        if (isset($_game_name)) {
+            $_map['game_name'] = $_game_name;
+        }
+        if (isset($_classify)) {
+            $_map['classify'] = $_classify;
+        }
+        if (isset($_rank_by) && in_array($_rank_by, array_keys($this->getRankByList()))) {
+            $_map['rank_by'] = $_rank_by;
+        }
+        $_map['classify'] = GameConst::GAME_MP; //只显示 小游戏
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_data = (new RankDataLogic())->game($_map, $_offset)->toArray();
+        $_total_cnt = $_data['total'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        while ($_p <= $_for_cnt) {
+            $_head = ['排行', '游戏名称', '客户端', '充值金额', '新增用户', '新增设备', '活跃用户', '付费ARPU', '活跃ARPU', '新增付费率', '活跃付费率'];
+            $_export_datas = [];
+            foreach ($_data['data'] as $_key => $_val) {
+                $_export_data['key'] = ($_p - 1) * $_offset + $_key + 1;
+                $_export_data['game'] = $_val['game']['name'];
+                $_export_data['classify'] = $_val['game']['classify'];
+                $_export_data['sum_money'] = $_val['sum_money'];
+                $_export_data['reg_cnt'] = $_val['reg_cnt'];
+                $_export_data['reg_device_cnt'] = $_val['reg_device_cnt'];
+                $_export_data['user_cnt'] = $_val['user_cnt'];
+                $_export_data['PaidARPU'] = empty($_val['pay_user_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['sum_money']
+                          / $_val['pay_user_cnt'], 2
+                      ) * 100 .'%';
+                $_export_data['ActiveARPU'] = empty($_val['user_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['sum_money']
+                          / $_val['user_cnt'], 2
+                      ) * 100 .'%';
+                $_export_data['NewPaymentRate'] = empty($_val['reg_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['reg_pay_cnt']
+                          / $_val['reg_cnt'], 2
+                      ) * 100 .'%';
+                $_export_data['ActivePaymentRate'] = empty($_val['user_cnt'])
+                    ? '0%'
+                    : round(
+                          $_val['pay_user_cnt']
+                          / $_val['user_cnt'], 2
+                      ) * 100 .'%';
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, '游戏排行', '.csv', true);
+                break;
+            } else {
+                $_file_name = '游戏排行'.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    Request::instance()->get(['page' => $_p]);
+                    $_data = (new RankDataLogic())->game($_map, $_offset)->toArray();
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, '游戏排行');
+    }
+
+    /**
+     * 游戏排行
+     * admin/mp.data.rank/game
+     *
+     * @throws
+     */
+    public function game() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportGame();
+        }
+        $_game_name = $this->request->param('game_name', '');
+        $_rank_by = $this->request->param('rank_by', '');
+        $_list_rows = $this->request->param('list_rows', 10);
+        list($_start_time, $_end_time) = $this->resolveTimeRange();
+        $this->_time($_start_time, $_end_time);
+        $this->assignRankBySelect($_rank_by);
+        $_map = [
+            'start_time' => $_start_time,
+            'end_time'   => $_end_time,
+        ];
+        if (!empty($_game_name)) {
+            $_map['game_name'] = $_game_name;
+        }
+        if (!empty($_classify)) {
+            $_map['classify'] = $_classify;
+        }
+        if (!empty($_rank_by) && in_array($_rank_by, array_keys($this->getRankByList()))) {
+            $_map['rank_by'] = $_rank_by;
+        }
+        $_map['classify'] = GameConst::GAME_MP; //只显示 小游戏
+        if ($_start_time == date('Y-m-d')) {
+            $items = (new DayDataLogic())->getTodayRankData($_map, $_list_rows);
+        } else {
+            $items = (new RankDataLogic())->game($_map, $_list_rows);
+        }
+        $_offset = (($items->currentPage() - 1) * $_list_rows);
+        $this->assign('offset', $_offset);
+        $this->assign('game_name', $_game_name);
+        $this->assign('items', $items->items());
+        $this->assign('page', $items->render());
+
+        return $this->fetch('box/data/game_rank');
+    }
+
+    /**
+     * 玩家排行
+     * admin/mp.data.rank/mem
+     *
+     * @throws
+     */
+    public function mem() {
+        $_param = $this->request->param();
+        $_page = $this->request->param('page', 1);
+        $_list_rows = $this->request->param('list_rows', 50);
+        $_mem_id_input = Filter::text('mem_id', $this->request->param('mem_id/d', ''), '请输入玩家ID');
+        $this->assign('mem_id_input', $_mem_id_input);
+        $_username_input = Filter::text('username', $this->request->param('username/s', ''), '请输入玩家账号');
+        $this->assign('username_input', $_username_input);
+        $_server_name_input = Filter::text('server_name', $this->request->param('server_name/s', ''), '请输入角色区服');
+        $this->assign('server_name_input', $_server_name_input);
+        $_role_name_input = Filter::text('role_name', $this->request->param('role_name/s', ''), '请输入角色名');
+        $this->assign('role_name_input', $_role_name_input);
+        $this->_time();
+        $this->_games(
+            get_val($_param, 'app_id', 0), GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE,
+            GameConst::GAME_IS_SDK, GameConst::GAME_MP
+        );
+        $_items = (new MemListLogic())->getRoleList($_param, $_page.','.$_list_rows, '-money');
+        $_items = (new Page())->paginate($_items['count'], $_items['list'], $_page, $_list_rows);
+        $this->assign('offset', ($_page - 1) * $_list_rows);
+        $this->assign('items', $_items->items());
+        $this->assign('page', $_items->render());
+
+        return $this->fetch('box/data/mem_rank');
+    }
+}

+ 230 - 0
admin/admin/controller/mp/fill/SubMemRankController.php

@@ -0,0 +1,230 @@
+<?php
+/**
+ * SubMemRankController.php UTF-8
+ * 填充假数据
+ *
+ * @date    : 5/17/2018 3:51 PM
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : luowei <lw@huosdk.com>
+ * @version : HuoMp 1.0
+ */
+
+namespace admin\admin\controller\mp\fill;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huolib\constant\CommonConst;
+use huolib\tool\Page;
+use huolib\tool\Time;
+use huomp\logic\fill\SubMemFakerLogic;
+use huomp\model\fill\LogDayMemFakerModel;
+use huomp\model\fill\MemFakerModel;
+
+class SubMemRankController extends AdminbaseController {
+    /**
+     * 填充数据列表
+     * admin/mp.fill.sub_mem_rank/index
+     */
+    public function index() {
+        $_param = $this->request->param();
+        $_nickname_name = Filter::text('nickname', get_val($_param, 'nickname', ''), '请输入昵称');
+        $this->assign('nickname_input', $_nickname_name);
+        $this->_time();
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 10);
+        $_param['is_delete'] = CommonConst::CONST_NOT_DELETE;
+        $_data = (new SubMemFakerLogic())->getList($_param, $_page.','.$_list_rows);
+        $_items = Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_items);
+        $this->assign('page', $_items->render());
+
+        return $this->fetch('box/fill/sub_mem_rank/index');
+    }
+
+    /**
+     * 填充数据列表
+     * admin/mp.fill.sub_mem_rank/add
+     */
+    public function add() {
+        return $this->fetch('box/fill/sub_mem_rank/add');
+    }
+
+    /**
+     * 填充数据列表
+     * admin/mp.fill.sub_mem_rank/addPost
+     */
+    public function addPost() {
+        $_param = $this->request->param();
+        $_result = $this->validate($_param, 'SubMemRank.add');
+        if (true !== $_result) {
+            $this->adminError($_result);
+        }
+        if ($_param['sub_mem_min'] == $_param['sub_mem_max']) {
+            $this->adminError('每日增加邀请人数,最小最大值不能一样');
+        }
+        if ($_param['sub_amount_min'] == $_param['sub_amount_max']) {
+            $this->adminError('每日增加收益数,最小最大值不能一样');
+        }
+        $_faker_model = new MemFakerModel();
+        $_rs = $_faker_model->addData($_param);
+        if (false == $_rs) {
+            $this->adminError('添加失败!');
+        }
+        $this->createMemFaker($_rs, true);
+        $this->adminSuccess('添加成功!');
+    }
+
+    /**
+     * 填充数据列表
+     * admin/mp.fill.sub_mem_rank/edit
+     */
+    public function edit() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError('参数缺失');
+        }
+        $_data = (new MemFakerModel())->getDetail($_id);
+        $this->assign('data', $_data);
+
+        return $this->fetch('box/fill/sub_mem_rank/edit');
+    }
+
+    /**
+     * 填充数据列表
+     * admin/mp.fill.sub_mem_rank/editPost
+     */
+    public function editPost() {
+        $_param = $this->request->param();
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError('参数缺失');
+        }
+        $_result = $this->validate($_param, 'SubMemRank.edit');
+        if (true !== $_result) {
+            $this->adminError($_result);
+        }
+        $_faker_model = new MemFakerModel();
+        $_faker_info = $_faker_model->getDetail($_id);
+        $_faker_info = array_merge($_faker_info, $_param);
+        if ($_faker_info['sub_mem_min'] == $_faker_info['sub_mem_max']) {
+            $this->adminError('每日增加邀请人数,最小最大值不能一样');
+        }
+        if ($_faker_info['sub_amount_min'] == $_faker_info['sub_amount_max']) {
+            $this->adminError('每日增加收益数,最小最大值不能一样');
+        }
+        $_rs = $_faker_model->updateData($_faker_info, $_id);
+        if (false == $_rs) {
+            $this->adminError('编辑失败!');
+        }
+        $this->adminSuccess('编辑成功!');
+    }
+
+    /**
+     * 填充数据列表
+     * admin/mp.fill.sub_mem_rank/delete
+     */
+    public function delete() {
+        $_ids = $this->request->param('ids/a', []);
+        $_faker_model = new MemFakerModel();
+        if (!empty($_ids)) {
+            foreach ($_ids as $_id) {
+                $_faker_info['is_delete'] = CommonConst::CONST_DELETED;
+                $_faker_info['delete_time'] = time();
+                $_faker_model->updateData($_faker_info, $_id);
+            }
+            $this->adminSuccess('删除成功!');
+        }
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError('参数缺失');
+        }
+        $_faker_info = $_faker_model->getDetail($_id);
+        if (empty($_faker_info)) {
+            $this->adminError('参数非法');
+        }
+        if ($_faker_info['is_delete'] == CommonConst::CONST_DELETED) {
+            $this->adminError('记录已经删除,请勿重复操作');
+        }
+        $_faker_info['is_delete'] = CommonConst::CONST_DELETED;
+        $_faker_info['delete_time'] = time();
+        $_rs = $_faker_model->updateData($_faker_info, $_id);
+        if (false == $_rs) {
+            $this->adminError('删除失败!');
+        }
+        $this->adminSuccess('删除成功!');
+    }
+
+    /**
+     * 填充数据列表
+     * admin/mp.fill.sub_mem_rank/updateMemFaker
+     */
+    public function updateMemFaker() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError('参数缺失');
+        }
+        $this->createMemFaker($_id);
+        $this->adminSuccess('更新成功!');
+    }
+
+    /**
+     * 手动生成数据
+     * admin/mp.fill.sub_mem_rank/createFaker
+     */
+    public function createFaker() {
+        $_ids = $this->request->param('ids/a', []);
+        list($start_time, $end_time) = Time::yesterday();
+        $_mem_faker_model = new MemFakerModel();
+        $_mem_faker_list = $_mem_faker_model->getList($_ids);
+        $_ldmf_model = new LogDayMemFakerModel();
+        foreach ($_mem_faker_list as $_mem_faker_info) {
+            $_faker_id = $_mem_faker_info['id'];
+            $_sub_mem_cnt = mt_rand($_mem_faker_info['sub_mem_min'], $_mem_faker_info['sub_mem_max']);
+            $_sub_amount = mt_rand($_mem_faker_info['sub_amount_min'], $_mem_faker_info['sub_amount_max']);
+            $_sum_amount = mt_rand($_mem_faker_info['sub_amount_min'], $_mem_faker_info['sub_amount_max']);
+            $_insert_data = [
+                'faker_id'    => $_faker_id,
+                'sub_mem_cnt' => $_sub_mem_cnt,
+                'sub_amount'  => $_sub_amount,
+                'sum_amount'  => $_sum_amount,
+                'create_time' => $start_time,
+            ];
+            $_ldmf_model->insertLog($_insert_data);
+            //累加
+            $_mem_faker_info['sub_mem_cnt'] += $_sub_mem_cnt;
+            $_mem_faker_info['sub_amount'] += $_sub_amount;
+            $_mem_faker_info['update_time'] = time();
+            $_mem_faker_model->updateData($_mem_faker_info, $_mem_faker_info['id']);
+        }
+        $this->adminSuccess('更新成功!');
+    }
+
+    protected function createMemFaker($id, $is_add = false) {
+        $_mem_faker_model = new MemFakerModel();
+        $_mem_faker_info = $_mem_faker_model->getDetail($id);
+        $_ldmf_model = new LogDayMemFakerModel();
+        $_faker_id = $_mem_faker_info['id'];
+        $_sub_mem_cnt = mt_rand($_mem_faker_info['sub_mem_min'], $_mem_faker_info['sub_mem_max']);
+        $_sub_amount = mt_rand($_mem_faker_info['sub_amount_min'], $_mem_faker_info['sub_amount_max']);
+        $_sum_amount = mt_rand($_mem_faker_info['sub_amount_min'], $_mem_faker_info['sub_amount_max']);
+        $_insert_data = [
+            'faker_id'    => $_faker_id,
+            'sub_mem_cnt' => $_sub_mem_cnt,
+            'sub_amount'  => $_sub_amount,
+            'sum_amount'  => $_sum_amount,
+            'create_time' => time(),
+        ];
+        $_ldmf_model->insertLog($_insert_data);
+        if (false == $is_add) {
+            //累加
+            $_mem_faker_info['sub_mem_cnt'] += $_sub_mem_cnt;
+            $_mem_faker_info['sub_amount'] += $_sub_amount;
+            $_mem_faker_info['update_time'] = time();
+            $_mem_faker_model->updateData($_mem_faker_info, $_mem_faker_info['id']);
+        }
+
+        return true;
+    }
+}
+

+ 642 - 0
admin/admin/controller/mp/financial/FinancialController.php

@@ -0,0 +1,642 @@
+<?php
+/**
+ * FinancialController.php  UTF-8
+ * 小游戏盒子财务管理
+ *
+ * @date    : 2018/8/16 9:55
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\mp\financial;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\agent\AgentCache;
+use huo\controller\finance\AoRequest;
+use huo\controller\finance\Settle;
+use huo\controller\member\MemCache;
+use huo\logic\agent\AgentListLogic;
+use huo\logic\finance\SettleHistoryLogic;
+use huo\logic\finance\SettleLogic;
+use huo\model\finance\SettleModel;
+use huo\model\user\RoleModel;
+use huo\model\user\UserModel;
+use huolib\constant\AgentConst;
+use huolib\constant\CommonConst;
+use huolib\constant\MemConst;
+use huolib\constant\SettleConst;
+use huolib\status\CommonStatus;
+use huolib\tool\Export;
+use huomp\controller\finance\RiskAnalysis;
+use huomp\logic\finance\IncomeAdminLogic;
+use huomp\logic\finance\SettleLogLogic;
+use huomp\model\member\UnusualMemModel;
+
+class FinancialController extends AdminBaseController {
+    protected $role_id = [AgentConst::AGENT_ROLE_MP_MEMBER, AgentConst::AGENT_ROLE_MP_AGENT];
+
+    public function _initialize() {
+        parent::_initialize();
+    }
+
+    /**
+     * 渠道余额
+     * admin/mp.financial.financial/balance
+     *
+     * @return mixed
+     */
+    public function balance() {
+        /* 搜索列表 */
+        $_param = $this->request->param();
+        $_agent_input = Filter::text('agent_name', get_val($_param, 'agent_name', ''), '请输入渠道昵称');
+        $this->assign('agent_input', $_agent_input);
+        $_mem_id_input = Filter::text('mem_id', get_val($_param, 'mem_id', ''), '请输入玩家ID');
+        $this->assign('mem_id_input', $_mem_id_input);
+        $_mem_username_input = Filter::text('mem_username', get_val($_param, 'mem_username', ''), '请输入玩家账号');
+        $this->assign('mem_username_input', $_mem_username_input);
+        $_mem_mobile_input = Filter::text('mem_mobile', get_val($_param, 'mem_mobile', ''), '请输入手机号');
+        $this->assign('mem_mobile_input', $_mem_mobile_input);
+        $_mem_real_name_input = Filter::text('mem_real_name', get_val($_param, 'mem_real_name', ''), '请输入真实姓名');
+        $this->assign('mem_real_name_input', $_mem_real_name_input);
+        $_roles = (new RoleModel())->getIdNames(['id' => ['in', $this->role_id]], true);
+        $this->assign('roles', $_roles);
+        $_role_array = [];
+        if (!empty($_roles)) {
+            foreach ($_roles as $_k => $_v) {
+                $_role_array[$_k] = $_v['name'];
+            }
+        }
+        $_role_select = Filter::selectCommon($_role_array, 'role_id', get_val($_param, 'role_id', 0));
+        $this->assign('role_select', $_role_select);
+        if (empty($_param['role_id'])) {
+            $_param['role_id'] = ['in', $this->role_id];
+        }
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 50);
+        $_data = (new AgentListLogic())->getRemainList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('box/financial/balance');
+    }
+
+    protected function _getFlag($flag, $assign = true) {
+        $_flag_arr = [
+            AoRequest::FLAG_REGISTER         => '注册奖励',
+            AoRequest::FLAG_OPEN_GAME        => '游戏奖励',
+            AoRequest::FLAG_INVITE_REGISTER  => '邀请注册奖励',
+            AoRequest::FLAG_INVITE_OPEN_GAME => '推广游戏奖励',
+            AoRequest::FLAG_FAVORITE         => '收藏奖励'
+        ];
+        if (false == $assign) {
+            return isset($_flag_arr[$flag]) ? $_flag_arr[$flag] : '';
+        }
+        $this->assign('flag', $_flag_arr);
+        $_flag_select = Filter::selectCommon($_flag_arr, 'flag', $flag);
+        $this->assign('flag_select', $_flag_select);
+    }
+
+    /**
+     * 收益明细
+     * admin/mp.financial.financial/income
+     */
+    public function income() {
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportIncome();
+        }
+        $_param = $this->request->param();
+        $_mem_input = Filter::text('mem_id', get_val($_param, 'mem_id', ''), '请输入玩家ID');
+        $this->assign('mem_input', $_mem_input);
+        $_mem_nc_input = Filter::text('nickname', get_val($_param, 'nickname', ''), '请输入玩家昵称');
+        $this->assign('mem_nc_input', $_mem_nc_input);
+        $_mem_username_input = Filter::text('mem_username', get_val($_param, 'mem_username', ''), '请输入玩家账号');
+        $this->assign('mem_username_input', $_mem_username_input);
+        $_mem_mobile_input = Filter::text('mem_mobile', get_val($_param, 'mem_mobile', ''), '请输入手机号');
+        $this->assign('mem_mobile_input', $_mem_mobile_input);
+        $_mem_real_name_input = Filter::text('mem_real_name', get_val($_param, 'mem_real_name', ''), '请输入真实姓名');
+        $this->assign('mem_real_name_input', $_mem_real_name_input);
+        if (!empty($_param['agent_id'])) {
+            $_agent_data = AgentCache::ins()->getInfoByAgentId($_param['agent_id']);
+            $_param['mem_id'] = $_agent_data['mem_id'];
+            unset($_agent_data);
+            unset($_param['agent_id']);
+        }
+        $this->_time();
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 50);
+        $_data = (new IncomeAdminLogic())->incomeList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('sum', $_data['sum']);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('box/financial/income');
+    }
+
+    /**
+     * 渠道收益明细导出数据
+     *
+     */
+    public function exportIncome() {
+        $_param = $this->request->param();
+        if (!empty($_param['agent_id'])) {
+            $_agent_data = AgentCache::ins()->getInfoByAgentId($_param['agent_id']);
+            $_param['mem_id'] = $_agent_data['mem_id'];
+            unset($_agent_data);
+            unset($_param['agent_id']);
+        }
+        $_p = 1;
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new IncomeAdminLogic())->incomeList($_param, $_page);
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '渠道收益明细';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '时间',
+                '玩家昵称',
+                '来源',
+                '描述',
+                '奖励金额'
+            ];
+            $_export_datas = [];
+            if (1 == $_p) {
+                $_total = [
+                    '汇总',
+                    '--',
+                    '--',
+                    '--',
+                    $_data['sum']
+                ];
+                $_export_datas[] = $_total;
+            }
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['title'] = $_val['title'];
+                $_export_data['sub_title'] = $_val['sub_title'];
+                $_export_data['desc'] = $_val['desc'];
+                $_export_data['amount'] = $_val['amount'];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new IncomeAdminLogic())->incomeList($_param, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 渠道平台币收入记录导出数据
+     *
+     * @param array $status
+     */
+    public function exportWithdraw($status) {
+        $_param['agent_id'] = $this->request->param('agent_id/d', 0);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-3 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $_param['type'] = SettleConst::SETTLE_TYPE_MP;  //只显示小程序提现
+        $_param['banknum'] = $this->request->param('banknum/s', '');
+        $_param['cardholder'] = $this->request->param('cardholder/s', '');
+        $_param['status'] = $status;
+        $_p = 1;  //第一页
+        $_offset = Export::MAX_ROWS;
+        $_page = $_p.','.$_offset;
+        $_data = (new SettleLogic())->getSettleList(0, $_param, $_page);
+        $_total_cnt = $_data['count'];
+        if ($_total_cnt <= 0) {
+            $_total_cnt = 1;
+        }
+        $_for_cnt = ceil($_total_cnt / $_offset);
+        $_file_name_arr = [];
+        $_file_name = '渠道提现记录';
+        while ($_p <= $_for_cnt) {
+            $_head = [
+                '申请时间',
+                '单号',
+                '渠道',
+                '提现金额',
+                '提现人',
+            ];
+            $_export_datas = [];
+            if (1 == $_p) {
+                $_total = [
+                    '汇总',
+                    '--',
+                    '--',
+                    $_data['sum']['amount'],
+                    '--',
+                ];
+                $_export_datas[] = $_total;
+            }
+            foreach ($_data['list'] as $_key => $_val) {
+                $_export_data['create_time'] = date('Y-m-d H:i:s', $_val['create_time']);
+                $_export_data['id'] = $_val['id'];
+                $_export_data['agent_name'] = $_val['agent_name'];
+                $_export_data['amount'] = $_val['amount'];
+                $_export_data['cardholder'] = $_val['cardholder'];
+                $_export_datas[] = $_export_data;
+            }
+            if (1 == $_for_cnt) {
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name, '.csv', true);
+                break;
+            } else {
+                $_file_name = $_file_name.$_p;
+                Export::exportCsv($_head, $_export_datas, $path = $this->admin_id, $_file_name);
+                $_file_name_arr[] = $_file_name.'.csv';
+                $_p++;
+                if ($_p > 1) {
+                    $_data = null;
+                    $_page = $_p.','.$_offset;
+                    $_data = (new SettleLogic())->getSettleList(0, $_param, $_page);
+                }
+            }
+        }
+        Export::exportZip($_file_name_arr, $path = $this->admin_id, $_file_name);
+    }
+
+    /**
+     * 获取提现列表
+     *
+     * @param        $status
+     * @param    int $tag 标签
+     */
+    public function getSettleList($status, $tag = SettleConst::SETTLE_TAG_0) {
+        $_param['mem_id'] = $this->request->param('mem_id/d', '');
+        $mem_id_text = Filter::text('mem_id', $_param['mem_id'], '请输入玩家ID');
+        $this->assign('mem_id_text', $mem_id_text);
+        $_param['agent_id'] = $this->request->param('agent_id/d', '');
+        $agent_id_text = Filter::text('agent_id', $_param['agent_id'], '请输入玩家即渠道ID');
+        $this->assign('agent_id_text', $agent_id_text);
+        $_param['agent_nickname'] = $this->request->param('agent_nickname/s', '');
+        $_agent_name_text = Filter::text('agent_nickname', $_param['agent_nickname'], '请输入渠道昵称');
+        $this->assign('agent_name_text', $_agent_name_text);
+        $_param['start_time'] = $this->request->param('start_time', date('Y-m-d', strtotime('-3 month')));
+        $_param['end_time'] = $this->request->param('end_time', date('Y-m-d'));
+        $this->_time($_param['start_time'], $_param['end_time']);
+        $_param['type'] = SettleConst::SETTLE_TYPE_MP;  //只显示小程序提现
+        $_param['cardholder'] = $this->request->param('cardholder/s', '');
+        $_cardholder_text = Filter::text('cardholder', $_param['cardholder'], '请输入提现人');
+        $this->assign('cardholder_text', $_cardholder_text);
+        $_param['status'] = $status;
+        $_param['tag'] = $tag;
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 50);
+        $_data = (new SettleLogic())->getSettleList(0, $_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->getUnusualTag();
+        $this->assign('sum', $_data['sum']);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+    }
+
+    /**
+     * 提现运营审核
+     * admin/mp.financial.financial/opcheck
+     *
+     * @return mixed
+     */
+    public function opCheck() {
+        $_status = SettleConst::SETTLE_STATUS_OP_CHECK;
+        $this->getSettleList($_status, SettleConst::SETTLE_TAG_1);
+
+        return $this->fetch('box/financial/opcheck');
+    }
+
+    /**
+     * 提现财务审核
+     * admin/mp.financial.financial/finCheck
+     *
+     * @return mixed
+     */
+    public function finCheck() {
+        $_status = SettleConst::SETTLE_STATUS_FIN_CHECK;
+        $this->getSettleList($_status, SettleConst::SETTLE_TAG_1);
+
+        return $this->fetch('box/financial/fincheck');
+    }
+
+    /**
+     * 提现记录
+     * admin/mp.financial.financial/withdraw
+     */
+    public function withdraw() {
+        $_status = $this->request->param('status/d', SettleConst::SETTLE_STATUS_OK);
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportWithdraw($_status);
+        }
+        $this->_settle_status($_status);
+        $this->getSettleList($_status, SettleConst::SETTLE_TAG_1);
+
+        return $this->fetch('box/financial/withdraw');
+    }
+
+    /**
+     * 提现记录
+     * admin/mp.financial.financial/unusual
+     */
+    public function unusual() {
+        $_status = $this->request->param('status/d', 0);
+        if ('1' == $this->request->param('export/d', 0)) {
+            return $this->exportWithdraw(0);
+        }
+        $this->_settle_status($_status);
+        $this->getSettleList($_status, SettleConst::SETTLE_TAG_2);
+
+        return $this->fetch('box/financial/unusual');
+    }
+
+    /**
+     * 提现状态选择器
+     *
+     * @param int $status
+     *
+     * @return array
+     */
+    public function _settle_status($status) {
+        $_statuses = SettleConst::getStatuses();
+        $this->assign('statuses', $_statuses);
+        $_statuses_select = Filter::selectCommon($_statuses, 'status', $status);
+        $this->assign('statuses_select', $_statuses_select);
+
+        return $_statuses;
+    }
+
+    /**
+     * 审核详情
+     * admin/financial.agent/edit
+     */
+    public function edit() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = (new SettleLogic())->getDetail($_id);
+        $_pay_pwd_show = CommonConst::STATUS_YES;
+        if (SettleConst::SETTLE_STATUS_OP_CHECK == $_data['status']) {
+            $_pay_pwd_show = CommonConst::STATUS_NO;
+        }
+        $this->assign('pay_pwd_show', $_pay_pwd_show);
+        $this->assign('data', $_data);
+
+        return $this->fetch('box/financial/edit');
+    }
+
+    /**
+     * 提现详情
+     *
+     * @return mixed
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     */
+    public function detail() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = (new SettleLogic())->getDetail($_id);
+        $this->assign('data', $_data);
+        /*审核记录*/
+        $_map = ['s_id' => $_data['id']];
+        $_history = (new SettleHistoryLogic())->getList($_map);
+        $this->assign('history', $_history);
+        /* 数据报表 */
+        $_risk_analysis = new RiskAnalysis($_data['agent_id']);
+        $_analysis_report = $_risk_analysis->getReport();
+        $this->assign('analysis_report', $_analysis_report);
+
+        return $this->fetch('box/financial/detail');
+    }
+
+    /**
+     * 设置提现状态
+     * admin/mp.financial.financial/setstatus
+     */
+    public function setStatus() {
+        $_id = $this->request->param('id/d', 0);
+        $_status = $this->request->param('status/d', 0);
+        $_content = $this->request->param('content/s', '');
+        if (empty($_status)) {
+            $this->adminError('请审核');
+        }
+        if (empty($_id) || empty($_status) || $_status < CommonConst::STATUS_NO || $_status > CommonConst::STATUS_YES) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = (new SettleLogic())->getDetail($_id);
+        if (SettleConst::SETTLE_STATUS_FIN_CHECK == $_data['status']) {
+            $this->verifyPayPwd();
+        }
+        switch ($_data['status']) {
+            case SettleConst::SETTLE_STATUS_OP_CHECK:
+                if (CommonConst::STATUS_NO == $_status) {
+                    /* 运营审核不通过 */
+                    $_status = SettleConst::SETTLE_STATUS_OP_NO;
+                } elseif (CommonConst::STATUS_YES == $_status) {
+                    /* 运营审核通过 */
+                    $_status = SettleConst::SETTLE_STATUS_FIN_CHECK;
+                }
+                break;
+            case SettleConst::SETTLE_STATUS_FIN_CHECK:
+                if (CommonConst::STATUS_NO == $_status) {
+                    /* 财务审核不通过 */
+                    $_status = SettleConst::SETTLE_STATUS_FIN_NO;
+                } elseif (CommonConst::STATUS_YES == $_status) {
+                    /* 财务审核通过 */
+                    $_status = SettleConst::SETTLE_STATUS_OK;
+                }
+                break;
+            default:
+                $this->adminError(lang('param error'));
+        }
+        $_rs = (new Settle())->setStatus($this->admin_id, $_id, $_status, $_content);
+        if (CommonStatus::NO_ERROR != $_rs['code']) {
+            $this->adminError($_rs['msg']);
+        }
+        $this->adminSuccess('设置成功');
+    }
+
+    /**
+     * 提现打款记录
+     * admin/mp.financial.financial/settleLog
+     */
+    public function settleLog() {
+        $_param = $this->request->param();
+        $_agent_input = Filter::text('agent_name', get_val($_param, 'agent_name', ''), '请输入渠道昵称');
+        $this->assign('agent_input', $_agent_input);
+        $this->_time();
+        $_type_select = Filter::selectCommon(
+            SettleConst::getTypes(), 'type', get_val($_param, 'type', SettleConst::SETTLE_TYPE_MP)
+        );
+        $this->assign('type_select', $_type_select);
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 50);
+        $_data = (new SettleLogLogic())->getMemLogList($_param, $_page.','.$_list_rows);
+        $_page_data = \huolib\tool\Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('box/financial/settle_log');
+    }
+
+    /**
+     * 批量审核
+     * admin/mp.financial.financial/batchSetStatus
+     */
+    public function batchSetStatus() {
+        $_param = $this->request->param();
+        $_ids = get_val($_param, 'ids', '');
+        $_fincheck = get_val($_param, 'fincheck', 0);
+        $_ids = explode(',', $_ids);
+        if (empty($_ids)) {
+            $this->adminError('请至少选择一个来审核');
+        }
+        if (1 == $_fincheck && count($_ids) > SettleConst::SETTLE_BATCH_LIMIT_50) {
+            $this->adminError('单次批量审核最多50个');
+        }
+        $_status = $this->request->param('status/d', 0);
+        $_content = $this->request->param('content/s', '');
+        if (empty($_status)) {
+            $this->adminError('请选择审核状态');
+        }
+        if ($_status < CommonConst::STATUS_NO || $_status > CommonConst::STATUS_YES) {
+            $this->adminError(lang('param error'));
+        }
+        $this->verifyPayPwd();
+        foreach ($_ids as $_id) {
+            $_data = (new SettleLogic())->getDetail($_id);
+            if (empty($_data)) {
+                $this->adminError('请确认参数是否正确');
+            }
+            switch ($_data['status']) {
+                case SettleConst::SETTLE_STATUS_OP_CHECK:
+                    if (CommonConst::STATUS_NO == $_status) {
+                        if (empty($_content)) {
+                            $this->adminError('请输入审核不通过原因');
+                        }
+                        /* 运营审核不通过 */
+                        $_status = SettleConst::SETTLE_STATUS_OP_NO;
+                    } elseif (CommonConst::STATUS_YES == $_status) {
+                        /* 运营审核通过 */
+                        $_status = SettleConst::SETTLE_STATUS_FIN_CHECK;
+                    }
+                    break;
+                case SettleConst::SETTLE_STATUS_FIN_CHECK:
+                    if (CommonConst::STATUS_NO == $_status) {
+                        if (empty($_content)) {
+                            $this->adminError('请输入审核不通过原因');
+                        }
+                        /* 财务审核不通过 */
+                        $_status = SettleConst::SETTLE_STATUS_FIN_NO;
+                    } elseif (CommonConst::STATUS_YES == $_status) {
+                        /* 财务审核通过 */
+                        $_status = SettleConst::SETTLE_STATUS_OK;
+                    }
+                    break;
+                default:
+                    $this->adminError(lang('param error'));
+            }
+            $_rs = (new Settle())->setStatus($this->admin_id, $_id, $_status, $_content);
+            if (CommonStatus::NO_ERROR != $_rs['code']) {
+                $this->adminError($_rs['msg']);
+            }
+        }
+        $this->adminSuccess('批量审核成功');
+    }
+
+    /**
+     * 标记异常用户
+     */
+    public function setUnusualMem() {
+        $_agent_id = $this->request->param('agent_id/d', 0);
+        $_mem_id = $this->request->param('mem_id/d', 0);
+        $_type = $this->request->param('type/d', 1);
+        $_user_model = new UserModel();
+        if (empty($_agent_id) && !empty($_mem_id)) {
+            $_agent_id = $_user_model->getIdByMemId($_mem_id);
+        } elseif (!empty($_agent_id) && empty($_mem_id)) {
+            $_mem_id = $_user_model->getMemIdById($_agent_id);
+        } else {
+            $this->adminError('参数错误!');
+        }
+        $_um_model = new UnusualMemModel();
+        if (MemConst::UNUSUAL_MEN_TYPE_0 == $_type) {
+            //标记为正常用户删除标记
+            $_rs = $_um_model->deleteByAgentId($_agent_id);
+        } else {
+            $_um_data = $_um_model->getDataByAgentId($_agent_id);
+            $_data = [
+                'mem_id'   => $_mem_id,
+                'agent_id' => $_agent_id,
+                'type'     => $_type,
+                'u_id'     => $this->admin_id
+            ];
+            if (empty($_um_data)) {
+                $_rs = $_um_model->addData($_data);
+            } else {
+                $_rs = $_um_model->updateDataByAgentId($_data, $_data['agent_id']);
+            }
+        }
+        if (false == $_rs) {
+            $this->adminError('标记失败!');
+        }
+        if (MemConst::UNUSUAL_MEN_TYPE_3 == $_type) { //标记为冻结用户则冻结
+            if (!empty($_data['mem_id'])) {
+                $_mem_data['status'] = MemConst::STATUS_FORBID;
+                MemCache::ins()->updateMem($_data['mem_id'], $_mem_data);
+            }
+        }
+        $this->adminSuccess('标记成功!');
+    }
+
+    public function getUnusualTag($type = 0) {
+        $_data = [
+            MemConst::UNUSUAL_MEN_TYPE_0 => '正常用户',
+            MemConst::UNUSUAL_MEN_TYPE_1 => '未知用户',
+            MemConst::UNUSUAL_MEN_TYPE_2 => '刷子用户',
+            MemConst::UNUSUAL_MEN_TYPE_3 => '冻结用户',
+            MemConst::UNUSUAL_MEN_TYPE_4 => '重名用户',
+            MemConst::UNUSUAL_MEN_TYPE_5 => '不可提现用户',
+        ];
+        $_unusual_tag = Filter::radioCommon($_data, 'type', $type);
+        $this->assign('unusual_tag_radio', $_unusual_tag);
+        $this->assign('unusual_tag', $_data);
+    }
+
+    /**
+     * 设置订单标记
+     */
+    public function setTag() {
+        $_id = $this->request->param('id/d', 0);
+        $_tag = $this->request->param('tag/d', 1);
+        if (empty($_id)) {
+            $this->adminError('参数错误!');
+        }
+        $_data['tag'] = $_tag;
+        $_rs = (new SettleModel())->updateData($_data, $_id);
+        if (false == $_rs) {
+            $this->adminError('设置失败!');
+        }
+        $this->adminSuccess('设置成功!');
+    }
+}

+ 1195 - 0
admin/admin/controller/mp/game/GameController.php

@@ -0,0 +1,1195 @@
+<?php
+/**
+ * GameController.php  UTF-8
+ * 游戏管理
+ *
+ * @date    : 2018/8/14 11:44
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\mp\game;
+
+use admin\admin\controller\game\GameController as GameBase;
+use admin\admin\controller\slide\SlideitemController;
+use cmf\view\Filter;
+use huo\controller\game\CategoryCache;
+use huo\controller\game\GameCache;
+use huo\controller\game\GamePayShowCache;
+use huo\controller\game\GamePaySwitchCache;
+use huo\controller\member\MemCache;
+use huo\logic\game\ChannelLogic;
+use huo\logic\game\GameLogic;
+use huo\logic\game\GamePayShowLogic;
+use huo\logic\game\GamePaySwitchLogic;
+use huo\logic\game\GamePriceLogic;
+use huo\model\game\GamecategoryModel;
+use huo\model\game\GameextModel;
+use huo\model\game\GameOrderSwitchModel;
+use huo\model\game\GamePriceModel;
+use huo\model\game\GameServerSwitchModel;
+use huo\model\game\GameversionModel;
+use huo\model\game\PsMemWhiteModel;
+use huo\model\slide\SlideItemModel;
+use huo\model\slide\SlideModel;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\MpConfConst;
+use huolib\constant\OrderConst;
+use huolib\constant\SlideConst;
+use huolib\tool\Page;
+use huomp\model\game\GameMiniModel;
+use huomp\model\weixin\MpConfModel;
+use think\Lang;
+use think\Validate;
+
+class GameController extends GameBase {
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_pay_switch'.EXT);
+        $this->classify = $this->request->param('classify/d', GameConst::GAME_MP);
+        $this->sdk = $this->request->param('is_sdk/d', GameConst::GAME_IS_SDK);
+        $this->index_url = url('admin/mp.game.game/index');
+        if (GameConst::GAME_IS_NOT_SDK == $this->sdk) {
+            $this->index_url = url('admin/mp.game.game/cpsgame');
+        }
+        if (GameConst::GAME_MP_BOX == $this->classify || GameConst::GAME_MP_RPBOX == $this->classify) {
+            $this->index_url = url('admin/mp.game.game/minibox');
+        }
+        if (GameConst::GAME_MP_PERSONAL == $this->classify) {
+            $this->index_url = url('admin/mp.game.game/personal');
+        }
+        $this->assign('back_url', $this->request->server('HTTP_REFERER'));
+    }
+
+    /**
+     * 小游戏盒子
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function minibox() {
+        $this->classify = GameConst::GAME_MP_BOX;
+        $this->index_url = url('admin/mp.game.game/minibox');
+
+        return parent::index();
+    }
+
+    /**
+     * 个人小程序
+     * admin/mp.game.game/personal
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function personal() {
+        $this->classify = GameConst::GAME_MP_PERSONAL;
+        $this->index_url = url('admin/mp.game.game/personal');
+
+        return parent::index();
+    }
+
+    /**
+     * CPS游戏
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function cpsgame() {
+        $this->classify = GameConst::GAME_MP;
+        $this->sdk = GameConst::GAME_IS_NOT_SDK;
+        $this->index_url = url('admin/mp.game.game/cpsgame');
+
+        return parent::index();
+    }
+
+    /**
+     * 游戏地址
+     *
+     * @return mixed
+     */
+    public function gameurl() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = GameCache::ins()->getInfoByAppId($_app_id);
+        if (empty($_data['gv'][0])) {
+            $this->adminError('param error');
+        }
+        $_package_url = isset($_data['gv'][0]['package_url']) ? $_data['gv'][0]['package_url'] : '';
+        $this->assign($_data);
+        $this->assign('package_url', $_package_url);
+
+        return $this->fetch('game/h5game/game');
+    }
+
+    /**
+     * 游戏地址
+     *
+     * @return mixed
+     */
+    public function editPackageUrl() {
+        $classify = GameConst::GAME_H5;
+        parent::addPackageUrl($classify, true);
+
+        return;
+    }
+
+    /**
+     * 游戏盒子编辑
+     * admin/mp.game.game/edit
+     */
+    public function edit() {
+        parent::edit();
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_game_mini = (new GameMiniModel())->getDataByAppId($_app_id);
+        $this->assign($_game_mini);
+        $_need_popup_array = $this->_need_popup();
+        $_need_popup_radio = Filter::radioCommon($_need_popup_array, 'need_popup', $_game_mini['need_popup']);
+        $this->assign('need_popup_radio', $_need_popup_radio);
+        if (GameConst::GAME_MP_PERSONAL == $this->classify) {
+            return $this->fetch('box/game/personal_edit');
+        }
+
+        return $this->fetch('box/game/edit');
+    }
+
+    /**
+     * 编辑游戏处理函数
+     *
+     * @throws
+     */
+    public function editPost() {
+        if ($this->request->isPost()) {
+            $_validate = new Validate(
+                [
+                    'id'       => 'require|number|token',
+                    'name'     => 'require',
+                    'down_cnt' => 'number|max:100000000',
+                ]
+            );
+            $_param = $this->request->post();
+            $_param = $this->trimAll($_param);
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+            }
+            $_app_id = $this->request->post('id/d', 0);
+            $_down_cnt = $this->request->post('down_cnt/d', 0);
+            $_g_all = $this->getDetail($_app_id);
+            $_rise_cnt = $_down_cnt - $_g_all['ext']['down_cnt'];
+            $_game_data['hot_order'] = $_g_all['hot_order'] + $_rise_cnt;
+            $_game_data['rise_order'] = $_g_all['rise_order'] + $_rise_cnt;
+            $_game_data['id'] = $_app_id;
+            $_game_data['classify'] = $this->request->post('classify/d', $this->classify);
+            $_game_data['icon'] = $this->request->post('icon/s', '');
+            $_game_data['icon'] = str_replace(STATICSITE.'/upload/', '', $_game_data['icon']);
+            $_game_data['name'] = $this->request->post('name/s', '');
+            $_game_data['cp_id'] = $this->request->post('cp_id/d', 0);
+            $_game_data['publicity'] = $this->request->post('publicity/s', '');
+            $_game_data['description'] = $this->request->post('description/s', '');
+            $_game_data['single_tag'] = $this->request->post('single_tag/s', '');
+            $_ext_info['share_title'] = $this->request->post('share_title/s', '');
+            if (!empty($_param['share_imgs']) && !empty($_param['share_titles'])) {
+                $_ext_info['share_img'] = [];
+                foreach ($_param['share_imgs'] as $_key => $_url) {
+                    $_photo_url = cmf_asset_relative_url($_url);
+                    array_push(
+                        $_ext_info['share_img'], ["url" => $_photo_url, "title" => $_param['share_titles'][$_key]]
+                    );
+                }
+            }
+            $_ext_info['fine_image'] = $this->request->post('fine_image/s', '');
+            $_ext_info['find_image'] = $this->request->post('find_image/s', '');
+            $_ext_info['rp_image'] = $this->request->post('rp_image/s', '');
+            $_ext_info['kefu_img'] = $this->request->post('kefu_img/s', '');
+            $_ext_info['splash_image'] = $this->request->post('splash_image/s', '');
+            $_ext_info['share_rule_img'] = $this->request->post('share_rule_img/s', '');
+            $_ext_info['auto_help'] = $this->request->post('auto_help/s', '');
+            $_ext_info['ios_text'] = $this->request->post('ios_text/s', '');
+            $_ext_info['agent_id'] = $this->request->post('agent_id/d', 0);
+            $_ext_info['mini_card_title'] = $this->request->post('mini_card_title/s', '');
+            $_ext_info['mini_card_url'] = $this->request->post('mini_card_url/s', '');
+            $_ext_info['mini_card_picture'] = $this->request->post('mini_card_picture/s', '');
+            $_ext_info['mini_card_pay_picture'] = $this->request->post('mini_card_pay_picture/s', '');
+            if (GameConst::GAME_MP_PERSONAL == $this->classify) {
+                $_ext_info['game_mini_appid'] = $this->request->post('game_mini_appid/s', '');  //个人小程序跳小游戏appid
+                $_ext_info['game_mini_state'] = $this->request->post('game_mini_state/s', '');  //个人小程序跳小游戏渠道标识
+                $_ext_info['start_image'] = $this->request->post('start_image/s', '');  //个人小程序跳小游戏启动背景图
+            }
+            $_game_data['ext_info'] = $_ext_info;
+            $_mini_game_data = [];
+            $_mini_game_data['app_id'] = $_app_id;
+            $_mini_game_data['mini_app_id'] = $this->request->post('mini_app_id/s', '');
+            $_mini_game_data['mini_app_secret'] = $this->request->post('mini_app_secret/s', '');
+            $_mini_game_data['mini_mch_id'] = $this->request->post('mini_mch_id/s', '');
+            $_mini_game_data['mini_api_key'] = $this->request->post('mini_api_key/s', '');
+            $_mini_game_data['mini_pay_id'] = $this->request->post('mini_pay_id/s', '');
+            $_mini_game_data['mini_app_key'] = $this->request->post('mini_app_key/s', '');
+            $_mini_game_data['mini_sand_app_key'] = $this->request->post('mini_sand_app_key/s', '');
+            $_mini_game_data['mini_rate'] = $this->request->post('mini_rate/f', 0);
+            $_mini_game_data['need_popup'] = $this->request->post('need_popup/d', 1);
+            $_mini_game_data['entrance_image'] = $this->request->post('entrance_image/s', '');
+            $_category = $this->request->post('category/a');
+            if (is_array($_category)) {
+                $_game_data['category'] = implode(',', $_category);
+            }
+            $_tag = $this->request->post('tag/a');
+            if (is_array($_tag)) {
+                $_game_data['tags'] = implode(',', $_tag);
+            }
+            if (!empty($_param['photo_names']) && !empty($_param['photo_urls'])) {
+                $_game_data['image'] = [];
+                foreach ($_param['photo_urls'] as $_key => $_url) {
+                    $_photo_url = cmf_asset_relative_url($_url);
+                    array_push(
+                        $_game_data['image'], ["url" => $_photo_url, "name" => $_param['photo_names'][$_key]]
+                    );
+                }
+            }
+            $_rs = GameCache::ins()->updateGame($_app_id, $_game_data);
+            if (false !== $_rs) {
+                $_gm_mini_model = new GameMiniModel();
+                $_mini_data = $_gm_mini_model->getDataByMpAppId($_mini_game_data['mini_app_id']);
+                if (!empty($_mini_data) && $_mini_data['app_id'] != $_app_id) {
+                    $this->adminError('该小程序ID已存在');
+                } else {
+                    $_is_exist = $_gm_mini_model->getDataByAppId($_app_id);
+                    if ($_is_exist) {
+                        $_gm_mini_model->updateData($_mini_game_data, $_app_id);
+                    } else {
+                        $_gm_mini_model->addData($_mini_game_data);
+                    }
+                }
+                /* 小程序配置 */
+                $_mp_conf_data = [
+                    'mp_id'      => get_val($_mini_game_data, 'mini_app_id', ''),
+                    'app_secret' => get_val($_mini_game_data, 'mini_app_secret', ''),
+                    'wx_name'    => get_val($_game_data, 'name', ''),
+                ];
+                (new MpConfModel())->updateGameMpConf($_app_id, MpConfConst::MP_CONF_TYPE_6, $_mp_conf_data);
+                $_gv_data['package_url'] = $this->request->post('package_url/s', '');
+//                $_gv_data['size'] = $this->request->post('size/s', '');
+                $_gv_data['version'] = $this->request->post('version/s', '');
+                $_gv_map['id'] = $_g_all['gv'][0]['id'];
+                $_gv_model = new GameversionModel();
+                $_gv_model->save($_gv_data, $_gv_map);
+                $_ge_data['down_cnt'] = $_down_cnt;
+                GameextModel::update($_ge_data, ['app_id' => $_app_id]);
+                $_gc_model = new GamecategoryModel();
+                $_c_cache = new CategoryCache();
+                if (!empty($_category)) {
+                    /* 先获取原有的cat_id 数组 */
+                    $_cate_ids = $_gc_model->getCateIdsByAppId($_app_id);
+                    if (!empty($_cate_ids)) {
+                        /* 获取现有的类型 */
+                        $_cate_ids = $_c_cache->returnTypeArray(GameConst::CATEGORY_TYPE_CATE, $_cate_ids);
+                        $_intersect = array_intersect($_cate_ids, $_category);  //取交集
+                        $_cate_ids = array_diff($_cate_ids, $_intersect);  //取差集 删除
+                        $_category = array_diff($_category, $_intersect);  //取差集 新增
+                        if (!empty($_cate_ids)) {
+                            /* 删除差集 */
+                            $_gc_map['id'] = ['gt', 0];
+                            $_gc_map['app_id'] = $_app_id;
+                            $_gc_map['cate_id'] = ['in', $_cate_ids];
+                            $_gc_model->where($_gc_map)->delete();
+                        }
+                    }
+                    if (!empty($_category)) {
+                        $_gc_data = [];
+                        foreach ($_category as $_v) {
+                            $_gc_temp_data['app_id'] = $_app_id;
+                            $_gc_temp_data['cate_id'] = $_v;
+                            $_gc_data[] = $_gc_temp_data;
+                        }
+                        $_gc_model->insertAll($_gc_data);
+                    }
+                }
+                if (!empty($_tag)) {
+                    /* 先获取原有的cat_id 数组 */
+                    $_tag_ids = $_gc_model->getCateIdsByAppId($_app_id);
+                    if (!empty($_tag_ids)) {
+                        /* 获取现有的类型 */
+                        $_tag_ids = $_c_cache->returnTypeArray(GameConst::CATEGORY_TYPE_HOME_TAG, $_tag_ids);
+                        $_intersect = array_intersect($_tag_ids, $_tag);  //取交集
+                        $_tag_ids = array_diff($_tag_ids, $_intersect);  //取差集 删除
+                        $_tag = array_diff($_tag, $_intersect);  //取差集 新增
+                        if (!empty($_tag_ids)) {
+                            /* 删除差集 */
+                            $_gc_map['id'] = ['gt', 0];
+                            $_gc_map['app_id'] = $_app_id;
+                            $_gc_map['cate_id'] = ['in', $_tag_ids];
+                            $_gc_model->where($_gc_map)->delete();
+                        }
+                    }
+                    if (!empty($_tag)) {
+                        $_gc_data = [];
+                        foreach ($_tag as $_v) {
+                            $_gc_temp_data['app_id'] = $_app_id;
+                            $_gc_temp_data['cate_id'] = $_v;
+                            $_gc_data[] = $_gc_temp_data;
+                        }
+                        $_gc_model->insertAll($_gc_data);
+                    }
+                }
+                $this->adminSuccess(lang('SUCCESS'), $this->index_url);
+            } else {
+                $this->adminError("ERROR");
+            }
+        } else {
+            $this->adminError("param error");
+        }
+    }
+
+    /**
+     *排序处理
+     */
+    public function listOrder() {
+        $ids = $this->request->post("list_orders/a");
+        if (!empty($ids)) {
+            foreach ($ids as $key => $r) {
+                $data['id'] = $key;
+                $data['list_order'] = $r;
+                GameCache::ins()->updateGame($key, $data);
+            }
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 删除游戏列表
+     *
+     * @return mixed
+     * @throws \think\exception\DbException
+     */
+    public function deleteIndex() {
+        $this->delete_index_url = url('admin/Game.h5game/deleteIndex');
+
+        return parent::deleteIndex();
+    }
+
+    /**
+     * 添加CP
+     */
+    public function cpsAdd() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $this->assign('app_id', $_app_id);
+
+        return $this->fetch('box/game/cps_add');
+    }
+
+    public function cpsAddPost() {
+        if ($this->request->isPost()) {
+            $_param = $this->request->param();
+            $_app_id = $_param['app_id'];
+            $result = $this->validate($_param, 'Channel.add');  //add场景验证
+            if (true !== $result) {
+                $this->adminError($result);
+            }
+            $_param['is_delete'] = CommonConst::CONST_NOT_DELETE;
+            $_param['create_time'] = time();
+            $_rs = (new ChannelLogic())->addChannel($_param, true);
+            if ($_rs) {
+                $_gc_class = GameCache::ins();
+                $_game_data = $_gc_class->getInfoByAppId($_app_id);
+                $_game_data['cp_id'] = $_rs;
+                $_rs = $_gc_class->updateGame($_app_id, $_game_data);
+            }
+        } else {
+            $_rs = false;
+        }
+        if ($_rs) {
+            $this->adminSuccess(lang('ADD_SUCCESS'), $this->index_url);
+        } else {
+            $this->adminSuccess(lang('ADD_FAILED'));
+        }
+    }
+
+    /**
+     * 编辑CP处理
+     *
+     * @return mixed
+     */
+    public function cps() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $_cp_name_select = Filter::selectCommon((new ChannelLogic())->getNamesById(), 'cp_id', $_data['cp_id']);
+        $this->assign('cp_name_select', $_cp_name_select);
+        $this->assign($_data);
+
+        return $this->fetch('box/game/cps');
+    }
+
+    /**
+     * app_id
+     * 编辑CP提交
+     */
+    public function cpsPost() {
+        $_validate = new Validate(
+            [
+                'app_id' => 'require|number|token',
+                'cp_id'  => 'require',
+            ]
+        );
+        $_param = $this->request->param();
+        if (!$_validate->check($_param)) {
+            $this->adminError($_validate->getError(), $this->request->server('HTTP_REFERER'));
+        }
+        $_app_id = $_param['app_id'];
+        $_gc_class = GameCache::ins();
+        $_game_data = $_gc_class->getInfoByAppId($_app_id);
+        $_game_data['cp_id'] = $_param['cp_id'];
+        $_rs = $_gc_class->updateGame($_app_id, $_game_data);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'), $this->request->server('HTTP_REFERER'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+
+    /***
+     * 编辑切换规则
+     * mp.game.game/payswitch
+     */
+    public function paySwitch() {
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_pay_switch'.EXT);
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_classify = $this->request->param('classify/d', GameConst::GAME_MP);
+        $this->_games($_app_id, 0, 2, 2, $_classify, false, true, [], '', 'disabled');
+        if (empty($_app_id)) {
+            $this->adminError(lang('param_error'));
+        }
+        $_data = GamePaySwitchCache::ins()->getInfoByAppId($_app_id);
+        $_system = ['and' => 1, 'ios' => 1];
+        if (empty($_data)) {
+            $_data['start_time'] = '00:00:00';
+            $_data['end_time'] = '23:59:59';
+            $_data['price'] = 0.00;
+            $_data['is_domestic'] = OrderConst::PAY_SWITCH_YES;
+            $_data['is_overseas'] = OrderConst::PAY_SWITCH_YES;
+            $_data['is_first'] = OrderConst::PAY_SWITCH_YES;
+            $_data['pay_type'] = OrderConst::PAY_SWITCH_PAY_TYPE_1;
+            $_data['switch_app_id'] = 0;
+            $_data['start_ip'] = '';
+            $_data['end_ip'] = '';
+            $_data['no_switch_version'] = '';
+            $_data['combat_num_mini'] = 0;
+            $_data['combat_num_max'] = 0;
+            $_data['ip_white'] = '';
+            $_data['area'] = '';
+            $_data['mem_id'] = '';
+        } else {
+            $_tmp_system = explode(',', $_data['system']);
+            if (!empty($_tmp_system)) {
+                if (in_array(GameConst::GAME_ANDROID, $_tmp_system)) {
+                    $_system['and'] = 2;
+                }
+                if (in_array(GameConst::GAME_IOS, $_tmp_system)) {
+                    $_system['ios'] = 2;
+                }
+            }
+        }
+        $this->assign('system', $_system);
+        $this->assign('data', $_data);
+        $this->assign('app_id', $_app_id);
+        $_mp_map['classify'] = ['in', [GameConst::GAME_MP_RPBOX, GameConst::GAME_MP_BOX]];
+        $_mps = (new GameLogic())->getIdNames($_mp_map);
+        $_mps_select = Filter::selectCommon($_mps, 'switch_app_id', $_data['switch_app_id'], 'select_2');
+        $this->assign('mps_select', $_mps_select);
+        $_pages = !empty($_data['pages']) ? $_data['pages'] : 'pages/pay/index';
+        $this->assign('pages', $_pages);
+
+        return $this->fetch('box/game/pay_switch');
+    }
+
+    /**
+     * 编辑切换规则提交
+     * mp.game.game/payswitchpost
+     *
+     * @throws
+     */
+    public function paySwitchPost() {
+        $_params = $this->request->param();
+        $_params['is_domestic'] = isset($_params['is_domestic']) ? $_params['is_domestic'] : 2;
+        $_params['is_overseas'] = isset($_params['is_overseas']) ? $_params['is_overseas'] : 2;
+        $_params['is_first'] = isset($_params['is_first']) ? $_params['is_first'] : 1;
+        $_params['system'] = isset($_params['system']) ? $_params['system'] : [3, 4];
+        $_params['system'] = implode(',', $_params['system']);
+        $_model = new GamePaySwitchLogic();
+        if (empty($_params['app_id'])) {
+            $this->adminError(lang('please select a game'));
+        }
+        if (!$_model->checkGame($_params['app_id'])) {
+            $_result = $_model->addPaySwitch($_params);
+            if (false == $_result) {
+                $this->adminError(lang('add').lang('failure'));
+            }
+            $this->adminSuccess(lang('add').lang('success'), url('admin/mp.game.game/index'));
+        }
+        $_result = GamePaySwitchCache::ins()->updatePaySwitch($_params['app_id'], $_params);
+        if (false == $_result) {
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/mp.game.game/index'));
+    }
+
+    /**
+     * 点击切换不切换
+     * mp.game.game/payswitchpost
+     * */
+    public function setSwitch() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_pay_switch = $this->request->param('pay_switch/d', 1);
+        if (empty($_app_id) || empty($_pay_switch)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data['pay_switch'] = $_pay_switch;
+        $_data['id'] = $_app_id;
+        $_rs = GameCache::ins()->updateGame($_app_id, $_data);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+
+    /**
+     * 编辑区服切换
+     * mp.game.game/setSeverSwitch
+     */
+    public function setSeverSwitch() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError('参数错误!');
+        }
+        $_game_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $this->assign('game', $_game_data);
+        $_gss_model = new GameServerSwitchModel();
+        $_ser_array = $_gss_model->getIdName($_app_id);  //获取区服id_name(id 为自增id 非区服id)
+        $_ids = $_gss_model->getSwitchNo($_app_id);  //获取切换标记为  不切换的id
+        $_check_box = Filter::checkCommon($_ser_array, 'switch_no[]', $_ids);
+        $this->assign('check_box', $_check_box);
+
+        return $this->fetch('box/game/sever_switch');
+    }
+
+    /**
+     * 编辑区服切换提交
+     * mp.game.game/setSeverSwitch
+     */
+    public function severSwitchPost() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_ids = $this->request->param('switch_no/a', []);  //新的不需要切换ids
+        $_gss_model = new GameServerSwitchModel();
+        $_old_ids = $_gss_model->getSwitchNo($_app_id);  //获取原不需要切换ids
+        /* 在新数组但不在旧数组的表示新增的,需要标记为不切换 */
+        $_no_ids = array_diff($_ids, $_old_ids);
+        if (!empty($_no_ids)) {
+            $_data = ['is_switch' => OrderConst::PAY_SWITCH_NO];
+            foreach ($_no_ids as $_v) {
+                $_gss_model->updateById($_v, $_data);
+            }
+        }
+        /* 在旧数组但不在新数组的表示为切换*/
+        $_yes_ids = array_diff($_old_ids, $_ids);
+        if (!empty($_yes_ids)) {
+            $_data = ['is_switch' => OrderConst::PAY_SWITCH_YES];
+            foreach ($_yes_ids as $_v) {
+                $_gss_model->updateById($_v, $_data);
+            }
+        }
+        $this->adminSuccess('更新成功!');
+    }
+
+    /**
+     * 支付切换玩家白名单
+     * mp.game.game/memWhite
+     */
+    public function memWhite() {
+        $_param = $this->request->param();
+        $_mem_text = Filter::text('mem_id', get_val($_param, 'mem_id', ''), '请输入玩家ID');
+        $this->assign('mem_text', $_mem_text);
+        $_username_text = Filter::text('username', get_val($_param, 'username', ''), '请输入玩家账号');
+        $this->assign('username_text', $_username_text);
+        $_nickname_text = Filter::text('nickname', get_val($_param, 'nickname', ''), '请输入玩家昵称');
+        $this->assign('nickname_text', $_nickname_text);
+        $this->_time();
+        if (empty($_param['app_id'])) {
+            $this->adminError('游戏ID错误!');
+        }
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 10);
+        $_data = (new PsMemWhiteModel())->getlist($_param, $_page.','.$_list_rows);
+        $_data = (new Page())->paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('page', $_data->render());
+        $this->assign('items', $_data->items());
+        /*搜索按钮*/
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $this->assign('filter_button', $_filter_button);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear',
+             'uri'   => url('mp.game.game/memWhite', ['app_id' => $_param['app_id']])]
+        );
+        $this->assign('filter_button_clear', $_filter_button_clear);
+        $this->assign('app_id', $_param['app_id']);
+
+        return $this->fetch('box/game/mem_white');
+    }
+
+    /**
+     * 添加玩家支付白名单
+     * mp.game.game/addMemWhite
+     */
+    public function addMemWhite() {
+        $_mem_id = $this->request->param('mem_id/d', 0);
+        if (empty($_mem_id)) {
+            $this->adminError('请输入玩家ID!');
+        }
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError('游戏ID错误!');
+        }
+        $_mem_data = MemCache::ins()->getInfoById($_mem_id);
+        if (empty($_mem_data)) {
+            $this->adminError('玩家ID有误!');
+        }
+        $_data = [];
+        $_data['app_id'] = $_app_id;
+        $_data['mem_id'] = $_mem_id;
+        $_data['username'] = get_val($_mem_data, 'username', '');
+        $_data['nickname'] = get_val($_mem_data, 'nickname', '');
+        $_rs = (new PsMemWhiteModel())->addData($_data);
+        if (false == $_rs) {
+            $this->adminError('添加失败!');
+        }
+        $this->adminSuccess('添加成功!');
+    }
+
+    /**
+     * 删除玩家白名单
+     *  mp.game.game/delMemWhite
+     */
+    public function delMemWhite() {
+        $_mem_id = $this->request->param('mem_id/d', 0);
+        if (empty($_mem_id)) {
+            $this->adminError('请输入玩家ID!');
+        }
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError('游戏ID错误!');
+        }
+        $_rs = (new PsMemWhiteModel())->delData($_app_id, $_mem_id);
+        if (false == $_rs) {
+            $this->adminError('删除失败!');
+        }
+        $this->adminSuccess('删除成功!');
+    }
+
+    /**
+     * 盒子闪屏图
+     * admin/mp.game.game/slide
+     */
+    public function slide() {
+        $_box_id = $this->request->param('box_id/d', 0);
+        if (empty($_box_id)) {
+            $this->adminError('缺少参数盒子ID');
+        }
+        $_code = SlideConst::SLIDE_MP_SPLASH_IMAGE.$_box_id;
+        $_slide_id = (new SlideModel())->getSlideIdByCode($_code);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_map = [];
+        $_map['slide_id'] = $_slide_id;
+        $_slide_items = (new SlideItemModel())->getList($_map, $_page.','.$_list_rows);
+        $_slide_items = (new Page())->paginate($_slide_items['count'], $_slide_items['list'], $_page, $_list_rows);
+        $this->_games(0, 0, 0, 0, GameConst::GAME_MP);
+        $this->assign('page', $_slide_items->render());
+        $this->assign('slide_items', $_slide_items->items());
+        $this->assign('slide_id', $_slide_id);
+        $this->assign('box_id', $_box_id);
+
+        return $this->fetch('box/game/slide/index');
+    }
+
+    /**
+     * 添加盒子闪屏图
+     * admin/mp.game.game/slide
+     */
+    public function slideAdd() {
+        $_param = $this->request->param();
+        $_param['type'] = SlideConst::SLIDE_TYPE_ONE_IMG;
+        $this->assign($_param);
+        $this->_games(0, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0, [GameConst::GAME_MP]);
+
+        return $this->fetch('box/game/slide/add');
+    }
+
+    /**
+     * 添加盒子闪屏图
+     * admin/mp.game.game/slideAddPost
+     */
+    public function slideAddPost() {
+        $_param = $this->request->param();
+        $_insert_data = [
+            'slide_id'    => $_param['slide_id'],
+            'title'       => $_param['title'],
+            'table_name'  => 'game',
+            'target_id'   => isset($_param['target_id']) ? $_param['target_id'] : 0,
+            'image'       => isset($_param['image']) ? $_param['image'] : '',
+            'description' => $_param['description']
+        ];
+        $_slide_item_model = new SlideItemModel();
+        $result = $_slide_item_model->save($_insert_data);
+        if (false === $result) {
+            $this->adminError($_slide_item_model->getError());
+        }
+        if (!empty($_param['slide_id'])) {
+            $_slide_item_model->ClCacheBySlideId($_param['slide_id']);
+        }
+        $this->adminSuccess(
+            lang('EDIT').' '.lang('SUCCESS'), url('admin/mp.game.game/slide', ['box_id' => $_param['box_id']])
+        );
+    }
+
+    /**
+     * 添加盒子闪屏图
+     * admin/mp.game.game/slideEdit
+     */
+    public function slideEdit() {
+        $_slide_item_id = $this->request->param('id/d', 0);
+        $_box_id = $this->request->param('box_id/d', 0);
+        if (empty($_slide_item_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_slide_ctrl = new SlideitemController();
+        $_slide_item = $_slide_ctrl->findSlideItemModel($_slide_item_id);
+        $this->assign('slide_item', $_slide_item);
+        $this->assign('box_id', $_box_id);
+        $this->_games(
+            $_slide_item->target_id, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0, GameConst::GAME_MP
+        );
+
+        return $this->fetch('box/game/slide/edit');
+    }
+
+    /**
+     * 添加盒子闪屏图
+     * admin/mp.game.game/slideEditPost
+     */
+    public function slideEditPost() {
+        $_param = $this->request->param();
+        $_slide_ctrl = new SlideitemController();
+        $_update_data = [
+            'title'       => $_param['title'],
+            'table_name'  => 'game',
+            'target_id'   => isset($_param['target_id']) ? $_param['target_id'] : 0,
+            'image'       => isset($_param['image']) ? cmf_asset_relative_url($_param['image']) : '',
+            'description' => $_param['description']
+        ];
+        $_slide_item = $_slide_ctrl->findSlideItemModel($_param['id']);
+        if (false === $_slide_item->save($_update_data)) {
+            $this->adminError($_slide_item->getError());
+        }
+        if (!empty($_param['slide_id'])) {
+            (new SlideItemModel())->ClCacheBySlideId($_param['slide_id']);
+        }
+        $this->adminSuccess(
+            lang('EDIT').' '.lang('SUCCESS'), url('admin/mp.game.game/slide', ['box_id' => $_param['box_id']])
+        );
+    }
+
+    /**
+     * 计费点设置列表
+     * admin/mp.game.game/gamePrice
+     */
+    public function gamePrice() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_product_code = $this->request->param('product_code/s', '');
+        $_code_text = Filter::text('product_code', $_product_code, '请输入商品ID');
+        $this->assign('code_text', $_code_text);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        if (empty($_app_id)) {
+            $this->adminError('缺少参数:app_id');
+        }
+        $_game_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $_this_title = [$_game_data['name']];
+        $this->assign('this_title', json_encode($_this_title));
+        $_map = ['app_id' => $_app_id, 'product_code' => $_product_code];
+        $_data = (new GamePriceLogic())->getList($_map, $_page.','.$_list_rows);
+        $_items = (new Page())->paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('page', $_items->render());
+        $this->assign('items', $_data['list']);
+        $this->assign('app_id', $_app_id);
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $this->assign('filter_button', $_filter_button);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear',
+             'uri'   => url(
+                 'admin/mp.game.game/gamePrice', ['app_id' => $_app_id]
+             )]
+        );
+        $this->assign('filter_button_clear', $_filter_button_clear);
+
+        return $this->fetch('box/game/price/game_price');
+    }
+
+    /**
+     * 计费点添加
+     * admin/mp.game.game/priceAdd
+     */
+    public function priceAdd() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $this->assign('app_id', $_app_id);
+
+        return $this->fetch('box/game/price/price_add');
+    }
+
+    public function priceAddPost() {
+        $_param = $this->request->param();
+        if (empty($_param['app_id']) || empty($_param['product_code']) || empty($_param['product_price'])) {
+            $this->adminError('参数错误!');
+        }
+        $_data = [];
+        $_time = time();
+        $_gp_model = new GamePriceModel();
+        foreach ($_param['product_code'] as $_k => $_V) {
+            /* 检查重复,app_id 和 product_code 相同时更新 */
+            $_map = [
+                'app_id'       => $_param['app_id'],
+                'product_code' => $_V
+            ];
+            $_rs = (new GamePriceLogic())->getId($_map);
+            if (!empty($_rs)) {
+                $_gp_data = ['product_price' => $_param['product_price'][$_k]];
+                $_gp_model->updateData($_rs, $_gp_data);
+                continue;
+            }
+            $_data[] = [
+                'app_id'        => $_param['app_id'],
+                'product_code'  => $_V,
+                'product_price' => $_param['product_price'][$_k],
+                'create_time'   => $_time,
+                'update_time'   => $_time,
+            ];
+        }
+        $_rs = $_gp_model->addData($_data);
+        if (false == $_rs) {
+            $this->adminError('添加失败!');
+        }
+        $this->adminSuccess('添加成功!');
+    }
+
+    /**
+     * 计费点编辑
+     * admin/game.iosGame/priceEdit
+     */
+    public function priceEdit() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError('缺少参数ID!');
+        }
+        $_data = (new GamePriceModel())->getInfoById($_id);
+        if (false == $_data) {
+            $this->adminError('系统错误!');
+        }
+        $this->assign($_data);
+
+        return $this->fetch('box/game/price/price_edit');
+    }
+
+    public function priceEditPost() {
+        $_param = $this->request->param();
+        if (empty($_param['id'])) {
+            $this->adminError('缺少参数ID!');
+        }
+        $_param['update_time'] = time();
+        $_rs = (new GamePriceModel())->updateData($_param['id'], $_param);
+        if (false == $_rs) {
+            $this->adminError('修改失败!');
+        }
+        $this->adminSuccess('修改成功!');
+    }
+
+    /**
+     * 计费点删除
+     * admin/game.iosGame/priceDelete
+     */
+    public function priceDelete() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError('缺少参数ID!');
+        }
+        $_rs = (new GamePriceModel())->deleteData($_id);
+        if (false == $_rs) {
+            $this->adminError('删除失败!');
+        }
+        $this->adminSuccess('删除成功!');
+    }
+
+    /**
+     * 点击显示不显示
+     * mp.game.game/payswitchpost
+     * */
+    public function setShow() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_pay_show = $this->request->param('pay_show/d', 2);
+        if (empty($_app_id) || empty($_pay_show)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data['pay_show'] = $_pay_show;
+        $_data['id'] = $_app_id;
+        $_rs = GameCache::ins()->updateGame($_app_id, $_data);
+        if (false === $_rs) {
+            $this->adminError(lang('ERROR'));
+        } else {
+            $this->adminSuccess(lang('SUCCESS'));
+        }
+    }
+
+    /***
+     * 编辑切换规则
+     * mp.game.game/payshow
+     */
+    public function payShow() {
+        Lang::load(APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_pay_show'.EXT);
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_classify = $this->request->param('classify/d', GameConst::GAME_MP);
+        $this->_games($_app_id, 0, 2, 2, $_classify, false, true, [], '', 'disabled');
+        if (empty($_app_id)) {
+            $this->adminError(lang('param_error'));
+        }
+        $_data = GamePayShowCache::ins()->getInfoByAppId($_app_id);
+        $_system = ['and' => 2, 'ios' => 2];
+        if (empty($_data)) {
+            $_data['start_time'] = '00:00:00';
+            $_data['end_time'] = '00:00:00';
+            $_data['price'] = 0.00;
+            $_data['is_domestic'] = CommonConst::STATUS_YES;
+            $_data['is_overseas'] = CommonConst::STATUS_YES;
+            $_data['start_ip'] = '';
+            $_data['end_ip'] = '';
+            $_data['no_show_version'] = '';
+            $_data['combat_num_mini'] = 0;
+            $_data['combat_num_max'] = 0;
+            $_data['level_mini'] = 0;
+            $_data['level_max'] = 0;
+            $_data['login_day_mini'] = 0;
+            $_data['login_day_max'] = 0;
+            $_data['ip_black'] = '';
+            $_data['area'] = '';
+            $_data['mem_id'] = '';
+        } else {
+            $_tmp_system = explode(',', $_data['system']);
+            if (!empty($_tmp_system)) {
+                if (in_array(GameConst::GAME_ANDROID, $_tmp_system)) {
+                    $_system['and'] = 2;
+                }
+                if (in_array(GameConst::GAME_IOS, $_tmp_system)) {
+                    $_system['ios'] = 2;
+                }
+            }
+        }
+        $this->assign('system', $_system);
+        $this->assign('data', $_data);
+        $this->assign('app_id', $_app_id);
+
+        return $this->fetch('box/game/pay_show');
+    }
+
+    /**
+     * 编辑切换规则提交
+     * mp.game.game/payshowpost
+     *
+     * @throws
+     */
+    public function payShowPost() {
+        $_params = $this->request->param();
+        $_params['is_domestic'] = isset($_params['is_domestic']) ? $_params['is_domestic'] : 2;
+        $_params['is_overseas'] = isset($_params['is_overseas']) ? $_params['is_overseas'] : 2;
+        $_params['system'] = isset($_params['system']) ? $_params['system'] : [3, 4];
+        $_params['system'] = implode(',', $_params['system']);
+        $_model = new GamePayShowLogic();
+        if (empty($_params['app_id'])) {
+            $this->adminError(lang('please select a game'));
+        }
+        if (!$_model->checkGame($_params['app_id'])) {
+            $_result = $_model->addPayShow($_params);
+            if (false == $_result) {
+                $this->adminError(lang('add').lang('failure'));
+            }
+            $this->adminSuccess(lang('add').lang('success'), url('admin/mp.game.game/index'));
+        }
+        $_result = GamePayShowCache::ins()->updatePayShow($_params['app_id'], $_params);
+        if (false == $_result) {
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/mp.game.game/index'));
+    }
+
+    /**
+     * 设置订单切量开关
+     * mp.game.game/setorderSwitch
+     * */
+    public function setOrderSwitch() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_order_switch = $this->request->param('order_switch/d', 1);
+        if (empty($_app_id) || empty($_order_switch)) {
+            $this->adminError(lang('param error'));
+        }
+        $_data['order_switch'] = $_order_switch;
+        $_data['id'] = $_app_id;
+        $_rs = GameCache::ins()->updateGame($_app_id, $_data);
+        if (false === $_rs) {
+            $this->adminError('关闭成功');
+        } else {
+            $this->adminSuccess('开启成功,请进一步设置规则');
+        }
+    }
+
+    /***
+     * 编辑游戏订单切量条件
+     * mp.game.game/orderswitch
+     */
+    public function orderSwitch() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $_classify = $this->request->param('classify/d', GameConst::GAME_MP);
+        $this->_games($_app_id, 0, 2, 2, $_classify, false, true, [], '', 'disabled');
+        if (empty($_app_id)) {
+            $this->adminError(lang('param_error'));
+        }
+        $_data = (new GameOrderSwitchModel())->parentGetInfoById($_app_id);
+        if (empty($_data)) {
+            $_data['start_time'] = '00:00:00';
+            $_data['end_time'] = '23:59:59';
+            $_data['price'] = 0.00;
+            $_data['agent_white'] = '';
+        }
+        $this->assign('data', $_data);
+        $this->assign('app_id', $_app_id);
+
+        return $this->fetch('box/game/order_switch');
+    }
+
+    /**
+     * 编辑游戏订单切量条件提交
+     * mp.game.game/orderswitchpost
+     *
+     * @throws
+     */
+    public function orderSwitchPost() {
+        $_params = $this->request->param();
+        $_app_id = get_val($_params, 'app_id');
+        $_price = get_val($_params, 'price');
+        $_agent_white = get_val($_params, 'agent_white');
+        if ($_price < 0) {
+            $this->adminError('最低切量金额必须大于0');
+        }
+        $_data = [
+            'start_time'  => $_params['start_time'],
+            'end_time'    => $_params['end_time'],
+            'price'       => $_price,
+            'agent_white' => $_agent_white,
+        ];
+        $_game_order_switch_model = new GameOrderSwitchModel();
+        $_info = $_game_order_switch_model->getInfoById($_app_id);
+        if (!empty($_info)) {
+            $_data = array_merge($_info, $_data);
+            $_game_order_switch_model->updateData($_data, $_app_id);
+        } else {
+            $_data['app_id'] = $_app_id;
+            $_game_order_switch_model->addData($_data);
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/mp.game.game/index'));
+    }
+
+    /**
+     * 关联游戏
+     * admin/game.game/linkGame
+     */
+    public function linkGame() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        if (empty($_app_id)) {
+            $this->adminError('参数错误');
+        }
+        $_game_data = GameCache::ins()->getInfoByAppId($_app_id);
+        $this->_games($_game_data['apple_id'], 0, CommonConst::CONST_NOT_DELETE, 0, GameConst::GAME_MP);
+        $this->assign($_game_data);
+
+        return $this->fetch('box/game/link_game');
+    }
+
+    /**
+     * 设置关联游戏
+     * admin/game.game/linkGamePost
+     */
+    public function linkGamePost() {
+        $_param = $this->request->param();
+        $_game_data = [
+            'apple_id' => $_param['app_id'],
+        ];
+        /* cp回调地址、渠道链接、扩展字段跟随关联游戏 */
+        $_original_game_info = GameCache::ins()->getInfoByAppId($_param['app_id']);
+        if (!empty($_original_game_info)) {
+            $_game_data['cp_payback_url'] = $_original_game_info['cp_payback_url'];
+            $_game_data['ext_info'] = [
+                'share_title' => isset($_original_game_info['ext_info']['share_title'])
+                    ? $_original_game_info['ext_info']['share_title'] : '',
+                'share_img'   => isset($_original_game_info['ext_info']['share_img'])
+                    ? $_original_game_info['ext_info']['share_img'] : '',
+            ];
+            $_game_data['status'] = GameConst::GAME_STATUS_ON;//设置为上线
+            $_game_data['pay_switch'] = $_original_game_info['pay_switch'];//跟随关联游戏
+            /* 支付切换规则 */
+            $_pay_switch = [
+                'app_id'   => $_param['id'],
+                'system'   => GameConst::GAME_ANDROID.','.GameConst::GAME_IOS,
+                'ip_white' => '',
+                'area'     => '',
+                'mem_id'   => '',
+            ];
+            $_model = new GamePaySwitchLogic();
+            $_original_game_pay_switch = $_model->getInfoByAppId($_param['app_id']);
+            if (!empty($_original_game_pay_switch)) {
+                $_pay_switch['switch_app_id'] = $_original_game_pay_switch['switch_app_id'];
+            }
+            if (!$_model->checkGame($_pay_switch['app_id'])) {
+                $_result = $_model->addPaySwitch($_pay_switch);
+                if (false == $_result) {
+                    $this->adminError('关联失败1');
+                }
+            }
+            GamePaySwitchCache::ins()->updatePaySwitch($_pay_switch['app_id'], $_pay_switch);
+            /* 版本信息 */
+            $_game_info = GameCache::ins()->getInfoByAppId($_param['id']);
+            $_gv_model = new GameversionModel();
+            $_map['id'] = $_game_info['gv'][0]['id'];
+            $_gv_data['package_url'] = $_original_game_info['gv'][0]['package_url'];
+            $_gv_model->save($_gv_data, $_map);
+        }
+        $_rs = GameCache::ins()->updateGame($_param['id'], $_game_data);
+        if (false == $_rs) {
+            $this->adminError('关联失败');
+        }
+        $this->adminSuccess('关联成功');
+    }
+
+    public function linkGameH5() {
+        $this->classify = GameConst::GAME_MP;
+        parent::linkGame();
+
+        return $this->fetch('box/game/link_game_h5');
+    }
+
+    public function linkGameH5Post() {
+        return parent::linkGamePost();
+    }
+}

+ 589 - 0
admin/admin/controller/mp/game/HomeTagController.php

@@ -0,0 +1,589 @@
+<?php
+/**
+ * HomeTagController.php UTF-8
+ * 首页标记管理
+ *
+ * @date    : 2017/11/18 10:48
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HuoMP 1.0
+ */
+
+namespace admin\admin\controller\mp\game;
+
+use admin\admin\controller\slide\SlideitemController;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\rate\Rate;
+use huo\logic\game\GameLogic;
+use huo\model\game\CategoryModel;
+use huo\model\game\GamecategoryModel;
+use huo\model\slide\SlideItemModel;
+use huo\model\slide\SlideModel;
+use huolib\constant\CacheConst;
+use huolib\constant\CategoryConst;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\SlideConst;
+use huolib\tool\Page;
+use huomp\logic\game\GameHomeTagLogic;
+use think\Cache;
+use think\Lang;
+use think\Validate;
+
+class HomeTagController extends AdminbaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(
+            [
+                APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'game_category'.EXT,
+                APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'wx'.EXT,
+            ]
+        );
+        parent::_initialize();
+    }
+
+    /**
+     * 获取不存在标签的游戏
+     *
+     * @param        $_cate_id
+     * @param int    $app_id
+     *
+     * @param string $disable
+     *
+     * @return array
+     */
+    protected function _getGames($_cate_id, $app_id = 0, $disable = '') {
+        /* 获取已绑定该公众号的游戏 */
+        $_app_ids = (new GamecategoryModel())->getAppIdsByCateId($_cate_id);
+        $_map = [
+            'id'        => ['not in', $_app_ids],
+            'is_delete' => CommonConst::CONST_NOT_DELETE,
+            'add_plat'  => true,
+            'classify'  => GameConst::GAME_MP
+        ];
+        $_games = (new GameLogic())->getIdNames($_map);
+        $this->assign('games', $_games);
+        $_games_select = Filter::selectCommon($_games, 'app_id', $app_id, 'select_2', $disable);
+        $this->assign('games_select', $_games_select);
+
+        return $_games;
+    }
+
+    /**
+     * 标签列表
+     */
+    public function index() {
+        $_type = CategoryConst::CATE_TYPE_HOME_4;
+        $_field = ['id', 'name', 'image', 'status', 'list_order', 'game_cnt', 'item_cnt'];
+        $_tags = (new CategoryModel())->getList(0, '-list_order', $_type, $_field, false);
+        $this->assign('list', $_tags);
+        $this->assign('type', $_type);
+
+        return $this->fetch('box/game/home_tag/index');
+    }
+
+    /**
+     * 其他标签列表
+     */
+    public function other() {
+        $_type = CategoryConst::CATE_TYPE_OTHER_5;
+        $_field = ['id', 'name', 'image', 'status', 'list_order', 'game_cnt', 'item_cnt'];
+        $_tags = (new CategoryModel())->getList(0, '-list_order', $_type, $_field, false);
+        $this->assign('list', $_tags);
+        $this->assign('type', $_type);
+
+        return $this->fetch('box/game/home_tag/other');
+    }
+
+    /**
+     * 添加游戏标签
+     */
+    public function add() {
+        $type = $this->request->param('type/d', CategoryConst::CATE_TYPE_HOME_4);
+        $this->assign('type', $type);
+        $_status_radio = Filter::radioCommon($this->_category_status(), 'status', GameConst::CATEGORY_TYPE_DISPLAY);
+        $this->assign('status_radio', $_status_radio);
+
+        return $this->fetch('box/game/home_tag/add');
+    }
+
+    public function _category_status() {
+        $_status = [
+            '1' => lang('HIDDEN'),
+            '2' => lang('DISPLAY'),
+        ];
+        $this->assign('category_status', $_status);
+
+        return $_status;
+    }
+
+    public function _category_type() {
+        $_type = [
+            '1' => lang('label'),
+            '2' => lang('features'),
+        ];
+        $this->assign('category_type', $_type);
+
+        return $_type;
+    }
+
+    /**
+     * 添加游戏标签处理函数
+     */
+    public function addPost() {
+        $_param = $this->request->param();
+        $_rute = ['name' => 'require'];
+        $_msg = ['name.require' => '标签名称不能为空'];
+        if (CategoryConst::CATE_TYPE_HOME_4 == $_param['type']) {
+            $_rute['image'] = 'require';
+            $_msg['image.require'] = '请上传图标';
+        }
+        $_validate = new Validate($_rute, $_msg);
+        if (!$_validate->check($_param)) {
+            $this->adminError($_validate->getError());
+        }
+        $_rs = (new CategoryModel())->addCategory($_param);
+        if ($_rs === false) {
+            $this->adminError(lang('add failure'));
+        }
+        if (CategoryConst::CATE_TYPE_OTHER_5 == $_param['type']) {
+            return $this->adminSuccess(lang('add success'), url('admin/mp.game.homeTag/other'));
+        }
+        /* 添加广告列表_str */
+        $_slide = [
+            'status'  => SlideConst::SLIDE_STATUS_SHOW,
+            'code'    => CategoryConst::CATE_TYPE_HOME_SLIDE.$_rs,  //code 固定前缀加cate_id
+            'name'    => '首页标记【'.$_param['name'].'】广告图',
+            'remark'  => '首页标记【'.$_param['name'].'】广告图',
+            'type_id' => SlideConst::SLIDE_TYPE_ONE_IMG,
+        ];
+        (new SlideModel())->addData($_slide);
+
+        /* 添加广告列表_end */
+
+        return $this->adminSuccess(lang('add success'), url('admin/mp.game.homeTag/index'));
+    }
+
+    /**
+     * 编辑游戏标签
+     */
+    public function edit() {
+        $_id = $this->request->param('id/d', 0);
+        if ($_id > 0) {
+            $_cate_model = new CategoryModel();
+            $_cate = $_cate_model->getInfoById($_id);
+            if (empty($_cate)) {
+                return $this->adminError('参数错误');
+            }
+            $this->assign($_cate);
+            $_status_radio = Filter::radioCommon($this->_category_status(), 'status', $_cate['status']);
+            $this->assign('status_radio', $_status_radio);
+
+            return $this->fetch('box/game/home_tag/edit');
+        } else {
+            return $this->adminError(lang('edit failure'));
+        }
+    }
+
+    /**
+     * 编辑游戏标签处理函数
+     */
+    public function editPost() {
+        $id = $this->request->param('id/d', 0);
+        if ($id > 0) {
+            $_param = $this->request->param();
+            $_rute = ['name' => 'require'];
+            $_msg = ['name.require' => '标签名称不能为空'];
+            if (CategoryConst::CATE_TYPE_HOME_4 == $_param['type']) {
+                $_rute['image'] = 'require';
+                $_msg['image.require'] = '请上传图标';
+            }
+            $_validate = new Validate($_rute, $_msg);
+            if (!$_validate->check($_param)) {
+                $this->adminError($_validate->getError());
+            }
+            $_rs = (new CategoryModel())->updateCategory($_param, $id);
+            if ($_rs === false) {
+                $this->adminError(lang('edit failure'));
+            }
+            if (CategoryConst::CATE_TYPE_OTHER_5 == $_param['type']) {
+                return $this->adminSuccess(lang('add success'), url('admin/mp.game.homeTag/other'));
+            }
+            $this->adminSuccess(lang('edit success'), url('admin/mp.game.homeTag/index'));
+        }
+    }
+
+    /**
+     * 删除
+     */
+    public function delete() {
+        $id = $this->request->param('id/d', 0);
+        if (CategoryConst::CATE_CATE_FIND == $id || CategoryConst::CATE_CATE_RP == $id) {
+            //红包和发现不可删
+            $this->adminError('该标签不可删除');
+        }
+        if ($id > 0) {
+            $_id = (new CategoryModel())->deleteCategory($id);
+            if (false === $_id) {
+                $this->adminError(lang('please delete subcategories'));
+            }
+            /* 删除cate_id对应的游戏 */
+            (new GamecategoryModel())->deleteDataByWhere(['cate_id' => $id]);
+            /* 参数首页标记对应的广告 */
+            $_code = CategoryConst::CATE_TYPE_HOME_SLIDE.$id;  //code 固定前缀加cate_id
+            (new SlideModel())->deleteDataByMap(['code' => $_code]);
+            $this->adminSuccess(lang('delete success'));
+        } else {
+            $this->adminError(lang('delete failure'));
+        }
+    }
+
+    /**
+     * 排序
+     */
+    public function listOrder() {
+        $_model = (new CategoryModel());
+        parent::listOrders($_model);
+        $this->adminSuccess("排序更新成功!");
+    }
+
+    /**
+     * 设置状态
+     * admin/mp.game.homeTag/setStatus
+     */
+    public function setStatus() {
+        $_id = $this->request->param('id/d', 0);
+        $_data = (new CategoryModel())->getInfoById($_id);
+        $_status = $this->request->param('status/d', GameConst::CATEGORY_TYPE_DISPLAY);
+        if (empty($_data)) {
+            $this->adminError('参数错误');
+        }
+        $_data['status'] = $_status;
+        $_rs = (new CategoryModel())->updateCategory($_data, $_id);
+        if (false == $_rs) {
+            $this->adminError('修改失败!');
+        }
+        $this->adminSuccess('修改成功!');
+    }
+
+    /**
+     * 标签对应游戏列表
+     * admin/mp.game.homeTag/game
+     */
+    public function game() {
+        $_param = $this->request->param();
+        if (empty($_param['tag_id'])) {
+            $this->adminError('缺少参数标签ID');
+        }
+        $_game_input = Filter::text('game', get_val($_param, 'game', ''), '请输入游戏名称');
+        $this->assign('game_input', $_game_input);
+        $_app_id_input = Filter::text('app_id', get_val($_param, 'app_id', ''), '请输入游戏ID');
+        $this->assign('app_id_input', $_app_id_input);
+        $_mapp_id_input = Filter::text('mini_app_id', get_val($_param, 'mini_app_id', ''), '请输入小程序ID');
+        $this->assign('mapp_id_input', $_mapp_id_input);
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 10);
+        $_data = (new GameHomeTagLogic())->getList($_param, $_page.','.$_list_rows);
+        $_page_data = Page::paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+        $this->assign('tag_id', $_param['tag_id']);
+        $_filter_button = Filter::button(['title' => lang('search'), 'type' => 'search']);
+        $this->assign('filter_button', $_filter_button);
+        $_filter_button_clear = Filter::button(
+            ['title' => lang('clear'), 'type' => 'clear',
+             'uri'   => url('admin/mp.game.homeTag/game', ['tag_id' => $_param['tag_id']])]
+        );
+        $this->assign('filter_button_clear', $_filter_button_clear);
+        /* 是否显示时间 */
+        $_time_show = false;
+        if (CategoryConst::CATE_CATE_FIND == $_param['tag_id']) {
+            $_time_show = true;
+        }
+        $this->assign('time_show', $_time_show);
+
+        return $this->fetch('box/game/home_tag/game');
+    }
+
+    /**
+     * 添加首页标签游戏
+     * admin/mp.game.homeTag/gameAdd
+     */
+    public function gameAdd() {
+        $_tag_id = $this->request->param('tag_id/d', 0);
+        if (empty($_tag_id)) {
+            $this->adminError('缺少参数标签ID');
+        }
+        //$this->_games(0, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0, GameConst::GAME_MP);
+        $this->_getGames($_tag_id, 0);
+        $this->assign('tag_id', $_tag_id);
+        /* 是否显示时间 */
+        $_time_show = false;
+        if (CategoryConst::CATE_CATE_FIND == $_tag_id) {
+            $_time_show = true;
+        }
+        $this->assign('time_show', $_time_show);
+
+        return $this->fetch('box/game/home_tag/gameAdd');
+    }
+
+    /**
+     * 添加首页标签游戏提交
+     * admin/mp.game.homeTag/gameAddPost
+     */
+    public function gameAddPost() {
+        $_param = $this->request->param();
+        $_rule = [
+            'cate_id' => 'require|unique:huo\model\game\GamecategoryModel,cate_id^app_id',
+            'app_id'  => 'require'
+        ];
+        $_msg = [
+            'cate_id.require' => '缺少参数标签ID',
+            'cate_id.unique'  => '相同的记录已存在',
+            'app_id.require'  => '缺少参数游戏ID'
+        ];
+        $_validate = new Validate($_rule, $_msg);
+        $_rs = $_validate->check($_param);
+        if (!$_rs) {
+            $this->adminError($_validate->getError());
+        }
+        $_param['find_time'] = isset($_param['find_time']) ? strtotime($_param['find_time']) : 0;
+//        if (CategoryConst::CATE_CATE_RP == $_param['cate_id']) {
+//            $_rmb_gain = (new Rate($_param['app_id']))->getMemReward();
+//            if (empty($_rmb_gain)) {
+//                $this->adminError('该游戏不含奖励,请先设置玩家奖励!');
+//            }
+//        }
+        $_rs = (new GamecategoryModel())->addData($_param);
+        if (false == $_rs) {
+            $this->adminError('添加失败!');
+        }
+        $this->adminSuccess('添加成功!');
+    }
+
+    /**
+     * 添加首页标签游戏
+     * admin/mp.game.homeTag/gameEdit
+     */
+    public function gameEdit() {
+        $_id = $this->request->param('id/d', 0);
+        $_tag_id = $this->request->param('tag_id/d', 0);
+        if (empty($_tag_id)) {
+            $this->adminError('缺少参数标签ID');
+        }
+        if (empty($_id)) {
+            $this->adminError('缺少参数ID');
+        }
+        $_data = (new GamecategoryModel())->getInfoById($_id);
+        if (empty($_data)) {
+            $this->adminError('参数错误');
+        }
+        //$this->_games($_data['app_id'], 0, CommonConst::CONST_NOT_DELETE, 0, GameConst::GAME_MP, false, true, [], '', 'disabled');
+        $this->_getGames($_tag_id, $_data['app_id']);
+        /* 是否显示时间 */
+        $_time_show = false;
+        if (CategoryConst::CATE_CATE_FIND == $_tag_id) {
+            $_time_show = true;
+        }
+        $_data['find_time'] = empty($_data['find_time']) ? date('Y-m-d') : date('Y-m-d', $_data['find_time']);
+        $this->assign('time_show', $_time_show);
+        $this->assign($_data);
+        $this->assign('tag_id', $_tag_id);
+
+        return $this->fetch('box/game/home_tag/gameEdit');
+    }
+
+    /**
+     * 添加首页标签游戏提交
+     * admin/mp.game.homeTag/gameEdit
+     */
+    public function gameEditPost() {
+        $_param = $this->request->param();
+        $_rule = [
+            'cate_id' => 'require',
+            'id'      => 'require'
+        ];
+        $_msg = [
+            'cate_id.require' => '缺少参数标签ID',
+            'id.require'      => '缺少参数ID'
+        ];
+        $_validate = new Validate($_rule, $_msg);
+        $_rs = $_validate->check($_param);
+        if (!$_rs) {
+            $this->adminError($_validate->getError());
+        }
+        $_find_time = isset($_param['find_time']) ? strtotime($_param['find_time']) : 0;
+        $_data = [
+            'find_time'  => $_find_time,
+            'list_order' => $_param['list_order']
+        ];
+        $_rs = (new GamecategoryModel())->updateData($_data, $_param['id']);
+        if (false == $_rs) {
+            $this->adminError('编辑失败!');
+        }
+        $this->adminSuccess('编辑成功!');
+    }
+
+    /**
+     * 首页标签游戏排序
+     * admin/mp.game.homeTag/gcListOrder
+     */
+    public function gcListOrder() {
+        $_model = (new GamecategoryModel());
+        parent::listOrders($_model);
+        Cache::clear(CacheConst::TAG_GAME_LIST);
+        $this->adminSuccess('排序更新成功!');
+    }
+
+    /***
+     * 首页标签游戏删除
+     * admin/mp.game.homeTag/gameDelete
+     */
+    public function gameDelete() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminSuccess('缺少参数ID');
+        }
+        $_rs = (new GamecategoryModel())->deleteDataByWhere(['id' => $_id]);
+        if (false == $_rs) {
+            $this->adminError('删除失败!');
+        }
+        $this->adminSuccess('删除成功!');
+    }
+
+    /**
+     * 标签广告图
+     * admin/mp.game.homeTag/slide
+     */
+    public function slide() {
+        $_tag_id = $this->request->param('tag_id/d', 0);
+        if (empty($_tag_id)) {
+            $this->adminError('缺少参数标签ID');
+        }
+        $_code = CategoryConst::CATE_TYPE_HOME_SLIDE.$_tag_id;
+        $_slide_id = (new SlideModel())->getSlideIdByCode($_code);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_map = [];
+        $_map['slide_id'] = $_slide_id;
+        $_slide_items = (new SlideItemModel())->getList($_map, $_page.','.$_list_rows);
+        $_slide_items = (new Page())->paginate($_slide_items['count'], $_slide_items['list'], $_page, $_list_rows);
+        $this->_games(0, 0, 0, 0, GameConst::GAME_MP);
+        $this->assign('page', $_slide_items->render());
+        $this->assign('slide_items', $_slide_items->items());
+        $this->assign('slide_id', $_slide_id);
+        $this->assign('tag_id', $_tag_id);
+
+        return $this->fetch('box/game/home_tag/slide/index');
+    }
+
+    /**
+     * 添加标签广告图
+     * admin/mp.game.homeTag/slide
+     */
+    public function slideAdd() {
+        $_param = $this->request->param();
+        $_param['type'] = SlideConst::SLIDE_TYPE_ONE_IMG;
+        $this->assign($_param);
+        $_target_types_radio = Filter::radioCommon((new SlideitemController())->_target_types(), 'target_type', 'url');
+        $this->assign('target_types_radio', $_target_types_radio);
+        $this->_games(0, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0, [GameConst::GAME_MP]);
+
+        return $this->fetch('box/game/home_tag/slide/add');
+    }
+
+    /**
+     * 添加标签广告图
+     * admin/mp.game.homeTag/slideAddPost
+     */
+    public function slideAddPost() {
+        $_param = $this->request->param();
+        (new SlideitemController())->validateParam($_param);
+        if ('url' == $_param['target_type']) {
+            $_param['target_id'] = 0;
+        } else {
+            $_param['url'] = '';
+        }
+        $_insert_data = [
+            'slide_id'    => $_param['slide_id'],
+            'title'       => $_param['title'],
+            'table_name'  => $_param['target_type'],
+            'target_id'   => isset($_param['target_id']) ? $_param['target_id'] : 0,
+            'image'       => isset($_param['image']) ? $_param['image'] : '',
+            'url'         => isset($_param['url']) ? $_param['url'] : '',
+            'description' => $_param['description']
+        ];
+        $_slide_item_model = new SlideItemModel();
+        $result = $_slide_item_model->save($_insert_data);
+        if (false === $result) {
+            $this->adminError($_slide_item_model->getError());
+        }
+        if (!empty($_param['slide_id'])) {
+            $_slide_item_model->ClCacheBySlideId($_param['slide_id']);
+        }
+        $this->adminSuccess(
+            lang('EDIT').' '.lang('SUCCESS'), url('admin/mp.game.homeTag/slide', ['tag_id' => $_param['tag_id']])
+        );
+    }
+
+    /**
+     * 添加标签广告图
+     * admin/mp.game.homeTag/slideEdit
+     */
+    public function slideEdit() {
+        $_slide_item_id = $this->request->param('id/d', 0);
+        $_tag_id = $this->request->param('tag_id/d', 0);
+        if (empty($_slide_item_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_slide_ctrl = new SlideitemController();
+        $_slide_item = $_slide_ctrl->findSlideItemModel($_slide_item_id);
+        $this->assign('slide_item', $_slide_item);
+        $_target_types_radio = Filter::radioCommon(
+            $_slide_ctrl->_target_types(), 'target_type', $_slide_item->table_name
+        );
+        $this->assign('target_types_radio', $_target_types_radio);
+        $this->assign('tag_id', $_tag_id);
+        $this->_games(
+            $_slide_item->target_id, GameConst::GAME_STATUS_ON, CommonConst::CONST_NOT_DELETE, 0, GameConst::GAME_MP
+        );
+
+        return $this->fetch('box/game/home_tag/slide/edit');
+    }
+
+    /**
+     * 添加标签广告图
+     * admin/mp.game.homeTag/slideEditPost
+     */
+    public function slideEditPost() {
+        $_param = $this->request->param();
+        $_slide_ctrl = new SlideitemController();
+        $_slide_ctrl->validateParam($_param);
+        if ('url' == $_param['target_type']) {
+            $_param['target_id'] = 0;
+        } else {
+            $_param['url'] = '';
+        }
+        $_update_data = [
+            'title'       => $_param['title'],
+            'table_name'  => $_param['target_type'],
+            'target_id'   => isset($_param['target_id']) ? $_param['target_id'] : 0,
+            'image'       => isset($_param['image']) ? cmf_asset_relative_url($_param['image']) : '',
+            'url'         => isset($_param['url']) ? $_param['url'] : '',
+            'description' => $_param['description']
+        ];
+        $_slide_item = $_slide_ctrl->findSlideItemModel($_param['id']);
+        if (false === $_slide_item->save($_update_data)) {
+            $this->adminError($_slide_item->getError());
+        }
+        if (!empty($_param['slide_id'])) {
+            (new SlideItemModel())->ClCacheBySlideId($_param['slide_id']);
+        }
+        $this->adminSuccess(
+            lang('EDIT').' '.lang('SUCCESS'), url('admin/mp.game.homeTag/slide', ['tag_id' => $_param['tag_id']])
+        );
+    }
+}
+

+ 147 - 0
admin/admin/controller/mp/game/PaySwitchController.php

@@ -0,0 +1,147 @@
+<?php
+/**
+ * paySwitchController.php  UTF-8
+ * 支付切换规则
+ *
+ * @date    : 2018/6/6 21:27
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\mp\game;
+
+use cmf\controller\AdminBaseController;
+use huo\controller\game\GamePaySwitchCache;
+use huo\logic\game\GamePaySwitchLogic;
+use huolib\constant\CommonConst;
+use huolib\constant\GameConst;
+use huolib\constant\OrderConst;
+use huolib\tool\Page;
+use think\Lang;
+
+class PaySwitchController extends AdminBaseController {
+    function _initialize() {
+        $langSet = $this->request->langset();
+        Lang::load(APP_PATH.'admin'.DS.'lang'.DS.$langSet.DS.'admin_pay_switch'.EXT);
+        parent::_initialize();
+    }
+
+    /**
+     * 切换规则列表
+     * admin/game.pay_switch/index
+     *
+     * @throws
+     */
+    public function index() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $this->_games(
+            $_app_id, 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, GameConst::GAME_MP, false, true
+        );
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 10);
+        $_list = (new GamePaySwitchLogic())->getLists($_app_id, $_page.','.$_list_rows);
+        $_page_data = Page::paginate($_list['count'], $_list['list'], $_page, $_list_rows);
+        $this->assign('items', $_page_data);
+        $this->assign('page', $_page_data->render());
+
+        return $this->fetch('box/game/pay_switch/index');
+    }
+
+    /**
+     * 添加切换规则
+     * admin/game.pay_switch/add
+     *
+     * @throws
+     */
+    public function add() {
+        $this->_games(
+            0, 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, GameConst::GAME_MP, false, true
+        );
+
+        return $this->fetch('box/game/pay_switch/add');
+    }
+
+    /**
+     * 添加切换规则提交
+     * admin/game.pay_switch/addPost
+     *
+     * @throws
+     */
+    public function addPost() {
+        $_params = $this->request->param();
+        $_params['is_domestic'] = isset($_params['is_domestic']) ? $_params['is_domestic'] : 2;
+        $_params['is_overseas'] = isset($_params['is_overseas']) ? $_params['is_overseas'] : 2;
+        $_params['is_first'] = isset($_params['is_first']) ? $_params['is_first'] : 1;
+        $_model = new GamePaySwitchLogic();
+        if (empty($_params['app_id'])) {
+            $this->adminError(lang('please select a game'));
+        } elseif ($_model->checkGame($_params['app_id'])) {
+            $this->adminError(lang('game_existed'));
+        }
+        $_result = $_model->addPaySwitch($_params);
+        if (false == $_result) {
+            $this->adminError(lang('add').lang('failure'));
+        }
+        $this->adminSuccess(lang('add').lang('success'), url('admin/game.paySwitch/index'));
+    }
+
+    /**
+     * 编辑切换规则
+     * admin/game.pay_switch/edit
+     *
+     * @throws
+     */
+    public function edit() {
+        $_app_id = $this->request->param('app_id/d', 0);
+        $this->_games(
+            $_app_id, 0, CommonConst::CONST_NOT_DELETE, GameConst::GAME_IS_SDK, GameConst::GAME_MP, false, true,
+            [], '', 'disabled'
+        );
+        if (empty($_app_id)) {
+            $this->adminError(lang('param_error'));
+        }
+        $_data = GamePaySwitchCache::ins()->getInfoByAppId($_app_id);
+        $this->assign('data', $_data);
+
+        return $this->fetch('box/game/pay_switch/edit');
+    }
+
+    /**
+     * 编辑切换规则提交
+     * admin/game.pay_switch/editPost
+     *
+     * @throws
+     */
+    public function editPost() {
+        $_params = $this->request->param();
+        if (empty($_params['app_id'])) {
+            $this->adminError(lang('please select a game'));
+        }
+        $_params['is_domestic'] = isset($_params['is_domestic']) ? $_params['is_domestic'] : OrderConst::PAY_SWITCH_NO;
+        $_params['is_overseas'] = isset($_params['is_overseas']) ? $_params['is_overseas'] : OrderConst::PAY_SWITCH_NO;
+        $_params['is_first'] = isset($_params['is_first']) ? $_params['is_first'] : OrderConst::PAY_SWITCH_YES;
+        $_result = GamePaySwitchCache::ins()->updatePaySwitch($_params['app_id'], $_params);
+        if (false == $_result) {
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/mp.game.paySwitch/index'));
+    }
+
+    public function setSwitch() {
+        $_data = [];
+        $_data['app_id'] = $this->request->param('app_id/d', 0);
+        $_field = $this->request->param('field/s', '');
+        $_status = $this->request->param('status/d', 1);
+        if (empty($_data['app_id']) || empty($_field)) {
+            $this->adminError(lang('param_error'));
+        }
+        $_data[$_field] = $_status;
+        $_result = GamePaySwitchCache::ins()->updatePaySwitch($_data['app_id'], $_data);
+        if (false == $_result) {
+            $this->adminError(lang('edit').lang('failure'));
+        }
+        $this->adminSuccess(lang('edit').lang('success'), url('admin/mp.game.paySwitch/index'));
+    }
+}

+ 849 - 0
admin/admin/controller/mp/hunter/HunterController.php

@@ -0,0 +1,849 @@
+<?php
+/**
+ * HunterController.php  UTF-8
+ * 更多挣钱 猎人平台
+ *
+ * @date    : 2018/9/19 15:46
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HuoMp 1.0
+ */
+
+namespace admin\admin\controller\mp\hunter;
+
+use admin\admin\controller\slide\SlideitemController;
+use admin\admin\validate\HunterValidate;
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huo\controller\wap\Option;
+use huo\logic\posts\PostsLogic as huoPostLogic;
+use huo\logic\slide\SlideLogic;
+use huo\model\posts\PostsModel;
+use huo\model\slide\SlideItemModel;
+use huo\model\slide\SlideModel;
+use huolib\constant\NewsConst;
+use huolib\constant\OptionConst;
+use huolib\constant\SlideConst;
+use huolib\tool\Page;
+use huomp\logic\hunter\HunterRankLogic;
+use huomp\logic\posts\PostsLogic;
+use huomp\model\hunter\HunterRankModel;
+use think\Lang;
+use think\Validate;
+
+class HunterController extends AdminbaseController {
+    protected $post_type = 0;
+    protected $back_url  = '';
+
+    function _initialize() {
+        parent::_initialize();
+        Lang::load(
+            [
+                APP_PATH.'admin/lang'.DS.$this->lang.DS.'hunter'.EXT,
+                APP_PATH.'admin/lang'.DS.$this->lang.DS.'admin_news'.EXT,
+            ]
+        );
+        $this->post_type = $this->request->param('post_type/d', NewsConst::NEWS_TYPE_HUNTER_AND);
+        $this->_setBase();
+    }
+
+    protected function _setBase() {
+        $this->assign('post_type', $this->post_type);
+        $this->back_url = url('admin/mp.hunter.hunter/andindex');
+        if (NewsConst::NEWS_TYPE_HUNTER_IOS == $this->post_type) {
+            $this->back_url = url('admin/mp.hunter.hunter/iosindex');
+        }
+        $this->assign('action', $this->back_url);
+    }
+
+    /**
+     * 新手必读设置
+     * admin/mp.hunter.hunter/index
+     */
+    public function index() {
+        $_id = $this->request->param('id/d', NewsConst::NEWS_ID_HUNTER_AND_NEW);
+        $_post = (new huoPostLogic())->getInfoById($_id);
+        if (empty($_post)) {
+            $_post = [
+                'id'           => $_id,
+                'post_title'   => lang('hunter_and_new'),
+                'post_content' => '',
+            ];
+            (new PostsModel())->adminAddPage($_post);
+        }
+        $this->assign('post', $_post);
+        $this->assign('hunter_and_new', NewsConst::NEWS_ID_HUNTER_AND_NEW);
+        $this->assign('hunter_ios_new', NewsConst::NEWS_ID_HUNTER_IOS_NEW);
+
+        return $this->fetch('box/hunter/index');
+    }
+
+    /**
+     * 新手必读更新提交
+     * admin/mp.hunter.hunter/saveProtocol
+     */
+    public function saveProtocol() {
+        $_param = $this->request->param();
+        $_data = $_param['post'];
+        $_validate = new Validate(
+            [
+                'post_title|标题'   => 'require',
+                'post_content|内容' => 'require',
+            ]
+        );
+        if (!$_validate->check($_data)) {
+            $this->adminError($_validate->getError());
+        }
+        $_data['post_status'] = NewsConst::NEWS_PUBLISHED;
+        $_data['comment_status'] = NewsConst::NEWS_COMMENT_STATUS_NOT_ALLOW;
+        $_data['published_time'] = date('Y-m-d H:i:s');
+        $_protocol = new PostsModel();
+        if (false === $_protocol->adminEditPage($_data)) {
+            $this->adminError(lang('ERROR'));
+        }
+        /* 生成静态 */
+        $this->_createStatic($_data['id']);
+        $this->createList();
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+
+    /**
+     * 安卓试玩
+     * admin/mp.hunter.hunter/andindex
+     */
+    public function andindex() {
+        $this->post_type = NewsConst::NEWS_TYPE_HUNTER_AND;
+        $this->_setBase();
+
+        return $this->getList();
+    }
+
+    /**
+     * IOS试玩
+     * admin/mp.hunter.hunter/iosindex
+     */
+    public function iosindex() {
+        $this->post_type = NewsConst::NEWS_TYPE_HUNTER_IOS;
+        $this->_setBase();
+
+        return $this->getList();
+    }
+
+    private function getList() {
+        $_param = $this->request->param();
+        /*搜索*/
+        $_keyword_input = Filter::text('keyword', get_val($_param, 'keyword', ''), lang('keywords'));
+        $this->assign('keyword_input', $_keyword_input);
+        $this->_time();
+        $_param['post_type'] = $this->post_type;
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 50);
+        $_data = (new PostsLogic())->getHunterList($_param, $_page.','.$_list_rows);
+        $_data = (new Page())->paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('item', $_data->items());
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('box/hunter/list');
+    }
+
+    /**
+     * 添加试玩
+     * admin/mp.hunter.hunter/add
+     */
+    public function add() {
+        $this->assign('type_and', NewsConst::NEWS_TYPE_HUNTER_AND);
+
+        return $this->fetch('box/hunter/add');
+    }
+
+    /**
+     * 添加试玩
+     * admin/mp.hunter.hunter/addPost
+     */
+    public function addPost() {
+        $_data = $this->request->param();
+        if (empty($_data['post']['post_type'])) {
+            $this->adminError('缺少文章类型参数post_type');
+        }
+        $this->post_type = $_data['post']['post_type'];
+        $this->_setBase();
+        $_scene = 'and_add';
+        if (NewsConst::NEWS_TYPE_HUNTER_IOS == $_data['post']['post_type']) {
+            $_scene = 'ios_add';
+        }
+        $_validate = new HunterValidate();
+        if (!$_validate->scene($_scene)->check($_data['post'])) {
+            $this->adminError($_validate->getError());
+        }
+        $_data['post']['more']['thumbnail'] = cmf_asset_relative_url($_data['post']['more']['thumbnail']);
+        if (!empty($_data['photo_names']) && !empty($_data['photo_urls'])) {
+            $_data['post']['more']['image'] = [];
+            foreach ($_data['photo_urls'] as $_key => $_url) {
+                $_photo_url = cmf_asset_relative_url($_url);
+                array_push(
+                    $_data['post']['more']['image'], ["url" => $_photo_url, "name" => $_data['photo_names'][$_key]]
+                );
+            }
+        }
+        $_rs = (new PostsModel())->adminAddPage($_data['post']);
+        if (false == $_rs) {
+            $this->adminError('添加失败!');
+        }
+        /* 生成静态 */
+        $this->_createStatic($_rs);
+        $this->createList($_data['post']['post_type']);
+        $this->adminSuccess('添加成功!', $this->back_url);
+    }
+
+    /**
+     *  编辑试玩
+     * admin/mp.hunter.hunter/edit
+     */
+    public function edit() {
+        $this->assign('type_and', NewsConst::NEWS_TYPE_HUNTER_AND);
+        $id = $this->request->param('id/d', 0);
+        $post = (new huoPostLogic())->getInfoById($id);
+        $this->post_type = $post['post_type'];
+        $this->_setBase();
+        $this->assign('post', $post);
+
+        return $this->fetch('box/hunter/edit');
+    }
+
+    /**
+     * 编辑页面提交
+     * admin/mp.hunter.hunter/editPost
+     */
+    public function editPost() {
+        $_data = $this->request->param();
+        if (empty($_data['post']['post_type'])) {
+            $this->adminError('缺少文章类型参数post_type');
+        }
+        $this->post_type = $_data['post']['post_type'];
+        $this->_setBase();
+        $_scene = 'and_edit';
+        if (NewsConst::NEWS_TYPE_HUNTER_IOS == $_data['post']['post_type']) {
+            $_scene = 'ios_edit';
+        }
+        $_validate = new HunterValidate();
+        if (!$_validate->scene($_scene)->check($_data['post'])) {
+            $this->adminError($_validate->getError());
+        }
+        $_data['post']['more']['thumbnail'] = cmf_asset_relative_url($_data['post']['more']['thumbnail']);
+        if (!empty($_data['photo_names']) && !empty($_data['photo_urls'])) {
+            $_data['post']['more']['image'] = [];
+            foreach ($_data['photo_urls'] as $_key => $_url) {
+                $_photo_url = cmf_asset_relative_url($_url);
+                array_push(
+                    $_data['post']['more']['image'], ["url" => $_photo_url, "name" => $_data['photo_names'][$_key]]
+                );
+            }
+        }
+        $_rs = (new PostsModel())->adminEditPage($_data['post']);
+        if (false == $_rs) {
+            $this->adminError('编辑失败!');
+        }
+        $this->_createStatic($_data['post']['id']);
+        $this->createList($_data['post']['post_type']);
+        $this->adminSuccess('编辑成功!', $this->back_url);
+    }
+
+    /**
+     * 删除试玩数据
+     * admin/mp.hunter.hunter/delete
+     */
+    public function delete() {
+        $_param = $this->request->param();
+        $_rs = (new PostsModel())->adminDeletePage($_param);
+        if (false == $_rs) {
+            $this->adminError('删除失败!');
+        }
+        $this->createRankList();
+        $this->createList();
+        $this->adminSuccess('删除成功!');
+    }
+
+    /**
+     * 设置状态
+     * admin/mp.hunter.hunter/setPostStatus
+     */
+    public function setPostStatus() {
+        $_param = $this->request->param();
+        $_map['id'] = $_param['id'];
+        $_data['post_status'] = $_param['status'];
+        if (2 == $_data['post_status']) {
+            $_data['published_time'] = time();
+        }
+        $_data['update_time'] = time();
+        $_post_model = new PostsModel();
+        $_res = $_post_model->useGlobalScope(false)->where($_map)->setField($_data);
+        if (true == $_res) {
+            $this->_createStatic($_param['id']);
+            $this->createList($_param['type']);
+            $this->adminSuccess(lang('edit success'));
+        } else {
+            $this->adminError(lang('edit failure'));
+        }
+    }
+
+    /**
+     * 轮播图
+     * admin/mp.hunter.hunter/slide
+     */
+    public function slide() {
+        $_code = SlideConst::SLIDE_HUNTER_INDEX;
+        $_slide_id = (new SlideModel())->getSlideIdByCode($_code);
+        $_page = $this->request->param('page/d', 1);
+        $_list_rows = $this->request->param('list_rows/d', 50);
+        $_map = [];
+        $_map['slide_id'] = $_slide_id;
+        $_slide_items = (new SlideItemModel())->getList($_map, $_page.','.$_list_rows);
+        $_slide_items = (new Page())->paginate($_slide_items['count'], $_slide_items['list'], $_page, $_list_rows);
+        $this->assign('page', $_slide_items->render());
+        $this->assign('slide_items', $_slide_items->items());
+        $this->assign('slide_id', $_slide_id);
+        $this->_getPosts();
+
+        return $this->fetch('box/hunter/slide/index');
+    }
+
+    /**
+     * 添加轮播图
+     * admin/mp.hunter.hunter/slideAdd
+     */
+    public function slideAdd() {
+        $_param = $this->request->param();
+        $_param['type'] = SlideConst::SLIDE_TYPE_SLIDE_IMG;
+        $this->assign($_param);
+        $this->_getPosts();
+        $this->_target_types();
+
+        return $this->fetch('box/hunter/slide/add');
+    }
+
+    /**
+     * 添加轮播图
+     * admin/mp.hunter.hunter/slideAddPost
+     */
+    public function slideAddPost() {
+        $_param = $this->request->param();
+        if ('url' == $_param['target_type']) {
+            $_param['target_id'] = 0;
+        } else {
+            $_param['url'] = '';
+        }
+        $_insert_data = [
+            'slide_id'    => $_param['slide_id'],
+            'title'       => $_param['title'],
+            'table_name'  => $_param['target_type'],
+            'target_id'   => isset($_param['target_id']) ? $_param['target_id'] : 0,
+            'image'       => isset($_param['image']) ? $_param['image'] : '',
+            'url'         => isset($_param['url']) ? $_param['url'] : '',
+            'description' => time()
+        ];
+        $_slide_item_model = new SlideItemModel();
+        $result = $_slide_item_model->save($_insert_data);
+        if (false === $result) {
+            $this->adminError($_slide_item_model->getError());
+        }
+        $this->createList();
+        $this->adminSuccess('添加成功!', url('admin/mp.hunter.hunter/slide'));
+    }
+
+    /**
+     * 编辑轮播图
+     * admin/mp.hunter.hunter/slideEdit
+     */
+    public function slideEdit() {
+        $_slide_item_id = $this->request->param('id/d', 0);
+        if (empty($_slide_item_id)) {
+            $this->adminError(lang('param error'));
+        }
+        $_slide_ctrl = new SlideitemController();
+        $_slide_item = $_slide_ctrl->findSlideItemModel($_slide_item_id);
+        $this->assign('slide_item', $_slide_item);
+        $this->_target_types($_slide_item->table_name);
+        $this->_getPosts($_slide_item->target_id);
+
+        return $this->fetch('box/hunter/slide/edit');
+    }
+
+    /**
+     * 编辑轮播图
+     * admin/mp.hunter.hunter/slideEditPost
+     */
+    public function slideEditPost() {
+        $_param = $this->request->param();
+        $_slide_ctrl = new SlideitemController();
+        if ('url' == $_param['target_type']) {
+            $_param['target_id'] = 0;
+        } else {
+            $_param['url'] = '';
+        }
+        $_update_data = [
+            'title'       => $_param['title'],
+            'table_name'  => $_param['target_type'],
+            'target_id'   => isset($_param['target_id']) ? $_param['target_id'] : 0,
+            'image'       => isset($_param['image']) ? cmf_asset_relative_url($_param['image']) : '',
+            'url'         => isset($_param['url']) ? $_param['url'] : '',
+            'description' => time(),
+        ];
+        $_slide_item = $_slide_ctrl->findSlideItemModel($_param['id']);
+        if (false === $_slide_item->save($_update_data)) {
+            $this->adminError($_slide_item->getError());
+        }
+        $this->createList();
+        $this->adminSuccess('编辑成功!', url('admin/mp.hunter.hunter/slide'));;
+    }
+
+    /**
+     * 删除轮播
+     * admin/mp.hunter.hunter/slideDelete
+     */
+    public function slideDelete() {
+        $id = $this->request->param('id', 0, 'intval');
+        $_rs = (new SlideItemModel())->deleteItem($id);
+        if ($_rs) {
+            $this->createList();
+            $this->adminSuccess(lang('SUCCESS'));
+        } else {
+            $this->adminError(lang('ERROR'));
+        }
+    }
+
+    /**
+     * 幻灯片页面隐藏
+     *admin/mp.hunter.hunter/ban
+     */
+    public function ban() {
+        $id = $this->request->param('id', 0, 'intval');
+        if ($id) {
+            $_rs = (new SlideItemModel())->updateData(['id' => $id], ['status' => 1]);
+            if ($_rs) {
+                $this->createList();
+                $this->adminSuccess(lang('SUCCESS'));
+            } else {
+                $this->adminError(lang('ERROR'));
+            }
+        } else {
+            $this->adminError(lang('ERROR'));
+        }
+    }
+
+    /**
+     * 幻灯片页面显示
+     *admin/mp.hunter.hunter/cancelBan
+     */
+    public function cancelBan() {
+        $id = $this->request->param('id', 0, 'intval');
+        if ($id) {
+            $_rs = (new SlideItemModel())->updateData(['id' => $id], ['status' => 2]);
+            if ($_rs) {
+                $this->createList();
+                $this->adminSuccess(lang('SUCCESS'));
+            } else {
+                $this->adminError(lang('ERROR'));
+            }
+        } else {
+            $this->adminError(lang('ERROR'));
+        }
+    }
+
+    /**
+     * 虚拟排行记录
+     * admin/mp.hunter.hunter/rank
+     */
+    public function rank() {
+        $_param = $this->request->param();
+        $_nickname_input = Filter::text('nickname', get_val($_param, 'nickname', ''), '请输入昵称');
+        $this->assign('nickname_input', $_nickname_input);
+        $_rank_by = get_val($_param, 'rank_by', 'day_money');
+        $this->_getRankBy($_rank_by);
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 50);
+        $_order = '-'.$_rank_by;
+        $this->_time();
+        $_data = (new HunterRankLogic())->getList($_param, $_page.','.$_list_rows, $_order);
+        $_data = (new Page())->paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('item', $_data->items());
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('box/hunter/rank/index');
+    }
+
+    /**
+     * 添加排行数据--显示玩家数据
+     * admin/mp.hunter.hunter/rankMem
+     */
+    public function rankMem() {
+        $_param = $this->request->param();
+        $_nickname_input = Filter::text('nickname', get_val($_param, 'nickname', ''), '请输入昵称');
+        $this->assign('nickname_input', $_nickname_input);
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 10);
+        $_data = (new HunterRankLogic())->getAgentExt($_param, $_page.','.$_list_rows);
+        $_data = (new Page())->paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('item', $_data->items());
+        $this->assign('page', $_data->render());
+
+        return $this->fetch('box/hunter/rank/rank_mem');
+    }
+
+    /**
+     * 添加排行数据
+     * admin/mp.hunter.hunter/rankAdd
+     */
+    public function rankAdd() {
+        $_param = $this->request->param();
+        $this->assign('data', $_param);
+
+        return $this->fetch('box/hunter/rank/add');
+    }
+
+    /**
+     * 添加排行数据
+     * admin/mp.hunter.hunter/rankAddPost
+     */
+    public function rankAddPost() {
+        $_param = $this->request->param();
+        $_rs = (new HunterRankModel())->addData($_param);
+        if (false == $_rs) {
+            $this->adminError('添加失败!');
+        }
+        $this->createRankList();
+        $this->createList();
+        $this->adminSuccess('添加成功!');
+    }
+
+    /**
+     * 一键添加添加排行数据
+     * admin/mp.hunter.hunter/rankOne
+     */
+    public function rankOne() {
+        $_ids = $this->request->param('ids/a');
+        foreach ($_ids as $v) {
+            $_v = explode(',', $v);
+            if (empty($_v[0])) {
+                continue;
+            }
+            $_mem_id = $_v[0];
+            $_day_money = empty($_v[1]) ? rand(1, 99) / 10 : $_v[1];
+            $_month_money = $_day_money + rand(1, 99);
+            $_total_money = $_month_money + rand(1, 99);
+            $_param = [
+                'mem_id'      => $_mem_id,
+                'day_money'   => $_day_money,
+                'month_money' => $_month_money,
+                'total_money' => $_total_money,
+            ];
+            (new HunterRankModel())->addData($_param);
+        }
+        $this->createRankList();
+        $this->createList();
+        $this->adminSuccess('添加成功!');
+    }
+
+    /**
+     * 编辑排行数据
+     * admin/mp.hunter.hunter/rankEdit
+     */
+    public function rankEdit() {
+        $_id = $this->request->param('id/d', 0);
+        $_data = (new HunterRankModel())->getInfoById($_id);
+        $this->assign('data', $_data);
+
+        return $this->fetch('box/hunter/rank/edit');
+    }
+
+    /**
+     * 编辑排行数据
+     * admin/mp.hunter.hunter/rankEditPost
+     */
+    public function rankEditPost() {
+        $_param = $this->request->param();
+        $_rs = (new HunterRankModel())->updateData($_param, $_param['id']);
+        if (false == $_rs) {
+            $this->adminError('编辑失败!');
+        }
+        $this->createRankList();
+        $this->createList();
+        $this->adminSuccess('编辑成功!');
+    }
+
+    /**
+     * 删除排行数据
+     * admin/mp.hunter.hunter/rankDelete
+     */
+    public function rankDelete() {
+        $_id = $this->request->param('id/d', 0);
+        $_ids = $this->request->param('ids/a');
+        if (!empty($_ids)) {
+            $_id = ['in', $_ids];
+        }
+        $_rs = (new HunterRankModel())->deleteData($_id);
+        if (false == $_rs) {
+            $this->adminError('删除失败!');
+        }
+        $this->createRankList();
+        $this->createList();
+        $this->adminSuccess('删除成功!');
+    }
+
+    /**
+     * 生成静态单页面
+     * admin/mp.hunter.hunter/createHtml
+     */
+    public function createHtml() {
+        $_id = $this->request->param('id/d', 0);
+        if (empty($_id)) {
+            $this->adminError('缺少参数ID');
+        }
+        $_rs = $this->_createStatic($_id);
+        if (false == $_rs) {
+            $this->adminError('更新失败!');
+        }
+        $this->adminSuccess('更新成功!');
+    }
+
+    /**
+     * 生成静态列表页
+     * admin/mp.hunter.hunter/createListHtml
+     */
+    public function createListHtml() {
+        $_type = $this->request->param('post_type', 'rank');
+        if ('rank' == $_type) {
+            /* 排行页 */
+            $this->createRankList();
+        } else {
+            $this->createList($_type);
+        }
+        $this->adminSuccess('更新成功!');
+    }
+
+    public function createRankList() {
+        $_hrl = new HunterRankLogic();
+        $_day_rank = $_hrl->getList([], '1,10', '-day_money');
+        $this->assign('day_rank', $_day_rank['list']);
+        $_month_rank = $_hrl->getList([], '1,10', '-month_money');
+        $this->assign('month_rank', $_month_rank['list']);
+        $_html = $this->fetch('box/hunter/template/rank');
+        file_put_contents(HUNTER_PATH.'rank.html', $_html);
+    }
+
+    public function createList($type = '') {
+        $_hpl_class = new huoPostLogic();
+        $_post_logic = new PostsLogic();
+        /* 获取轮播图 */
+        $_slide_items = (new SlideLogic())->getHtmlSlide();
+        $this->assign('slide', $_slide_items);
+        $_hrl = new HunterRankLogic();
+        $_rank_last_time = $_hrl->lastUpdateTime();
+        $this->assign('rank_last_time', $_rank_last_time);
+        /* 获取排行榜 */
+        $_rank_list = $_hrl->getHtmlList();
+        $this->assign('rank_list', $_rank_list);
+        /* 获取分享配置 */
+        $_m = new Option();
+        $_item = $_m->getOptionData(OptionConst::HUNTER_SHARE_CFG, 1, true);
+        if (!empty($_item['option_value'])) {
+            $_item['option_value'] = json_decode($_item['option_value'], true);
+        }
+        $this->assign(
+            'wx_app_id', empty($_item['option_value']['wx_app_id']) ? '' : $_item['option_value']['wx_app_id']
+        );
+        if (empty($type) || NewsConst::NEWS_TYPE_HUNTER_AND == $type) {  //安卓列表页
+            /* 安卓列表页地址更新到入口 */
+            $_index_html = '<?php echo \'<script>location.href="'.STATICSITE
+                           .'/hunter/ios_index.html?wx_app_id=\'.$_GET[\'wx_app_id\'].\'&'.time()
+                           .'"</script>\';';
+            file_put_contents(CMF_ROOT.'public/box/hunter.php', $_index_html);
+            /* 安卓列表 */
+            /*获取新手必读*/
+            $_and_new = $_hpl_class->getInfoById(NewsConst::NEWS_ID_HUNTER_AND_NEW);
+            $this->assign('and_new', $_and_new);
+            /*获取列表*/
+            $_and_list = $_post_logic->getHtmlList(NewsConst::NEWS_TYPE_HUNTER_AND);
+            $this->assign('and_list', $_and_list['list']);
+            $_wx_share = empty($_item['option_value']['android']) ? [] : $_item['option_value']['android'];
+            $this->assign('wx_share', $_wx_share);
+            $_html = $this->fetch('box/hunter/template/and_index');
+            file_put_contents(HUNTER_PATH.'and_index.html', $_html);
+        }
+        if (empty($type) || NewsConst::NEWS_TYPE_HUNTER_IOS == $type) {
+            /* ios列表 */
+            $_ios_new = $_hpl_class->getInfoById(NewsConst::NEWS_ID_HUNTER_IOS_NEW);
+            $this->assign('ios_new', $_ios_new);
+            $_ios_list = $_post_logic->getHtmlList(NewsConst::NEWS_TYPE_HUNTER_IOS);
+            $this->assign('ios_list', $_ios_list['list']);
+            $_wx_share = empty($_item['option_value']['ios']) ? [] : $_item['option_value']['ios'];
+            $this->assign('wx_share', $_wx_share);
+            $_html = $this->fetch('box/hunter/template/ios_index');
+            file_put_contents(HUNTER_PATH.'ios_index.html', $_html);
+        }
+    }
+
+    /**
+     * 全部页面更新
+     */
+    public function createAll() {
+        /* 生成所有单页 */
+        $_type = [NewsConst::NEWS_TYPE_HUNTER_AND, NewsConst::NEWS_TYPE_HUNTER_IOS];
+        $_ids = (new PostsLogic())->getAllIds($_type);
+        if (!empty($_ids)) {
+            foreach ($_ids as $_v) {
+                $this->_createStatic($_v);
+            }
+        }
+        $this->createRankList();
+        $this->createList();
+        $this->adminSuccess('更新成功!');
+    }
+
+    /**
+     * 生成单页面
+     *
+     * @param $id
+     *
+     * @return bool
+     */
+    protected function _createStatic($id) {
+        if (empty($id)) {
+            return false;
+        }
+        $_hpl_class = new huoPostLogic();
+        $_data = $_hpl_class->getInfoById($id);
+        $_data['post_keywords'] = empty($_data['post_keywords']) ? [] : explode(',', $_data['post_keywords']);
+        if (empty($_data)) {
+            return false;
+        }
+        $this->assign('data', $_data);
+        $_template = 'box/hunter/template/read';
+        if (NewsConst::NEWS_TYPE_HUNTER_AND == $_data['post_type']) {
+            $_top = $_hpl_class->getTop($id, [NewsConst::NEWS_TYPE_HUNTER_AND]);
+            $this->assign('top', $_top);
+            $_template = 'box/hunter/template/and_money';
+        }
+        if (NewsConst::NEWS_TYPE_HUNTER_IOS == $_data['post_type']) {
+            $_template = 'box/hunter/template/ios_money';
+        }
+        $_html = $this->fetch($_template);
+        file_put_contents(HUNTER_PATH.$id.'.html', $_html);
+
+        return true;
+    }
+
+    /**
+     * 获取列表选择
+     *
+     * @param $_post_id
+     *
+     * @return array
+     */
+    public function _getPosts($_post_id = 0) {
+        $_map = [
+            'post_type' => ['in', [NewsConst::NEWS_TYPE_HUNTER_IOS, NewsConst::NEWS_TYPE_HUNTER_AND]]
+        ];
+        $_data = (new PostsModel())->getIdName($_map);
+        $_post_select = Filter::selectCommon($_data, 'post_id', $_post_id);
+        $this->assign('post_select', $_post_select);
+        $this->assign('posts', $_data);
+
+        return $_data;
+    }
+
+    /**
+     * 获取目标类型
+     *
+     * @param string $type
+     *
+     * @return array
+     */
+    public function _target_types($type = 'url') {
+        $_target_types = [
+            'url'   => '链接',
+            'posts' => '文章',
+        ];
+        $_target_types_radio = Filter::radioCommon($_target_types, 'target_type', $type);
+        $this->assign('target_types_radio', $_target_types_radio);
+        $this->assign('target_types', $_target_types);
+
+        return $_target_types;
+    }
+
+    /**
+     * 获取排行
+     *
+     * @param $rank_by
+     *
+     * @return array
+     */
+    public function _getRankBy($rank_by = '') {
+        $_array = [
+            'day_money'   => '本日金额',
+            'month_money' => '本月金额',
+            'total_money' => '总金额'
+        ];
+        $_rank_by_select = Filter::selectCommon($_array, 'rank_by', $rank_by);
+        $this->assign('ank_by_select', $_rank_by_select);
+
+        return $_array;
+    }
+
+    /**
+     * 分享配置
+     * admin/mp.hunter.hunter/shareCfg
+     */
+    public function shareCfg() {
+        $setting_name = OptionConst::HUNTER_SHARE_CFG;
+        $_option_value = [
+            'wx_app_id' => '',
+            'android'   => [
+                'title' => '',
+                'desc'  => '',
+                'image' => ''
+            ],
+            'ios'       => [
+                'title' => '',
+                'desc'  => '',
+                'image' => ''
+            ],
+        ];
+        $_m = new Option();
+        $_item = $_m->getOptionData($setting_name, 1, true, json_encode($_option_value));
+        if (!empty($_item['option_value'])) {
+            $_item['option_value'] = json_decode($_item['option_value'], true);
+            $_option_value = array_merge($_option_value, $_item['option_value']);
+        }
+        $this->assign($_option_value);
+
+        return $this->fetch('box/hunter/share_cfg');
+    }
+
+    /**
+     * 分享配置
+     * admin/mp.hunter.hunter/shareCfgPost
+     */
+    public function shareCfgPost() {
+        $_setting_name = OptionConst::HUNTER_SHARE_CFG;
+        $_param = $this->request->param();
+        $_option_vale = [
+            'wx_app_id' => get_val($_param, 'wx_app_id', ''),
+            'android'   => [
+                'title' => empty($_param['android']) ? '' : $_param['android']['title'],
+                'desc'  => empty($_param['android']) ? '' : $_param['android']['desc'],
+                'image' => empty($_param['android']) ? '' : $_param['android']['image']
+            ],
+            'ios'       => [
+                'title' => empty($_param['ios']) ? '' : $_param['ios']['title'],
+                'desc'  => empty($_param['ios']) ? '' : $_param['ios']['desc'],
+                'image' => empty($_param['ios']) ? '' : $_param['ios']['image']
+            ],
+        ];
+        $_res = (new Option())->saveOptionData($_setting_name, json_encode($_option_vale));
+        if (!$_res) {
+            $this->adminError(lang('ERROR'));
+        }
+        $this->adminSuccess(lang('SUCCESS'));
+    }
+}

+ 66 - 0
admin/admin/controller/mp/member/MemRiskController.php

@@ -0,0 +1,66 @@
+<?php
+/**
+ * MemRiskController.php  UTF-8
+ * huosdk_mini_program
+ *
+ * @date    : 2018/10/11 19:44
+ *
+ * @license 这不是一个自由软件,未经授权不许任何使用和传播。
+ * @author  : chenbingling <cbl@huosdk.com>
+ * @version : HUOSDK 8.0
+ */
+
+namespace admin\admin\controller\mp\member;
+
+use cmf\controller\AdminBaseController;
+use cmf\view\Filter;
+use huolib\constant\RiskConst;
+use huolib\tool\Page;
+use huorisk\logic\MemRiskLogic;
+use think\Cache;
+
+class MemRiskController extends AdminbaseController {
+    protected function _getLevel($level) {
+        $_level_data = RiskConst::getRiskLevelMsg($level, true);
+        $_select = Filter::selectCommon($_level_data, 'risk_level', $level);
+        $this->assign('level_select', $_select);
+
+        return empty($_level_data[$level]) ? '' : $_level_data[$level];
+    }
+
+    /**
+     * 风控列表
+     */
+    public function index() {
+        $_param = $this->request->param();
+        $_mem_id_input = Filter::text('mem_id', get_val($_param, 'mem_id', ''), '请输入玩家ID');
+        $this->assign('mem_id_input', $_mem_id_input);
+        $_username_input = Filter::text('username', get_val($_param, 'username', ''), '请输入玩家账号');
+        $this->assign('username_input', $_username_input);
+        $_nickname_input = Filter::text('nickname', get_val($_param, 'nickname', ''), '请输入玩家昵称');
+        $this->assign('nickname_input', $_nickname_input);
+        $_sub_cnt_mini_input = Filter::text('sub_cnt_mini', get_val($_param, 'sub_cnt_mini', ''), '徒弟数量');
+        $this->assign('sub_cnt_mini_input', $_sub_cnt_mini_input);
+        $_sub_cnt_max_input = Filter::text('sub_cnt_max', get_val($_param, 'sub_cnt_max', ''), '徒弟数量');
+        $this->assign('sub_cnt_max_input', $_sub_cnt_max_input);
+        $this->_getLevel(get_val($_param, 'risk_level', 0));
+        $_type_data = [
+            'withdraw' => '提现比',
+            'expand'   => '拓展比',
+            'wechat'   => '微信比',
+            'same_ip'  => '同IP比',
+            'warrant'  => '授权比',
+            'realname' => '实名比',
+        ];
+        $_type_check = Filter::checkCommon($_type_data, 'type[]', $this->request->param('type/a',[]));
+        $this->assign('type_check', $_type_check);
+        $_page = get_val($_param, 'page', 1);
+        $_list_rows = get_val($_param, 'list_rows', 50);
+        $_data = (new MemRiskLogic())->getList($_param, $_page.','.$_list_rows);
+        $_items = (new Page())->paginate($_data['count'], $_data['list'], $_page, $_list_rows);
+        $this->assign('items', $_data['list']);
+        $this->assign('page', $_items->render());
+
+        return $this->fetch('box/member/mem_risk');
+    }
+}

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