Phalcon Framework 5.12.1

Error: Class "Phalcon\Validation\Validator\StringLength" not found

/var/www/html/app/modules/Admin/Form/RegisterForm.php (40)
# Admin\Form\RegisterForm -> initialize
# Phalcon\Forms\Form -> __construct
/var/www/html/app/modules/Admin/Controller/IndexController.php (695)
<?php
 
/**
 * IndexController
 * @copyright Copyright (c) 2020 Markboo (http://cnski.cn)
 * @author Markboo <markboo@foxmail.com>
 */
 
namespace Admin\Controller;
 
use Admin\Form\CompanyRegisterForm;
use Admin\Form\LoginForm;
use Admin\Form\RegisterForm;
use Admin\Model\UserVerify;
use Application\Mvc\Controller;
use Application\Mvc\Model\Model;
use Application\Utils\Captcha;
use Application\Utils\SendMail;
use Application\Utils\WeixinAuth\WeixinAuth;
use Distribution\Model\Shop;
use Finance\Model\Dealings;
use Managements\Model\AdminUser;
use Managements\Model\CompanyBranch;
use Managements\Model\Companys;
use Managements\Model\Role;
use Managements\Model\Staff;
use Phalcon\Forms\Form;
use Phalcon\Http\Response;
use Phalcon\Mvc\Model\Transaction;
use Phalcon\Mvc\Model\Transaction\Failed as TransactionFailed;
use Phalcon\Mvc\Model\Transaction\Manager as TransactionManager;
use Phalcon\Mvc\View;
use stdClass;
use System\Model\BillingAccount;
use System\Model\InOutType;
use System\Model\RecPayDetailDefaultType;
use System\Model\RoleTemplate;
 
class IndexController extends Controller
{
    public $controller_title = '后台管理系统'; //控制器名称
    public $controller_role = false; //是否使用权限控制,true: 将展示在权限管理页面
    public $default_all_permission = true;  //默认全部用户授权,false: 将展示在权限管理页面
    private $timeout = 300;
 
    /**
     * 初始化登录画面
     */
    public function indexAction()
    {
        $this->session->set('frame', true);
        $this->setFrameEnvironment();
        $this->view->languages_disabled = true;
        $auth = $this->session->get('auth');
        if (!$auth || !isset($auth->admin_session) || !$auth->admin_session) {
            $this->redirect($this->url->get() . 'admin/index/login?f=frame');
            return;
        } else {
            $staff = Staff::getUserInfo($auth->user_id, $auth->company_id);
            if ($staff) {
                $this->session->set('auth', Staff::getAuthDataFromCache($auth->company_id, $auth->user_id));
                $res = BillingAccount::isWarningAccount($auth->company_id);
                if ($res !== false) {
                    $this->view->billing_warning = $res;
                } else {
                    $this->view->billing_warning = '';
                }
            } else {
                $this->logoutAction();
            }
        }
        $this->helper->title($this->helper->at('控制面板'), true);
        $this->helper->activeMenu()->setActive('admin-home');
    }
 
    /**
     * 初始化登录画面
     */
    public function homeAction()
    {
        $this->setAdminEnvironment();
        $this->view->languages_disabled = true;
        $auth = $this->session->get('auth');
        if (!$auth) {
            if (isset($auth->company_id) && isset($auth->user_id)) {
                $this->session->set('auth', Staff::getAuthDataFromCache($auth->company_id, $auth->user_id));
            }
        }
        $company_id = $this->getAuthInfo('company_id');
        $res = BillingAccount::isWarningAccount($company_id);
        if ($res !== false) {
            $this->view->billing_warning = $res;
        } else {
            $this->view->billing_warning = '';
        }
        $this->view->company_id = $company_id;
        $this->helper->title($this->helper->at('首页面板'), true);
        $this->helper->activeMenu()->setActive('admin-home');
    }
 
    /**
     * isLogin 判断如果已经登录,则直接跳转至控制台首页
     */
    private function isLoginToIndex()
    {
        $auth = $this->session->get('auth');
        if (isset($auth) && isset($auth->admin_session) && $auth->admin_session) {
            $this->redirect($this->url->get() . 'admin/index?f=frame');
            return;
        }
    }
 
    /**
     * 微信扫码登录
     * @return string|mixed|void
     */
    public function wxLoginAction()
    {
        $appid = "wx9f374e7d76d1ca4d"; //系统的公众号appid
        $secret = "9f620fa78b5ecb23c8eafb901e2f7c9b";
        $code = $this->request->getQuery('code', 'string', '');
        $state = $this->request->getQuery('state', 'string', '');
        $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
        if (!empty($code) && !empty($state)) {
            $data = WeixinAuth::weixinAuthAccessToken($appid, $secret, $code);
            if ($data->openid && $data->unionid) {
                $conditions = "openid = :openid: OR unionid = :unionid:";
                $parameters = ["openid" => $data->openid, "unionid" => $data->unionid];
                $user = AdminUser::findFirst([$conditions, "bind" => $parameters]);
                if ($user) {
                    $staff_info = Staff::getFirstUserInfo($user->id);
                    if (!$staff_info) {
                        $this->view->error = true;
                        $this->view->message = $this->helper->translate("无效的登录名或密码!");
                    } else {
                        if ($staff_info->isActive()) {
                            $company_staffs = Staff::find([
                                "user_id = :user_id: and active = '1'",
                                "bind" => ["user_id" => $staff_info->user_id]
                            ]);
                            $company_ids = [];
                            foreach ($company_staffs as $item) {
                                $company_ids[] = strval($item->company_id);
                            }
                            if (sizeof(Companys::find([
                                "conditions" => "company_id IN ({company_ids:array}) AND active = :active:",
                                "bind" => [
                                    "company_ids" => $company_ids,
                                    "active" => '1'
                                ]
                            ])) == 0) {
                                $this->flash->clear();
                                $this->flash->error($this->helper->translate("无效的登录用户!"));
                            } else {
                                $this->session->set('auth', Staff::getAuthDataFromCache($staff_info->company_id, $staff_info->user_id));
                                $this->redirect($this->url->get().'admin?f=frame');
                                $this->view->disable();
                                return;
                            }
                        } else {
                            $this->flash->clear();
                            $this->flash->error($this->helper->translate("用户不是一个激活用户!"));
                        }
                    }
                } else {
                    $this->flash->clear();
                    $this->flash->error($this->helper->translate("没有绑定该微信的用户,请使用账号密码登录!"));
                }
            } else {
                $this->flash->clear();
                $this->flash->error($this->helper->translate("扫码授权失败,请刷新重试!"));
            }
        } else {
            $this->flash->clear();
            $this->flash->error($this->helper->translate("扫码失败,请刷新重试!"));
        }
        $this->redirect($this->url->get().'admin/index/login?f=frame');
        $this->view->disable();
        return;
    }
 
    /**
     * 绑定微信
     */
    public function wxbindAction()
    {
        $appid = "wx9f374e7d76d1ca4d";
        $secret = "9f620fa78b5ecb23c8eafb901e2f7c9b";
        $code = $this->request->getQuery('code', 'string', '');
        $state = $this->request->getQuery('state', 'string', '');
        $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
        if (!empty($code) && !empty($state) && !empty($state)) {
            $data = WeixinAuth::weixinAuthAccessToken($appid, $secret, $code);
            if ($data->openid && $data->unionid) {
                $conditions = "openid = :openid: or unionid = :unionid:";
                $parameters = ["openid" => $data->openid, "unionid" => $data->unionid];
                $check_user = AdminUser::findFirst([$conditions, "bind" => $parameters]);
                if (!$check_user) {
                    $user_id = $state;
                    $conditions = "id = :id:";
                    $parameters = ["id" => $user_id];
                    $user = AdminUser::findFirst([$conditions, "bind" => $parameters]);
                    if ($user) {
                        $user->openid = $data->openid;
                        $user->unionid = $data->unionid;
                        if ($user->update()) {
                            $staff_info = Staff::getFirstUserInfo($user->id);
                            $this->session->set('auth', Staff::getAuthDataFromCache($staff_info->company_id, $staff_info->user_id));
                            $this->view->message = "绑定成功!";
                        } else {
                            $this->view->message = "绑定失败,请刷新重试!";
                        }
                    }
                } else {
                    $this->view->message = "绑定失败,该微信已经被其他账号绑定,请更换重试!";
                }
            } else {
                $this->view->message = "扫码授权失败,请刷新重试!";
            }
        } else {
            $this->view->message = "扫码失败,请刷新重试!";
        }
    }
 
    /**
     * 判断一个用用是否三次以上登录错误显示图形验证码
     * @param string $user_name 登录用户名
     * @return boolean
     */
    private function getCaptchaShow($user_name)
    {
        $cache = $this->di->get('cache');
        $captcha_count = $cache->get('captcha_'.$user_name);
        $show_captcha = false;
        if ($captcha_count >= 3) {
            $show_captcha = true;
        }
        $cache->set('captcha_'.$user_name, $captcha_count + 1);
        return $show_captcha;
    }
 
    /**
     * 登录动作
     * @return mixed|void
     */
    public function loginAction()
    {
        $this->isLoginToIndex();
        $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
        $ref = $this->request->getPost('r', 'string', '');
        if (empty($ref)) $ref = $this->request->getQuery('r', 'string', '');
        $this->view->ref = $ref;
        /** @var Form $form */
        $form = new LoginForm();
        $this->view->form = $form;
        $this->view->show_captcha = false;
        $config = $this->di->get('config');
        $system_name = $config->system_name;
        $this->view->system_name = $system_name;
        $style_mode = isset($_COOKIE['style_mode']) ? true : false;
        if ($style_mode) {
            $this->view->main_style = "dark-body";
        } else {
            $this->view->main_style = "";
        }
        if ($this->request->isPost()) {
            if ($this->security->checkToken()) {
                if ($form->isValid($this->request->getPost())) {
                    $captcha = $this->request->getPost('captcha', 'string');
                    $login = $this->request->getPost('login', 'string');
                    $password = $this->request->getPost('password', 'string');
                    $show_captcha = $this->getCaptchaShow($login);
                    if (!empty($captcha)) {
                        //校验图形验证码
                        $check_captcha = $this->checkCaptcha($captcha);
                        if (!empty($check_captcha)) {
                            $this->flash->error($check_captcha);
                            $this->view->show_captcha = $show_captcha;
                            return;
                        }
                    }
                    $user = AdminUser::findFirst([
                        "conditions" => "login = :login: OR mobile = :mobile:",
                        "bind" => ["login" => $login, "mobile" => $login],
                        "order" => "id ASC"  // 或 "id DESC",确保每次返回同一行
                    ]);
                    $this->view->show_captcha = $show_captcha;
                    if ($user) {
                        if ($user->checkPassword($password)) {
                            $staff_info = Staff::getFirstUserInfo($user->id);
                            if (!$staff_info) {
                                $this->flash->clear();
                                $this->flash->error($this->helper->translate("[10012]无效的登录名或密码!"));
                            } else {
                                if ($staff_info->isActive()) {
                                    $company_staffs = Staff::find([
                                        "user_id = :user_id: AND active = '1' AND is_online = '1'",
                                        "bind" => ["user_id" => $staff_info->user_id]
                                    ]);
                                    $company_ids = [];
                                    foreach ($company_staffs as $item) {
                                        $company_ids[] = strval($item->company_id);
                                    }
                                    if (empty($company_ids) or sizeof(Companys::find([
                                        "conditions" => "company_id IN ({company_ids:array}) AND active = :active:",
                                        "bind" => [
                                            "company_ids" => $company_ids,
                                            "active" => '1'
                                        ]
                                    ])) == 0) {
                                        $this->flash->clear();
                                        $this->flash->error($this->helper->translate("[10014]无效的登录用户"));
                                    }
                                    $staff_auth_data = $staff_info->saveAuthDataToCache();
                                    $this->session->set('auth', $staff_auth_data);
                                    $user->updateLastLoginDatetime();
                                    if ($ref == '') {
                                        $this->redirect($this->url->get() . 'admin?f=frame');
                                        $this->view->disable();
                                        return;
                                    } else {
                                        $ref = pack('H*', $ref);
                                        $this->redirect($ref);
                                        $this->view->disable();
                                        return;
                                    }
                                } else {
                                    $this->flash->clear();
                                    $this->flash->error($this->helper->translate("[10013]用户不是一个激活用户!"));
                                }
                            }
                        } else {
                            $this->flash->clear();
                            $this->flash->error($this->helper->translate("[10010]无效的登录名或密码!"));
                        }
                    } else {
                        $this->flash->clear();
                        $this->flash->error($this->helper->translate("[10011]无效的登录名!"));
                    }
                } else {
                    foreach ($form->getMessages() as $message) {
                        $this->flash->error($message);
                    }
                }
            } else {
                $clear = $this->request->getQuery('clear', 'string', '');
                if ($clear == 'true') {
                    $this->logoutAction();
                } else {
                    $this->flash->error($this->helper->translate("安全错误!登录页面禁止刷新!"));
                }
            }
        }
        return;
    }
 
    /**
     * 注册公司
     * @return mixed|void
     */
    public function companyRegisterAction()
    {
        $this->isLoginToIndex();
        $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
        /** @var Form $form */
        $form = new CompanyRegisterForm();
        $company_type = $this->request->getPost('company_type', 'string');
        $form->get("company_type")->setDefault($company_type);
        $this->view->form = $form;
        $config = $this->di->get('config');
        $system_name = $config->system_name;
        $this->view->system_name = $system_name;
        $manage_company_id = '00001';
        $ref = $this->request->getPost('r', 'string', '');
        if (empty($ref)) $ref = $this->request->getQuery('r', 'string', '');
        $this->view->ref = $ref;
        if ($this->request->isPost()) {
            if ($this->security->checkToken()) {
                if ($form->isValid($this->request->getPost())) {
                    $captcha = $this->request->getPost('captcha', 'string');
                    $company_name = $this->request->getPost('company_name', 'string');
                    $company_nm_short = $this->request->getPost('company_nm_short', 'string');
                    $company_address = $this->request->getPost('company_address', 'string');
                    $name = $this->request->getPost('name', 'string');
                    $mobile = $this->request->getPost('mobile', 'string');
                    $password = $this->request->getPost('password', 'string');
                    $address_select = $this->request->getPost('address_province', 'string');
                    $address_select_city = $this->request->getPost('address_city', 'string');
                    $address_select_area = $this->request->getPost('address_area', 'string');
                    //校验图形验证码
                    $check_captcha = $this->checkCaptcha($captcha);
                    if (!empty($check_captcha)) {
                        $this->flash->error($check_captcha);
                        return;
                    }
                    if (!preg_match("/^1[34578]\d{9}$/", $mobile)) {
                        $this->flash->error("电话号码格式不正确,请重新输入");
                        return;
                    }
                    //数据库查找用户
                    $conditions = "(login = :login: OR mobile = :mobile:)";
                    $company_conditions = "(company_telephone = :company_telephone:)";
                    $parameters = ["login" => $mobile, "mobile" => $mobile];
                    $company = Companys::findFirst([$company_conditions, "bind" => ["company_telephone" => $mobile]]);
                    //如果用户存在
                    if ($company) {
                        $this->flash->error($this->helper->translate("手机号已经被注册!"));
                    } else {
                        try {
                            //创建事务管理器
                            $transactionManager = new TransactionManager();
                            //获取事务
                            /** @var Transaction $transaction */
                            $transaction = $transactionManager->get();
                            //开始创建管用户id和保存密码
                            $admin_user = AdminUser::findFirst([$conditions, "bind" => $parameters]);
                            if (!$admin_user) {
                                $admin_user = new AdminUser();
                                $admin_user->setTransaction($transaction);
                                $admin_user->id = ukey_next_id();
                                $admin_user->login = $mobile;
                                $admin_user->name = $name;
                                $admin_user->mobile = $mobile;
                                $admin_user->setUserPassword($password);
                                if (!$admin_user->create()) {
                                    foreach ($admin_user->getMessages() as $message) {
                                        error_log($message);
                                    }
                                    $transaction->rollback();
                                }
                            } else {
                                $admin_user->setTransaction($transaction);
                                $admin_user->setUserPassword($password);
                                if (!$admin_user->update()) {
                                    $transaction->rollback($admin_user->getErrorMessage());
                                }
                            }
                            $authData = new stdClass();
                            $authData->id = $admin_user->id;
                            $authData->name = $name;
                            $authData->manage_company_id = $manage_company_id;
                            $this->session->set('auth', $authData);
                            //开始创建公司
                            $company_model = new Companys();
                            $company_model->manage_company_id = $manage_company_id;
                            $company_model->company_id = ukey_next_id();
                            $company_model->company_name = $company_name;
                            $company_model->company_nm_short = $company_nm_short;
                            $company_model->company_address = $company_address;
                            $company_model->company_liaison = $name;
                            $company_model->company_telephone = $mobile;
                            $company_model->company_type = $company_type;
                            $company_model->active = 1;
                            $company_model->address_select = $address_select;
                            $company_model->address_select_city = $address_select_city;
                            $company_model->address_select_district = $address_select_area;
                            $company_model->setTransaction($transaction);
                            if (!$company_model->create()) {
                                foreach ($company_model->getMessages() as $message) {
                                    error_log($message);
                                }
                                $transaction->rollback();
                            }
                            $dealing_model = new Dealings();
                            $dealing_model->manage_company_id = $company_model->manage_company_id;
                            $dealing_model->company_id = $company_model->manage_company_id;
                            $dealing_model->dealings_name = $company_name;
                            $dealing_model->dealings_nm_short = $company_nm_short;
                            $dealing_model->liaisons = $name;
                            $dealing_model->tel = $mobile;
                            $dealing_model->finance_type_id = '1';//固定客户
                            $dealing_model->active = '1';
                            $dealing_model->setTransaction($transaction);
                            if (!$dealing_model->create()) {
                                foreach ($dealing_model->getMessages() as $message) {
                                    error_log($message);
                                }
                                $transaction->rollback();
                            }
                            $billing_model = new BillingAccount();
                            $billing_model->manage_company_id = $manage_company_id; //管理公司ID
                            $billing_model->company_id = $company_model->company_id; //计费组织ID
                            $billing_model->billing_start_datetime = date("Y-m-d");  //开始日期
                            $billing_model->service_life = date("Y-m-d", strtotime("+15 days"));  //计费到期日期默认等于开始日期
                            $billing_model->price = 0.04; //计费到期日期默认等于开始日期
                            $billing_model->goods_max_qty = 1000;
                            $billing_model->dealings_id = $dealing_model->dealings_id;
                            $billing_model->balance = 200;
                            $billing_model->billing_mode = '2'; //按订单数量收费
                            $billing_model->setTransaction($transaction);
                            if (!$billing_model->create()) {
                                foreach ($billing_model->getMessages() as $message) {
                                    error_log($message);
                                }
                                $transaction->rollback();
                            }
                            //创建基础管理部门
                            $branch_model = new CompanyBranch();
                            $branch_model->setTransaction($transaction);
                            $branch_model->manage_company_id = $manage_company_id;
                            $branch_model->company_id = $company_model->company_id;
                            $branch_model->branch_id = ukey_next_id();
                            $branch_model->branch_name = '管理部门';
                            $branch_model->branch_liaison = $name;
                            $branch_model->branch_telephone = $mobile;
                            $branch_model->active = 1;
                            if (!$branch_model->create()) {
                                foreach ($branch_model->getMessages() as $message) {
                                    error_log($message);
                                }
                                $transaction->rollback();
                            }
                            //通过角色模板创建角色
                            $role_template_model = RoleTemplate::cloneRoleByRoleTemplateIdWithCompanyId($manage_company_id, $company_type);
                            $role_id = '';
                            if ($role_template_model) {
                                foreach ($role_template_model as $template) {
                                    $role_model = new Role();
                                    $role_model->setTransaction($transaction);
                                    $role_model->title = $template->title;
                                    $role_model->allow_list = $template->allow_list;
                                    $role_model->organization_permissions = $template->organization_permissions;
                                    $role_model->data_permissions = $template->data_permissions;
                                    $role_model->order_data_permissions = $template->order_data_permissions;
                                    $role_model->customer_data_permissions = $template->customer_data_permissions;
                                    $role_model->manage_company_id = $manage_company_id;
                                    $role_model->company_id = $company_model->company_id;
                                    if (!$role_model->create()) {
                                        foreach ($role_model->getMessages() as $message) {
                                            error_log($message);
                                        }
                                        $transaction->rollback();
                                    } else {
                                        if ($template->is_default_role_id == 1) {
                                            $role_id = $role_model->role_id;
                                        }
                                    }
                                }
                            }
                            //为公司创建收发明细项
                            $company_payment_type_ids = RecPayDetailDefaultType::createPaymentTypeForRegisterCompany($company_type, $company_model->company_id, $transaction);
                            //为公司创建出入库类型
                            InOutType::createInOutTypeForRegisterCompany($company_type, $company_model->company_id, $transaction, $company_payment_type_ids);
                            //开始创建管理员用户
                            $new_staff = new Staff();
                            $new_staff->setTransaction($transaction);
                            $new_staff->user_id = $admin_user->id;
                            $new_staff->role = $role_id;
                            $new_staff->name = $new_staff->nick_name = $name;
                            $new_staff->company_id = $company_model->company_id;
                            $new_staff->manage_company_id = $manage_company_id;
                            $new_staff->branch_id = $branch_model->branch_id;
                            $new_staff->active = 1;
                            $new_staff->mobile = $mobile;
                            $new_staff->staff_status = '2'; //审核状态:已审核
                            if (!$new_staff->create()) {
                                foreach ($new_staff->getMessages() as $message) {
                                    error_log($message);
                                }
                                $transaction->rollback();
                            } else {
                                $this->session->remove('auth');
                            }
                            $transaction->commit();
                            $company_model->saveCompanyToCacheForRegister();
                            Shop::createDefaultShop($company_model);
                            $this->flash->success($this->helper->at('企业注册成功!截止至'.strval($billing_model->service_life)."贵公司可体验试用".strval($billing_model->balance)."单"));
                            $this->redirect($this->url->get() . 'admin/index/finish');
                        } catch (TransactionFailed $e) {
                            $this->session->remove('auth');
                            error_log('[' . __METHOD__ . ']:' . "Failed, reason: Transaction Failed!" . $e->getMessage(), 0);
                            $this->flash->error($this->helper->at('企业注册失败!'));
                        }
                    }
                } else {
                    foreach ($form->getMessages() as $message) {
                        $this->flash->error($message);
                    }
                }
            } else {
                $this->flash->error($this->helper->translate("安全错误!登录页面禁止刷新!"));
            }
        }
    }
 
    /**
     * 注册完成
     */
    public function finishAction()
    {
        $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
        $config = $this->di->get('config');
        $system_name = $config->system_name;
        $this->view->system_name = $system_name;
    }
 
    /**
     * 注册用户
     * @return mixed|void
     */
    public function registerAction()
    {
        $this->isLoginToIndex();
        $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
        /** @var Form $form */
        $form = new RegisterForm();
        $this->view->form = $form;
        $config = $this->di->get('config');
        $system_name = $config->system_name;
        $this->view->system_name = $system_name;
        $ref = $this->request->getPost('r', 'string', '');
        if ($ref == '') $ref = $this->request->getQuery('r', 'string', '');
        $this->view->ref = $ref;
        if ($this->request->isPost()) {
            $post = $this->request->getPost();
            if ($this->security->checkToken()) {
                if ($form->isValid($this->request->getPost())) {
                    $captcha = $this->request->getPost('captcha', 'string');
                    $login = $this->request->getPost('login', 'string');
                    $email = $this->request->getPost('email', 'string');
                    $mobile = $this->request->getPost('mobile', 'string');
                    //校验图形验证码
                    $check_captcha = $this->checkCaptcha($captcha);
                    if ($check_captcha !== '') {
                        $this->flash->error($check_captcha);
                        return;
                    }
                    if (!preg_match("/^1[34578]\d{9}$/", $mobile)) {
                        $this->flash->error("电话号码格式不正确,请重新输入");
                        return;
                    }
                    //数据库查找用户
                    $conditions = "(login = :login: OR mobile = :mobile:)";
                    $parameters = ["login" => $login, "mobile" => $mobile];
                    $user = AdminUser::findFirst([$conditions, "bind" => $parameters]);
                    //如果用户存在
                    if ($user) {
                        $this->flash->error($this->helper->translate("登陆用户名或者手机号/Email已经被注册!"));
                    } else {
                        $conditions = "(email = :email: OR mobile = :mobile:)";
                        $parameters = ["email" => $email, "mobile" => $mobile];
                        $staff = Staff::findFirst([$conditions, "bind" => $parameters]);
                        if ($staff) {
                            $this->flash->error($this->helper->translate("登陆用户名或者手机号/Email已经被注册!"));
                        } else {
                            $new_staff = new Staff();
                            $form->bind($post, $new_staff);
                            $new_staff->id = ukey_next_id();
                            $new_staff->page_limit = 15;
                            if ($new_staff->save()) {
                                $this->flash->success($this->helper->at('创建用户成功,请登录!'));
                                $this->redirect($this->url->get().'admin/index/login');
                                return;
                            } else {
                                $this->flashErrors($new_staff);
                            }
                        }
                    }
                } else {
                    foreach ($form->getMessages() as $message) {
                        $this->flash->error($message);
                    }
                }
            } else {
                $this->flash->error($this->helper->translate("安全错误!登录页面禁止刷新!"));
            }
        }
    }
 
    /**
     * 登出
     **/
    public function logoutAction()
    {
        if ($this->request->isPost()) {
            if ($this->security->checkToken()) {
                $this->session->remove('auth');
            } else {
                $this->flash->error("安全错误!");
            }
        } else {
            $this->session->remove('auth');
        }
        return $this->redirect($this->url->get() . 'admin?f=frame');
    }
 
    /**
     * 忘记密码
     * @return mixed|void
     */
    public function forgetAction()
    {
        $this->isLoginToIndex();
        $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
        $form = new RegisterForm();
        $this->view->form = $form;
        $ref = $this->request->getPost('r', 'string', '');
        if ($ref == '') $ref = $this->request->getPost('r', 'string', '');
        $this->view->ref = $ref;
        if ($this->request->isPost()) {
            if ($this->security->checkToken()) {
                $captcha = $this->request->getPost('captcha', 'string');
                $login = $this->request->getPost('login', 'string');
                $email = $this->request->getPost('email', 'string');
                //校验图形验证码
                $check_captcha = $this->checkCaptcha($captcha);
                if ($check_captcha !== '') {
                    $this->flash->error($check_captcha);
                    return;
                }
                //数据库查找用户
                $conditions = "login = :login: and email = :email:";
                $parameters = ["login" => $login, "email" => $email];
                $user = AdminUser::findFirst([$conditions, "bind" => $parameters]);
                //如果用户存在
                if ($user) {
                    $randStr = str_shuffle('1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
                    $rand = hash('sha512', substr($randStr, 0, 32));
                    $verify = UserVerify::findFirst([$conditions, "bind" => $parameters]);
                    //是否已经发送过验证码
                    if ($verify) {
                        $verify->verify_code = $rand;
                    } else {
                        $verify = new UserVerify();
                        $verify->id = ukey_next_id();
                        $verify->login = $login;
                        $verify->email = $email;
                        $verify->verify_code = $rand;
                    }
                    //更新验证码,并发送验证码邮件
                    if ($verify->save()) {
                        $this->sendForgotMail($email, $rand);
                        $this->session->set('forget', 'true');
                        $this->redirect($this->url->get() . 'admin/index/confirm');
                    } else {
                        $this->flash->error("发送验证码失败!");
                        foreach ($verify->getMessages() as $message) {
                            error_log($message->getMessage());
                        }
                    }
                } else {
                    $this->flash->error($this->helper->translate("该用户名或者Email不存在!"));
                }
            } else {
                $this->flash->error($this->helper->translate("安全错误!登录页面禁止刷新!"));
            }
        }
    }
 
    /**
     * 去确认邮件
     */
    public function confirmAction()
    {
        $this->isLoginToIndex();
        $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
        $form = new RegisterForm();
        $this->view->form = $form;
        if ($this->session->has("forget")) {
            $this->view->title = 'STEP 2 去确认邮件';
            $this->flash->success("向指定的邮件地址发送邮件成功,请您去邮箱确认邮件,如果您没有收到,可以试着去邮箱的垃圾桶里翻翻看,也许或者被被您的邮箱系统拦截了!");
            $this->session->remove("forget");
        } else {
            $this->view->title = '验证信息';
        }
    }
 
    /**
     * 报告页面
     */
    public function reportAction()
    {
        $this->view->company_id = $this->getAuthInfo('company_id');
        $this->setBlankEnvironment();
        $this->helper->title($this->helper->at('数据看板'), true);
    }
 
    /**
     * 校验邮箱,并修改密码
     * @return mixed|void
     */
    public function verifyAction()
    {
        $this->isLoginToIndex();
        $this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
        $form = new RegisterForm();
        $this->view->form = $form;
        //校验表单
        $verify_code = $this->request->getQuery('email_verify', 'string', '') ?: $this->request->getPost('email_verify', 'string');
        if (!empty($verify_code)) {
            //数据库查找用户
            $conditions = "verify_code = :verify_code:";
            $parameters = ["verify_code" => $verify_code];
            $verify = UserVerify::findFirst([$conditions, "bind" => $parameters]);
            if ($verify) {
                $password = $this->request->getPost('password', 'string', '');
                if (!empty($password)) {
                    $user = AdminUser::findFirst([
                        "login = :login: AND email = :email:",
                        "bind" => ["login" => $verify->login, "email" => $verify->email]
                    ]);
                    $user->setUserPassword($password);
                    if ($user->update()) {
                        if ($verify->delete()) {
                            $this->view->success = true;
                            $this->flash->success('修改密码成功,请返回重新登录!');
                            $this->dispatcher->forward(["action" => "confirm"]);
                            return;
                        }
                    } else {
                        $this->flash->error('密码修改失败,原因可能发生在写入数据库时,请试着重新验证邮箱!');
                        $this->dispatcher->forward(["action" => "confirm"]);
                        return;
                    }
                } else {
                    return;
                }
                if ($verify->getDatetimeValidity()) {
                    $user = AdminUser::findFirst([
                        "login = :login: AND email = :email:",
                        "bind" => ["login" => $verify->login, "email" => $verify->email]
                    ]);
                    if ($user) {
                        $this->flash->success('邮箱验证成功,请输入新密码!');
                        $this->view->email_verify = $verify_code;
                        return;
                    } else {
                        $this->flash->error('没有找到该用户,无法完成修改密码!');
                        $this->dispatcher->forward(["action" => "confirm"]);
                        return;
                    }
                } else {
                    $this->flash->error('验证码时间失效,无法使用!');
                    $this->dispatcher->forward(["action" => "confirm"]);
                    return;
                }
            } else {
                $this->flash->error('邮箱验证失败,无效的邮箱验证码!');
                $this->dispatcher->forward(["action" => "confirm"]);
                return;
            }
        } else {
            $this->flash->error('邮箱验证失败,无效的请求!');
            $this->dispatcher->forward(["action" => "login"]);
            return;
        }
    }
 
    /**
     * 发行图形验证码
     */
    public function captchaAction()
    {
        $this->view->disable();
        $response = new Response();
        $captcha = new Captcha();
        $response->setHeader("Content-Type", "image/png");
        $response->setContent($captcha->CreateImage($this->session)->asImage());
        return $response;
    }
 
    /**
     * 获取角色列表接口
     */
    public function ajaxGetRoleListAction()
    {
        $response = ['success' => false, 'message' => '系统参数有误', 'data' => []];
        if ($this->request->getPost()) {
            $company_type = $this->request->getPost('company_type', 'string', '');
            if ($company_type != '') {
                $model = RoleTemplate::getRoleListByCompanyType($company_type);
                if ($model) {
                    $response['data'] = $model;
                    $response['success'] = true;
                    $response['message'] = $this->helper->translate("数据获取成功!");
                } else {
                    $response['message'] = $this->helper->translate("暂无数据!");
                }
            } else {
                $response['message'] = $this->helper->translate("暂无数据!");
            }
        } else {
            $response['message'] = $this->helper->translate("提交数据格式错误!");
        }
        $this->returnJSON($response);
    }
 
    /**
     * 发行图形验证码
     */
    public function changeCompanyAction()
    {
        $response = ['success' => false, 'message' => '系统参数有误', 'data' => []];
        if ($this->request->getPost()) {
            $company_id = $this->request->getPost('company_id', 'string', '');
            if ($company_id) {
                $user_id = $this->getAuthInfo('id');
                $staff_info = Staff::changeUserInfo($user_id, $company_id);
                if ($staff_info) {
                    if ($staff_info->isActive()) {
                        $auth_data = Staff::getAuthDataFromCache($company_id, $user_id);
                        $this->session->set('auth', $auth_data);
                        $cache = $this->di->get('cache');
                        $cache->set('last_login_company_' . $user_id, $company_id);
                        $response['success'] = true;
                        $response['data'] = $auth_data;
                        $response['message'] = $this->helper->translate("切换成功!");
                    } else {
                        $response['message'] = $this->helper->translate("当前用户无效!");
                    }
                } else {
                    $response['message'] = $this->helper->translate("当前用户无效!");
                }
            } else {
                $response['message'] = $this->helper->translate("切换失败!");
            }
        } else {
            $response['message'] = $this->helper->translate("验证表单时出现错误!");
        }
        $this->returnJSON($response);
    }
 
    /**
     * 验证验证码
     * @param $captcha
     * @return string
     */
    private function checkCaptcha($captcha)
    {
        $captcha_session = $this->session->get(Captcha::$session_var);
        $message = '';
        $re = preg_match('/\d{10}/', $captcha_session, $matches);
        if (!$re) {
            $message = $this->helper->translate("验证码获取错误!!");
        }
        if (strtotime('now') - $matches[0] > $this->timeout) {
            $message = $this->helper->translate("验证码超时,请刷新验证码!");
        }
        $captcha_word = explode("_", $captcha_session);
        if ($captcha_word[0] !== $captcha) {
            $message = $this->helper->translate("验证码验证错误!");
        }
        return $message;
    }
 
    /**
     * 发送密码找回邮件模板
     * @param $email
     * @param $rand
     * @noinspection ALL
     * @return void
     */
    public function sendForgotMail($email, $rand)
    {
        $config = $this->di->get('config');
        $server_name = $config->server_name;
        $mail = new SendMail();
        $mail->setServer("localhost", "u-center@eqiyu.com", "wodi67775");
        $mail->setFrom("u-center@eqiyu.com");
        $mail->setReceiver($email);
        $mail->setMailInfo(
            "[系统]安全中心 - 找回密码",
        '<div id="mailContentContainer" class="qmbox qm_con_body_content"><style type="text/css">
      .qmbox *{ margin:0; padding:0; color:#333;}
      .qmbox body{ margin:0; padding:0; font:12px Verdana, Arial, Helvetica, sans-serif;}
      .qmbox a,.qmbox a:link,.qmbox a:visited{color:#80C1E5;font-size:12px;text-decoration:none;}
      .qmbox a:hover{color:#80C1E5;font-size:12px;text-decoration:underline}
      .qmbox a:active{color:#80C1E5;font-size:12px;text-decoration:none;}
      .qmbox ul{list-style:none;}
      .qmbox .marginTop10{margin-top:10px;}
      .qmbox .marginTop15{margin-top:15px;}
      .qmbox .marginTop20{margin-top:20px;}
      .qmbox .marginTop30{margin-top:30px;}
      .qmbox .marginTop40{margin-top:40px;}
      .qmbox .largefont{font-size:20px}
      .qmbox .blackFont{color:#000}
      .qmbox .smallFont{font-size:12px;}
      .qmbox .gray9{color:#999}
      .qmbox #main{width:850px;height:600px;margin:0 auto;}
      .qmbox .linktowb{display:block;width:179px;height:86px;padding:105px 0 0 102px}
      .qmbox .top_div{width:850px;height:85px;background:rgba(24, 149, 232, 0.58) url() no-repeat 0 0;_margin-bottom:-6px}
      .qmbox .bottom_div{width:850px;height:515px;background:rgba(24, 149, 232, 0.58) url() no-repeat 0 0;}
      .qmbox .middle_content{width:630px;height:402px; margin-left:105px;}
      .qmbox .information{margin-left:30px;padding-bottom:105px}
      .qmbox #main2{width:850px;height:600px;margin:0 auto;}
      .qmbox #main2 .bottom_div{width:850px;height:515px;background:rgba(24, 149, 232, 0.58) url() no-repeat 0 0;}
      .qmbox .information2{margin-left:30px;padding-right:30px;width:570px}
      .qmbox .information2 a,.qmbox .information2 a:link,.qmbox .information2 a:visited{color:#0081CB;font-size:14px;text-decoration:none;}
      .qmbox .information2 a:hover{color:#0081CB;font-size:14px;text-decoration:underline}
      .qmbox .information2 a:active{color:#0081CB;font-size:14px;text-decoration:none;}
      .qmbox .aboutMy{width: 565px;padding-bottom:25px;border-bottom:1px dashed #ccc;}
      .qmbox .aboutMy h1{font:bold 18px "微软雅黑",宋体;color:#F98100}
      .qmbox .aboutMy p{font-size:14px;}
      .qmbox .aboutMy .currentInfo .redNomber{font-size:20px;color:#cb0000;}
      .qmbox .aboutMy .currentInfo p{margin-top:20px}
      .qmbox .information2 .links{font-family:Arial, Helvetica, sans-serif}
      .qmbox .shuming{text-align:right;line-height:20px;color:#656565;}
      .qmbox information2 .mailAddr{font-size:20px;color:#000}
      .qmbox .aboutMy2{width: 565px;padding-bottom:25px;border-bottom:1px dashed #ccc;}
      .qmbox .aboutMy2 h1{font:bold 18px "微软雅黑",宋体;color:#F98100}
      .qmbox .aboutMy2 p{font-size:14px;}
      .qmbox .aboutMy2 .currentInfo2{padding:30px 0;}
      .qmbox .aboutMy2 .currentInfo2 p{margin-top:10px;}
      .qmbox .information2 .info2 p{font:12px 宋体;color:#656565;margin:15px 0;}
      .qmbox .foot{text-align:center;margin-top:90px;color:#656565}
      .qmbox .foot3{text-align:center;margin-top:100px;color:#656565}
      .qmbox style, .qmbox script, .qmbox head, .qmbox link, .qmbox meta {display: none !important;}
      </style>
      <div id="main2"> 
    <div class="top_div"><a target="_blank" href="'.$server_name.'" class="linktowb"></a></div>
    <div class="bottom_div">
        <div class="middle_content">
      <div class="information2">
          <div class="aboutMy2">
        <h1>Hi,亲爱的用户!</h1>
        <div class="currentInfo2">
            <p>您在设置找回密码操作的验证链接地址为:</p>
            <p>
            <span style="color:#F98100;font:bold 18px &quot;微软雅黑&quot;,宋体;">
            <span style="border-bottom:1px dashed #ccc;z-index:1" t="7" onclick="return false;" data="270241">
            <a href="'.$server_name . '/admin/index/verify?email_verify='.$rand.'">'.$rand.'</a>
            </span>
            </span>
            </p>
            <p style="font-size:12px;color:#656565">(请在30分钟内完成验证,30分钟后验证码失效,你需要重新进行验证。)</p>
        </div>
          </div>
          <div class="info2">
        <div class="marginTop20">
            <p>此验证码只能使用一次,验证成功自动失效;</p>
            <p>如果你错误的收到了本电子邮件,请您忽略上述内容</p>
        </div>
          </div>
          <p class="shuming marginTop40">系统<br>
             <span style="border-bottom:1px dashed #ccc;" t="5" times="">' . date('Y-m-d', time()) . '</span></p>
      </div>
      <div class="foot3">本邮件是系统发出的邮件,请勿直接回复。</div>
        </div>
    </div>
    </div></div>',
            ""
        );
        $mail->sendMail();
    }
 
    /**
     * 检查数据页面《此页面隐藏页面》
     */
    public function checkdataAction()
    {
        $this->setBlankEnvironment();
    }
}

                            
# Admin\Controller\IndexController -> forgetAction
# Phalcon\Dispatcher\AbstractDispatcher -> callActionMethod
# Phalcon\Dispatcher\AbstractDispatcher -> dispatch
/var/www/html/app/Bootstrap.php (661)
<?php
 
namespace MookeCMS;
 
use Phalcon\Http\Response;
use Phalcon\DI\FactoryDefault;
use Phalcon\Db\Adapter\Pdo\Mysql;
use Phalcon\Mvc\Url;
use Phalcon\Mvc\Application;
use Phalcon\Mvc\View\Engine\Php;
use Phalcon\Mvc\View;
use Phalcon\Db\Profiler;
use Phalcon\Support\Registry;
use Phalcon\Autoload\Loader;
use Phalcon\Cache\Cache;
use Phalcon\Cache\Adapter\Stream;
use Phalcon\Storage\SerializerFactory;
use Phalcon\Cache\Adapter\Libmemcached;
use Phalcon\Cache\Adapter\Redis;
use Phalcon\Assets\Filter\Jsmin;
use Phalcon\Flash\Session as FlashSession;
use Phalcon\Storage\AdapterFactory;
use Phalcon\Mvc\Model\Metadata\Memory;
use Phalcon\Support\Debug;
use Phalcon\Exception;
use Phalcon\Mvc\Dispatcher\Exception as DispatcherException;
use Phalcon\Session\Manager as SessionManager;
use Phalcon\Session\Adapter\Stream as SessionStream;
use Phalcon\Logger\Adapter\Stream as LoggerStream;
use Phalcon\Logger\Logger;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Incubator\MongoDB\Mvc\Collection\Manager as CollectionManager;
use MongoDB\Client as MongoDBClient;
use MongoDB\Driver\ReadPreference;
use Application\Mvc\Helper;
use Application\Acl\DefaultAcl;
use Application\Mvc\Router\DefaultRouter;
use Application\Mvc\Config;
use Application\Mvc\View\Engine\Volt;
use Application\Widget\Proxy;
use Application\Utils\ModuleName;
use System\Model\Configuration;
use MookeCMS\Plugin\Title;
use MookeCMS\Plugin\CheckPoint;
use MookeCMS\Plugin\Localization;
use MookeCMS\Plugin\AdminLocalization;
use MookeCMS\Plugin\Acl;
use MookeCMS\Plugin\MobileDetect;
use MookeCMS\Plugin\Role;
 
/**
 * Bootstrap
 * @copyright Copyright (c) 2020 Markboo (http://cnski.cn)
 * @author Markboo <markboo@foxmail.com>
 */
class Bootstrap
{
    /**
     * 启动函数
     **/
    public function run()
    {
        //创建di
        $di = new FactoryDefault();
 
        //载入配置
        require_once APPLICATION_PATH . '/modules/Application/Mvc/Config.php';
 
        $config = Config::get();
        $di->setShared('config', $config);
 
        //检查系统状态,各依赖关系是否可用
        $this->checkSystemStatus($di);
 
        //创建注册器
        $registry = new Registry();
        $di->set('registry', $registry);
 
        //创建载入器
        $loader = new Loader();
        $loader->setNamespaces($config->loader->namespaces->toArray());
 
        //通过配置文件注册目录
        $loader->setDirectories([APPLICATION_PATH . "/plugins/"]);
        $loader->register();
 
        require_once APPLICATION_PATH . '/../vendor/autoload.php';
 
        try {
            //创建mysql数据库连接
            $db = new Mysql([
                "host"     => $config->database->host,
                "username" => $config->database->username,
                "password" => $config->database->password,
                "dbname"   => $config->database->dbname,
                "charset"  => $config->database->charset,
            ]);
            $di->set('db', $db);
        } catch (\Exception $e) {
            $this->exceptionExit(null, "数据库尚未启动!");
        }
 
        // 设置 mongo 连接
        $di->setShared("mongo", function() use ($config) {
            // 使用新版 MongoDB\Client
            $dsn = $config->mongodb->server;
            $client = new MongoDBClient($dsn);
            // 新版驱动中 setSlaveOkay() 已废弃,使用 readPreference 替代
            // 设置从库读取优先级
            $db = $client->selectDatabase($config->mongodb->db, [
                'readPreference' => new ReadPreference(ReadPreference::SECONDARY_PREFERRED)
            ]);
            // 检查主从状态
            try {
                $isMaster = $db->command(['isMaster' => 1])->toArray()[0] ?? [];
                if (isset($isMaster['ismaster']) && $isMaster['ismaster'] == false && isset($isMaster['primary'])) {
                    // 切换到主节点
                    $primaryDsn = 'mongodb://' . $isMaster['primary'];
                    $client = new MongoDBClient($primaryDsn);
                    $db = $client->selectDatabase($config->mongodb->db, [
                        'readPreference' => new ReadPreference(ReadPreference::SECONDARY_PREFERRED)
                    ]);
                }
            } catch (\Exception $e) {
                // 记录日志但不中断
                error_log("MongoDB 主从检查失败: " . $e->getMessage());
            }
            return $db;
        });
 
        // 在服务注册部分添加 设置collectionManager
        $di->setShared('collectionsManager', function() {
            return new CollectionManager();
        });
 
        //初始化图
        $this->initView($di);
 
        //创建url
        $url = new Url();
        $url->setBasePath($config->base_path);
        $url->setBaseUri($config->base_path) ;
        $di->set('url', $url);
 
        //初始化缓存Cache
        $this->initCache($di);
 
        //读取CMS配置模块的配置
        $cmsModel = new Configuration();
        $registry->cms = $cmsModel->getConfig();
 
        //Application
        $application = new Application();
        $application->registerModules($config->modules->toArray());
 
        //事务管理器
        $this->initEventManager($di);
 
        //初始化Session
        $this->initSession($di);
 
        //初始化log记录
        try {
            $payLogAdapter = new LoggerStream(APPLICATION_PATH . $config->work_path->pay_log_file);
            $paylogger = new Logger('launch', ['main' => $payLogAdapter]);
            $di->set('paylogger', $paylogger);
 
            $kingdeeLogAdapter = new LoggerStream(APPLICATION_PATH . $config->work_path->kingdee_log_file);
            $kingdeelogger = new Logger('launch', ['main' => $kingdeeLogAdapter]);
            $di->set('kinglogger', $kingdeelogger);
 
            $weixinLogAdapter = new LoggerStream(APPLICATION_PATH . $config->work_path->weixin_log_file);
            $weixinlogger = new Logger('launch', ['main' => $weixinLogAdapter]);
            $di->set('weixinlogger', $weixinlogger);
 
            $launchLogAdapter = new LoggerStream(APPLICATION_PATH . '/../data/logs/launch_log.log');
            $launchLogger = new Logger('launch', ['main' => $launchLogAdapter]);
            $di->set('launchLogger', $launchLogger);
 
            $debugLogAdapter = new LoggerStream(APPLICATION_PATH . '/../data/logs/debug_log.log');
            $debugLogger = new Logger('launch', ['main' => $debugLogAdapter]);
            $di->set('debugLogger', $debugLogger);
 
            $kingdeeStockLogAdapter = new LoggerStream(APPLICATION_PATH . '/../data/logs/kingdee_stock_logger.log');
            $kingdeeStockLogger = new Logger('launch', ['main' => $kingdeeStockLogAdapter]);
            $di->set('kingdeeStockLogger', $kingdeeStockLogger);
 
            $inventorycostLogAdapter = new LoggerStream(APPLICATION_PATH . '/../data/logs/inventorycost_logger.log');
            $inventorycostLogger = new Logger('launch', ['main' => $inventorycostLogAdapter]);
            $di->set('inventorycostLogger', $inventorycostLogger);
        } catch (\Exception $e) {
            $this->exceptionExit($e, '支付日志写入出错!<br>返回错误信息:');
        }
 
        //JS Assets
//        $this->initAssetsManager($di);
 
        //提示框标签
        //使用 Flash Session(推荐,支持重定向后保留消息)
        $flash = new FlashSession();
        $flash->setCssClasses([
            'error'   => 'ui orange inverted flash segment',
            'success' => 'ui green inverted flash segment',
            'notice'  => 'ui blue inverted flash segment',
            'warning' => 'ui orange inverted flash segment'
        ]);
 
        $di->set('flash', $flash);
        $di->set('helper', new Helper());
        $di->set('modules', function() use ($application) { return $application->getModules(); }, true);
 
        //载入访问控制策略
        $acl = new DefaultAcl();
        $di->set('acl', $acl);
 
        //初始化路由
        $this->initRouting($application, $di);
 
        $application->setDI($di);
 
        //主调度进程开始
        $this->dispatch($di);
    }
 
    /**
     * 检查系统状态,各依赖关系是否可用
     * @param $di
     * @return void
     */
    private function checkSystemStatus($di)
    {
        $config = $di->get('config');
        $this->ensureWritableLogFile($config->work_path->pay_log_file);
        $this->ensureWritableLogDir($config->work_path->data_path);
        $this->ensureWritableLogDir($config->work_path->qrcode_path);
        $this->ensureWritableLogDir($config->work_path->upload_file);
    }
 
    /**
     * 初始化路由
     * @param $application
     * @param $di
     * @return void
     */
    private function initRouting($application, $di)
    {
        $router = new DefaultRouter();
        $router->setDi($di);
        foreach ($application->getModules() as $module) {
            $routesClassName = str_replace('Module', 'Routes', $module['className']);
            if (class_exists($routesClassName)) {
                $routesClass = new $routesClassName();
                $router = $routesClass->init($router);
            }
            $initClassName = str_replace('Module', 'Init', $module['className']);
            if (class_exists($initClassName)) {
                new $initClassName();
            }
        }
        $di->set('router', $router);
    }
 
    /**
     * 初始化资源文件管理
     * @param $di
     * @return void
     **/
    private function initAssetsManager($di)
    {
        $config = $di->get('config');
 
        // 直接从 DI 中获取已经注册的 tag 服务
        $tagFactory = $di->get('tag');
        $assetsManager = new Manager($tagFactory);
 
        // 移除 ->setLocal(true) 和 ->addFilter()
        // Phalcon 5 中资源本地区域由 Asset 对象本身决定
        $js_collection = $assetsManager->collection('js')
            ->setTargetPath(ROOT.'/assets/js.js')
            ->setTargetUri('assets/js.js')
            ->join(true);
 
        if ($config->assets->js) {
            foreach ($config->assets->js as $js) {
                // 使用 addJs 时,第 3 个参数表示是否本地资源
                $js_collection->addJs(ROOT.'/'.$js, false, true);  // 第3个参数 $local = true
            }
        }
 
        // Admin JS Assets
        $assetsManager->collection('modules-admin-js')
            ->setTargetPath(ROOT.'/assets/modules-admin.js')
            ->setTargetUri('assets/modules-admin.js')
            ->join(true);
 
        $less = '/modules/Admin/assets/admin.less';
 
        // Admin LESS Assets
        $assetsManager->collection('modules-admin-css')
            ->setTargetPath(ROOT.'/assets/modules-admin.css')
            ->setTargetUri('/assets/modules-admin.css')
            ->join(true)
            ->addCss(ROOT.$less, false, true);  // 第3个参数 $local = true
 
        $di->set('assets', $assetsManager);
    }
 
    /**
     * 初始化事件管理器
     * @param $di
     * @return void
     **/
    private function initEventManager( $di )
    {
        $eventsManager = new EventsManager();
        $dispatcher = new Dispatcher();
 
        /** @var $eventsManager */
        /** (前置拦截)在调度器开始分发循环之前触发,此时控制器和动作尚未执行,适合做前置处理:权限检查、本地化设置、移动端检测等 */
        $eventsManager->attach("dispatch:beforeDispatchLoop", function($event, $dispatcher) use ($di) {
            new CheckPoint($di->get('request'));
            new Localization($dispatcher);
            new AdminLocalization($di->get('config'));
            new Acl($di->get('acl'), $dispatcher, $di->get('view'));
            new MobileDetect($di->get('session'), $di->get('view'), $di->get('request'));
            new Role($di->get('session'), $di->get('view'));
        });
 
        /** @var $eventsManager */
        /** (后置处理)在调度器完成分发循环之后触发,此时控制器和动作已经执行完毕,适合做后置处理:修改响应内容、添加全局标题等*/
        $eventsManager->attach("dispatch:afterDispatchLoop", function($event, $dispatcher) use ($di) {
            new Title($di);
        });
 
        //Profiler
        $registry = $di->get('registry');
 
        if ($registry->cms['PROFILER']) {
            $profiler = new Profiler();
            $di->set('profiler', $profiler);
            /** @var TYPE_NAME $eventsManager */
            $eventsManager->attach('db', function($event, $db) use ($profiler) {
                if ($event->getType() == 'beforeQuery') {
                    $profiler->startProfile($db->getSQLStatement());
                }
                if ($event->getType() == 'afterQuery') {
                    $profiler->stopProfile();
                }
            });
        }
 
        $db = $di->get('db');
        $db->setEventsManager($eventsManager);
 
        $dispatcher->setEventsManager($eventsManager);
        $di->set('dispatcher', $dispatcher);
    }
 
    /**
     * 初始化视图引擎
     * @param $di
     * @return mixed $view
     **/
    private function initView($di)
    {
        $view = new View();
 
        define('MAIN_VIEW_PATH', '../../../views/');
        $view->setMainView(MAIN_VIEW_PATH . 'main');
        $view->setLayoutsDir(MAIN_VIEW_PATH . '/layouts/');
        $view->setLayout('main');
        $view->setPartialsDir(MAIN_VIEW_PATH . '/partials/');
        $compiledPath = APPLICATION_PATH . '/../data/cache/volt/';
 
        // 确保目录存在
        if (!is_dir($compiledPath)) {
            umask(0);
            mkdir($compiledPath, 0755, true);
            // 可选:设置所有者
            chown($compiledPath, 'apache');
        }
        // 检查是否可写
        if (!is_writable($compiledPath)) {
            chmod($compiledPath, 0755);
        }
        $volt = new Volt($view, $di);
        $volt->setOptions(['path' => $compiledPath]);
        $volt->initCompiler();
 
        $compiler = $volt->getCompiler();
        //加入md5过滤器,用在供货管理页面的时间验证上
        $compiler->addFilter('hash', 'md5');
 
        $compiler->addFunction('contains_text', function($resolvedArgs, $exprArgs) {
            return 'stripos(' . $resolvedArgs . ')';
        });
 
        $compiler->addFunction('number_format', function($resolvedArgs) {
            return '(is_null(' . $resolvedArgs . ') ? 0 : number_format(floatval(' . $resolvedArgs . '), 2))';
        });
 
        $compiler->addFunction('is_numeric', function($resolvedArgs) {
            return 'is_numeric(' . $resolvedArgs . ')';
        });
 
        $compiler->addFunction('number', function($resolvedArgs) {
            return '(is_null(' . $resolvedArgs . ') ? 0 : number_format(floatval(' . $resolvedArgs . '), 0))';
        });
 
        $compiler->addFunction('date_format', function($resolvedArgs) {
            return 'date(' . $resolvedArgs . ')';
        });
 
        $compiler->addFunction('strtotime', function($resolvedArgs) {
            return 'strtotime('.$resolvedArgs.')';
        });
 
        $compiler->addFunction('isset', function($arg) {
            return 'isset('.$arg.')';
        });
 
        $compiler->addFunction('date_ymd', function($resolvedArgs) {
            return 'date(\'Y年m月d日 H:i:s\', '.$resolvedArgs.')';
        });
 
        $compiler->addFunction('allow_check', function($arg) use ($di) {
            return 0;
        });
 
        $compiler->addFunction('replace_json', function($arg) {
            return 11;
        });
 
        $compiler->addFunction('mb_substr', 'mb_substr');
        $compiler->addFunction('timestamp', 'time');
        $compiler->addFunction("dump", "print_r");
        $compiler->addFunction('in_array', 'in_array');
        $compiler->addFunction('phpinfo', 'phpinfo');
        $compiler->addFilter('mb_substr', 'mb_substr');
 
        $phtml = new Php($view, $di);
        $viewEngines = [
            ".volt"  => $volt,
            ".phtml" => $phtml,
        ];
 
        $view->registerEngines($viewEngines);
        $view->timestamp = time();
 
        $ajax = $di->get('request')->getQuery('_ajax');
        if ($ajax) {
            $view->setRenderLevel(View::LEVEL_LAYOUT);
        }
 
        $di->set('view', $view);
        return $view;
    }
 
    /**
     * 初始化Session
     * @desc
     * @param $di
     */
    private function initSession($di)
    {
        $config = $di->get('config');
        $sessionManager = new SessionManager();
 
        switch ($config->session) {
            case 'redis':
                //初始化session并保存至redis里
                //创建必要的工厂
                $serializerFactory = new SerializerFactory();
                $adapterFactory = new AdapterFactory($serializerFactory);
                $adapter = new Redis($adapterFactory, [
                    "host" => $config->redis->host,
                    "port" => $config->redis->port,
                    "auth" => $config->redis->password,  // 添加密码
                    "lifetime" => $config->redis->lifetime,
                    "persistent" => $config->redis->persistent,
                    "prefix" => $config->redis->prefix,
                    "index" => 0  // Redis 数据库索引
                ]);
                break;
            case 'file':
                $savePath = APPLICATION_PATH . '/../data/cache/sessions';
                if (!is_dir($savePath)) {
                    mkdir($savePath, 0755, true);
                }
                // 初始化session并保存至file里
                $adapter = new SessionStream([
                    'savePath' => $savePath
                ]);
                // 设置适配器到管理器
                break;
        }
 
        if (!$adapter) {
            error_log('init session exception exit;');
            $this->exceptionExit(null, $config->session.'初始化Session保存服务访问出错、Session保存位置检查异常!<br>返回错误信息:');
        }
 
        $sessionManager->setAdapter($adapter);
 
        try {
            $sessionManager->start();
        } catch (Exception $e) {
            error_log('--- session exception ---');
            $this->exceptionExit($e, $config->session.'初始化Session保存服务访问出错、Session启动异常<br>返回错误信息:');
        }
 
        $di->set('session', $sessionManager);
    }
 
    /**
     * 初始化缓存,file类型、memcached类型
     * @param $di
     * @return void
     */
    private function initCache($di)
    {
        $config = $di->get('config');
        $cache = null;
 
        // Phalcon 5 不再需要 Frontend,直接使用 Adapter
        $defaultOptions = [
            'lifetime' => 31536000,
            'prefix' => HOST_HASH,
        ];
 
        switch ($config->cache) {
            case 'file':
                $serializerFactory = new SerializerFactory();
                $adapter = new Stream($serializerFactory, array_merge($defaultOptions, [
                    'storageDir' => APPLICATION_PATH . "/../data/cache/backend/",
                ]));
                $cache = new Cache($adapter);
            break;
            case 'memcache':
                $serializerFactory = new SerializerFactory();
                $adapter = new Libmemcached($serializerFactory, array_merge($defaultOptions, [
                    'servers' => [[
                        'host' => $config->memcache->host,
                        'port' => $config->memcache->port,
                        'weight' => 100,
                    ]],
                ]));
                $cache = new Cache($adapter);
            break;
            case 'mongodb':
                $serializerFactory = new SerializerFactory();
                $adapter = new Redis($serializerFactory, array_merge($defaultOptions, [
                    'host' => $config->redis->host,
                    'port' => $config->redis->port,
                    "auth" => $config->redis->password,  // 添加密码
                    'index' => 0,
                ]));
                $cache = new Cache($adapter);
            break;
        }
 
        //SerializerFactory 用于 Redis 缓存
        $serializerFactory = new SerializerFactory();
 
        //Search Cache
        $searchAdapter = new Redis($serializerFactory, [
            "host" => $config->redis->host,
            "port" => $config->redis->port,
            "auth" => $config->redis->password,  // 添加密码
            "lifetime" => 31536000,
            "persistent" => $config->redis->persistent,  //是否使用持久连接
            "prefix" => 'SearchMapping_', //缓存键名前缀
            "index" => 2 //数据库索引(0-15)
        ]);
        $search_cache = new Cache($searchAdapter);
 
        //Lock Cache
        $lockAdapter = new Redis($serializerFactory, [
            "host" => $config->redis->host,
            "port" => $config->redis->port,
            "auth" => $config->redis->password,  // 添加密码
            "lifetime" => 300,
            "persistent" => $config->redis->persistent,
            "prefix" => 'Business_Lock_',
            "index" => 2
        ]);
        $lock_cache = new Cache($lockAdapter);
 
        //Serial Cache
        $serialAdapter = new Redis($serializerFactory, [
            "host" => $config->redis->host,
            "port" => $config->redis->port,
            "auth" => $config->redis->password,  // 添加密码
            "lifetime" => 31536000,
            "persistent" => true,
            "prefix" => 'Mnemonic_Code_',
            "index" => 5
        ]);
        $serial_cache = new Cache($serialAdapter);
 
        //Front Cache
        $frontAdapter = new Redis($serializerFactory, [
            "host" => $config->redis->host,
            "port" => $config->redis->port,
            "auth" => $config->redis->password,  // 添加密码
            "lifetime" => 604800, //缓存存活 7 天
            "persistent" => $config->redis->persistent,
            "prefix" => 'Front_Cache_',
            "index" => 4
        ]);
        $front_cache = new Cache($frontAdapter);
 
        $di->set('cache', $cache, true);
        $di->set('modelsCache', $cache, true);
        $di->set('search_cache', $search_cache, true);
        $di->set('lock_cache', $lock_cache, true);
        $di->set('mnemonic_code_cache', $serial_cache, true);
        $di->set('front_cache', $front_cache, true);
 
        Proxy::$cache = $cache;
 
        $modelsMetadata = new Memory();
        $di->set('modelsMetadata', $modelsMetadata);
    }
 
    /**
     * 调度器管理
     * @param $di
     * @return void
     **/
    private function dispatch($di)
    {
        $router = $di['router'];
        // Phalcon 5 需要传入请求 URI
        $request = $di['request'];
        $router->handle($request->getURI());
        $view = $di['view'];
        $dispatcher = $di['dispatcher'];
        $response = $di['response'];
        $dispatcher->setModuleName($router->getModuleName());
        $dispatcher->setControllerName($router->getControllerName());
        $dispatcher->setActionName($router->getActionName());
        $dispatcher->setParams($router->getParams());
 
        $moduleName = ModuleName::camelize($router->getModuleName());
 
        $ModuleClassName = $moduleName . '\Module';
        if (class_exists($ModuleClassName)) {
            $module = new $ModuleClassName;
            $module->registerAutoloaders();
            $module->registerServices($di);
        }
 
        $view->start();
 
        $registry = $di['registry'];
        if ($registry->cms['DEBUG_MODE']) {
            $debug = new Debug();
            $debug->listen();
            $dispatcher->dispatch();
        } else {
            try {
                $dispatcher->dispatch();
            } catch (Exception $e) {
                $view->setViewsDir(__DIR__ . '/modules/Index/views/');
                $view->setPartialsDir('');
                $view->e = $e;
                if ($e instanceof DispatcherException) {
                    $response->setHeader(404, 'Not Found');
                    $view->title = '错误页面';
                    $view->partial('error/error404');
                } else {
                    $response->setHeader(503, 'Service Unavailable');
                    $view->title = '错误页面';
                    $view->partial('error/error503');
                }
                $response->sendHeaders();
                echo $response->getContent();
                return;
            }
        }
 
        $view->render(
            $dispatcher->getControllerName(),
            $dispatcher->getActionName(),
            $dispatcher->getParams()
        );
 
        $view->finish();
        $response = $di['response'];
 
        //AJAX
        $request = $di['request'];
        $_ajax = $request->getQuery('_ajax');
 
        if ($_ajax) {
            $contents = $view->getContent();
            $return = new \stdClass();
            $return->html = $contents;
            $return->title = $di->get('helper')->title()->get();
            $return->success = true;
            if ($view->bodyClass) {
                $return->bodyClass = $view->bodyClass;
            }
            $headers = $response->getHeaders()->toArray();
            if (isset($headers[404]) || isset($headers[503])) {
                $return->success = false;
            }
            $response->setContentType('application/json', 'UTF-8');
            $response->setContent(json_encode($return));
        } else {
            $response->setContent($view->getContent());
        }
        $response->sendHeaders();
        echo $response->getContent();
    }
 
    /**
     * @desc 处理异常,并结束脚本
     * @param $exception
     * @param $msg
     * @param $is_exit
     */
    private function exceptionExit($exception, $msg, $is_exit = true)
    {
        $message = ($exception) ? $msg . $exception->getMessage() : $msg;
        $response = new Response();
        $response->setContent($message . '<br>');
        $response->send();
        if ($is_exit) exit();
    }
 
    /**
     * 确保日志文件可写
     * @param string $configPath 配置文件中的路径
     * @return void
     */
    private function ensureWritableLogFile($configPath)
    {
        if (empty($configPath)) {
            return;
        }
 
        $fullPath = APPLICATION_PATH . $configPath;
        $dir = dirname($fullPath);
 
        // 目录不存在则创建
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }
 
        // 文件不存在则创建,存在则确保可写
        if (!file_exists($fullPath)) {
            touch($fullPath);
            chmod($fullPath, 0644);
        } elseif (!is_writeable($fullPath)) {
            chmod($fullPath, 0644);
        }
    }
 
    /**
     * 确保日志目录可写
     * @param string $configPath 配置文件中的路径
     * @return void
     */
    private function ensureWritableLogDir($configPath)
    {
        if (empty($configPath)) {
            return;
        }
 
        $fullPath = APPLICATION_PATH . $configPath;
 
        // 目录不存在则创建
        if (!is_dir($fullPath)) {
            mkdir($fullPath, 0755, true);
        }
 
        // 目录不可写则修改权限
        if (!is_writeable($fullPath)) {
            chmod($fullPath, 0755);
        }
    }
}

                            
# MookeCMS\Bootstrap -> dispatch
/var/www/html/app/Bootstrap.php (223)
<?php
 
namespace MookeCMS;
 
use Phalcon\Http\Response;
use Phalcon\DI\FactoryDefault;
use Phalcon\Db\Adapter\Pdo\Mysql;
use Phalcon\Mvc\Url;
use Phalcon\Mvc\Application;
use Phalcon\Mvc\View\Engine\Php;
use Phalcon\Mvc\View;
use Phalcon\Db\Profiler;
use Phalcon\Support\Registry;
use Phalcon\Autoload\Loader;
use Phalcon\Cache\Cache;
use Phalcon\Cache\Adapter\Stream;
use Phalcon\Storage\SerializerFactory;
use Phalcon\Cache\Adapter\Libmemcached;
use Phalcon\Cache\Adapter\Redis;
use Phalcon\Assets\Filter\Jsmin;
use Phalcon\Flash\Session as FlashSession;
use Phalcon\Storage\AdapterFactory;
use Phalcon\Mvc\Model\Metadata\Memory;
use Phalcon\Support\Debug;
use Phalcon\Exception;
use Phalcon\Mvc\Dispatcher\Exception as DispatcherException;
use Phalcon\Session\Manager as SessionManager;
use Phalcon\Session\Adapter\Stream as SessionStream;
use Phalcon\Logger\Adapter\Stream as LoggerStream;
use Phalcon\Logger\Logger;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Incubator\MongoDB\Mvc\Collection\Manager as CollectionManager;
use MongoDB\Client as MongoDBClient;
use MongoDB\Driver\ReadPreference;
use Application\Mvc\Helper;
use Application\Acl\DefaultAcl;
use Application\Mvc\Router\DefaultRouter;
use Application\Mvc\Config;
use Application\Mvc\View\Engine\Volt;
use Application\Widget\Proxy;
use Application\Utils\ModuleName;
use System\Model\Configuration;
use MookeCMS\Plugin\Title;
use MookeCMS\Plugin\CheckPoint;
use MookeCMS\Plugin\Localization;
use MookeCMS\Plugin\AdminLocalization;
use MookeCMS\Plugin\Acl;
use MookeCMS\Plugin\MobileDetect;
use MookeCMS\Plugin\Role;
 
/**
 * Bootstrap
 * @copyright Copyright (c) 2020 Markboo (http://cnski.cn)
 * @author Markboo <markboo@foxmail.com>
 */
class Bootstrap
{
    /**
     * 启动函数
     **/
    public function run()
    {
        //创建di
        $di = new FactoryDefault();
 
        //载入配置
        require_once APPLICATION_PATH . '/modules/Application/Mvc/Config.php';
 
        $config = Config::get();
        $di->setShared('config', $config);
 
        //检查系统状态,各依赖关系是否可用
        $this->checkSystemStatus($di);
 
        //创建注册器
        $registry = new Registry();
        $di->set('registry', $registry);
 
        //创建载入器
        $loader = new Loader();
        $loader->setNamespaces($config->loader->namespaces->toArray());
 
        //通过配置文件注册目录
        $loader->setDirectories([APPLICATION_PATH . "/plugins/"]);
        $loader->register();
 
        require_once APPLICATION_PATH . '/../vendor/autoload.php';
 
        try {
            //创建mysql数据库连接
            $db = new Mysql([
                "host"     => $config->database->host,
                "username" => $config->database->username,
                "password" => $config->database->password,
                "dbname"   => $config->database->dbname,
                "charset"  => $config->database->charset,
            ]);
            $di->set('db', $db);
        } catch (\Exception $e) {
            $this->exceptionExit(null, "数据库尚未启动!");
        }
 
        // 设置 mongo 连接
        $di->setShared("mongo", function() use ($config) {
            // 使用新版 MongoDB\Client
            $dsn = $config->mongodb->server;
            $client = new MongoDBClient($dsn);
            // 新版驱动中 setSlaveOkay() 已废弃,使用 readPreference 替代
            // 设置从库读取优先级
            $db = $client->selectDatabase($config->mongodb->db, [
                'readPreference' => new ReadPreference(ReadPreference::SECONDARY_PREFERRED)
            ]);
            // 检查主从状态
            try {
                $isMaster = $db->command(['isMaster' => 1])->toArray()[0] ?? [];
                if (isset($isMaster['ismaster']) && $isMaster['ismaster'] == false && isset($isMaster['primary'])) {
                    // 切换到主节点
                    $primaryDsn = 'mongodb://' . $isMaster['primary'];
                    $client = new MongoDBClient($primaryDsn);
                    $db = $client->selectDatabase($config->mongodb->db, [
                        'readPreference' => new ReadPreference(ReadPreference::SECONDARY_PREFERRED)
                    ]);
                }
            } catch (\Exception $e) {
                // 记录日志但不中断
                error_log("MongoDB 主从检查失败: " . $e->getMessage());
            }
            return $db;
        });
 
        // 在服务注册部分添加 设置collectionManager
        $di->setShared('collectionsManager', function() {
            return new CollectionManager();
        });
 
        //初始化图
        $this->initView($di);
 
        //创建url
        $url = new Url();
        $url->setBasePath($config->base_path);
        $url->setBaseUri($config->base_path) ;
        $di->set('url', $url);
 
        //初始化缓存Cache
        $this->initCache($di);
 
        //读取CMS配置模块的配置
        $cmsModel = new Configuration();
        $registry->cms = $cmsModel->getConfig();
 
        //Application
        $application = new Application();
        $application->registerModules($config->modules->toArray());
 
        //事务管理器
        $this->initEventManager($di);
 
        //初始化Session
        $this->initSession($di);
 
        //初始化log记录
        try {
            $payLogAdapter = new LoggerStream(APPLICATION_PATH . $config->work_path->pay_log_file);
            $paylogger = new Logger('launch', ['main' => $payLogAdapter]);
            $di->set('paylogger', $paylogger);
 
            $kingdeeLogAdapter = new LoggerStream(APPLICATION_PATH . $config->work_path->kingdee_log_file);
            $kingdeelogger = new Logger('launch', ['main' => $kingdeeLogAdapter]);
            $di->set('kinglogger', $kingdeelogger);
 
            $weixinLogAdapter = new LoggerStream(APPLICATION_PATH . $config->work_path->weixin_log_file);
            $weixinlogger = new Logger('launch', ['main' => $weixinLogAdapter]);
            $di->set('weixinlogger', $weixinlogger);
 
            $launchLogAdapter = new LoggerStream(APPLICATION_PATH . '/../data/logs/launch_log.log');
            $launchLogger = new Logger('launch', ['main' => $launchLogAdapter]);
            $di->set('launchLogger', $launchLogger);
 
            $debugLogAdapter = new LoggerStream(APPLICATION_PATH . '/../data/logs/debug_log.log');
            $debugLogger = new Logger('launch', ['main' => $debugLogAdapter]);
            $di->set('debugLogger', $debugLogger);
 
            $kingdeeStockLogAdapter = new LoggerStream(APPLICATION_PATH . '/../data/logs/kingdee_stock_logger.log');
            $kingdeeStockLogger = new Logger('launch', ['main' => $kingdeeStockLogAdapter]);
            $di->set('kingdeeStockLogger', $kingdeeStockLogger);
 
            $inventorycostLogAdapter = new LoggerStream(APPLICATION_PATH . '/../data/logs/inventorycost_logger.log');
            $inventorycostLogger = new Logger('launch', ['main' => $inventorycostLogAdapter]);
            $di->set('inventorycostLogger', $inventorycostLogger);
        } catch (\Exception $e) {
            $this->exceptionExit($e, '支付日志写入出错!<br>返回错误信息:');
        }
 
        //JS Assets
//        $this->initAssetsManager($di);
 
        //提示框标签
        //使用 Flash Session(推荐,支持重定向后保留消息)
        $flash = new FlashSession();
        $flash->setCssClasses([
            'error'   => 'ui orange inverted flash segment',
            'success' => 'ui green inverted flash segment',
            'notice'  => 'ui blue inverted flash segment',
            'warning' => 'ui orange inverted flash segment'
        ]);
 
        $di->set('flash', $flash);
        $di->set('helper', new Helper());
        $di->set('modules', function() use ($application) { return $application->getModules(); }, true);
 
        //载入访问控制策略
        $acl = new DefaultAcl();
        $di->set('acl', $acl);
 
        //初始化路由
        $this->initRouting($application, $di);
 
        $application->setDI($di);
 
        //主调度进程开始
        $this->dispatch($di);
    }
 
    /**
     * 检查系统状态,各依赖关系是否可用
     * @param $di
     * @return void
     */
    private function checkSystemStatus($di)
    {
        $config = $di->get('config');
        $this->ensureWritableLogFile($config->work_path->pay_log_file);
        $this->ensureWritableLogDir($config->work_path->data_path);
        $this->ensureWritableLogDir($config->work_path->qrcode_path);
        $this->ensureWritableLogDir($config->work_path->upload_file);
    }
 
    /**
     * 初始化路由
     * @param $application
     * @param $di
     * @return void
     */
    private function initRouting($application, $di)
    {
        $router = new DefaultRouter();
        $router->setDi($di);
        foreach ($application->getModules() as $module) {
            $routesClassName = str_replace('Module', 'Routes', $module['className']);
            if (class_exists($routesClassName)) {
                $routesClass = new $routesClassName();
                $router = $routesClass->init($router);
            }
            $initClassName = str_replace('Module', 'Init', $module['className']);
            if (class_exists($initClassName)) {
                new $initClassName();
            }
        }
        $di->set('router', $router);
    }
 
    /**
     * 初始化资源文件管理
     * @param $di
     * @return void
     **/
    private function initAssetsManager($di)
    {
        $config = $di->get('config');
 
        // 直接从 DI 中获取已经注册的 tag 服务
        $tagFactory = $di->get('tag');
        $assetsManager = new Manager($tagFactory);
 
        // 移除 ->setLocal(true) 和 ->addFilter()
        // Phalcon 5 中资源本地区域由 Asset 对象本身决定
        $js_collection = $assetsManager->collection('js')
            ->setTargetPath(ROOT.'/assets/js.js')
            ->setTargetUri('assets/js.js')
            ->join(true);
 
        if ($config->assets->js) {
            foreach ($config->assets->js as $js) {
                // 使用 addJs 时,第 3 个参数表示是否本地资源
                $js_collection->addJs(ROOT.'/'.$js, false, true);  // 第3个参数 $local = true
            }
        }
 
        // Admin JS Assets
        $assetsManager->collection('modules-admin-js')
            ->setTargetPath(ROOT.'/assets/modules-admin.js')
            ->setTargetUri('assets/modules-admin.js')
            ->join(true);
 
        $less = '/modules/Admin/assets/admin.less';
 
        // Admin LESS Assets
        $assetsManager->collection('modules-admin-css')
            ->setTargetPath(ROOT.'/assets/modules-admin.css')
            ->setTargetUri('/assets/modules-admin.css')
            ->join(true)
            ->addCss(ROOT.$less, false, true);  // 第3个参数 $local = true
 
        $di->set('assets', $assetsManager);
    }
 
    /**
     * 初始化事件管理器
     * @param $di
     * @return void
     **/
    private function initEventManager( $di )
    {
        $eventsManager = new EventsManager();
        $dispatcher = new Dispatcher();
 
        /** @var $eventsManager */
        /** (前置拦截)在调度器开始分发循环之前触发,此时控制器和动作尚未执行,适合做前置处理:权限检查、本地化设置、移动端检测等 */
        $eventsManager->attach("dispatch:beforeDispatchLoop", function($event, $dispatcher) use ($di) {
            new CheckPoint($di->get('request'));
            new Localization($dispatcher);
            new AdminLocalization($di->get('config'));
            new Acl($di->get('acl'), $dispatcher, $di->get('view'));
            new MobileDetect($di->get('session'), $di->get('view'), $di->get('request'));
            new Role($di->get('session'), $di->get('view'));
        });
 
        /** @var $eventsManager */
        /** (后置处理)在调度器完成分发循环之后触发,此时控制器和动作已经执行完毕,适合做后置处理:修改响应内容、添加全局标题等*/
        $eventsManager->attach("dispatch:afterDispatchLoop", function($event, $dispatcher) use ($di) {
            new Title($di);
        });
 
        //Profiler
        $registry = $di->get('registry');
 
        if ($registry->cms['PROFILER']) {
            $profiler = new Profiler();
            $di->set('profiler', $profiler);
            /** @var TYPE_NAME $eventsManager */
            $eventsManager->attach('db', function($event, $db) use ($profiler) {
                if ($event->getType() == 'beforeQuery') {
                    $profiler->startProfile($db->getSQLStatement());
                }
                if ($event->getType() == 'afterQuery') {
                    $profiler->stopProfile();
                }
            });
        }
 
        $db = $di->get('db');
        $db->setEventsManager($eventsManager);
 
        $dispatcher->setEventsManager($eventsManager);
        $di->set('dispatcher', $dispatcher);
    }
 
    /**
     * 初始化视图引擎
     * @param $di
     * @return mixed $view
     **/
    private function initView($di)
    {
        $view = new View();
 
        define('MAIN_VIEW_PATH', '../../../views/');
        $view->setMainView(MAIN_VIEW_PATH . 'main');
        $view->setLayoutsDir(MAIN_VIEW_PATH . '/layouts/');
        $view->setLayout('main');
        $view->setPartialsDir(MAIN_VIEW_PATH . '/partials/');
        $compiledPath = APPLICATION_PATH . '/../data/cache/volt/';
 
        // 确保目录存在
        if (!is_dir($compiledPath)) {
            umask(0);
            mkdir($compiledPath, 0755, true);
            // 可选:设置所有者
            chown($compiledPath, 'apache');
        }
        // 检查是否可写
        if (!is_writable($compiledPath)) {
            chmod($compiledPath, 0755);
        }
        $volt = new Volt($view, $di);
        $volt->setOptions(['path' => $compiledPath]);
        $volt->initCompiler();
 
        $compiler = $volt->getCompiler();
        //加入md5过滤器,用在供货管理页面的时间验证上
        $compiler->addFilter('hash', 'md5');
 
        $compiler->addFunction('contains_text', function($resolvedArgs, $exprArgs) {
            return 'stripos(' . $resolvedArgs . ')';
        });
 
        $compiler->addFunction('number_format', function($resolvedArgs) {
            return '(is_null(' . $resolvedArgs . ') ? 0 : number_format(floatval(' . $resolvedArgs . '), 2))';
        });
 
        $compiler->addFunction('is_numeric', function($resolvedArgs) {
            return 'is_numeric(' . $resolvedArgs . ')';
        });
 
        $compiler->addFunction('number', function($resolvedArgs) {
            return '(is_null(' . $resolvedArgs . ') ? 0 : number_format(floatval(' . $resolvedArgs . '), 0))';
        });
 
        $compiler->addFunction('date_format', function($resolvedArgs) {
            return 'date(' . $resolvedArgs . ')';
        });
 
        $compiler->addFunction('strtotime', function($resolvedArgs) {
            return 'strtotime('.$resolvedArgs.')';
        });
 
        $compiler->addFunction('isset', function($arg) {
            return 'isset('.$arg.')';
        });
 
        $compiler->addFunction('date_ymd', function($resolvedArgs) {
            return 'date(\'Y年m月d日 H:i:s\', '.$resolvedArgs.')';
        });
 
        $compiler->addFunction('allow_check', function($arg) use ($di) {
            return 0;
        });
 
        $compiler->addFunction('replace_json', function($arg) {
            return 11;
        });
 
        $compiler->addFunction('mb_substr', 'mb_substr');
        $compiler->addFunction('timestamp', 'time');
        $compiler->addFunction("dump", "print_r");
        $compiler->addFunction('in_array', 'in_array');
        $compiler->addFunction('phpinfo', 'phpinfo');
        $compiler->addFilter('mb_substr', 'mb_substr');
 
        $phtml = new Php($view, $di);
        $viewEngines = [
            ".volt"  => $volt,
            ".phtml" => $phtml,
        ];
 
        $view->registerEngines($viewEngines);
        $view->timestamp = time();
 
        $ajax = $di->get('request')->getQuery('_ajax');
        if ($ajax) {
            $view->setRenderLevel(View::LEVEL_LAYOUT);
        }
 
        $di->set('view', $view);
        return $view;
    }
 
    /**
     * 初始化Session
     * @desc
     * @param $di
     */
    private function initSession($di)
    {
        $config = $di->get('config');
        $sessionManager = new SessionManager();
 
        switch ($config->session) {
            case 'redis':
                //初始化session并保存至redis里
                //创建必要的工厂
                $serializerFactory = new SerializerFactory();
                $adapterFactory = new AdapterFactory($serializerFactory);
                $adapter = new Redis($adapterFactory, [
                    "host" => $config->redis->host,
                    "port" => $config->redis->port,
                    "auth" => $config->redis->password,  // 添加密码
                    "lifetime" => $config->redis->lifetime,
                    "persistent" => $config->redis->persistent,
                    "prefix" => $config->redis->prefix,
                    "index" => 0  // Redis 数据库索引
                ]);
                break;
            case 'file':
                $savePath = APPLICATION_PATH . '/../data/cache/sessions';
                if (!is_dir($savePath)) {
                    mkdir($savePath, 0755, true);
                }
                // 初始化session并保存至file里
                $adapter = new SessionStream([
                    'savePath' => $savePath
                ]);
                // 设置适配器到管理器
                break;
        }
 
        if (!$adapter) {
            error_log('init session exception exit;');
            $this->exceptionExit(null, $config->session.'初始化Session保存服务访问出错、Session保存位置检查异常!<br>返回错误信息:');
        }
 
        $sessionManager->setAdapter($adapter);
 
        try {
            $sessionManager->start();
        } catch (Exception $e) {
            error_log('--- session exception ---');
            $this->exceptionExit($e, $config->session.'初始化Session保存服务访问出错、Session启动异常<br>返回错误信息:');
        }
 
        $di->set('session', $sessionManager);
    }
 
    /**
     * 初始化缓存,file类型、memcached类型
     * @param $di
     * @return void
     */
    private function initCache($di)
    {
        $config = $di->get('config');
        $cache = null;
 
        // Phalcon 5 不再需要 Frontend,直接使用 Adapter
        $defaultOptions = [
            'lifetime' => 31536000,
            'prefix' => HOST_HASH,
        ];
 
        switch ($config->cache) {
            case 'file':
                $serializerFactory = new SerializerFactory();
                $adapter = new Stream($serializerFactory, array_merge($defaultOptions, [
                    'storageDir' => APPLICATION_PATH . "/../data/cache/backend/",
                ]));
                $cache = new Cache($adapter);
            break;
            case 'memcache':
                $serializerFactory = new SerializerFactory();
                $adapter = new Libmemcached($serializerFactory, array_merge($defaultOptions, [
                    'servers' => [[
                        'host' => $config->memcache->host,
                        'port' => $config->memcache->port,
                        'weight' => 100,
                    ]],
                ]));
                $cache = new Cache($adapter);
            break;
            case 'mongodb':
                $serializerFactory = new SerializerFactory();
                $adapter = new Redis($serializerFactory, array_merge($defaultOptions, [
                    'host' => $config->redis->host,
                    'port' => $config->redis->port,
                    "auth" => $config->redis->password,  // 添加密码
                    'index' => 0,
                ]));
                $cache = new Cache($adapter);
            break;
        }
 
        //SerializerFactory 用于 Redis 缓存
        $serializerFactory = new SerializerFactory();
 
        //Search Cache
        $searchAdapter = new Redis($serializerFactory, [
            "host" => $config->redis->host,
            "port" => $config->redis->port,
            "auth" => $config->redis->password,  // 添加密码
            "lifetime" => 31536000,
            "persistent" => $config->redis->persistent,  //是否使用持久连接
            "prefix" => 'SearchMapping_', //缓存键名前缀
            "index" => 2 //数据库索引(0-15)
        ]);
        $search_cache = new Cache($searchAdapter);
 
        //Lock Cache
        $lockAdapter = new Redis($serializerFactory, [
            "host" => $config->redis->host,
            "port" => $config->redis->port,
            "auth" => $config->redis->password,  // 添加密码
            "lifetime" => 300,
            "persistent" => $config->redis->persistent,
            "prefix" => 'Business_Lock_',
            "index" => 2
        ]);
        $lock_cache = new Cache($lockAdapter);
 
        //Serial Cache
        $serialAdapter = new Redis($serializerFactory, [
            "host" => $config->redis->host,
            "port" => $config->redis->port,
            "auth" => $config->redis->password,  // 添加密码
            "lifetime" => 31536000,
            "persistent" => true,
            "prefix" => 'Mnemonic_Code_',
            "index" => 5
        ]);
        $serial_cache = new Cache($serialAdapter);
 
        //Front Cache
        $frontAdapter = new Redis($serializerFactory, [
            "host" => $config->redis->host,
            "port" => $config->redis->port,
            "auth" => $config->redis->password,  // 添加密码
            "lifetime" => 604800, //缓存存活 7 天
            "persistent" => $config->redis->persistent,
            "prefix" => 'Front_Cache_',
            "index" => 4
        ]);
        $front_cache = new Cache($frontAdapter);
 
        $di->set('cache', $cache, true);
        $di->set('modelsCache', $cache, true);
        $di->set('search_cache', $search_cache, true);
        $di->set('lock_cache', $lock_cache, true);
        $di->set('mnemonic_code_cache', $serial_cache, true);
        $di->set('front_cache', $front_cache, true);
 
        Proxy::$cache = $cache;
 
        $modelsMetadata = new Memory();
        $di->set('modelsMetadata', $modelsMetadata);
    }
 
    /**
     * 调度器管理
     * @param $di
     * @return void
     **/
    private function dispatch($di)
    {
        $router = $di['router'];
        // Phalcon 5 需要传入请求 URI
        $request = $di['request'];
        $router->handle($request->getURI());
        $view = $di['view'];
        $dispatcher = $di['dispatcher'];
        $response = $di['response'];
        $dispatcher->setModuleName($router->getModuleName());
        $dispatcher->setControllerName($router->getControllerName());
        $dispatcher->setActionName($router->getActionName());
        $dispatcher->setParams($router->getParams());
 
        $moduleName = ModuleName::camelize($router->getModuleName());
 
        $ModuleClassName = $moduleName . '\Module';
        if (class_exists($ModuleClassName)) {
            $module = new $ModuleClassName;
            $module->registerAutoloaders();
            $module->registerServices($di);
        }
 
        $view->start();
 
        $registry = $di['registry'];
        if ($registry->cms['DEBUG_MODE']) {
            $debug = new Debug();
            $debug->listen();
            $dispatcher->dispatch();
        } else {
            try {
                $dispatcher->dispatch();
            } catch (Exception $e) {
                $view->setViewsDir(__DIR__ . '/modules/Index/views/');
                $view->setPartialsDir('');
                $view->e = $e;
                if ($e instanceof DispatcherException) {
                    $response->setHeader(404, 'Not Found');
                    $view->title = '错误页面';
                    $view->partial('error/error404');
                } else {
                    $response->setHeader(503, 'Service Unavailable');
                    $view->title = '错误页面';
                    $view->partial('error/error503');
                }
                $response->sendHeaders();
                echo $response->getContent();
                return;
            }
        }
 
        $view->render(
            $dispatcher->getControllerName(),
            $dispatcher->getActionName(),
            $dispatcher->getParams()
        );
 
        $view->finish();
        $response = $di['response'];
 
        //AJAX
        $request = $di['request'];
        $_ajax = $request->getQuery('_ajax');
 
        if ($_ajax) {
            $contents = $view->getContent();
            $return = new \stdClass();
            $return->html = $contents;
            $return->title = $di->get('helper')->title()->get();
            $return->success = true;
            if ($view->bodyClass) {
                $return->bodyClass = $view->bodyClass;
            }
            $headers = $response->getHeaders()->toArray();
            if (isset($headers[404]) || isset($headers[503])) {
                $return->success = false;
            }
            $response->setContentType('application/json', 'UTF-8');
            $response->setContent(json_encode($return));
        } else {
            $response->setContent($view->getContent());
        }
        $response->sendHeaders();
        echo $response->getContent();
    }
 
    /**
     * @desc 处理异常,并结束脚本
     * @param $exception
     * @param $msg
     * @param $is_exit
     */
    private function exceptionExit($exception, $msg, $is_exit = true)
    {
        $message = ($exception) ? $msg . $exception->getMessage() : $msg;
        $response = new Response();
        $response->setContent($message . '<br>');
        $response->send();
        if ($is_exit) exit();
    }
 
    /**
     * 确保日志文件可写
     * @param string $configPath 配置文件中的路径
     * @return void
     */
    private function ensureWritableLogFile($configPath)
    {
        if (empty($configPath)) {
            return;
        }
 
        $fullPath = APPLICATION_PATH . $configPath;
        $dir = dirname($fullPath);
 
        // 目录不存在则创建
        if (!is_dir($dir)) {
            mkdir($dir, 0755, true);
        }
 
        // 文件不存在则创建,存在则确保可写
        if (!file_exists($fullPath)) {
            touch($fullPath);
            chmod($fullPath, 0644);
        } elseif (!is_writeable($fullPath)) {
            chmod($fullPath, 0644);
        }
    }
 
    /**
     * 确保日志目录可写
     * @param string $configPath 配置文件中的路径
     * @return void
     */
    private function ensureWritableLogDir($configPath)
    {
        if (empty($configPath)) {
            return;
        }
 
        $fullPath = APPLICATION_PATH . $configPath;
 
        // 目录不存在则创建
        if (!is_dir($fullPath)) {
            mkdir($fullPath, 0755, true);
        }
 
        // 目录不可写则修改权限
        if (!is_writeable($fullPath)) {
            chmod($fullPath, 0755);
        }
    }
}

                            
# MookeCMS\Bootstrap -> run
/var/www/html/public/index.php (22)
<?php
error_reporting(E_ALL & ~E_DEPRECATED); //关闭动态属性警告 DEPRECATED 警告
 
chdir(dirname(__DIR__));
 
const ROOT = __DIR__;
const APPLICATION_PATH = ROOT . '/../app';
 
isset($_SERVER['HTTP_HOST']) ?
    define('HOST_HASH', substr(md5($_SERVER['HTTP_HOST']), 0, 12)) :
    define('HOST_HASH', substr(md5('devel.eqiyu.com' ), 0, 12));
 
defined('APPLICATION_ENV') || define('APPLICATION_ENV', getenv('APPLICATION_ENV') ?: 'production');
 
if (!function_exists('ukey_next_id')) {
    function ukey_next_id(): string {return '';}
}
 
require_once APPLICATION_PATH . '/Bootstrap.php';
 
$bootstrap = new MookeCMS\Bootstrap();
$bootstrap->run();
                            
Key
Value
_url /admin/index/forget
Key
Value
USER apache
HOME /usr/share/httpd
SCRIPT_NAME /public/index.php
REQUEST_URI /admin/index/forget
QUERY_STRING _url=/admin/index/forget
REQUEST_METHOD GET
SERVER_PROTOCOL HTTP/1.1
GATEWAY_INTERFACE CGI/1.1
REDIRECT_QUERY_STRING _url=/admin/index/forget
REDIRECT_URL /public/admin/index/forget
REMOTE_PORT 31344
SCRIPT_FILENAME /var/www/html/public/index.php
SERVER_ADMIN root@localhost
CONTEXT_DOCUMENT_ROOT /var/www/html
CONTEXT_PREFIX
REQUEST_SCHEME https
DOCUMENT_ROOT /var/www/html
REMOTE_ADDR 216.73.217.35
SERVER_PORT 443
SERVER_ADDR 172.27.201.241
SERVER_NAME devel.eqiyu.com
SERVER_SOFTWARE Apache/2.4.62 (Rocky Linux) OpenSSL/3.5.1
SERVER_SIGNATURE
PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
HTTP_HOST devel.eqiyu.com
HTTP_ACCEPT_ENCODING gzip, br, zstd, deflate
HTTP_USER_AGENT Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
HTTP_ACCEPT */*
proxy-nokeepalive 1
SSL_SESSION_RESUMED Initial
SSL_SESSION_ID 99be8271ec91748047e52d73304cd933e9528062dec55e3aadea0ee4b791d1af
SSL_SERVER_A_SIG sha256WithRSAEncryption
SSL_SERVER_A_KEY rsaEncryption
SSL_SERVER_I_DN CN=Encryption Everywhere DV TLS CA - G2,OU=www.digicert.com,O=DigiCert Inc,C=US
SSL_SERVER_S_DN CN=devel.eqiyu.com
SSL_SERVER_V_END Sep 13 23:59:59 2026 GMT
SSL_SERVER_V_START Jun 16 00:00:00 2026 GMT
SSL_SERVER_M_SERIAL 0E1DE6D103013407E826BADF08AB8197
SSL_SERVER_M_VERSION 3
SSL_CLIENT_VERIFY NONE
SSL_CIPHER_ALGKEYSIZE 256
SSL_CIPHER_USEKEYSIZE 256
SSL_CIPHER_EXPORT false
SSL_CIPHER TLS_AES_256_GCM_SHA384
SSL_COMPRESS_METHOD NULL
SSL_SECURE_RENEG true
SSL_PROTOCOL TLSv1.3
SSL_VERSION_LIBRARY OpenSSL/3.5.1
SSL_VERSION_INTERFACE mod_ssl/2.4.62
SSL_SERVER_SAN_DNS_1 www.devel.eqiyu.com
SSL_SERVER_SAN_DNS_0 devel.eqiyu.com
SSL_SERVER_I_DN_CN Encryption Everywhere DV TLS CA - G2
SSL_SERVER_I_DN_OU www.digicert.com
SSL_SERVER_I_DN_O DigiCert Inc
SSL_SERVER_I_DN_C US
SSL_SERVER_S_DN_CN devel.eqiyu.com
SSL_TLS_SNI devel.eqiyu.com
HTTPS on
APPLICATION_ENV production
UNIQUE_ID ajPNOgJAbiZgPfgFaYE-oAAAAIk
REDIRECT_STATUS 200
REDIRECT_SSL_TLS_SNI devel.eqiyu.com
REDIRECT_HTTPS on
REDIRECT_APPLICATION_ENV production
REDIRECT_UNIQUE_ID ajPNOgJAbiZgPfgFaYE-oAAAAIk
REDIRECT_REDIRECT_STATUS 200
REDIRECT_REDIRECT_SSL_TLS_SNI devel.eqiyu.com
REDIRECT_REDIRECT_HTTPS on
REDIRECT_REDIRECT_UNIQUE_ID ajPNOgJAbiZgPfgFaYE-oAAAAIk
FCGI_ROLE RESPONDER
PHP_SELF /public/index.php
REQUEST_TIME_FLOAT 1781779770.3269
REQUEST_TIME 1781779770
#
Path
0 /var/www/html/public/index.php
1 /var/www/html/app/Bootstrap.php
2 /var/www/html/app/modules/Application/Mvc/Config.php
3 /var/www/html/app/config/environment/production.php
4 /var/www/html/app/config/global.php
5 /var/www/html/app/config/modules.php
6 /var/www/html/app/modules/Application/Loader/Modules.php
7 /var/www/html/vendor/autoload.php
8 /var/www/html/vendor/composer/autoload_real.php
9 /var/www/html/vendor/composer/ClassLoader.php
10 /var/www/html/vendor/composer/include_paths.php
11 /var/www/html/vendor/composer/autoload_static.php
12 /var/www/html/vendor/ralouphie/getallheaders/src/getallheaders.php
13 /var/www/html/vendor/symfony/deprecation-contracts/function.php
14 /var/www/html/vendor/adbario/php-dot-notation/src/helpers.php
15 /var/www/html/vendor/guzzlehttp/guzzle/src/functions_include.php
16 /var/www/html/vendor/guzzlehttp/guzzle/src/functions.php
17 /var/www/html/vendor/cakephp/core/functions.php
18 /var/www/html/vendor/cakephp/core/functions_global.php
19 /var/www/html/vendor/symfony/polyfill-mbstring/bootstrap.php
20 /var/www/html/vendor/symfony/polyfill-mbstring/bootstrap80.php
21 /var/www/html/vendor/paragonie/random_compat/lib/random.php
22 /var/www/html/vendor/cakephp/utility/bootstrap.php
23 /var/www/html/vendor/cakephp/utility/Inflector.php
24 /var/www/html/vendor/halaxa/json-machine/src/functions.php
25 /var/www/html/vendor/symfony/polyfill-php85/bootstrap.php
26 /var/www/html/vendor/mongodb/mongodb/src/functions.php
27 /var/www/html/vendor/wzhih/guomi/src/overwrite.php
28 /var/www/html/app/modules/Application/Mvc/View/Engine/Volt.php
29 /var/www/html/app/modules/Application/Widget/Proxy.php
30 /var/www/html/app/modules/System/Model/Configuration.php
31 /var/www/html/app/modules/Application/Mvc/Helper.php
32 /var/www/html/app/modules/Menu/Helper/Menu.php
33 /var/www/html/app/modules/Application/Acl/DefaultAcl.php
34 /var/www/html/app/modules/Managements/Model/Staff.php
35 /var/www/html/app/modules/Application/Mvc/Model/Model.php
36 /var/www/html/app/modules/Managements/Model/Companys.php
37 /var/www/html/app/modules/Application/Mvc/Modules.php
38 /var/www/html/app/modules/Admin/Controller/AdminUserController.php
39 /var/www/html/app/modules/Application/Mvc/Controller.php
40 /var/www/html/app/modules/Admin/Controller/IndexController.php
41 /var/www/html/app/modules/Analysis/Controller/ApiController.php
42 /var/www/html/app/modules/Eshop/Controller/CartController.php
43 /var/www/html/app/modules/Eshop/Controller/IndexController.php
44 /var/www/html/app/modules/Goods/Controller/AdminController.php
45 /var/www/html/app/modules/Goods/Controller/IndexController.php
46 /var/www/html/app/modules/Index/Controller/BarcodeController.php
47 /var/www/html/app/modules/Index/Controller/IndexController.php
48 /var/www/html/app/modules/Import/Controller/ApiController.php
49 /var/www/html/app/modules/Import/Controller/ExporterController.php
50 /var/www/html/app/modules/Import/Controller/FeeController.php
51 /var/www/html/app/modules/Import/Controller/LogisticsController.php
52 /var/www/html/app/modules/Import/Controller/LogisticsGoodsController.php
53 /var/www/html/app/modules/Import/Controller/NetworkController.php
54 /var/www/html/app/modules/Import/Controller/NetworkCustomerController.php
55 /var/www/html/app/modules/Import/Controller/NetworkCustomerFeeController.php
56 /var/www/html/app/modules/Import/Controller/NetworkCustomerStaffController.php
57 /var/www/html/app/modules/Import/Controller/NetworkSettlePriceController.php
58 /var/www/html/app/modules/Import/Controller/PackageController.php
59 /var/www/html/app/modules/Import/Controller/PrintController.php
60 /var/www/html/app/modules/Import/Controller/ReviewNoticeController.php
61 /var/www/html/app/modules/Import/Controller/StaffController.php
62 /var/www/html/app/modules/Import/Controller/TransportController.php
63 /var/www/html/app/modules/Managements/Controller/ApiController.php
64 /var/www/html/app/modules/Managements/Controller/BranchController.php
65 /var/www/html/app/modules/Managements/Controller/CompanyController.php
66 /var/www/html/app/modules/Managements/Controller/RoleController.php
67 /var/www/html/app/modules/Managements/Controller/StaffController.php
68 /var/www/html/app/modules/Distribution/Controller/AgentController.php
69 /var/www/html/app/modules/Distribution/Controller/ApiController.php
70 /var/www/html/app/modules/Distribution/Controller/RetailerController.php
71 /var/www/html/app/modules/Distribution/Controller/ShopController.php
72 /var/www/html/app/modules/Mobile/Controller/ActivityController.php
73 /var/www/html/app/modules/Mobile/Controller/AdminController.php
74 /var/www/html/vendor/wechatdeveloper/include.php
75 /var/www/html/app/modules/Mobile/Controller/ApiController.php
76 /var/www/html/app/modules/Mobile/Controller/AuthController.php
77 /var/www/html/app/modules/Mobile/Controller/AutomatController.php
78 /var/www/html/app/modules/Mobile/Controller/BlockController.php
79 /var/www/html/app/modules/Mobile/Controller/CommercialController.php
80 /var/www/html/app/modules/Mobile/Controller/CommonController.php
81 /var/www/html/app/modules/Mobile/Controller/DevelController.php
82 /var/www/html/app/modules/Mobile/Controller/DominoController.php
83 /var/www/html/app/modules/Mobile/Controller/GushiciController.php
84 /var/www/html/app/modules/Mobile/Controller/IndexController.php
85 /var/www/html/app/modules/Mobile/Controller/LogisticsController.php
86 /var/www/html/app/modules/Mobile/Controller/MessageController.php
87 /var/www/html/app/modules/Mobile/Controller/NetworkerController.php
88 /var/www/html/app/modules/Mobile/Controller/PaymentController.php
89 /var/www/html/app/modules/Mobile/Controller/PiccController.php
90 /var/www/html/app/modules/Mobile/Controller/PostsController.php
91 /var/www/html/app/modules/Mobile/Controller/RetailController.php
92 /var/www/html/app/modules/Mobile/Controller/ShopController.php
93 /var/www/html/app/modules/Mobile/Controller/SxbController.php
94 /var/www/html/app/modules/Mobile/Controller/TestController.php
95 /var/www/html/app/modules/Mobile/Controller/WechatController.php
96 /var/www/html/app/modules/Mobile/Controller/WeixinworkController.php
97 /var/www/html/app/modules/Mobile/Controller/WmsController.php
98 /var/www/html/app/modules/Open/Controller/ApiController.php
99 /var/www/html/app/modules/Open/Controller/CassMallController.php
100 /var/www/html/app/modules/Open/Controller/CompanyCustomizeServiceController.php
101 /var/www/html/app/modules/Open/Controller/GjpqqdController.php
102 /var/www/html/app/modules/Open/Controller/LunjuanfengController.php
103 /var/www/html/app/modules/Open/Controller/WeixinopenController.php
104 /var/www/html/app/modules/Sales/Controller/ApiController.php
105 /var/www/html/app/modules/Sales/Controller/BarcodeController.php
106 /var/www/html/app/modules/Sales/Controller/CartController.php
107 /var/www/html/app/modules/Sales/Controller/LogisticsProfitController.php
108 /var/www/html/app/modules/Sales/Controller/OrderController.php
109 /var/www/html/app/modules/Sales/Controller/PromoBudgetController.php
110 /var/www/html/app/modules/Sales/Controller/SuborderController.php
111 /var/www/html/app/modules/Purchase/Controller/AdminController.php
112 /var/www/html/app/modules/Purchase/Controller/ApiController.php
113 /var/www/html/app/modules/Purchase/Controller/GoodsPriceController.php
114 /var/www/html/app/modules/Purchase/Controller/ManageController.php
115 /var/www/html/app/modules/Purchase/Controller/PurchaseRefundController.php
116 /var/www/html/app/modules/Purchase/Controller/RequestController.php
117 /var/www/html/app/modules/Purchase/Controller/SupplierController.php
118 /var/www/html/app/modules/Reports/Controller/AdminController.php
119 /var/www/html/app/modules/Reports/Controller/ApiController.php
120 /var/www/html/app/modules/Shipment/Controller/ApiController.php
121 /var/www/html/app/modules/Shipment/Controller/CustomerController.php
122 /var/www/html/app/modules/Shipment/Controller/DriverController.php
123 /var/www/html/app/modules/Shipment/Controller/FeeController.php
124 /var/www/html/app/modules/Shipment/Controller/FreightRuleController.php
125 /var/www/html/app/modules/Shipment/Controller/NetworkController.php
126 /var/www/html/app/modules/Shipment/Controller/OperatorController.php
127 /var/www/html/app/modules/Shipment/Controller/PlanController.php
128 /var/www/html/app/modules/Shipment/Controller/RotasController.php
129 /var/www/html/app/modules/Shipment/Controller/RouteController.php
130 /var/www/html/app/modules/Shipment/Controller/ServiceMatrixController.php
131 /var/www/html/app/modules/Shipment/Controller/ServiceProductController.php
132 /var/www/html/app/modules/Shipment/Controller/ShippingOrderController.php
133 /var/www/html/app/modules/Shipment/Controller/TransportAccountController.php
134 /var/www/html/app/modules/Shipment/Controller/TransportController.php
135 /var/www/html/app/modules/Shipment/Controller/TransportOrderController.php
136 /var/www/html/app/modules/Shipment/Controller/VehicleController.php
137 /var/www/html/app/modules/Shipment/Controller/VehicleTypeController.php
138 /var/www/html/app/modules/Shop/Controller/ApiController.php
139 /var/www/html/app/modules/Shop/Controller/ClientAddressController.php
140 /var/www/html/app/modules/Shop/Controller/ClientController.php
141 /var/www/html/app/modules/Shop/Controller/CustomerFlagController.php
142 /var/www/html/app/modules/Shop/Controller/CustomerLevelController.php
143 /var/www/html/app/modules/Shop/Controller/CustomerTypeController.php
144 /var/www/html/app/modules/Shop/Controller/InviteController.php
145 /var/www/html/app/modules/Shop/Controller/PointController.php
146 /var/www/html/app/modules/Shop/Controller/SearchHistoryController.php
147 /var/www/html/app/modules/Shop/Controller/ShopsController.php
148 /var/www/html/app/modules/Shop/Controller/VisitController.php
149 /var/www/html/app/modules/Stock/Controller/ApiController.php
150 /var/www/html/app/modules/Stock/Controller/CapacityController.php
151 /var/www/html/app/modules/Stock/Controller/CategoryController.php
152 /var/www/html/app/modules/Stock/Controller/DeliveryController.php
153 /var/www/html/app/modules/Stock/Controller/DispatchBillController.php
154 /var/www/html/app/modules/Stock/Controller/DropShippingController.php
155 /var/www/html/app/modules/Stock/Controller/GoodsTrackController.php
156 /var/www/html/app/modules/Stock/Controller/ImportController.php
157 /var/www/html/app/modules/Stock/Controller/InOutTypeController.php
158 /var/www/html/app/modules/Stock/Controller/InboundController.php
159 /var/www/html/app/modules/Stock/Controller/InventoryController.php
160 /var/www/html/app/modules/Stock/Controller/MovingController.php
161 /var/www/html/app/modules/Stock/Controller/OperatorController.php
162 /var/www/html/app/modules/Stock/Controller/OutboundController.php
163 /var/www/html/app/modules/Stock/Controller/PickingController.php
164 /var/www/html/app/modules/Stock/Controller/PositionController.php
165 /var/www/html/app/modules/Stock/Controller/ProductOwnerController.php
166 /var/www/html/app/modules/Stock/Controller/ReceiptController.php
167 /var/www/html/app/modules/Stock/Controller/SereSummaryController.php
168 /var/www/html/app/modules/Stock/Controller/ShelveBatchController.php
169 /var/www/html/app/modules/Stock/Controller/StockHistoryController.php
170 /var/www/html/app/modules/Stock/Controller/TakeController.php
171 /var/www/html/app/modules/Stock/Controller/TransferController.php
172 /var/www/html/app/modules/Stock/Controller/WarehouseAreaController.php
173 /var/www/html/app/modules/Stock/Controller/WarehouseController.php
174 /var/www/html/app/modules/Stock/Controller/WarningController.php
175 /var/www/html/app/modules/Stock/Controller/WaveOrderController.php
176 /var/www/html/app/modules/Stock/Controller/WaveRuleController.php
177 /var/www/html/app/modules/Content/Controller/ApiController.php
178 /var/www/html/app/modules/Content/Controller/HotkeyController.php
179 /var/www/html/app/modules/Content/Controller/PosterController.php
180 /var/www/html/app/modules/Content/Controller/ServicerController.php
181 /var/www/html/app/modules/Content/Controller/SmallappController.php
182 /var/www/html/app/modules/Content/Controller/WeixinController.php
183 /var/www/html/app/modules/Content/Controller/WorkServicerController.php
184 /var/www/html/app/modules/Finance/Controller/AbstractController.php
185 /var/www/html/app/modules/Finance/Controller/AccountController.php
186 /var/www/html/app/modules/Finance/Controller/AgentProfitController.php
187 /var/www/html/app/modules/Finance/Controller/ApiController.php
188 /var/www/html/app/modules/Finance/Controller/AssistantResourceController.php
189 /var/www/html/app/modules/Finance/Controller/BankdaybookController.php
190 /var/www/html/app/modules/Finance/Controller/BillController.php
191 /var/www/html/app/modules/Finance/Controller/CostAdjustController.php
192 /var/www/html/app/modules/Finance/Controller/CreditController.php
193 /var/www/html/app/modules/Finance/Controller/CurrencyController.php
194 /var/www/html/app/modules/Finance/Controller/DaybookController.php
195 /var/www/html/app/modules/Finance/Controller/DealingsController.php
196 /var/www/html/app/modules/Finance/Controller/DisburseController.php
197 /var/www/html/app/modules/Finance/Controller/FinanceAccountController.php
198 /var/www/html/app/modules/Finance/Controller/HistoryController.php
199 /var/www/html/app/modules/Finance/Controller/InboundCostController.php
200 /var/www/html/app/modules/Finance/Controller/InventoryCostController.php
201 /var/www/html/app/modules/Finance/Controller/NoticeController.php
202 /var/www/html/app/modules/Finance/Controller/PayableController.php
203 /var/www/html/app/modules/Finance/Controller/PaybackController.php
204 /var/www/html/app/modules/Finance/Controller/PaymentTypeController.php
205 /var/www/html/app/modules/Finance/Controller/PaymoneyController.php
206 /var/www/html/app/modules/Finance/Controller/RebateController.php
207 /var/www/html/app/modules/Finance/Controller/ReceiptController.php
208 /var/www/html/app/modules/Finance/Controller/ReceivableController.php
209 /var/www/html/app/modules/Finance/Controller/ReceiveController.php
210 /var/www/html/app/modules/Finance/Controller/RecpayTypeController.php
211 /var/www/html/app/modules/Finance/Controller/SalesReportController.php
212 /var/www/html/app/modules/Finance/Controller/SereSummaryController.php
213 /var/www/html/app/modules/Finance/Controller/SettingsController.php
214 /var/www/html/app/modules/Finance/Controller/StatementAccountController.php
215 /var/www/html/app/modules/Finance/Controller/TitleController.php
216 /var/www/html/app/modules/Finance/Controller/TransferController.php
217 /var/www/html/app/modules/Finance/Controller/VerificationController.php
218 /var/www/html/app/modules/Finance/Controller/WithdrawalAccountController.php
219 /var/www/html/app/modules/Aftersale/Controller/AgencyclaimController.php
220 /var/www/html/app/modules/Aftersale/Controller/ApiController.php
221 /var/www/html/app/modules/Aftersale/Controller/AppraisalsController.php
222 /var/www/html/app/modules/Aftersale/Controller/CategoryController.php
223 /var/www/html/app/modules/Aftersale/Controller/FactoryController.php
224 /var/www/html/app/modules/Aftersale/Controller/IdentifyController.php
225 /var/www/html/app/modules/Aftersale/Controller/NumberController.php
226 /var/www/html/app/modules/Aftersale/Controller/ProcessController.php
227 /var/www/html/app/modules/Aftersale/Controller/RefundsController.php
228 /var/www/html/app/modules/Aftersale/Controller/RegisterController.php
229 /var/www/html/app/modules/Aftersale/Controller/RequestController.php
230 /var/www/html/app/modules/Aftersale/Controller/ReturnAddressController.php
231 /var/www/html/app/modules/Aftersale/Controller/SymptomController.php
232 /var/www/html/app/modules/Setting/Controller/AddressController.php
233 /var/www/html/app/modules/Setting/Controller/AdminappConfigController.php
234 /var/www/html/app/modules/Setting/Controller/ApiController.php
235 /var/www/html/app/modules/Setting/Controller/BaseGoodsController.php
236 /var/www/html/app/modules/Setting/Controller/CategoryController.php
237 /var/www/html/app/modules/Setting/Controller/CompanyBrandController.php
238 /var/www/html/app/modules/Setting/Controller/CountryController.php
239 /var/www/html/app/modules/Setting/Controller/CurrencyController.php
240 /var/www/html/app/modules/Setting/Controller/FloorController.php
241 /var/www/html/app/modules/Setting/Controller/JobController.php
242 /var/www/html/app/modules/Setting/Controller/PackController.php
243 /var/www/html/app/modules/Setting/Controller/PaymentController.php
244 /var/www/html/app/modules/Setting/Controller/PrintTemplateController.php
245 /var/www/html/app/modules/Setting/Controller/RoomController.php
246 /var/www/html/app/modules/Setting/Controller/SearchMappingController.php
247 /var/www/html/app/modules/Setting/Controller/SmsTemplateController.php
248 /var/www/html/app/modules/Setting/Controller/TariffController.php
249 /var/www/html/app/modules/Setting/Controller/UnitsController.php
250 /var/www/html/app/modules/Setting/Controller/WorkflowController.php
251 /var/www/html/app/modules/Operation/Controller/ApiController.php
252 /var/www/html/app/modules/Operation/Controller/DominoController.php
253 /var/www/html/app/modules/Operation/Controller/EvaluateController.php
254 /var/www/html/app/modules/Operation/Controller/GoodsCollectionController.php
255 /var/www/html/app/modules/Operation/Controller/LotteryController.php
256 /var/www/html/app/modules/Operation/Controller/PriceReviewController.php
257 /var/www/html/app/modules/Operation/Controller/PromotionController.php
258 /var/www/html/app/modules/Operation/Controller/ShareController.php
259 /var/www/html/app/modules/Operation/Controller/ShopGoodsController.php
260 /var/www/html/app/modules/Operation/Controller/SpuController.php
261 /var/www/html/app/modules/System/Controller/ApiController.php
262 /var/www/html/app/modules/System/Controller/AppConfigController.php
263 /var/www/html/app/modules/System/Controller/BillingController.php
264 /var/www/html/app/modules/System/Controller/CompanyTypeController.php
265 /var/www/html/app/modules/System/Controller/ConfigurationController.php
266 /var/www/html/app/modules/System/Controller/CrontabLogController.php
267 /var/www/html/app/modules/System/Controller/DownloadTaskController.php
268 /var/www/html/app/modules/System/Controller/FilesController.php
269 /var/www/html/app/modules/System/Controller/InOutTypeController.php
270 /var/www/html/app/modules/System/Controller/LanguageController.php
271 /var/www/html/app/modules/System/Controller/MessageController.php
272 /var/www/html/app/modules/System/Controller/MissionController.php
273 /var/www/html/app/modules/System/Controller/NotifyController.php
274 /var/www/html/app/modules/System/Controller/ProfileController.php
275 /var/www/html/app/modules/System/Controller/RecPayDetailDefaultTypeController.php
276 /var/www/html/app/modules/System/Controller/RoleController.php
277 /var/www/html/app/modules/System/Controller/ThirdController.php
278 /var/www/html/app/modules/System/Controller/TranslateController.php
279 /var/www/html/app/modules/Platform/Controller/AlibabaController.php
280 /var/www/html/app/modules/Platform/Controller/GuanjiapoController.php
281 /var/www/html/app/modules/Platform/Controller/JingdongController.php
282 /var/www/html/app/modules/Platform/Controller/PinduoduoController.php
283 /var/www/html/app/modules/Platform/Controller/TaobaoController.php
284 /var/www/html/app/modules/Platform/Controller/ToutiaoController.php
285 /var/www/html/app/modules/Platform/Controller/VipshopController.php
286 /var/www/html/app/modules/Automat/Controller/ApiController.php
287 /var/www/html/app/modules/Automat/Controller/DeviceController.php
288 /var/www/html/app/modules/Automat/Controller/IndexController.php
289 /var/www/html/app/modules/Automat/Controller/ManagerController.php
290 /var/www/html/app/modules/Automat/Controller/OrdersController.php
291 /var/www/html/app/modules/Automat/Controller/SiteController.php
292 /var/www/html/app/modules/Automat/Controller/StaffController.php
293 /var/www/html/app/modules/Automat/Controller/StockController.php
294 /var/www/html/app/modules/Automat/Controller/TaskController.php
295 /var/www/html/app/modules/Support/Controller/ActivityController.php
296 /var/www/html/app/modules/Support/Controller/ApiController.php
297 /var/www/html/app/modules/Support/Controller/StaffController.php
298 /var/www/html/app/modules/Support/Controller/SuixinbaoController.php
299 /var/www/html/app/modules/Support/Controller/TrucksController.php
300 /var/www/html/app/modules/Hotel/Controller/ApiController.php
301 /var/www/html/app/modules/Hotel/Controller/CleanCheckController.php
302 /var/www/html/app/modules/Hotel/Controller/CleanWorkController.php
303 /var/www/html/app/modules/Hotel/Controller/FloorRoomController.php
304 /var/www/html/app/modules/Hotel/Controller/HotelOrderController.php
305 /var/www/html/app/modules/Hotel/Controller/RoomRepairController.php
306 /var/www/html/app/config/allow.php
307 /var/www/html/app/config/deny.php
308 /var/www/html/app/modules/Application/Mvc/Router/DefaultRouter.php
309 /var/www/html/app/modules/Admin/Routes.php
310 /var/www/html/app/modules/Analysis/Routes.php
311 /var/www/html/app/modules/Eshop/Routes.php
312 /var/www/html/app/modules/Goods/Routes.php
313 /var/www/html/app/modules/Application/Mvc/Helper/CmsCache.php
314 /var/www/html/app/modules/Index/Routes.php
315 /var/www/html/app/modules/Import/Routes.php
316 /var/www/html/app/modules/Managements/Routes.php
317 /var/www/html/app/modules/Distribution/Routes.php
318 /var/www/html/app/modules/Mobile/Routes.php
319 /var/www/html/app/modules/Open/Routes.php
320 /var/www/html/app/modules/Sales/Routes.php
321 /var/www/html/app/modules/Purchase/Routes.php
322 /var/www/html/app/modules/Reports/Routes.php
323 /var/www/html/app/modules/Shipment/Routes.php
324 /var/www/html/app/modules/Shop/Routes.php
325 /var/www/html/app/modules/Stock/Routes.php
326 /var/www/html/app/modules/Content/Routes.php
327 /var/www/html/app/modules/Finance/Routes.php
328 /var/www/html/app/modules/Aftersale/Routes.php
329 /var/www/html/app/modules/Setting/Routes.php
330 /var/www/html/app/modules/Operation/Routes.php
331 /var/www/html/app/modules/System/Routes.php
332 /var/www/html/app/modules/Platform/Routes.php
333 /var/www/html/app/modules/Automat/Routes.php
334 /var/www/html/app/modules/Support/Routes.php
335 /var/www/html/app/modules/Hotel/Routes.php
336 /var/www/html/app/modules/Application/Utils/ModuleName.php
337 /var/www/html/app/modules/Admin/Module.php
338 /var/www/html/app/plugins/CheckPoint.php
339 /var/www/html/app/plugins/Localization.php
340 /var/www/html/app/plugins/AdminLocalization.php
341 /var/www/html/data/translations/admin/cn.php
342 /var/www/html/app/plugins/Acl.php
343 /var/www/html/app/plugins/MobileDetect.php
344 /var/www/html/vendor/mobiledetect/mobiledetectlib/src/MobileDetect.php
345 /var/www/html/vendor/mobiledetect/mobiledetectlib/src/Cache/Cache.php
346 /var/www/html/vendor/psr/simple-cache/src/CacheInterface.php
347 /var/www/html/vendor/mobiledetect/mobiledetectlib/src/Cache/CacheItem.php
348 /var/www/html/app/plugins/Role.php
349 /var/www/html/app/modules/Admin/Form/RegisterForm.php
Memory
Usage 6291456