├── tests ├── _data │ └── .gitkeep ├── _output │ └── .gitignore ├── acceptance │ ├── _bootstrap.php │ ├── AboutCest.php │ ├── HomeCest.php │ ├── LoginCest.php │ └── ContactCest.php ├── functional │ ├── _bootstrap.php │ ├── LoginFormCest.php │ └── ContactFormCest.php ├── unit │ ├── _bootstrap.php │ └── common │ │ ├── models │ │ ├── UserTest.php │ │ ├── PayOrderTest.php │ │ └── DrawMoneyOrderTest.php │ │ └── helper │ │ ├── SignTest.php │ │ └── ErrorCodeTest.php ├── _support │ ├── Helper │ │ └── Api.php │ ├── ApiTester.php │ ├── FunctionalTester.php │ ├── UnitTester.php │ └── AcceptanceTester.php ├── _bootstrap.php ├── api.suite.yml ├── unit.suite.yml ├── acceptance.suite.yml.example ├── functional.suite.yml ├── bin │ ├── yii.bat │ └── yii └── api │ └── BaseCest.php ├── runtime └── .gitignore ├── app ├── home │ ├── web │ │ ├── assets │ │ │ └── .gitignore │ │ ├── index.php │ │ └── css │ │ │ └── site.css │ ├── views │ │ ├── site │ │ │ ├── index.php │ │ │ ├── error.php │ │ │ ├── email-activate.php │ │ │ └── register.php │ │ ├── layouts │ │ │ ├── footer.php │ │ │ └── left.php │ │ ├── _form_error_alert.php │ │ ├── user │ │ │ ├── pay-info.php │ │ │ ├── verify-pay-password.php │ │ │ ├── save-pay-password.php │ │ │ ├── base-info.php │ │ │ └── save-login-password.php │ │ ├── product │ │ │ └── index.php │ │ ├── draw-money-order │ │ │ ├── create.php │ │ │ ├── view.php │ │ │ └── index.php │ │ ├── pay-order │ │ │ └── view.php │ │ └── change-user-money-log │ │ │ └── index.php │ ├── controllers │ │ ├── BaseController.php │ │ ├── DataReportController.php │ │ ├── ChangeUserMoneyLogController.php │ │ ├── PayOrderController.php │ │ ├── ProductController.php │ │ ├── UserController.php │ │ └── DrawMoneyOrderController.php │ ├── assets │ │ └── AppAsset.php │ └── config │ │ ├── params.php │ │ └── main.php ├── backend │ ├── web │ │ ├── assets │ │ │ └── .gitignore │ │ ├── index.php │ │ └── css │ │ │ └── site.css │ ├── views │ │ ├── site │ │ │ ├── about.php │ │ │ ├── error.php │ │ │ ├── index.php │ │ │ ├── contact.php │ │ │ └── login.php │ │ ├── user │ │ │ ├── create.php │ │ │ ├── update.php │ │ │ ├── _form.php │ │ │ ├── _search.php │ │ │ └── pay-product-allot.php │ │ ├── product │ │ │ ├── create.php │ │ │ ├── update.php │ │ │ ├── _form.php │ │ │ ├── _search.php │ │ │ ├── view.php │ │ │ └── index.php │ │ ├── pay-channel │ │ │ ├── create.php │ │ │ ├── update.php │ │ │ ├── _search.php │ │ │ ├── _form.php │ │ │ └── view.php │ │ ├── pay-channel-account │ │ │ ├── create.php │ │ │ ├── update.php │ │ │ ├── _form.php │ │ │ ├── _search.php │ │ │ └── view.php │ │ ├── layouts │ │ │ ├── main-login.php │ │ │ ├── left.php │ │ │ └── main.php │ │ ├── draw-money-order │ │ │ ├── update.php │ │ │ └── _form.php │ │ ├── change-user-money-log │ │ │ └── view.php │ │ └── admin-log │ │ │ └── index.php │ ├── controllers │ │ ├── BaseController.php │ │ ├── ChangeUserMoneyLogController.php │ │ ├── DataReportController.php │ │ └── DrawMoneyOrderController.php │ ├── assets │ │ └── AppAsset.php │ └── config │ │ └── main.php └── api │ ├── config │ └── main.php │ ├── controllers │ ├── BaseController.php │ └── SiteController.php │ ├── payment │ ├── Payment.php │ ├── Channel.php │ └── channel │ │ └── DemoChannel.php │ └── web │ └── index.php ├── .bowerrc ├── vagrant ├── config │ ├── .gitignore │ └── vagrant-local.example.yml ├── nginx │ ├── log │ │ └── .gitignore │ └── app.conf.example └── provision │ ├── always-as-root.sh │ ├── once-as-vagrant.sh │ └── once-as-root.sh ├── install.sh ├── common ├── config │ ├── const.php │ ├── init.php │ ├── test_db.php │ ├── bootstrap.php │ ├── db.php │ ├── params.php │ ├── test.php │ └── console.php ├── helper │ ├── ErrorCode.php │ └── Sign.php ├── components │ ├── AdminLogControl.php │ └── AccessControl.php ├── models │ ├── search │ │ ├── UserToPayChannelSearch.php │ │ ├── AdminLogSearch.php │ │ ├── ProductSearch.php │ │ ├── PayChannelAccountSearch.php │ │ └── PayChannelSearch.php │ ├── form │ │ ├── UserVerifyPayPasswordForm.php │ │ ├── UserSavePasswordForm.php │ │ ├── AdminLoginForm.php │ │ ├── QueryPayOrderForm.php │ │ ├── UserLoginForm.php │ │ └── UserRegisterForm.php │ ├── AdminLog.php │ ├── EmailCode.php │ ├── PayChannelAccount.php │ └── ChangeUserMoneyLog.php └── widgets │ └── Alert.php ├── commands ├── BaseController.php └── PayOrderController.php ├── docker-compose.yml ├── .gitignore ├── yii.bat ├── yii ├── mail └── layouts │ └── html.php ├── codeception.yml ├── README.md ├── migrations ├── m200514_054741_create_email_code.php ├── m200514_082449_dump_base_data.php ├── m200514_054757_create_menu.php ├── m200514_054901_create_product.php ├── m200514_054934_create_user_to_pay_channel.php ├── m200514_035402_create_admin_log.php ├── m200514_054507_create_admin.php ├── m170907_052038_rbac_add_index_on_auth_assignment_user_id.php ├── m200514_054653_create_change_user_money_log.php ├── m200514_054815_create_pay_channel.php ├── m200514_054917_create_user.php ├── m200514_054714_create_draw_money_order.php ├── m200514_054830_create_pay_channel_account.php └── m180523_151638_rbac_updates_indexes_without_prefix.php └── Vagrantfile /tests/_data/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /runtime/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/acceptance/_bootstrap.php: -------------------------------------------------------------------------------- 1 | 'api', 4 | 'basePath' => dirname(__DIR__), 5 | 'controllerNamespace' => 'api\controllers', 6 | 'components' => [ 7 | ] 8 | ]; 9 | -------------------------------------------------------------------------------- /common/config/init.php: -------------------------------------------------------------------------------- 1 | amOnPage(Url::toRoute('/site/about')); 10 | $I->see('About', 'h1'); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/unit.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | 3 | # suite for unit (internal) tests. 4 | # RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. 5 | 6 | class_name: UnitTester 7 | modules: 8 | enabled: 9 | - Asserts 10 | - Yii2: 11 | part: [orm, email, fixtures] 12 | -------------------------------------------------------------------------------- /app/home/views/site/index.php: -------------------------------------------------------------------------------- 1 | title = 'My Yii Application'; 6 | ?> 7 |
8 | 9 |
10 |

VAST PAYMENT!!!

11 |
12 | 13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /tests/acceptance.suite.yml.example: -------------------------------------------------------------------------------- 1 | class_name: AcceptanceTester 2 | modules: 3 | enabled: 4 | - WebDriver: 5 | url: http://127.0.0.1:8080/ 6 | browser: firefox 7 | - Yii2: 8 | part: orm 9 | entryScript: index-test.php 10 | cleanup: false 11 | -------------------------------------------------------------------------------- /common/config/bootstrap.php: -------------------------------------------------------------------------------- 1 | user_id = Yii::$app->user->getId(); 15 | parent::init(); 16 | } 17 | } -------------------------------------------------------------------------------- /app/home/views/layouts/footer.php: -------------------------------------------------------------------------------- 1 | 9 | 10 | -------------------------------------------------------------------------------- /vagrant/provision/always-as-root.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #== Bash helpers == 4 | 5 | function info { 6 | echo " " 7 | echo "--> $1" 8 | echo " " 9 | } 10 | 11 | #== Provision script == 12 | 13 | info "Provision-script user: `whoami`" 14 | 15 | info "Restart web-stack" 16 | service php7.0-fpm restart 17 | service nginx restart 18 | service mysql restart -------------------------------------------------------------------------------- /tests/functional.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | 3 | # suite for functional (integration) tests. 4 | # emulate web requests and make application process them. 5 | # (tip: better to use with frameworks). 6 | 7 | # RUN `build` COMMAND AFTER ADDING/REMOVING MODULES. 8 | #basic/web/index.php 9 | class_name: FunctionalTester 10 | modules: 11 | enabled: 12 | - Filesystem 13 | - Yii2 14 | -------------------------------------------------------------------------------- /tests/unit/common/models/UserTest.php: -------------------------------------------------------------------------------- 1 | 'yii\db\Connection', 5 | 'dsn' => 'mysql:host=localhost;dbname=payment', 6 | 'username' => 'root', 7 | 'password' => 'root', 8 | 'charset' => 'utf8', 9 | 'tablePrefix'=> 'p_', 10 | // Schema cache options (for production environment) 11 | //'enableSchemaCache' => true, 12 | //'schemaCacheDuration' => 60, 13 | //'schemaCache' => 'cache', 14 | ]; 15 | -------------------------------------------------------------------------------- /tests/unit/common/models/PayOrderTest.php: -------------------------------------------------------------------------------- 1 | title = 'About'; 8 | $this->params['breadcrumbs'][] = $this->title; 9 | ?> 10 |
11 |

title) ?>

12 | 13 |

14 | This is the About page. You may modify the following file to customize its content: 15 |

16 | 17 | 18 |
19 | -------------------------------------------------------------------------------- /app/backend/controllers/BaseController.php: -------------------------------------------------------------------------------- 1 | user->isGuest) { 15 | $this->_admin = Admin::findOne(Yii::$app->user->getId()); 16 | } 17 | parent::init(); 18 | } 19 | } -------------------------------------------------------------------------------- /app/home/views/_form_error_alert.php: -------------------------------------------------------------------------------- 1 | 4 |
5 |
6 | getErrorSummary($formValidate) as $message): ?> 7 | ['class' => 'alert-dismissible alert-danger'], 9 | 'body' => $message 10 | ]) ?> 11 | 12 |
13 |
-------------------------------------------------------------------------------- /app/home/web/index.php: -------------------------------------------------------------------------------- 1 | run(); 12 | -------------------------------------------------------------------------------- /tests/acceptance/HomeCest.php: -------------------------------------------------------------------------------- 1 | amOnPage(Url::toRoute('/site/index')); 10 | $I->see('My Company'); 11 | 12 | $I->seeLink('About'); 13 | $I->click('About'); 14 | $I->wait(2); // wait for page to be opened 15 | 16 | $I->see('This is the About page.'); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/api/web/index.php: -------------------------------------------------------------------------------- 1 | run(); 14 | -------------------------------------------------------------------------------- /app/backend/web/index.php: -------------------------------------------------------------------------------- 1 | run(); 14 | -------------------------------------------------------------------------------- /app/backend/views/user/create.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', 'Create User'); 9 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Users'), 'url' => ['index']]; 10 | $this->params['breadcrumbs'][] = $this->title; 11 | ?> 12 |
13 | 14 |

title) ?>

15 | 16 | render('_form', [ 17 | 'model' => $model, 18 | ]) ?> 19 | 20 |
21 | -------------------------------------------------------------------------------- /app/api/payment/Channel.php: -------------------------------------------------------------------------------- 1 | successShow = $successShow; 14 | $this->supplier_order_id = $supplier_order_id; 15 | return true; 16 | } 17 | 18 | public function notifyFail($failShow) 19 | { 20 | $this->failShow = $failShow; 21 | return false; 22 | } 23 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # phpstorm project files 2 | .idea 3 | 4 | # netbeans project files 5 | nbproject 6 | 7 | # zend studio for eclipse project files 8 | .buildpath 9 | .project 10 | .settings 11 | 12 | # windows thumbnail cache 13 | Thumbs.db 14 | 15 | # composer vendor dir 16 | /vendor 17 | 18 | # composer itself is not needed 19 | composer.phar 20 | 21 | # Mac DS_Store Files 22 | .DS_Store 23 | 24 | # phpunit itself is not needed 25 | phpunit.phar 26 | # local phpunit config 27 | /phpunit.xml 28 | 29 | tests/_output/* 30 | tests/_support/_generated 31 | 32 | #vagrant folder 33 | /.vagrant -------------------------------------------------------------------------------- /yii.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem ------------------------------------------------------------- 4 | rem Yii command line bootstrap script for Windows. 5 | rem 6 | rem @author Qiang Xue 7 | rem @link http://www.yiiframework.com/ 8 | rem @copyright Copyright (c) 2008 Yii Software LLC 9 | rem @license http://www.yiiframework.com/license/ 10 | rem ------------------------------------------------------------- 11 | 12 | @setlocal 13 | 14 | set YII_PATH=%~dp0 15 | 16 | if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe 17 | 18 | "%PHP_COMMAND%" "%YII_PATH%yii" %* 19 | 20 | @endlocal 21 | -------------------------------------------------------------------------------- /tests/bin/yii.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem ------------------------------------------------------------- 4 | rem Yii command line bootstrap script for Windows. 5 | rem 6 | rem @author Qiang Xue 7 | rem @link http://www.yiiframework.com/ 8 | rem @copyright Copyright (c) 2008 Yii Software LLC 9 | rem @license http://www.yiiframework.com/license/ 10 | rem ------------------------------------------------------------- 11 | 12 | @setlocal 13 | 14 | set YII_PATH=%~dp0 15 | 16 | if "%PHP_COMMAND%" == "" set PHP_COMMAND=php.exe 17 | 18 | "%PHP_COMMAND%" "%YII_PATH%yii" %* 19 | 20 | @endlocal 21 | -------------------------------------------------------------------------------- /vagrant/config/vagrant-local.example.yml: -------------------------------------------------------------------------------- 1 | # Your personal GitHub token 2 | github_token: 3 | # Read more: https://github.com/blog/1509-personal-api-tokens 4 | # You can generate it here: https://github.com/settings/tokens 5 | 6 | # Guest OS timezone 7 | timezone: Europe/London 8 | 9 | # Are we need check box updates for every 'vagrant up'? 10 | box_check_update: false 11 | 12 | # Virtual machine name 13 | machine_name: yii2basic 14 | 15 | # Virtual machine IP 16 | ip: 192.168.83.137 17 | 18 | # Virtual machine CPU cores number 19 | cpus: 1 20 | 21 | # Virtual machine RAM 22 | memory: 1024 23 | -------------------------------------------------------------------------------- /app/api/payment/channel/DemoChannel.php: -------------------------------------------------------------------------------- 1 | request->post(); 20 | return $this->notifySuccess('SUCCESS', $lPost['supplier_order_id']); 21 | } 22 | 23 | public function callback() 24 | { 25 | } 26 | 27 | public function query() 28 | { 29 | } 30 | } -------------------------------------------------------------------------------- /app/backend/views/product/create.php: -------------------------------------------------------------------------------- 1 | title = '创建产品'; 9 | $this->params['breadcrumbs'][] = ['label' => '产品列表', 'url' => ['index']]; 10 | $this->params['breadcrumbs'][] = $this->title; 11 | ?> 12 |
13 |
14 |
15 |

title) ?>

16 |
17 | render('_form', [ 18 | 'model' => $model, 19 | ]) ?> 20 |
21 |
22 | -------------------------------------------------------------------------------- /app/backend/views/pay-channel/create.php: -------------------------------------------------------------------------------- 1 | title = '新增支付通道'; 9 | $this->params['breadcrumbs'][] = ['label' => '支付通道列表', 'url' => ['index']]; 10 | $this->params['breadcrumbs'][] = $this->title; 11 | ?> 12 |
13 |
14 |
15 |

title) ?>

16 |
17 | render('_form', [ 18 | 'model' => $model, 19 | ]) ?> 20 |
21 |
22 | -------------------------------------------------------------------------------- /commands/PayOrderController.php: -------------------------------------------------------------------------------- 1 | andFilterWhere(['status'=>PayOrder::STATUS_HAVE_PAID]) 15 | ->andFilterWhere(['between', 'inform_num', 1, 5 ]) 16 | ->orderBy(['notify_at'=>'desc']) 17 | ->all(); 18 | 19 | foreach($oqlPayOrder as $k => $v){ 20 | $v->notifyUser(); 21 | } 22 | return ExitCode::OK; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/home/views/site/error.php: -------------------------------------------------------------------------------- 1 | title = $name; 11 | ?> 12 |
13 | 14 |

title) ?>

15 | 16 |
17 | 18 |
19 | 20 |

21 | The above error occurred while the Web server was processing your request. 22 |

23 |

24 | Please contact us if you think this is a server error. Thank you. 25 |

26 | 27 |
28 | -------------------------------------------------------------------------------- /tests/_support/ApiTester.php: -------------------------------------------------------------------------------- 1 | amOnPage(Url::toRoute('/site/login')); 10 | $I->see('Login', 'h1'); 11 | 12 | $I->amGoingTo('try to login with correct credentials'); 13 | $I->fillField('input[name="AdminLoginForm[username]"]', 'backend'); 14 | $I->fillField('input[name="AdminLoginForm[password]"]', 'backend'); 15 | $I->click('login-button'); 16 | $I->wait(2); // wait for button to be clicked 17 | 18 | $I->expectTo('see user info'); 19 | $I->see('Logout'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /yii: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | run(); 21 | exit($exitCode); 22 | -------------------------------------------------------------------------------- /app/home/views/user/pay-info.php: -------------------------------------------------------------------------------- 1 | title = $model->username; 10 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '基本信息'), 'url' => ['/user/base-info']]; 11 | $this->params['breadcrumbs'][] = $this->title; 12 | \yii\web\YiiAsset::register($this); 13 | ?> 14 |
15 | 16 |

title) ?>

17 | $model, 19 | 'attributes' => [ 20 | 'account', 21 | 'pay_md5_key', 22 | ], 23 | ]) ?> 24 | 25 |
26 | -------------------------------------------------------------------------------- /app/backend/views/pay-channel-account/create.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '新增支付子账号'); 9 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '支付子账号列表'), 'url' => ['index']]; 10 | $this->params['breadcrumbs'][] = $this->title; 11 | ?> 12 | 22 | -------------------------------------------------------------------------------- /tests/_support/UnitTester.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class AppAsset extends AssetBundle 19 | { 20 | public $basePath = '@webroot'; 21 | public $baseUrl = '@web'; 22 | public $css = [ 23 | 'css/site.css', 24 | ]; 25 | public $js = [ 26 | ]; 27 | public $depends = [ 28 | 'yii\web\YiiAsset', 29 | 'yii\bootstrap\BootstrapAsset', 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /app/backend/assets/AppAsset.php: -------------------------------------------------------------------------------- 1 | 16 | * @since 2.0 17 | */ 18 | class AppAsset extends AssetBundle 19 | { 20 | public $basePath = '@webroot'; 21 | public $baseUrl = '@web'; 22 | public $css = [ 23 | 'css/site.css', 24 | ]; 25 | public $js = [ 26 | ]; 27 | public $depends = [ 28 | 'yii\web\YiiAsset', 29 | 'yii\bootstrap\BootstrapAsset', 30 | ]; 31 | } 32 | -------------------------------------------------------------------------------- /app/home/views/layouts/left.php: -------------------------------------------------------------------------------- 1 | 4 | user->getId()):?> 5 |
6 |
7 | params['menuList']; 9 | 10 | $lsItem = []; 11 | foreach($lsItemConf as $k => $v){ 12 | $lsItem[$k]['label'] = $v['label']; 13 | foreach($v['content'] as $k2 => $v2){ 14 | $lsItem[$k]['content'][] = '' . $v2['name'] . ''; 15 | } 16 | } 17 | echo Collapse::widget(['items' => $lsItem,]); 18 | ?> 19 |
20 |
21 | -------------------------------------------------------------------------------- /tests/_support/AcceptanceTester.php: -------------------------------------------------------------------------------- 1 | title = '更改产品: ' . $model->name; 9 | $this->params['breadcrumbs'][] = ['label' => '产品列表', 'url' => ['index']]; 10 | $this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; 11 | $this->params['breadcrumbs'][] = 'Update'; 12 | ?> 13 |
14 |
15 |
16 |

title) ?>

17 |
18 | render('_form', [ 19 | 'model' => $model, 20 | ]) ?> 21 |
22 |
23 | -------------------------------------------------------------------------------- /app/backend/views/pay-channel/update.php: -------------------------------------------------------------------------------- 1 | title = '更新支付通道: ' . $model->name; 9 | $this->params['breadcrumbs'][] = ['label' => '支付通道列表', 'url' => ['index']]; 10 | $this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; 11 | $this->params['breadcrumbs'][] = '更新'; 12 | ?> 13 |
14 | 15 |
16 |
17 |

title) ?>

18 |
19 | render('_form', [ 20 | 'model' => $model, 21 | ]) ?> 22 |
23 |
24 | -------------------------------------------------------------------------------- /app/backend/views/layouts/main-login.php: -------------------------------------------------------------------------------- 1 | 10 | beginPage() ?> 11 | 12 | 13 | 14 | 15 | 16 | 17 | <?= Html::encode($this->title) ?> 18 | head() ?> 19 | 20 | 21 | 22 | beginBody() ?> 23 | 24 | 25 | 26 | endBody() ?> 27 | 28 | 29 | endPage() ?> 30 | -------------------------------------------------------------------------------- /tests/unit/common/helper/SignTest.php: -------------------------------------------------------------------------------- 1 | 100, 'order_id'=>1234567890]; 28 | $oqUser = User::findOne($this->user_id); 29 | $ohSign = new Sign('md5'); 30 | $result = $ohSign->verify($ohSign->encrypt($lData, $oqUser), $lData, $oqUser); 31 | $this->assertTrue($result, 'md5验签不通过'); 32 | } 33 | } -------------------------------------------------------------------------------- /mail/layouts/html.php: -------------------------------------------------------------------------------- 1 | 8 | beginPage() ?> 9 | 10 | 11 | 12 | 13 | <?= Html::encode($this->title) ?> 14 | head() ?> 15 | 16 | 17 | beginBody() ?> 18 | 19 | endBody() ?> 20 | 21 | 22 | endPage() ?> 23 | -------------------------------------------------------------------------------- /vagrant/provision/once-as-vagrant.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #== Import script args == 4 | 5 | github_token=$(echo "$1") 6 | 7 | #== Bash helpers == 8 | 9 | function info { 10 | echo " " 11 | echo "--> $1" 12 | echo " " 13 | } 14 | 15 | #== Provision script == 16 | 17 | info "Provision-script user: `whoami`" 18 | 19 | info "Configure composer" 20 | composer config --global github-oauth.github.com ${github_token} 21 | echo "Done!" 22 | 23 | info "Install project dependencies" 24 | cd /app 25 | composer --no-progress --prefer-dist install 26 | 27 | info "Create bash-alias 'app' for vagrant user" 28 | echo 'alias app="cd /app"' | tee /home/vagrant/.bash_aliases 29 | 30 | info "Enabling colorized prompt for guest console" 31 | sed -i "s/#force_color_prompt=yes/force_color_prompt=yes/" /home/vagrant/.bashrc 32 | -------------------------------------------------------------------------------- /app/backend/views/user/update.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '更改用户: {name}', [ 9 | 'name' => $model->username, 10 | ]); 11 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '用户列表'), 'url' => ['index']]; 12 | $this->params['breadcrumbs'][] = ['label' => $model->username, 'url' => ['view', 'id' => $model->id]]; 13 | $this->params['breadcrumbs'][] = Yii::t('app', '更改用户'); 14 | ?> 15 |
16 |
17 |
18 |

title) ?>

19 |
20 | render('_form', [ 21 | 'model' => $model, 22 | ]) ?> 23 |
24 |
-------------------------------------------------------------------------------- /tests/bin/yii: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | [ 21 | 'db' => require __DIR__ . '/../../config/test_db.php' 22 | ] 23 | ] 24 | ); 25 | 26 | 27 | $application = new yii\console\Application($config); 28 | $exitCode = $application->run(); 29 | exit($exitCode); 30 | -------------------------------------------------------------------------------- /app/backend/views/draw-money-order/update.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '修改提款订单: {name}', [ 9 | 'name' => $model->sys_order_id, 10 | ]); 11 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '提款订单列表'), 'url' => ['index']]; 12 | $this->params['breadcrumbs'][] = ['label' => $model->sys_order_id, 'url' => ['view', 'id' => $model->id]]; 13 | $this->params['breadcrumbs'][] = Yii::t('app', '更改订单'); 14 | ?> 15 |
16 |
17 |
18 |

title) ?>

19 |
20 | render('_form', [ 21 | 'model' => $model, 22 | ]) ?> 23 |
24 |
-------------------------------------------------------------------------------- /app/backend/views/product/_form.php: -------------------------------------------------------------------------------- 1 | 10 | 'horizontal']); ?> 11 | errorSummary($model); ?> 12 | 13 |
14 |
15 | 16 | field($model, 'name')->textInput(['maxlength' => true]) ?> 17 | 18 | field($model, 'status')->dropDownList(Product::enumState('status')) ?> 19 |
20 |
21 | 25 | 26 | -------------------------------------------------------------------------------- /app/backend/views/user/_form.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 'horizontal']); ?> 12 | errorSummary($model); ?> 13 | 14 |
15 |
16 | 17 | field($model, 'username')->textInput(['maxlength' => true,'readonly'=>'true']) ?> 18 | 19 | field($model, 'status')->dropDownList(User::enumState('status')) ?> 20 | 21 |
22 |
23 | 27 | 28 | -------------------------------------------------------------------------------- /codeception.yml: -------------------------------------------------------------------------------- 1 | actor: Tester 2 | bootstrap: _bootstrap.php 3 | paths: 4 | tests: tests 5 | log: tests/_output 6 | data: tests/_data 7 | helpers: tests/_support 8 | settings: 9 | memory_limit: 1024M 10 | colors: true 11 | modules: 12 | config: 13 | Yii2: 14 | configFile: 'common/config/test.php' 15 | 16 | # To enable code coverage: 17 | #coverage: 18 | # #c3_url: http://localhost:8080/index-test.php/ 19 | # enabled: true 20 | # #remote: true 21 | # #remote_config: '../codeception.yml' 22 | # whitelist: 23 | # include: 24 | # - models/* 25 | # - controllers/* 26 | # - commands/* 27 | # - mail/* 28 | # blacklist: 29 | # include: 30 | # - assets/* 31 | # - config/* 32 | # - runtime/* 33 | # - vendor/* 34 | # - views/* 35 | # - web/* 36 | # - tests/* 37 | -------------------------------------------------------------------------------- /tests/unit/common/helper/ErrorCodeTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(ErrorCode::explain(ErrorCode::SYSTEM_ERR), '系统错误!!!', '错误码解析错误'); 24 | $this->assertEquals(ErrorCode::explain(ErrorCode::NOT_FOUND_ERR), '找不到对应的接口','错误码解析错误2'); 25 | $this->assertEquals(ErrorCode::explain(ErrorCode::PAYMENT_FORM_ERR), '请求格式错误','错误码解析错误3'); 26 | $this->assertNotEquals(ErrorCode::explain(ErrorCode::CHANNEL_FILE_ERR), '','错误码解析错误4'); 27 | $this->assertEquals(ErrorCode::explain(99999), '','错误码解析错误5'); 28 | } 29 | } -------------------------------------------------------------------------------- /common/config/params.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'userTable' => '{{%admin}}', 6 | ], 7 | 'pagination'=>[ 8 | 'pageSize' => 20, 9 | ], 10 | 'filterDateRangeOptions'=>[ 11 | 'pluginOptions'=>[ 12 | 'autoUpdateOnInit'=>false, 13 | 'showWeekNumbers' => false, 14 | 'useWithAddon'=>true, 15 | 'convertFormat'=>true, 16 | 'timePicker'=>false, 17 | 'locale'=>[ 18 | 'format' => 'YYYY-MM-DD', 19 | 'separator'=>' 到 ', 20 | 'applyLabel' => '确定', 21 | 'cancelLabel' => '取消', 22 | 'fromLabel' => '起始时间', 23 | 'toLabel' => '结束时间', 24 | 'daysOfWeek'=>false, 25 | ], 26 | 'opens'=>'left', 27 | ], 28 | 'options' => [ 29 | 'placeholder' => '请选择...', 30 | ], 31 | ], 32 | ]; 33 | -------------------------------------------------------------------------------- /app/home/views/user/verify-pay-password.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '验证支付登录密码'); 9 | $this->params['breadcrumbs'][] = Yii::t('app', '验证支付登录密码'); 10 | ?> 11 |
12 | 23 | 24 |
25 | -------------------------------------------------------------------------------- /tests/api/BaseCest.php: -------------------------------------------------------------------------------- 1 | andFilterWhere(['user_id'=>$this->_user->id])->all(); 14 | 15 | if(count($oqlUserToPayChannel) == 0){ 16 | codecept_debug('用户没有分配到通道'); 17 | } 18 | 19 | $productId = 0; 20 | foreach($oqlUserToPayChannel as $k => $v){ 21 | $oqPayChannel = $v->payChannel; 22 | if($oqPayChannel->status == PayChannel::STATUS_ON && $oqPayChannel->is_del == PayChannel::DEL_STATE_NO){ 23 | $productId = $oqPayChannel->product_id; 24 | break; 25 | } 26 | } 27 | if($productId == 0){ 28 | codecept_debug('用户分配到通道不可用'); 29 | } 30 | return $productId; 31 | } 32 | } -------------------------------------------------------------------------------- /app/home/views/site/email-activate.php: -------------------------------------------------------------------------------- 1 | title = '账号激活成功'; 14 | $this->params['breadcrumbs'][] = $this->title; 15 | $form = ActiveForm::begin([]); 16 | 17 | ?> 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/home/views/product/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '产品列表'); 10 | $this->params['breadcrumbs'][] = $this->title; 11 | ?> 12 |
13 | 14 |

title) ?>

15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | $v):?> 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
产品名称费率(单位:千分之一)
~
32 | 33 | 34 | 35 |
36 | -------------------------------------------------------------------------------- /app/backend/views/product/_search.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 38 | -------------------------------------------------------------------------------- /app/home/views/draw-money-order/create.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '提款申请'); 9 | $this->params['breadcrumbs'][] = $this->title; 10 | ?> 11 |
12 | 13 |

title) ?>

14 | 15 | 32 |
33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vast_pay 2 | php版本 第四方支付web系统v1.0 3 | 4 | ###一,安装 5 | ####window安装 6 | 直接运行以下命令 7 | 8 | ./install 9 | 10 | ####linux安装 11 | 1,先将根目录的install.sh文件赋予可执行权限 12 | 2,设置runtime目录可读可写权限 13 | 3,运行以下命令 14 | 15 | ./install 16 | 17 | ####如果install命令无法执行按以下步骤自行安装 18 | 19 | 1,执行安装扩展命令 20 | 21 | composer -vvv install 22 | 如果安装过程运行提示vendor\bower/jquery/dist文件不存在 23 | 请执行以下命令 24 | composer global require "fxp/composer-asset-plugin:^1.4.0" 25 | 26 | 2,执行数据库迁移命令 27 | 28 | php yii migrate 29 | 如果无法执行数据库迁移,请自行将根目录下的migrations文件夹下的sql文件导入数据库 30 | 先导入base_table.sql再导入base_data.sql 31 | 32 | 33 | ###二,nginx配置 34 | nginx的配置放在根目录的vagrant\nginx下的app.conf 请根据实际自行修改
35 | 项目分为三个部分 36 | 37 | 前台 /app/home 38 | 后台 /app/backend 39 | api /app/api 40 | 41 | 42 | ###三,定时任务的配置 43 | * * * * * php yii pay-order/notify-user 44 | 45 | ###四,下版本优化 46 | 47 | 1,增加redis缓存 48 | 2,将现有的models层分离出Repository 和业务逻辑层Service 49 | 3,优化定时任务 50 | 4,增加定时查询上游确认订单的正确性 51 | 5,增加代付接口 52 | 6,增加风控设置 53 | 7,增加通道和产品,提款的图表分析 54 | 8,优化前端显示和前台用户操作 -------------------------------------------------------------------------------- /common/helper/ErrorCode.php: -------------------------------------------------------------------------------- 1 | '系统错误!!!', 21 | self::NOT_FOUND_ERR => '找不到对应的接口', 22 | self::PAYMENT_FORM_ERR =>'请求格式错误', 23 | self::PAYMENT_DATA_ERR => '数据验证失败', 24 | self::CHANNEL_NOT_FOUND => '没有开通支付模式', 25 | self::CHANNEL_ACCOUNT_NOT_FOUNT => '支付账号错误', 26 | self::GENERATE_ORDER_ERR => '生成订单错误!!!', 27 | self::CHANNEL_FILE_ERR => '接口文件不存在', 28 | self::CHANNEL_ORDER_NOT_FOUND_ERR => '订单不存在', 29 | ]; 30 | return isset($lErrorCode[$code]) ? $lErrorCode[$code]:''; 31 | } 32 | } -------------------------------------------------------------------------------- /app/backend/views/pay-channel-account/update.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '更改支付子账号: {name}', [ 10 | 'name' => $model->id, 11 | ]); 12 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '支付通道列表'), 'url' => Url::to(['/pay-channel/index'])]; 13 | $this->params['breadcrumbs'][] = [ 14 | 'label' => Yii::t('app', '支付子账号列表: {pay_channel_name}', ['pay_channel_name'=>$model->payChannel->name]), 15 | 'url' => ['index', 'pay_channel_id'=>$model->pay_channel_id], 16 | ]; 17 | $this->params['breadcrumbs'][] = ['label' => $model->id, 'url' => ['view', 'id' => $model->id]]; 18 | $this->params['breadcrumbs'][] = Yii::t('app', '更改'); 19 | ?> 20 | 30 | -------------------------------------------------------------------------------- /common/helper/Sign.php: -------------------------------------------------------------------------------- 1 | type = $type; 11 | } 12 | 13 | //根据用户提交的加密方式自动选择对应的方法,后续改成每种加密方式单独一个类 14 | public function encrypt($lData, $oqUser) 15 | { 16 | $typeName = 'encrypt' . ucfirst($this->type); 17 | return $this->$typeName($lData, $oqUser); 18 | } 19 | 20 | public function verify($sign, $lData, $oqUser) 21 | { 22 | $typeName = 'verify' . ucfirst($this->type); 23 | return $this->$typeName($sign, $lData, $oqUser); 24 | } 25 | 26 | protected function encryptMd5($lData, $oqUser) 27 | { 28 | ksort($lData); 29 | $signString = ''; 30 | foreach($lData as $k => $v){ 31 | if($v !== ''){ 32 | $signString .= $k . '=' . $v . '&'; 33 | } 34 | } 35 | return strtolower(md5($signString . 'key='. $oqUser->pay_md5_key)); 36 | } 37 | 38 | protected function verifyMd5($sign, $lData, $oqUser) 39 | { 40 | return $this->encryptMd5($lData, $oqUser) === $sign; 41 | } 42 | } -------------------------------------------------------------------------------- /tests/acceptance/ContactCest.php: -------------------------------------------------------------------------------- 1 | amOnPage(Url::toRoute('/site/contact')); 10 | } 11 | 12 | public function contactPageWorks(AcceptanceTester $I) 13 | { 14 | $I->wantTo('ensure that contact page works'); 15 | $I->see('Contact', 'h1'); 16 | } 17 | 18 | public function contactFormCanBeSubmitted(AcceptanceTester $I) 19 | { 20 | $I->amGoingTo('submit contact form with correct data'); 21 | $I->fillField('#contactform-name', 'tester'); 22 | $I->fillField('#contactform-email', 'tester@example.com'); 23 | $I->fillField('#contactform-subject', 'test subject'); 24 | $I->fillField('#contactform-body', 'test content'); 25 | $I->fillField('#contactform-verifycode', 'testme'); 26 | 27 | $I->click('contact-button'); 28 | 29 | $I->wait(2); // wait for button to be clicked 30 | 31 | $I->dontSeeElement('#contact-form'); 32 | $I->see('Thank you for contacting us. We will respond to you as soon as possible.'); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /common/components/AdminLogControl.php: -------------------------------------------------------------------------------- 1 | user->isGuest) { 15 | 16 | $omAdminLog = new AdminLog(); 17 | $omAdminLog->admin_id = Yii::$app->user->identity->id; 18 | $omAdminLog->admin_name = Yii::$app->user->identity->username; 19 | 20 | $omAdminLog->route = Url::to(); 21 | $omAdminLog->admin_ip = Yii::$app->request->userIP; 22 | $headers = Yii::$app->request->headers; 23 | if ($headers->has('User-Agent')) { 24 | $omAdminLog->admin_agent = $headers->get('User-Agent'); 25 | } 26 | $omAdminLog->created_at = time(); 27 | if (!strpos($omAdminLog->route, 'admin-log') && 28 | !strpos($omAdminLog->route, 'assets') && 29 | !strpos($omAdminLog->route, 'debug')){ 30 | $omAdminLog->save(); 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /vagrant/nginx/app.conf.example: -------------------------------------------------------------------------------- 1 | server { 2 | charset utf-8; 3 | client_max_body_size 128M; 4 | sendfile off; 5 | 6 | listen 80; ## listen for ipv4 7 | #listen [::]:80 default_server ipv6only=on; ## listen for ipv6 8 | 9 | server_name yii2basic.test; 10 | root /app/web/; 11 | index index.php; 12 | 13 | access_log /app/vagrant/nginx/log/yii2basic.access.log; 14 | error_log /app/vagrant/nginx/log/yii2basic.error.log; 15 | 16 | location / { 17 | # Redirect everything that isn't a real file to index.php 18 | try_files $uri $uri/ /index.php$is_args$args; 19 | } 20 | 21 | # uncomment to avoid processing of calls to non-existing static files by Yii 22 | #location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ { 23 | # try_files $uri =404; 24 | #} 25 | #error_page 404 /404.html; 26 | 27 | location ~ \.php$ { 28 | include fastcgi_params; 29 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 30 | #fastcgi_pass 127.0.0.1:9000; 31 | fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; 32 | try_files $uri =404; 33 | } 34 | 35 | location ~ /\.(ht|svn|git) { 36 | deny all; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/home/config/params.php: -------------------------------------------------------------------------------- 1 | [ 5 | [ 6 | 'label'=>'商户信息', 7 | 'content'=>[ 8 | ['name'=>'基本信息','url'=>'/user/base-info'], 9 | ['name'=>'交易信息','url'=>'/user/pay-info'], 10 | ['name'=>'提款申请','url'=>'/draw-money-order/create'], 11 | ['name'=>'修改登录密码','url'=>'/user/save-login-password'], 12 | ['name'=>'修改支付密码','url'=>'/user/save-pay-password'], 13 | ], 14 | ], 15 | 16 | [ 17 | 'label'=>'订单管理', 18 | 'content'=>[ 19 | ['name'=>'支付订单列表','url'=>'/pay-order/index'], 20 | ['name'=>'提款订单列表','url'=>'/draw-money-order/index'], 21 | ['name'=>'资金日志','url'=>'/change-user-money-log/index'], 22 | ], 23 | ], 24 | 25 | [ 26 | 'label'=>'支付产品', 27 | 'content'=>[ 28 | ['name'=>'产品列表','url'=>'/product/index'], 29 | ], 30 | ], 31 | 32 | [ 33 | 'label'=>'数据分析', 34 | 'content'=>[ 35 | ['name'=>'产品报表','url'=>'/data-report/product-analyze'], 36 | ], 37 | ], 38 | ], 39 | ]; 40 | -------------------------------------------------------------------------------- /common/models/search/UserToPayChannelSearch.php: -------------------------------------------------------------------------------- 1 | $query, 33 | ]); 34 | 35 | $this->load($params); 36 | 37 | if (!$this->validate()) { 38 | return $dataProvider; 39 | } 40 | 41 | $query->andFilterWhere([ 42 | 'id' => $this->id, 43 | 'pay_channel_id' => $this->pay_channel_id, 44 | 'user_id' => $this->user_id, 45 | ]); 46 | 47 | return $dataProvider; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /common/config/test.php: -------------------------------------------------------------------------------- 1 | 'basic-tests', 11 | 'basePath' => dirname(__DIR__), 12 | 'aliases' => [ 13 | '@bower' => '@vendor/bower-asset', 14 | '@npm' => '@vendor/npm-asset', 15 | ], 16 | 'language' => 'en-US', 17 | 'components' => [ 18 | 'db' => $db, 19 | 'mailer' => [ 20 | 'useFileTransport' => true, 21 | ], 22 | 'assetManager' => [ 23 | 'basePath' => __DIR__ . '/../web/assets', 24 | ], 25 | 'urlManager' => [ 26 | 'showScriptName' => true, 27 | ], 28 | 'user' => [ 29 | 'identityClass' => 'app\models\User', 30 | ], 31 | 'request' => [ 32 | 'cookieValidationKey' => 'test', 33 | 'enableCsrfValidation' => false, 34 | // but if you absolutely need it set cookie domain to localhost 35 | /* 36 | 'csrfCookie' => [ 37 | 'domain' => 'localhost', 38 | ], 39 | */ 40 | ], 41 | ], 42 | 'params' => $params, 43 | ]; 44 | -------------------------------------------------------------------------------- /migrations/m200514_054741_create_email_code.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 20 | 'id' => $this->primaryKey(), 21 | 'email' => $this->string()->notNull(), 22 | 'code' => $this->string()->notNull(), 23 | ], $tableOptions); 24 | $this->createIndex('email', self::TABLE_NAME, ['email'], false); 25 | } 26 | 27 | /** 28 | * {@inheritdoc} 29 | */ 30 | public function safeDown() 31 | { 32 | echo "m200514_054741_create_email_code cannot be reverted.\n"; 33 | 34 | return false; 35 | } 36 | 37 | /* 38 | // Use up()/down() to run migration code without a transaction. 39 | public function up() 40 | { 41 | 42 | } 43 | 44 | public function down() 45 | { 46 | echo "m200514_054741_create_email_code cannot be reverted.\n"; 47 | 48 | return false; 49 | } 50 | */ 51 | } 52 | -------------------------------------------------------------------------------- /app/backend/config/main.php: -------------------------------------------------------------------------------- 1 | 'backend', 4 | 'basePath' => dirname(__DIR__), 5 | 'controllerNamespace' => 'backend\controllers', 6 | 'components' => [ 7 | 'authManager' => [ 8 | 'class' => 'yii\rbac\DbManager', 9 | 'defaultRoles' => ['guest'], 10 | ], 11 | 'user' => [ 12 | 'identityClass' => 'common\models\Admin', 13 | 'enableAutoLogin' => true, 14 | ], 15 | 16 | ], 17 | 'aliases' => [ 18 | '@mdm/admin' => '@vendor/mdmsoft/yii2-admin', 19 | ], 20 | 'modules' => [ 21 | 'admin' => [ 22 | 'class' => 'mdm\admin\Module', 23 | 'mainLayout' => '@backend/views/layouts/main.php', 24 | ], 25 | 'gridview' => [ 26 | 'class' => '\kartik\grid\Module', 27 | ], 28 | 'datecontrol' => [ 29 | 'class' => '\kartik\datecontrol\Module', 30 | ], 31 | 'treemanager' => [ 32 | 'class' => '\kartik\tree\Module', 33 | ] 34 | 35 | ], 36 | 'on beforeRequest' => function($event) { 37 | common\components\AdminLogControl::write($event); 38 | }, 39 | 'as access' => [ 40 | 'class' => 'mdm\admin\components\AccessControl', 41 | 'allowActions' => [ 42 | 'site/captcha', 43 | ] 44 | ], 45 | ]; 46 | -------------------------------------------------------------------------------- /app/backend/views/user/_search.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 49 | -------------------------------------------------------------------------------- /common/models/form/UserVerifyPayPasswordForm.php: -------------------------------------------------------------------------------- 1 | '验证支付密码(初次设置与登录密码一致)', 26 | ]; 27 | } 28 | 29 | /** 30 | * 验证支付密码 31 | */ 32 | public function validatePassword($attribute, $params) 33 | { 34 | $user = User::findOne(Yii::$app->user->getId()); 35 | if (!$user || !$user->validatePassword($this->password)) { 36 | $this->addError($attribute, '密码错误.'); 37 | } 38 | } 39 | 40 | public function verify(callable $callback, $lsPost, Controller $controller) 41 | { 42 | if ($this->load($lsPost) && $this->validate()){ 43 | return call_user_func($callback, $controller); 44 | }else{ 45 | return $controller->render('@home/views/user/verify-pay-password', [ 46 | 'formValidate' => $this, 47 | ]); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /common/models/AdminLog.php: -------------------------------------------------------------------------------- 1 | 255], 36 | [['admin_ip'], 'string', 'max' => 15], 37 | ]; 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | public function attributeLabels() 44 | { 45 | return [ 46 | 'id' => 'ID', 47 | 'route' => '访问路由', 48 | 'created_at' => '创建时间', 49 | 'admin_id' => '管理员id', 50 | 'admin_ip' => '访问ip', 51 | 'admin_agent' => 'Agent', 52 | 'admin_name' => '管理员名称', 53 | ]; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/backend/views/change-user-money-log/view.php: -------------------------------------------------------------------------------- 1 | title = $model->id; 10 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', 'Change User Money Logs'), 'url' => ['index']]; 11 | $this->params['breadcrumbs'][] = $this->title; 12 | \yii\web\YiiAsset::register($this); 13 | ?> 14 |
15 | 16 |

title) ?>

17 | 18 |

19 | $model->id], ['class' => 'btn btn-primary']) ?> 20 | $model->id], [ 21 | 'class' => 'btn btn-danger', 22 | 'data' => [ 23 | 'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'), 24 | 'method' => 'post', 25 | ], 26 | ]) ?> 27 |

28 | 29 | $model, 31 | 'attributes' => [ 32 | 'id', 33 | 'user_id', 34 | 'change_money', 35 | 'before_money', 36 | 'after_money', 37 | 'type', 38 | 'created_at', 39 | 'updated_at', 40 | 'extra', 41 | ], 42 | ]) ?> 43 | 44 |
45 | -------------------------------------------------------------------------------- /migrations/m200514_082449_dump_base_data.php: -------------------------------------------------------------------------------- 1 | db; 19 | $transaction = $db->beginTransaction(); 20 | $sqlStr = file_get_contents(Yii::$app->basePath . self::FILE_PATH); 21 | $lSqlStr = explode("\n", trim( $sqlStr, "\n")); 22 | 23 | foreach ($lSqlStr as $k=>$v){ 24 | if (!Yii::$app->db->createCommand($v)->execute()){ 25 | $transaction->rollBack(); 26 | return false; 27 | } 28 | } 29 | $transaction->commit(); 30 | return true; 31 | } 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function safeDown() 36 | { 37 | echo "m200514_082449_dump_base_data cannot be reverted.\n"; 38 | 39 | return false; 40 | } 41 | 42 | /* 43 | // Use up()/down() to run migration code without a transaction. 44 | public function up() 45 | { 46 | 47 | } 48 | 49 | public function down() 50 | { 51 | echo "m200514_082449_dump_base_data cannot be reverted.\n"; 52 | 53 | return false; 54 | } 55 | */ 56 | } 57 | -------------------------------------------------------------------------------- /migrations/m200514_054757_create_menu.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 19 | 'id' => $this->primaryKey(), 20 | 'name' => $this->string(128)->notNull(), 21 | 'parent' => $this->integer(), 22 | 'route' => $this->string(), 23 | 'order' => $this->integer(), 24 | 'data' => $this->binary(), 25 | "FOREIGN KEY ([[parent]]) REFERENCES ".self::TABLE_NAME."([[id]]) ON DELETE SET NULL ON UPDATE CASCADE", 26 | ], $tableOptions); 27 | } 28 | 29 | /** 30 | * {@inheritdoc} 31 | */ 32 | public function safeDown() 33 | { 34 | echo "m200514_054757_create_menu cannot be reverted.\n"; 35 | 36 | return false; 37 | } 38 | 39 | /* 40 | // Use up()/down() to run migration code without a transaction. 41 | public function up() 42 | { 43 | 44 | } 45 | 46 | public function down() 47 | { 48 | echo "m200514_054757_create_menu cannot be reverted.\n"; 49 | 50 | return false; 51 | } 52 | */ 53 | } 54 | -------------------------------------------------------------------------------- /common/config/console.php: -------------------------------------------------------------------------------- 1 | 'basic-console', 8 | 'basePath' => dirname(dirname(__DIR__)), 9 | 'bootstrap' => ['log'], 10 | 'controllerNamespace' => 'app\commands', 11 | 'aliases' => [ 12 | '@bower' => '@vendor/bower-asset', 13 | '@npm' => '@vendor/npm-asset', 14 | '@tests' => '@app/tests', 15 | ], 16 | 'components' => [ 17 | 'authManager' => [ 18 | 'class' => 'yii\rbac\DbManager', 19 | ], 20 | 'cache' => [ 21 | 'class' => 'yii\caching\FileCache', 22 | ], 23 | 'log' => [ 24 | 'targets' => [ 25 | [ 26 | 'class' => 'yii\log\FileTarget', 27 | 'levels' => ['error', 'warning'], 28 | ], 29 | ], 30 | ], 31 | 'db' => $db, 32 | ], 33 | 'params' => $params, 34 | 35 | /* 36 | 'controllerMap' => [ 37 | 'fixture' => [ // Fixture generation command line. 38 | 'class' => 'yii\faker\FixtureController', 39 | ], 40 | ], 41 | */ 42 | ]; 43 | 44 | if (YII_ENV_DEV) { 45 | // configuration adjustments for 'dev' environment 46 | $config['bootstrap'][] = 'gii'; 47 | $config['modules']['gii'] = [ 48 | 'class' => 'yii\gii\Module', 49 | ]; 50 | } 51 | 52 | return $config; 53 | -------------------------------------------------------------------------------- /app/backend/views/pay-channel/_search.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 53 | -------------------------------------------------------------------------------- /common/models/EmailCode.php: -------------------------------------------------------------------------------- 1 | 255], 33 | ]; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function attributeLabels() 40 | { 41 | return [ 42 | 'id' => 'ID', 43 | 'email' => 'Email', 44 | 'code' => '激活码', 45 | ]; 46 | } 47 | 48 | public function sendCode($email) 49 | { 50 | $this->email = $email; 51 | $this->code = Helper::randomStr(); 52 | if ($this->save()) { 53 | $subject = Yii::$app->name . '账号激活!!!'; 54 | $htmlBody = '点击链接激活邮箱:' . Yii::$app->request->hostInfo . '/site/email-activate/' . $this->code; 55 | return Helper::sendEmail($email, $subject, $htmlBody); 56 | } 57 | return false; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/backend/views/site/error.php: -------------------------------------------------------------------------------- 1 | title = $name; 11 | ?> 12 |
13 | 14 |
15 |

16 | 17 |
18 |

19 | 20 |

21 | 22 |

23 | 24 |

25 | The above error occurred while the Web server was processing your request. 26 | Please contact us if you think this is a server error. Thank you. 27 | Meanwhile, you may return to dashboard or try using the search 28 | form. 29 |

30 | 31 |
32 |
33 | 34 | 35 |
36 | 38 |
39 |
40 |
41 |
42 |
43 | 44 |
45 | -------------------------------------------------------------------------------- /app/backend/views/pay-channel-account/_form.php: -------------------------------------------------------------------------------- 1 | 13 | 'horizontal']); ?> 14 | errorSummary($model); ?> 15 |
16 | 35 |
36 | 37 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /app/backend/views/pay-channel-account/_search.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 53 | -------------------------------------------------------------------------------- /migrations/m200514_054901_create_product.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 20 | 'id' => $this->primaryKey(), 21 | 'name' => $this->string()->unique()->notNull(), 22 | 'status' => $this->tinyInteger()->unsigned()->notNull()->defaultValue(1), 23 | 'is_del' => $this->tinyInteger()->unsigned()->notNull()->defaultValue(0), 24 | 'created_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 25 | 'updated_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 26 | ], $tableOptions); 27 | } 28 | 29 | /** 30 | * {@inheritdoc} 31 | */ 32 | public function safeDown() 33 | { 34 | echo "m200514_054901_create_product cannot be reverted.\n"; 35 | 36 | return false; 37 | } 38 | 39 | /* 40 | // Use up()/down() to run migration code without a transaction. 41 | public function up() 42 | { 43 | 44 | } 45 | 46 | public function down() 47 | { 48 | echo "m200514_054901_create_product cannot be reverted.\n"; 49 | 50 | return false; 51 | } 52 | */ 53 | } 54 | -------------------------------------------------------------------------------- /app/backend/views/admin-log/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '用户操作日志'); 10 | $this->params['breadcrumbs'][] = $this->title; 11 | ?> 12 | 13 |
14 |
15 |
16 |
17 |

title; ?>

18 |
19 |
20 | $dataProvider, 22 | 'filterModel' => $searchModel, 23 | 'columns' => [ 24 | ['class' => 'yii\grid\SerialColumn'], 25 | 'admin_name', 26 | 'admin_id', 27 | 'admin_ip', 28 | 'route', 29 | 'admin_agent', 30 | [ 31 | 'attribute' => 'created_at', 32 | 'format' => ['date', 'php:Y-m-d H:i:s'], 33 | 'filterType' =>GridView::FILTER_DATE_RANGE, 34 | 'filterWidgetOptions'=> Yii::$app->params['filterDateRangeOptions'], 35 | ], 36 | ], 37 | ]); ?> 38 |
39 |
40 |
41 |
42 | -------------------------------------------------------------------------------- /migrations/m200514_054934_create_user_to_pay_channel.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 19 | 'id' => $this->primaryKey(), 20 | 'user_id' => $this->integer()->unsigned()->notNull(), 21 | 'pay_channel_id' => $this->integer()->unsigned()->notNull(), 22 | 'created_at' => $this->integer()->unsigned()->notNull(), 23 | 'updated_at' => $this->integer()->unsigned()->notNull(), 24 | ], $tableOptions); 25 | $this->createIndex('user_id', self::TABLE_NAME, ['user_id', 'pay_channel_id'], false); 26 | } 27 | 28 | /** 29 | * {@inheritdoc} 30 | */ 31 | public function safeDown() 32 | { 33 | echo "m200514_054934_create_user_to_pay_channel cannot be reverted.\n"; 34 | 35 | return false; 36 | } 37 | 38 | /* 39 | // Use up()/down() to run migration code without a transaction. 40 | public function up() 41 | { 42 | 43 | } 44 | 45 | public function down() 46 | { 47 | echo "m200514_054934_create_user_to_pay_channel cannot be reverted.\n"; 48 | 49 | return false; 50 | } 51 | */ 52 | } 53 | -------------------------------------------------------------------------------- /migrations/m200514_035402_create_admin_log.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 19 | 'id' => $this->primaryKey(), 20 | 'route' => $this->string()->notNull()->defaultValue(''), 21 | 'admin_id' => $this->integer()->unsigned()->notNull()->defaultValue(0), 22 | 'admin_name' => $this->string()->notNull()->defaultValue(''), 23 | 'admin_ip' => $this->string()->notNull()->defaultValue(''), 24 | 'admin_agent' => $this->string()->notNull()->defaultValue(''), 25 | 'created_at' => $this->integer()->notNull()->defaultValue(0), 26 | ], $tableOptions); 27 | } 28 | 29 | /** 30 | * {@inheritdoc} 31 | */ 32 | public function safeDown() 33 | { 34 | echo "m200514_035402_create_admin_log cannot be reverted.\n"; 35 | 36 | return false; 37 | } 38 | 39 | /* 40 | // Use up()/down() to run migration code without a transaction. 41 | public function up() 42 | { 43 | 44 | } 45 | 46 | public function down() 47 | { 48 | echo "m200514_035402_create_admin_log cannot be reverted.\n"; 49 | 50 | return false; 51 | } 52 | */ 53 | } 54 | -------------------------------------------------------------------------------- /app/home/views/user/save-pay-password.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '修改支付密码: {name}', [ 9 | 'name' => $model->username, 10 | ]); 11 | $this->params['breadcrumbs'][] = Yii::t('app', '商户信息'); 12 | $this->params['breadcrumbs'][] = Yii::t('app', '修改支付密码'); 13 | ?> 14 |
15 | 16 |

title) ?>

17 | 18 | 19 |
20 | 21 | errorSummary($formValidate); ?> 22 | 23 | field($formValidate, 'password')->passwordInput() ?> 24 | 25 | field($formValidate, 'confirm_password')->passwordInput() ?> 26 | 27 | 28 |
29 | 'btn btn-success']) ?> 30 |
31 | 32 | 33 | 34 |
35 | 36 |
37 |

38 |

39 |

40 | 返回 41 |
42 |

43 |
44 | 45 |
46 | -------------------------------------------------------------------------------- /app/backend/views/site/index.php: -------------------------------------------------------------------------------- 1 | title = '服务器信息'; 6 | ?> 7 | 8 | 9 | 10 |
11 |
12 | 13 |
14 |
15 |

服务器信息

16 |
17 |
18 |
19 | 20 | 29 | 30 | 31 | 32 | $v):?> 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 |
41 |
42 |
43 |
44 |
45 | 46 | -------------------------------------------------------------------------------- /app/home/views/pay-order/view.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '订单: {sys_order_id}', [ 11 | 'sys_order_id' => $model->sys_order_id, 12 | ]); 13 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '支付订单列表'), 'url' => ['index']]; 14 | $this->params['breadcrumbs'][] = $this->title; 15 | \yii\web\YiiAsset::register($this); 16 | ?> 17 |
18 |

title) ?>

19 | $model, 21 | 'attributes' => [ 22 | 'sys_order_id', 23 | 'user_order_id', 24 | 'product.name', 25 | 'user_account', 26 | 'pay_money', 27 | 'user_money', 28 | 'cost_money', 29 | [ 30 | 'attribute' => 'profit_rate', 31 | 'label' => '成本费率', 32 | ], 33 | 'user_notify_url:url', 34 | 'user_callback_url:url', 35 | 'user_extra_field', 36 | [ 37 | 'attribute' => 'status', 38 | 'value'=>function($data){ 39 | return PayOrder::enumState('status', $data->status); 40 | }, 41 | ], 42 | [ 43 | 'attribute' => 'created_at', 44 | 'format' => ['date', 'php:Y-m-d H:i:s'], 45 | ], 46 | [ 47 | 'attribute' => 'notify_at', 48 | 'label' => '支付时间', 49 | 'format' => ['date', 'php:Y-m-d H:i:s'], 50 | ], 51 | ], 52 | ]) ?> 53 |
54 | -------------------------------------------------------------------------------- /app/backend/views/pay-channel/_form.php: -------------------------------------------------------------------------------- 1 | 14 | 15 | 'horizontal']); ?> 16 | errorSummary($model); ?> 17 | 18 |
19 |
20 | 21 | field($model, 'product_id')->dropDownList( 22 | ArrayHelper::merge([''=>'请选择'], $omProduct->getIdToNameList(Product::DEL_STATE_NO)) 23 | ) ?> 24 | 25 | field($model, 'name')->textInput(['maxlength' => true]) ?> 26 | 27 | field($model, 'code')->textInput(['maxlength' => true]) ?> 28 | 29 | field($model, 'profit_rate')->Input('number') ?> 30 | 31 | field($model, 'cost_rate')->Input('number') ?> 32 | 33 | field($model, 'weight')->Input('number') ?> 34 | 35 | field($model, 'request_url')->textInput(['maxlength' => true]) ?> 36 | 37 | field($model, 'status')->dropDownList( 38 | PayChannel::enumState('status') 39 | ) ?> 40 |
41 |
42 | 43 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /app/backend/views/draw-money-order/_form.php: -------------------------------------------------------------------------------- 1 | 16 | 'horizontal']); ?> 17 | errorSummary($model); ?> 18 |
19 |
20 | 21 | 22 | field($model, 'user_id')->textInput(['disabled'=>true]) ?> 23 | 24 | field($model, 'sys_order_id')->textInput(['disabled'=>true]) ?> 25 | 26 | field($model, 'account_name')->textInput(['disabled'=>true]) ?> 27 | 28 | field($model, 'account_number')->textInput(['disabled'=>true]) ?> 29 | 30 | field($model, 'money')->textInput(['value'=>Helper::formatMoney($model->money),'disabled'=>true]) ?> 31 | 32 | field($model, 'receipt_number')->textInput(['maxlength' => true]) ?> 33 | 34 | field($model, 'remark')->textInput(['maxlength' => true]) ?> 35 | 36 | field($model, 'status')->dropDownList($lsStatus) ?> 37 | 38 |
39 |
40 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/home/config/main.php: -------------------------------------------------------------------------------- 1 | 'home', 7 | 'basePath' => dirname(__DIR__), 8 | 'controllerNamespace' => 'home\controllers', 9 | 'as access' => [ 10 | 'class' => 'common\components\AccessControl', 11 | 'allowActions' => [ 12 | 'site/*', 13 | ], 14 | ], 15 | 'components' => [ 16 | 'user' => [ 17 | 'identityClass' => 'common\models\User', 18 | 'enableAutoLogin' => true, 19 | ], 20 | 21 | 'log' => [ 22 | 'traceLevel' => YII_DEBUG ? 3 : 0, 23 | 'targets' => [ 24 | [ 25 | 'class' => 'yii\log\FileTarget', 26 | 'levels' => ['error', 'warning'], 27 | 'logFile' => '@runtime/logs/home/'.date('Ym').'/app.error.log', 28 | 'logVars' => [], 29 | 'prefix' => $logPrefix, 30 | ], 31 | [ 32 | 'class' => 'yii\log\FileTarget', 33 | 'levels' => ['info'], 34 | 'logFile' => '@runtime/logs/home/'.date('Ym').'/app.info.log', 35 | 'logVars' => [], 36 | 'prefix' => $logPrefix, 37 | ], 38 | ], 39 | ], 40 | ], 41 | 'modules' => [ 42 | 'gridview' => [ 43 | 'class' => '\kartik\grid\Module', 44 | ], 45 | 46 | // 'user' => [ 47 | // 'class' => 'dektrium\user\Module', 48 | // 'confirmWithin' => 21600, 49 | // 'cost' => 12, 50 | // 'admins' => ['admin'] 51 | // ], 52 | ], 53 | 'params' => $params, 54 | 55 | ]; 56 | -------------------------------------------------------------------------------- /app/home/views/user/base-info.php: -------------------------------------------------------------------------------- 1 | title = $model->username; 11 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '基本信息'), 'url' => ['/user/base-info']]; 12 | $this->params['breadcrumbs'][] = $this->title; 13 | \yii\web\YiiAsset::register($this); 14 | ?> 15 |
16 | 17 |

title) ?>

18 | $model, 20 | 'attributes' => [ 21 | 'username', 22 | 'email:email', 23 | [ 24 | 'attribute'=>'money', 25 | 'value' => function($data) { 26 | return Helper::formatMoney($data->money); 27 | }, 28 | 'headerOptions' => ['width' => '80'], 29 | ], 30 | [ 31 | 'attribute'=>'status', 32 | 'value' => function($data) { 33 | return User::enumState('status', $data->status); 34 | }, 35 | 'headerOptions' => ['width' => '80'], 36 | ], 37 | [ 38 | 'attribute' => 'pre_login_at', 39 | 'format' => ['date', 'php:Y-m-d H:i:s'], 40 | ], 41 | [ 42 | 'attribute' => 'created_at', 43 | 'format' => ['date', 'php:Y-m-d H:i:s'], 44 | ], 45 | [ 46 | 'attribute' => 'updated_at', 47 | 'format' => ['date', 'php:Y-m-d H:i:s'], 48 | ], 49 | ], 50 | ]) ?> 51 | 52 |
53 | -------------------------------------------------------------------------------- /app/home/controllers/DataReportController.php: -------------------------------------------------------------------------------- 1 | getProductGroupMoneySum($this->user_id); 18 | 19 | $lsProductMoneySum = []; 20 | foreach($oqlPayOrderSum as $k => $v){ 21 | $lsProductMoneySum['product_name'][] = $v->product->name; 22 | $lsProductMoneySum['pay_money'][] = $v->pay_money; 23 | $lsProductMoneySum['user_money'][] = $v->user_money; 24 | $lsProductMoneySum['cost_money'][] = $v->cost_money; 25 | $lsProductMoneySum['profit_money'][] = $v->profit_money; 26 | } 27 | 28 | $oqlPayOrder = $osPayOrder->getBeforetimeOrder('-30 day',$this->user_id); 29 | $lsEverydayMoneySum = []; 30 | $lDate = []; 31 | foreach($oqlPayOrder as $k => $v){ 32 | $date = date('Ymd',$v->notify_at); 33 | $lDate[$date] = date('Y-m-d',$v->notify_at); 34 | $lsEverydayMoneySum['pay_money'][$date] += $v->pay_money; 35 | $lsEverydayMoneySum['user_money'][$date] += $v->user_money; 36 | $lsEverydayMoneySum['cost_money'][$date] += $v->cost_money; 37 | $lsEverydayMoneySum['profit_money'][$date] += $v->profit_money; 38 | } 39 | 40 | return $this->render('product-analyze',[ 41 | 'lsProductMoneySum' => $lsProductMoneySum, 42 | 'lDate' => $lDate, 43 | 'lsEverydayMoneySum'=>$lsEverydayMoneySum, 44 | ]); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/home/views/user/save-login-password.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '修改登录密码: {name}', [ 9 | 'name' => $model->username, 10 | ]); 11 | $this->params['breadcrumbs'][] = Yii::t('app', '商户信息'); 12 | $this->params['breadcrumbs'][] = Yii::t('app', '修改登录密码'); 13 | ?> 14 |
15 | 16 |

title) ?>

17 | 18 | 19 | 35 | 36 |
37 |

38 |

39 |

40 | 41 | 'btn btn-lg btn-primary', 43 | 'style'=> 'font-size: 16px'] 44 | );?> 45 | 46 |
47 |

48 |
49 | 50 |
51 | -------------------------------------------------------------------------------- /app/backend/views/layouts/left.php: -------------------------------------------------------------------------------- 1 | 47 | -------------------------------------------------------------------------------- /common/models/form/UserSavePasswordForm.php: -------------------------------------------------------------------------------- 1 | [6, 16], 'message'=>'用户名请输入长度为8-16个字符'], 18 | ['confirm_password','compare','compareAttribute'=>'password','message'=>'两次输入密码不一致'], 19 | ]; 20 | } 21 | 22 | public function attributeLabels() 23 | { 24 | return [ 25 | 'password' => '新密码', 26 | 'confirm_password' => '确认密码', 27 | ]; 28 | } 29 | 30 | /** 31 | * 修改登录密码 32 | */ 33 | public function saveLoginPassword($userId) 34 | { 35 | if (!$this->validate()) { 36 | return false; 37 | } 38 | $oqUser = User::findOne($userId); 39 | $oqUser->generateLoginPassword($this->password); 40 | if ($oqUser->save() === false){ 41 | $this->addError('username', '修改密码失败,请联系管理员!!!'); 42 | return false; 43 | } 44 | return true; 45 | } 46 | 47 | /** 48 | * 修改支付密码 49 | */ 50 | public function savePayPassword($userId) 51 | { 52 | if (!$this->validate()) { 53 | return false; 54 | } 55 | $oqUser = User::findOne($userId); 56 | $oqUser->generatePayPassword($this->password); 57 | if ($oqUser->save() === false){ 58 | $this->addError('username', '修改密码失败,请联系管理员!!!'); 59 | return false; 60 | } 61 | return true; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/backend/controllers/ChangeUserMoneyLogController.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'class' => VerbFilter::className(), 22 | 'actions' => [ 23 | 'delete' => ['POST'], 24 | ], 25 | ], 26 | ]; 27 | } 28 | 29 | public function actionIndex() 30 | { 31 | $searchModel = new ChangeUserMoneyLogSearch(); 32 | $dataProvider = $searchModel->search(Yii::$app->request->queryParams); 33 | 34 | return $this->render('index', [ 35 | 'searchModel' => $searchModel, 36 | 'dataProvider' => $dataProvider, 37 | ]); 38 | } 39 | 40 | /** 41 | * 导出excel 42 | */ 43 | public function actionExport() 44 | { 45 | $lsQueryParam = Yii::$app->request->queryParams; 46 | 47 | header('Content-Type: application/vnd.ms-excel;'); 48 | $osChangeUserMoneyLog = new ChangeUserMoneyLogSearch(); 49 | $osChangeUserMoneyLog->export($lsQueryParam); 50 | } 51 | 52 | protected function findModel($id) 53 | { 54 | if (($model = ChangeUserMoneyLog::findOne($id)) !== null) { 55 | return $model; 56 | } 57 | 58 | throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.')); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /migrations/m200514_054507_create_admin.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 20 | 'id' => $this->primaryKey(), 21 | 'username' => $this->string(32)->notNull(), 22 | 'auth_key' => $this->string(32)->notNull(), 23 | 'password_hash' => $this->string()->notNull(), 24 | 'password_reset_token' => $this->string(), 25 | 'email' => $this->string()->notNull(), 26 | 'status' => $this->smallInteger()->unsigned()->notNull()->defaultValue(10), 27 | 'pre_login_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 28 | 'pre_login_ip' => $this->string()->notNull()->defaultValue(''), 29 | 'created_at' => $this->integer()->unsigned()->notNull(), 30 | 'updated_at' => $this->integer()->unsigned()->notNull(), 31 | ], $tableOptions); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function safeDown() 38 | { 39 | echo "m200514_054507_create_admin cannot be reverted.\n"; 40 | 41 | return false; 42 | } 43 | 44 | /* 45 | // Use up()/down() to run migration code without a transaction. 46 | public function up() 47 | { 48 | 49 | } 50 | 51 | public function down() 52 | { 53 | echo "m200514_054507_create_admin cannot be reverted.\n"; 54 | 55 | return false; 56 | } 57 | */ 58 | } 59 | -------------------------------------------------------------------------------- /migrations/m170907_052038_rbac_add_index_on_auth_assignment_user_id.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0.13 19 | */ 20 | class m170907_052038_rbac_add_index_on_auth_assignment_user_id extends Migration 21 | { 22 | public $column = 'user_id'; 23 | public $index = 'auth_assignment_user_id_idx'; 24 | 25 | /** 26 | * @throws yii\base\InvalidConfigException 27 | * @return DbManager 28 | */ 29 | protected function getAuthManager() 30 | { 31 | $authManager = Yii::$app->getAuthManager(); 32 | if (!$authManager instanceof DbManager) { 33 | throw new InvalidConfigException('You should configure "authManager" component to use database before executing this migration.'); 34 | } 35 | 36 | return $authManager; 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function up() 43 | { 44 | $authManager = $this->getAuthManager(); 45 | $this->db = $authManager->db; 46 | 47 | $this->createIndex($this->index, $authManager->assignmentTable, $this->column); 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function down() 54 | { 55 | $authManager = $this->getAuthManager(); 56 | $this->db = $authManager->db; 57 | 58 | $this->dropIndex($this->index, $authManager->assignmentTable); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /migrations/m200514_054653_create_change_user_money_log.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 19 | 'id' => $this->primaryKey(), 20 | 'user_id' => $this->integer()->unsigned()->notNull(), 21 | 'change_money' => $this->decimal(12,3)->notNull(), 22 | 'before_money' => $this->decimal(12,3)->unsigned()->notNull(), 23 | 'after_money' => $this->decimal(12,3)->unsigned()->notNull(), 24 | 'type' => $this->tinyInteger()->unsigned()->notNull(), 25 | 'extra' => $this->string()->notNull()->defaultValue(''), 26 | 'created_at' => $this->integer()->unsigned()->notNull(), 27 | 'updated_at' => $this->integer()->unsigned()->notNull(), 28 | ], $tableOptions); 29 | $this->createIndex('user_id', self::TABLE_NAME, ['user_id'], false); 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function safeDown() 36 | { 37 | echo "m200514_054653_create_change_user_money_log cannot be reverted.\n"; 38 | 39 | return false; 40 | } 41 | 42 | /* 43 | // Use up()/down() to run migration code without a transaction. 44 | public function up() 45 | { 46 | 47 | } 48 | 49 | public function down() 50 | { 51 | echo "m200514_054653_create_change_user_money_log cannot be reverted.\n"; 52 | 53 | return false; 54 | } 55 | */ 56 | } 57 | -------------------------------------------------------------------------------- /app/backend/controllers/DataReportController.php: -------------------------------------------------------------------------------- 1 | getProductGroupMoneySum(); 16 | 17 | $lsProductMoneySum = []; 18 | foreach($oqlPayOrderSum as $k => $v){ 19 | $lsProductMoneySum['product_name'][] = $v->product->name; 20 | $lsProductMoneySum['pay_money'][] = $v->pay_money; 21 | $lsProductMoneySum['user_money'][] = $v->user_money; 22 | $lsProductMoneySum['cost_money'][] = $v->cost_money; 23 | $lsProductMoneySum['profit_money'][] = $v->pay_money - $v->user_money - $v->cost_money; 24 | } 25 | 26 | 27 | $oqlPayOrder = $osPayOrder->getBeforetimeOrder(); 28 | $lsEverydayMoneySum = []; 29 | $lDate = []; 30 | foreach($oqlPayOrder as $k => $v){ 31 | $date = date('Ymd',$v->notify_at); 32 | $lDate[$date] = date('Y-m-d',$v->notify_at); 33 | $lsEverydayMoneySum['pay_money'][$date] += $v->pay_money; 34 | $lsEverydayMoneySum['user_money'][$date] += $v->user_money; 35 | $lsEverydayMoneySum['cost_money'][$date] += $v->cost_money; 36 | $lsEverydayMoneySum['profit_money'][$date] += ($v->pay_money - $v->user_money - $v->cost_money); 37 | } 38 | 39 | return $this->render('product-analyze',[ 40 | 'lsProductMoneySum' => $lsProductMoneySum, 41 | 'lDate' => $lDate, 42 | 'lsEverydayMoneySum'=>$lsEverydayMoneySum, 43 | ]); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/functional/LoginFormCest.php: -------------------------------------------------------------------------------- 1 | amOnRoute('site/login'); 8 | } 9 | 10 | public function openLoginPage(\FunctionalTester $I) 11 | { 12 | $I->see('Login', 'h1'); 13 | 14 | } 15 | 16 | // demonstrates `amLoggedInAs` method 17 | public function internalLoginById(\FunctionalTester $I) 18 | { 19 | $I->amLoggedInAs(100); 20 | $I->amOnPage('/'); 21 | $I->see('Logout (backend)'); 22 | } 23 | 24 | // demonstrates `amLoggedInAs` method 25 | public function internalLoginByInstance(\FunctionalTester $I) 26 | { 27 | $I->amLoggedInAs(\app\models\User::findByUsername('backend')); 28 | $I->amOnPage('/'); 29 | $I->see('Logout (backend)'); 30 | } 31 | 32 | public function loginWithEmptyCredentials(\FunctionalTester $I) 33 | { 34 | $I->submitForm('#login-form', []); 35 | $I->expectTo('see validations errors'); 36 | $I->see('Username cannot be blank.'); 37 | $I->see('Password cannot be blank.'); 38 | } 39 | 40 | public function loginWithWrongCredentials(\FunctionalTester $I) 41 | { 42 | $I->submitForm('#login-form', [ 43 | 'AdminLoginForm[username]' => 'backend', 44 | 'AdminLoginForm[password]' => 'wrong', 45 | ]); 46 | $I->expectTo('see validations errors'); 47 | $I->see('Incorrect username or password.'); 48 | } 49 | 50 | public function loginSuccessfully(\FunctionalTester $I) 51 | { 52 | $I->submitForm('#login-form', [ 53 | 'AdminLoginForm[username]' => 'backend', 54 | 'AdminLoginForm[password]' => 'backend', 55 | ]); 56 | $I->see('Logout (backend)'); 57 | $I->dontSeeElement('form#login-form'); 58 | } 59 | } -------------------------------------------------------------------------------- /common/models/form/AdminLoginForm.php: -------------------------------------------------------------------------------- 1 | hasErrors()) { 35 | $oqAdmin = $this->getAdmin(); 36 | 37 | if (!$oqAdmin || !$oqAdmin->validateLoginPassword($this->password)) { 38 | $this->addError($attribute, 'Incorrect username or password.'); 39 | } 40 | } 41 | } 42 | 43 | public function login() 44 | { 45 | $oqAdmin = $this->getAdmin(); 46 | if ($this->validate()) { 47 | $result = Yii::$app->user->login($oqAdmin, $this->remember_me ? 3600*24*30 : 0); 48 | $oqAdmin->pre_login_at = time(); 49 | $oqAdmin->pre_login_ip = Yii::$app->request->userIP; 50 | $oqAdmin->save(); 51 | return $result; 52 | } 53 | return false; 54 | } 55 | 56 | public function getAdmin() 57 | { 58 | if ($this->_admin === false) { 59 | $this->_admin = Admin::findByLoginName($this->username); 60 | } 61 | 62 | return $this->_admin; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/backend/views/layouts/main.php: -------------------------------------------------------------------------------- 1 | controller->action->id === 'login') { 9 | /** 10 | * Do not use this code in your template. Remove it. 11 | * Instead, use the code $this->layout = '//main-login'; in your controller. 12 | */ 13 | echo $this->render( 14 | 'main-login', 15 | ['content' => $content] 16 | ); 17 | } else { 18 | 19 | if (Yii::$app->user->isGuest) { 20 | Yii::$app->controller->redirect('/site/login'); 21 | } 22 | 23 | backend\assets\AppAsset::register($this); 24 | 25 | 26 | dmstr\web\AdminLteAsset::register($this); 27 | 28 | $directoryAsset = Yii::$app->assetManager->getPublishedUrl('@vendor/almasaeed2010/adminlte/dist'); 29 | ?> 30 | beginPage() ?> 31 | 32 | 33 | 34 | 35 | 36 | 37 | <?= Html::encode($this->title) ?> 38 | head() ?> 39 | 40 | 41 | beginBody() ?> 42 |
43 | 44 | render( 45 | 'header.php', 46 | ['directoryAsset' => $directoryAsset] 47 | ) ?> 48 | 49 | render( 50 | 'left.php', 51 | ['directoryAsset' => $directoryAsset] 52 | ) 53 | ?> 54 | 55 | render( 56 | 'content.php', 57 | ['content' => $content, 'directoryAsset' => $directoryAsset] 58 | ) ?> 59 | 60 |
61 | 62 | endBody() ?> 63 | 64 | 65 | endPage() ?> 66 | 67 | -------------------------------------------------------------------------------- /common/models/form/QueryPayOrderForm.php: -------------------------------------------------------------------------------- 1 | [10, 32], 'message'=>'订单长度10-32'], 24 | ['random_string', 'string', 'length'=>32, 'message'=>'随机字符32位'], 25 | ['sign_type', 'in', 'range' => ['md5']], 26 | ]; 27 | } 28 | 29 | public function checkData() 30 | { 31 | if(!$this->validate()){ 32 | return false; 33 | } 34 | 35 | if ($this->getUser() === null){ 36 | $this->addError('account', '用户不存在或者用户禁止交易!'); 37 | return false; 38 | } 39 | 40 | if(!$this->verifySign()){ 41 | $this->addError('sign', '签名错误!'); 42 | return false; 43 | } 44 | 45 | return true; 46 | } 47 | 48 | public function verifySign() 49 | { 50 | $oqUser = $this->getUser(); 51 | $lData = [ 52 | 'account' => $this->account , 53 | 'order_id' => $this->order_id , 54 | 'random_string' => $this->random_string , 55 | 'sign_type' => $this->sign_type , 56 | ]; 57 | return (new Sign( $this->sign_type))->verify($this->sign, $lData, $oqUser); 58 | } 59 | 60 | public function getUser() 61 | { 62 | if ($this->_user === false) { 63 | $this->_user = User::findByAccount($this->account); 64 | } 65 | 66 | return $this->_user; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/backend/views/product/view.php: -------------------------------------------------------------------------------- 1 | title = $model->name; 11 | $this->params['breadcrumbs'][] = ['label' => '产品列表', 'url' => ['index']]; 12 | $this->params['breadcrumbs'][] = $this->title; 13 | \yii\web\YiiAsset::register($this); 14 | ?> 15 | 16 |
17 |
18 |

title) ?>

19 |
20 |
21 |
22 |

23 | $model->id], ['class' => 'btn btn-primary']) ?> 24 | $model->id], [ 25 | 'class' => 'btn btn-danger', 26 | 'data' => [ 27 | 'confirm' => '您确定要删除此项目吗?', 28 | 'method' => 'post', 29 | ], 30 | ]) ?> 31 |

32 | 33 | $model, 35 | 'attributes' => [ 36 | 'id', 37 | 'name', 38 | [ 39 | 'attribute'=>'status', 40 | 'value' => function($data){ 41 | return Product::enumState('status', $data->status); 42 | }, 43 | ], 44 | [ 45 | 'attribute' => 'created_at', 46 | 'format' => ['date', 'php:Y-m-d H:i:s'], 47 | ], 48 | [ 49 | 'attribute' => 'updated_at', 50 | 'format' => ['date', 'php:Y-m-d H:i:s'], 51 | ], 52 | ], 53 | ]) ?> 54 |
55 |
56 |
57 | -------------------------------------------------------------------------------- /app/home/controllers/ChangeUserMoneyLogController.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'class' => VerbFilter::className(), 22 | 'actions' => [ 23 | 'delete' => ['POST'], 24 | ], 25 | ], 26 | ]; 27 | } 28 | 29 | /** 30 | * 资金更改日志 31 | */ 32 | public function actionIndex() 33 | { 34 | $searchModel = new ChangeUserMoneyLogSearch(); 35 | $lsQueryParam = Yii::$app->request->queryParams; 36 | $lsQueryParam['ChangeUserMoneyLogSearch']['user_id'] = $this->user_id; 37 | $dataProvider = $searchModel->search($lsQueryParam); 38 | 39 | return $this->render('index', [ 40 | 'searchModel' => $searchModel, 41 | 'dataProvider' => $dataProvider, 42 | ]); 43 | } 44 | 45 | /** 46 | * 导出excel 47 | */ 48 | public function actionExport() 49 | { 50 | header('Content-Type: application/vnd.ms-excel;'); 51 | 52 | $lsQueryParam = Yii::$app->request->queryParams; 53 | $lsQueryParam['ChangeUserMoneyLogSearch']['user_id'] = $this->user_id; 54 | 55 | $osChangeUserMoneyLog = new ChangeUserMoneyLogSearch(); 56 | $osChangeUserMoneyLog->export($lsQueryParam); 57 | } 58 | 59 | protected function findModel($id) 60 | { 61 | if (($model = ChangeUserMoneyLog::findOne(['id'=>$id, 'user_id'=> $this->user_id])) !== null) { 62 | return $model; 63 | } 64 | 65 | throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.')); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /migrations/m200514_054815_create_pay_channel.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 19 | 'id' => $this->primaryKey(), 20 | 'product_id' => $this->integer()->unsigned()->notNull(), 21 | 'name' => $this->string()->unique()->notNull(), 22 | 'code' => $this->string()->unique()->notNull(), 23 | 'profit_rate' => $this->integer()->unsigned()->notNull()->defaultValue(0), 24 | 'cost_rate' => $this->integer()->unsigned()->notNull()->defaultValue(0), 25 | 'weight' => $this->tinyInteger()->unsigned()->notNull()->defaultValue(0), 26 | 'request_url' => $this->string()->notNull()->defaultValue(''), 27 | 'status' => $this->tinyInteger()->unsigned()->notNull()->defaultValue(1), 28 | 'is_del' => $this->tinyInteger()->unsigned()->notNull()->defaultValue(0), 29 | 'created_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 30 | 'updated_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 31 | ], $tableOptions); 32 | $this->createIndex('product_id', self::TABLE_NAME, ['product_id'], false); 33 | } 34 | 35 | /** 36 | * {@inheritdoc} 37 | */ 38 | public function safeDown() 39 | { 40 | echo "m200514_054815_create_pay_channel cannot be reverted.\n"; 41 | 42 | return false; 43 | } 44 | 45 | /* 46 | // Use up()/down() to run migration code without a transaction. 47 | public function up() 48 | { 49 | 50 | } 51 | 52 | public function down() 53 | { 54 | echo "m200514_054815_create_pay_channel cannot be reverted.\n"; 55 | 56 | return false; 57 | } 58 | */ 59 | } 60 | -------------------------------------------------------------------------------- /migrations/m200514_054917_create_user.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 20 | 'id' => $this->primaryKey(), 21 | 'username' => $this->string(32)->notNull(), 22 | 'auth_key' => $this->string(32)->notNull(), 23 | 'password_hash' => $this->string()->notNull(), 24 | 'password_reset_token' => $this->string(), 25 | 'pay_password_hash' => $this->string()->notNull(), 26 | 'pay_password_reset_token' => $this->string(), 27 | 'email' => $this->string()->notNull(), 28 | 'account' => $this->string()->unique()->notNull(), 29 | 'pay_md5_key' => $this->string()->notNull(), 30 | 'money' => $this->decimal(12,3)->notNull()->defaultValue('0.000'), 31 | 'status' => $this->smallInteger()->unsigned()->notNull()->defaultValue(10), 32 | 'pre_login_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 33 | 'pre_login_ip' => $this->string()->notNull()->defaultValue(''), 34 | 'created_at' => $this->integer()->unsigned()->notNull(), 35 | 'updated_at' => $this->integer()->unsigned()->notNull(), 36 | ], $tableOptions); 37 | } 38 | 39 | /** 40 | * {@inheritdoc} 41 | */ 42 | public function safeDown() 43 | { 44 | echo "m200514_054917_create_user cannot be reverted.\n"; 45 | 46 | return false; 47 | } 48 | 49 | /* 50 | // Use up()/down() to run migration code without a transaction. 51 | public function up() 52 | { 53 | 54 | } 55 | 56 | public function down() 57 | { 58 | echo "m200514_054917_create_user cannot be reverted.\n"; 59 | 60 | return false; 61 | } 62 | */ 63 | } 64 | -------------------------------------------------------------------------------- /migrations/m200514_054714_create_draw_money_order.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 20 | 'id' => $this->primaryKey(), 21 | 'user_id' => $this->integer()->unsigned()->notNull(), 22 | 'sys_order_id' => $this->string()->notNull(), 23 | 'account_name' => $this->string()->notNull(), 24 | 'account_number' => $this->string()->notNull(), 25 | 'receipt_number' => $this->string()->notNull(), 26 | 'money' => $this->integer()->unsigned()->defaultValue('0'), 27 | 'remark' => $this->string()->notNull()->defaultValue(''), 28 | 'status' => $this->tinyInteger()->unsigned()->defaultValue('0'), 29 | 'success_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 30 | 'created_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 31 | 'updated_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 32 | ], $tableOptions); 33 | $this->createIndex('user_id', self::TABLE_NAME, ['user_id'], false); 34 | $this->createIndex('sys_order_id', self::TABLE_NAME, ['sys_order_id'], false); 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function safeDown() 41 | { 42 | echo "m200514_054714_create_draw_money_order cannot be reverted.\n"; 43 | 44 | return false; 45 | } 46 | 47 | /* 48 | // Use up()/down() to run migration code without a transaction. 49 | public function up() 50 | { 51 | 52 | } 53 | 54 | public function down() 55 | { 56 | echo "m200514_054714_create_draw_money_order cannot be reverted.\n"; 57 | 58 | return false; 59 | } 60 | */ 61 | } 62 | -------------------------------------------------------------------------------- /app/backend/views/user/pay-product-allot.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '支付产品分配: {name}', [ 10 | 'name' => $oqUser->username, 11 | ]); 12 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '用户列表'), 'url' => ['index']]; 13 | $this->params['breadcrumbs'][] = ['label' => $oqUser->username, 'url' => ['view', 'id' => $oqUser->id]]; 14 | $this->params['breadcrumbs'][] = Yii::t('app', '支付产品分配'); 15 | ?> 16 |
17 |
18 |
19 |

title) ?>

20 |
21 | 22 | 'horizontal']); ?> 23 | errorSummary($model); ?> 24 | 25 |
26 |
27 | $v):?> 28 |
29 | 30 |
31 | 'pay_channel_ids['.$v->id . '][]', 33 | 'value'=>$lsUserProduct[$v->id], 34 | 'data' => ArrayHelper::map($v->payChannels,'id', 'name'), 35 | 'options' => ['multiple' => true,'placeholder' => '请选择 ...'], 36 | 'pluginOptions' => ['allowClear'=>true], 37 | ]);?> 38 |
39 |
40 | 41 |
42 |
43 | 47 | 48 | 49 |
50 |
-------------------------------------------------------------------------------- /migrations/m200514_054830_create_pay_channel_account.php: -------------------------------------------------------------------------------- 1 | createTable(self::TABLE_NAME, [ 19 | 'id' => $this->primaryKey(), 20 | 'pay_channel_id' => $this->integer()->unsigned()->notNull(), 21 | 'account' => $this->string()->notNull()->defaultValue(''), 22 | 'appid' => $this->string()->notNull()->defaultValue(''), 23 | 'md5_key' => $this->string()->notNull()->defaultValue(''), 24 | 'private_key' => $this->string()->notNull()->defaultValue(''), 25 | 'public_key' => $this->string()->notNull()->defaultValue(''), 26 | 'extra' => $this->string()->notNull()->defaultValue(''), 27 | 'weight' => $this->tinyInteger()->unsigned()->notNull()->defaultValue(0), 28 | 'status' => $this->tinyInteger()->unsigned()->notNull()->defaultValue(1), 29 | 'is_del' => $this->tinyInteger()->unsigned()->notNull()->defaultValue(0), 30 | 'created_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 31 | 'updated_at' => $this->integer()->unsigned()->notNull()->defaultValue(0), 32 | ], $tableOptions); 33 | $this->createIndex('pay_channel_id', self::TABLE_NAME, ['pay_channel_id'], false); 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function safeDown() 40 | { 41 | echo "m200514_054830_create_pay_channel_account cannot be reverted.\n"; 42 | 43 | return false; 44 | } 45 | 46 | /* 47 | // Use up()/down() to run migration code without a transaction. 48 | public function up() 49 | { 50 | 51 | } 52 | 53 | public function down() 54 | { 55 | echo "m200514_054830_create_pay_channel_account cannot be reverted.\n"; 56 | 57 | return false; 58 | } 59 | */ 60 | } 61 | -------------------------------------------------------------------------------- /tests/functional/ContactFormCest.php: -------------------------------------------------------------------------------- 1 | amOnPage(['site/contact']); 8 | } 9 | 10 | public function openContactPage(\FunctionalTester $I) 11 | { 12 | $I->see('Contact', 'h1'); 13 | } 14 | 15 | public function submitEmptyForm(\FunctionalTester $I) 16 | { 17 | $I->submitForm('#contact-form', []); 18 | $I->expectTo('see validations errors'); 19 | $I->see('Contact', 'h1'); 20 | $I->see('Name cannot be blank'); 21 | $I->see('Email cannot be blank'); 22 | $I->see('Subject cannot be blank'); 23 | $I->see('Body cannot be blank'); 24 | $I->see('The verification code is incorrect'); 25 | } 26 | 27 | public function submitFormWithIncorrectEmail(\FunctionalTester $I) 28 | { 29 | $I->submitForm('#contact-form', [ 30 | 'ContactForm[name]' => 'tester', 31 | 'ContactForm[email]' => 'tester.email', 32 | 'ContactForm[subject]' => 'test subject', 33 | 'ContactForm[body]' => 'test content', 34 | 'ContactForm[verifyCode]' => 'testme', 35 | ]); 36 | $I->expectTo('see that email address is wrong'); 37 | $I->dontSee('Name cannot be blank', '.help-inline'); 38 | $I->see('Email is not a valid email address.'); 39 | $I->dontSee('Subject cannot be blank', '.help-inline'); 40 | $I->dontSee('Body cannot be blank', '.help-inline'); 41 | $I->dontSee('The verification code is incorrect', '.help-inline'); 42 | } 43 | 44 | public function submitFormSuccessfully(\FunctionalTester $I) 45 | { 46 | $I->submitForm('#contact-form', [ 47 | 'ContactForm[name]' => 'tester', 48 | 'ContactForm[email]' => 'tester@example.com', 49 | 'ContactForm[subject]' => 'test subject', 50 | 'ContactForm[body]' => 'test content', 51 | 'ContactForm[verifyCode]' => 'testme', 52 | ]); 53 | $I->seeEmailIsSent(); 54 | $I->dontSeeElement('#contact-form'); 55 | $I->see('Thank you for contacting us. We will respond to you as soon as possible.'); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /migrations/m180523_151638_rbac_updates_indexes_without_prefix.php: -------------------------------------------------------------------------------- 1 | 18 | * @since 2.0.16 19 | */ 20 | class m180523_151638_rbac_updates_indexes_without_prefix extends Migration 21 | { 22 | /** 23 | * @throws yii\base\InvalidConfigException 24 | * @return DbManager 25 | */ 26 | protected function getAuthManager() 27 | { 28 | $authManager = Yii::$app->getAuthManager(); 29 | if (!$authManager instanceof DbManager) { 30 | throw new InvalidConfigException('You should configure "authManager" component to use database before executing this migration.'); 31 | } 32 | 33 | return $authManager; 34 | } 35 | 36 | /** 37 | * {@inheritdoc} 38 | */ 39 | public function up() 40 | { 41 | $authManager = $this->getAuthManager(); 42 | $this->db = $authManager->db; 43 | 44 | $this->dropIndex('auth_assignment_user_id_idx', $authManager->assignmentTable); 45 | $this->createIndex('{{%idx-auth_assignment-user_id}}', $authManager->assignmentTable, 'user_id'); 46 | 47 | $this->dropIndex('idx-auth_item-type', $authManager->itemTable); 48 | $this->createIndex('{{%idx-auth_item-type}}', $authManager->itemTable, 'type'); 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | public function down() 55 | { 56 | $authManager = $this->getAuthManager(); 57 | $this->db = $authManager->db; 58 | 59 | $this->dropIndex('{{%idx-auth_assignment-user_id}}', $authManager->assignmentTable); 60 | $this->createIndex('auth_assignment_user_id_idx', $authManager->assignmentTable, 'user_id'); 61 | 62 | 63 | $this->dropIndex('{{%idx-auth_item-type}}', $authManager->itemTable); 64 | $this->createIndex('idx-auth_item-type', $authManager->itemTable, 'type'); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /app/home/views/draw-money-order/view.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '提款申请:{sys_order_id}',[ 12 | 'sys_order_id' => $model->sys_order_id, 13 | ]); 14 | $this->params['breadcrumbs'][] = $this->title; 15 | \yii\web\YiiAsset::register($this); 16 | ?> 17 |
18 | 19 |

title) ?>

20 | $model, 22 | 'attributes' => [ 23 | 'sys_order_id', 24 | 'account_name', 25 | 'account_number', 26 | [ 27 | 'attribute' => 'receipt_number', 28 | 'value' => function($data) { 29 | return $data->receipt_number == '' ? null :$data->receipt_number; 30 | }, 31 | ], 32 | [ 33 | 'attribute'=>'money', 34 | 'value' => function($data) { 35 | return Helper::formatMoney($data->money); 36 | }, 37 | ], 38 | [ 39 | 'attribute' => 'remark', 40 | 'value' => function($data) { 41 | return $data->remark == '' ? null :$data->remark; 42 | }, 43 | ], 44 | [ 45 | 'attribute' => 'status', 46 | 'value' => function($data) { 47 | return DrawMoneyOrder::enumState('status', $data->status) ; 48 | }, 49 | ], 50 | [ 51 | 'attribute' => 'success_at', 52 | 'value' => function($data) { 53 | return $data->success_at == 0 ? null :date('Y-m-d H:i:s', $data->success_at); 54 | }, 55 | ], 56 | [ 57 | 'attribute' => 'created_at', 58 | 'format' => ['date', 'php:Y-m-d H:i:s'], 59 | ], 60 | [ 61 | 'attribute' => 'updated_at', 62 | 'format' => ['date', 'php:Y-m-d H:i:s'], 63 | ], 64 | ], 65 | ]) ?> 66 | 67 |
68 | -------------------------------------------------------------------------------- /app/home/views/change-user-money-log/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '资金日志'); 13 | $this->params['breadcrumbs'][] = $this->title; 14 | ?> 15 |
16 | 17 |

title) ?>

18 |
19 | request->queryParams], ['class' => 'btn btn-primary']) ?> 20 |
21 | $dataProvider, 23 | 'filterModel' => $searchModel, 24 | 'columns' => [ 25 | ['class' => 'yii\grid\SerialColumn'], 26 | [ 27 | 'attribute'=>'change_money', 28 | 'value' => function($data) { 29 | return Helper::formatMoney($data->change_money); 30 | }, 31 | ], 32 | [ 33 | 'attribute'=>'before_money', 34 | 'value' => function($data) { 35 | return Helper::formatMoney($data->before_money); 36 | }, 37 | ], 38 | [ 39 | 'attribute'=>'after_money', 40 | 'value' => function($data) { 41 | return Helper::formatMoney($data->after_money); 42 | }, 43 | ], 44 | [ 45 | 'attribute'=>'type', 46 | 'value' => function($data){ 47 | return ChangeUserMoneyLog::enumState('type', $data->type); 48 | }, 49 | 'filter' => ChangeUserMoneyLog::enumState('type'), 50 | ], 51 | 'extra', 52 | [ 53 | 'attribute' => 'created_at', 54 | 'format' => ['date', 'php:Y-m-d H:i:s'], 55 | 'filterType' =>GridView::FILTER_DATE_RANGE, 56 | 'filterWidgetOptions'=> Yii::$app->params['filterDateRangeOptions'], 57 | ], 58 | ], 59 | ]); ?> 60 |
61 | -------------------------------------------------------------------------------- /app/home/controllers/PayOrderController.php: -------------------------------------------------------------------------------- 1 | [ 21 | 'class' => VerbFilter::className(), 22 | 'actions' => [ 23 | 'delete' => ['POST'], 24 | ], 25 | ], 26 | ]; 27 | } 28 | 29 | /** 30 | * 订单列表. 31 | */ 32 | public function actionIndex() 33 | { 34 | $lsQueryParam = Yii::$app->request->queryParams; 35 | $lsQueryParam['PayOrderSearch']['user_id'] = $this->user_id; 36 | 37 | $searchModel = new PayOrderSearch(); 38 | $dataProvider = $searchModel->search($lsQueryParam); 39 | 40 | $omProduct = new Product(); 41 | $lProductIdToName = $omProduct->getIdToNameList(); 42 | return $this->render('index', [ 43 | 'searchModel' => $searchModel, 44 | 'dataProvider' => $dataProvider, 45 | 'lProductIdToName' => $lProductIdToName, 46 | ]); 47 | } 48 | 49 | /** 50 | * 订单详情. 51 | */ 52 | public function actionView($id) 53 | { 54 | return $this->render('view', [ 55 | 'model' => $this->findModel($id), 56 | ]); 57 | } 58 | 59 | /** 60 | * 导出excel 61 | */ 62 | public function actionExport() 63 | { 64 | header('Content-Type: application/vnd.ms-excel;'); 65 | 66 | $lsQueryParam = Yii::$app->request->queryParams; 67 | $lsQueryParam['PayOrderSearch']['user_id'] = $this->user_id; 68 | 69 | $osPayOrder = new PayOrderSearch(); 70 | $osPayOrder->export($lsQueryParam); 71 | } 72 | 73 | protected function findModel($id) 74 | { 75 | if (($model = PayOrder::findOne(['id'=>$id, 'user_id'=> $this->user_id])) !== null) { 76 | return $model; 77 | } 78 | 79 | throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.')); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /common/models/form/UserLoginForm.php: -------------------------------------------------------------------------------- 1 | '用户名', 35 | 'password' => '密码', 36 | 'verify_code' => '验证码', 37 | 'remember_me' => '记住我', 38 | ]; 39 | } 40 | 41 | /** 42 | * 验证登录密码 43 | */ 44 | public function validatePassword($attribute, $params) 45 | { 46 | if (!$this->hasErrors()) { 47 | $user = $this->getUser(); 48 | if (!$user || $user->status === User::STATUS_REGISTER_AUDIT){ 49 | $this->addError($attribute, User::enumState('status', $user->status)); 50 | return false; 51 | } 52 | 53 | if (!$user || !$user->validatePassword($this->password)) { 54 | $this->addError($attribute, '用户名或密码错误.'); 55 | return false; 56 | } 57 | } 58 | return true; 59 | } 60 | 61 | /** 62 | * 用户登录操作 63 | */ 64 | public function login() 65 | { 66 | if ($this->validate()) { 67 | $result = Yii::$app->user->login($this->getUser(), $this->remember_me ? 3600*24*30 : 0); 68 | if ($result){ 69 | $this->_user->pre_login_at = time(); 70 | $this->_user->save(); 71 | } 72 | return $result; 73 | } 74 | return false; 75 | } 76 | 77 | public function getUser() 78 | { 79 | if ($this->_user === false) { 80 | $this->_user = User::findByUsername($this->username); 81 | } 82 | 83 | return $this->_user; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/home/controllers/ProductController.php: -------------------------------------------------------------------------------- 1 | [ 19 | 'class' => VerbFilter::className(), 20 | 'actions' => [ 21 | 'delete' => ['POST'], 22 | ], 23 | ], 24 | ]; 25 | } 26 | 27 | /** 28 | * 用户开通产品的基本信息 29 | */ 30 | public function actionIndex() 31 | { 32 | $omUserToPayChannel = new UserToPayChannel(); 33 | $lsUserChannel = $omUserToPayChannel->getNormalUserChannels($this->user_id); 34 | $omProduct = new Product(); 35 | $oqlProduct = $omProduct->getAllNormalProducts(); 36 | 37 | $lsProduct = []; 38 | foreach ($oqlProduct as $k => $v){ 39 | foreach($lsUserChannel as $k2 => $v2){ 40 | $lsProduct[$v2['product_id']]['name'] = $v->name; 41 | 42 | $isMin = $lsProduct[$v2['product_id']]['min_cost_rate'] > $v2['cost_rate']; 43 | $hasMin = isset($lsProduct[$v2['product_id']]['min_cost_rate']); 44 | if ($hasMin == false || $isMin){ 45 | $lsProduct[$v2['product_id']]['min_cost_rate'] = $v2['cost_rate']; 46 | } 47 | 48 | $isMax = $lsProduct[$v2['product_id']]['max_cost_rate'] < $v2['cost_rate']; 49 | $hasMax = isset($lsProduct[$v2['product_id']]['max_cost_rate']); 50 | if ($hasMax == false || $isMax){ 51 | $lsProduct[$v2['product_id']]['max_cost_rate'] = $v2['cost_rate']; 52 | } 53 | } 54 | } 55 | 56 | return $this->render('index', [ 57 | 'lsProduct' => $lsProduct, 58 | 'omProduct' =>$omProduct, 59 | ]); 60 | } 61 | 62 | 63 | protected function findModel($id) 64 | { 65 | if (($model = Product::findOne($id)) !== null) { 66 | return $model; 67 | } 68 | 69 | throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.')); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /common/components/AccessControl.php: -------------------------------------------------------------------------------- 1 | _user instanceof User) { 18 | $this->_user = Instance::ensure($this->_user, User::className()); 19 | } 20 | return $this->_user; 21 | } 22 | 23 | public function setUser($user) 24 | { 25 | $this->_user = $user; 26 | } 27 | 28 | public function beforeAction($action) 29 | { 30 | $user = $this->getUser(); 31 | return $this->denyAccess($user); 32 | } 33 | 34 | protected function denyAccess($user) 35 | { 36 | if ($user->getIsGuest()) { 37 | $user->loginRequired(); 38 | } 39 | return true; 40 | } 41 | 42 | protected function isActive($action) 43 | { 44 | $uniqueId = $action->getUniqueId(); 45 | if ($uniqueId === Yii::$app->getErrorHandler()->errorAction) { 46 | return false; 47 | } 48 | $user = $this->getUser(); 49 | if ($this->owner instanceof Module) { 50 | // convert action uniqueId into an ID relative to the module 51 | $mid = $this->owner->getUniqueId(); 52 | $id = $uniqueId; 53 | if ($mid !== '' && strpos($id, $mid . '/') === 0) { 54 | $id = substr($id, strlen($mid) + 1); 55 | } 56 | } else { 57 | $id = $action->id; 58 | } 59 | 60 | if($user->isGuest){ 61 | foreach ($this->allowActions as $route) { 62 | if (substr($route, -1) === '*') { 63 | $route = rtrim($route, "*"); 64 | if ($route === '' || strpos($id, $route) === 0) { 65 | return false; 66 | } 67 | } else { 68 | if ($id === $route) { 69 | return false; 70 | } 71 | } 72 | } 73 | } 74 | if ($user->isGuest && is_array($user->loginUrl) && isset($user->loginUrl[0]) && $uniqueId === trim($user->loginUrl[0], '/')) { 75 | return false; 76 | } 77 | return true; 78 | } 79 | } -------------------------------------------------------------------------------- /common/models/search/AdminLogSearch.php: -------------------------------------------------------------------------------- 1 | $query, 51 | 'pagination' => Yii::$app->params['pagination'], 52 | 'sort' => [ 53 | 'defaultOrder' => [ 54 | 'created_at' => SORT_DESC, 55 | ] 56 | ], 57 | ]); 58 | 59 | $this->load($params); 60 | 61 | if (!$this->validate()) { 62 | 63 | return $dataProvider; 64 | } 65 | 66 | // grid filtering conditions 67 | $query->andFilterWhere([ 68 | 'id' => $this->id, 69 | 'admin_id' => $this->admin_id, 70 | ]); 71 | 72 | $lCreatedAt = Helper::cuttingDateRange($this->created_at); 73 | if ($lCreatedAt !== []){ 74 | $query->andFilterWhere(['between', 'created_at', $lCreatedAt[0], $lCreatedAt[1]]); 75 | } 76 | 77 | $query->andFilterWhere(['like', 'route', $this->route]) 78 | ->andFilterWhere(['like', 'admin_ip', $this->admin_ip]) 79 | ->andFilterWhere(['like', 'admin_agent', $this->admin_agent]) 80 | ->andFilterWhere(['like', 'admin_name', $this->admin_name]); 81 | 82 | return $dataProvider; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/backend/web/css/site.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | } 5 | 6 | .wrap { 7 | min-height: 100%; 8 | height: auto; 9 | margin: 0 auto -60px; 10 | padding: 0 0 60px; 11 | } 12 | 13 | .wrap > .container { 14 | padding: 70px 15px 20px; 15 | } 16 | 17 | .footer { 18 | height: 60px; 19 | background-color: #f5f5f5; 20 | border-top: 1px solid #ddd; 21 | padding-top: 20px; 22 | } 23 | 24 | .jumbotron { 25 | text-align: center; 26 | background-color: transparent; 27 | } 28 | 29 | .jumbotron .btn { 30 | font-size: 21px; 31 | padding: 14px 24px; 32 | } 33 | 34 | .not-set { 35 | color: #c55; 36 | font-style: italic; 37 | } 38 | 39 | /* add sorting icons to gridview sort links */ 40 | a.asc:after, a.desc:after { 41 | position: relative; 42 | top: 1px; 43 | display: inline-block; 44 | font-family: 'Glyphicons Halflings'; 45 | font-style: normal; 46 | font-weight: normal; 47 | line-height: 1; 48 | padding-left: 5px; 49 | } 50 | 51 | a.asc:after { 52 | content: /*"\e113"*/ "\e151"; 53 | } 54 | 55 | a.desc:after { 56 | content: /*"\e114"*/ "\e152"; 57 | } 58 | 59 | .sort-numerical a.asc:after { 60 | content: "\e153"; 61 | } 62 | 63 | .sort-numerical a.desc:after { 64 | content: "\e154"; 65 | } 66 | 67 | .sort-ordinal a.asc:after { 68 | content: "\e155"; 69 | } 70 | 71 | .sort-ordinal a.desc:after { 72 | content: "\e156"; 73 | } 74 | 75 | .grid-view th { 76 | white-space: nowrap; 77 | } 78 | 79 | .hint-block { 80 | display: block; 81 | margin-top: 5px; 82 | color: #999; 83 | } 84 | 85 | .error-summary { 86 | color: #a94442; 87 | background: #fdf7f7; 88 | border-left: 3px solid #eed3d7; 89 | padding: 10px 20px; 90 | margin: 0 0 15px 0; 91 | } 92 | 93 | /* align the logout "link" (button in form) of the navbar */ 94 | .nav li > form > button.logout { 95 | padding: 15px; 96 | border: none; 97 | } 98 | 99 | @media(max-width:767px) { 100 | .nav li > form > button.logout { 101 | display:block; 102 | text-align: left; 103 | width: 100%; 104 | padding: 10px 15px; 105 | } 106 | } 107 | 108 | .nav > li > form > button.logout:focus, 109 | .nav > li > form > button.logout:hover { 110 | text-decoration: none; 111 | } 112 | 113 | .nav > li > form > button.logout:focus { 114 | outline: none; 115 | } 116 | -------------------------------------------------------------------------------- /app/home/web/css/site.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | } 5 | 6 | .wrap { 7 | min-height: 100%; 8 | height: auto; 9 | margin: 0 auto -60px; 10 | padding: 0 0 60px; 11 | } 12 | 13 | .wrap > .container { 14 | padding: 70px 15px 20px; 15 | } 16 | 17 | .footer { 18 | height: 60px; 19 | background-color: #f5f5f5; 20 | border-top: 1px solid #ddd; 21 | padding-top: 20px; 22 | } 23 | 24 | .jumbotron { 25 | text-align: center; 26 | background-color: transparent; 27 | } 28 | 29 | .jumbotron .btn { 30 | font-size: 21px; 31 | padding: 14px 24px; 32 | } 33 | 34 | .not-set { 35 | color: #c55; 36 | font-style: italic; 37 | } 38 | 39 | /* add sorting icons to gridview sort links */ 40 | a.asc:after, a.desc:after { 41 | position: relative; 42 | top: 1px; 43 | display: inline-block; 44 | font-family: 'Glyphicons Halflings'; 45 | font-style: normal; 46 | font-weight: normal; 47 | line-height: 1; 48 | padding-left: 5px; 49 | } 50 | 51 | a.asc:after { 52 | content: /*"\e113"*/ "\e151"; 53 | } 54 | 55 | a.desc:after { 56 | content: /*"\e114"*/ "\e152"; 57 | } 58 | 59 | .sort-numerical a.asc:after { 60 | content: "\e153"; 61 | } 62 | 63 | .sort-numerical a.desc:after { 64 | content: "\e154"; 65 | } 66 | 67 | .sort-ordinal a.asc:after { 68 | content: "\e155"; 69 | } 70 | 71 | .sort-ordinal a.desc:after { 72 | content: "\e156"; 73 | } 74 | 75 | .grid-view th { 76 | white-space: nowrap; 77 | } 78 | 79 | .hint-block { 80 | display: block; 81 | margin-top: 5px; 82 | color: #999; 83 | } 84 | 85 | .error-summary { 86 | color: #a94442; 87 | background: #fdf7f7; 88 | border-left: 3px solid #eed3d7; 89 | padding: 10px 20px; 90 | margin: 0 0 15px 0; 91 | } 92 | 93 | /* align the logout "link" (button in form) of the navbar */ 94 | .nav li > form > button.logout { 95 | padding: 15px; 96 | border: none; 97 | } 98 | 99 | @media(max-width:767px) { 100 | .nav li > form > button.logout { 101 | display:block; 102 | text-align: left; 103 | width: 100%; 104 | padding: 10px 15px; 105 | } 106 | } 107 | 108 | .nav > li > form > button.logout:focus, 109 | .nav > li > form > button.logout:hover { 110 | text-decoration: none; 111 | } 112 | 113 | .nav > li > form > button.logout:focus { 114 | outline: none; 115 | } 116 | -------------------------------------------------------------------------------- /app/backend/controllers/DrawMoneyOrderController.php: -------------------------------------------------------------------------------- 1 | [ 24 | 'class' => VerbFilter::className(), 25 | 'actions' => [ 26 | 'delete' => ['POST'], 27 | ], 28 | ], 29 | ]; 30 | } 31 | 32 | /** 33 | * 提款订单列表 34 | */ 35 | public function actionIndex() 36 | { 37 | $osDrawMoneyOrder = new DrawMoneyOrderSearch(); 38 | $dataProvider = $osDrawMoneyOrder->search(Yii::$app->request->queryParams); 39 | 40 | return $this->render('index', [ 41 | 'searchModel' => $osDrawMoneyOrder, 42 | 'dataProvider' => $dataProvider, 43 | ]); 44 | } 45 | 46 | /** 47 | * 提款订单详情 48 | */ 49 | public function actionView($id) 50 | { 51 | return $this->render('view', [ 52 | 'model' => $this->findModel($id), 53 | ]); 54 | } 55 | 56 | /** 57 | * 修改提款订单 58 | */ 59 | public function actionUpdate($id) 60 | { 61 | $oqDrawMoney = $this->findModel($id); 62 | if ($oqDrawMoney->load(Yii::$app->request->post()) && $oqDrawMoney->saveApply()) { 63 | return $this->redirect(['view', 'id' => $oqDrawMoney->id]); 64 | } 65 | 66 | return $this->render('update', [ 67 | 'model' => $oqDrawMoney, 68 | ]); 69 | } 70 | 71 | /** 72 | * 导出excel 73 | */ 74 | public function actionExport() 75 | { 76 | header('Content-Type: application/vnd.ms-excel;'); 77 | $osDrawMoneyOrder = new DrawMoneyOrderSearch(); 78 | $osDrawMoneyOrder->export(Yii::$app->request->queryParams); 79 | } 80 | 81 | 82 | protected function findModel($id) 83 | { 84 | if (($oqDrawMoney = DrawMoneyOrder::findOne($id)) !== null) { 85 | return $oqDrawMoney; 86 | } 87 | 88 | throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.')); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /vagrant/provision/once-as-root.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #== Import script args == 4 | 5 | timezone=$(echo "$1") 6 | 7 | #== Bash helpers == 8 | 9 | function info { 10 | echo " " 11 | echo "--> $1" 12 | echo " " 13 | } 14 | 15 | #== Provision script == 16 | 17 | info "Provision-script user: `whoami`" 18 | 19 | export DEBIAN_FRONTEND=noninteractive 20 | 21 | info "Configure timezone" 22 | timedatectl set-timezone ${timezone} --no-ask-password 23 | 24 | info "Prepare root password for MySQL" 25 | debconf-set-selections <<< "mariadb-server-10.0 mysql-server/root_password password \"''\"" 26 | debconf-set-selections <<< "mariadb-server-10.0 mysql-server/root_password_again password \"''\"" 27 | echo "Done!" 28 | 29 | info "Update OS software" 30 | apt-get update 31 | apt-get upgrade -y 32 | 33 | info "Install additional software" 34 | apt-get install -y php7.0-curl php7.0-cli php7.0-intl php7.0-mysqlnd php7.0-gd php7.0-fpm php7.0-mbstring php7.0-xml unzip nginx mariadb-server-10.0 php.xdebug 35 | 36 | info "Configure MySQL" 37 | sed -i "s/.*bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/mariadb.conf.d/50-server.cnf 38 | mysql -uroot <<< "CREATE USER 'root'@'%' IDENTIFIED BY ''" 39 | mysql -uroot <<< "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'" 40 | mysql -uroot <<< "DROP USER 'root'@'localhost'" 41 | mysql -uroot <<< "FLUSH PRIVILEGES" 42 | echo "Done!" 43 | 44 | info "Configure PHP-FPM" 45 | sed -i 's/user = www-data/user = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf 46 | sed -i 's/group = www-data/group = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf 47 | sed -i 's/owner = www-data/owner = vagrant/g' /etc/php/7.0/fpm/pool.d/www.conf 48 | cat << EOF > /etc/php/7.0/mods-available/xdebug.ini 49 | zend_extension=xdebug.so 50 | xdebug.remote_enable=1 51 | xdebug.remote_connect_back=1 52 | xdebug.remote_port=9000 53 | xdebug.remote_autostart=1 54 | EOF 55 | echo "Done!" 56 | 57 | info "Configure NGINX" 58 | sed -i 's/user www-data/user vagrant/g' /etc/nginx/nginx.conf 59 | echo "Done!" 60 | 61 | info "Enabling site configuration" 62 | ln -s /app/vagrant/nginx/app.conf /etc/nginx/sites-enabled/app.conf 63 | echo "Done!" 64 | 65 | info "Removing default site configuration" 66 | rm /etc/nginx/sites-enabled/default 67 | echo "Done!" 68 | 69 | info "Initailize databases for MySQL" 70 | mysql -uroot <<< "CREATE DATABASE yii2basic" 71 | mysql -uroot <<< "CREATE DATABASE yii2basic_test" 72 | echo "Done!" 73 | 74 | info "Install composer" 75 | curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer -------------------------------------------------------------------------------- /app/home/views/site/register.php: -------------------------------------------------------------------------------- 1 | title = '用户注册'; 14 | $this->params['breadcrumbs'][] = $this->title; 15 | $form = ActiveForm::begin([]); 16 | 17 | ?> 18 | 19 | 20 | render('/_form_error_alert',['formValidate'=>$formValidate])?> 21 |
22 |
23 | 24 |
25 |
26 |

title) ?>

27 |
28 | 29 |
30 | 31 | field($formValidate, 'email') ?> 32 | 33 | field($formValidate, 'username') ?> 34 | 35 | field($formValidate, 'password')->passwordInput() ?> 36 | 37 | field($formValidate, 'confirm_password')->passwordInput() ?> 38 | field($formValidate, 'verify_code') 40 | ->widget(Captcha::className(), [ 41 | 'captchaAction'=>Url::to('site/captcha'), 42 | 'imageOptions'=>[ 43 | 'title'=>'换一个', 44 | 'alt'=>'换一个', 45 | ], 46 | 'options' => ['placeholder' => $formValidate->getAttributeLabel('verify_code')], 47 | 'template' => "
{input}
\n
{image}
", 48 | ]) ?> 49 | 'btn btn-success btn-block']) ?> 50 | 51 | 52 |
53 |
54 |

55 | 56 |

57 |
58 |
59 | 60 | ['class' => 'alert-dismissible alert-success'], 62 | 'body' => $registerHint 63 | ]) ?> 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /common/widgets/Alert.php: -------------------------------------------------------------------------------- 1 | session->setFlash('error', 'This is the message'); 12 | * Yii::$app->session->setFlash('success', 'This is the message'); 13 | * Yii::$app->session->setFlash('info', 'This is the message'); 14 | * ``` 15 | * 16 | * Multiple messages could be set as follows: 17 | * 18 | * ```php 19 | * Yii::$app->session->setFlash('error', ['Error 1', 'Error 2']); 20 | * ``` 21 | * 22 | * @author Kartik Visweswaran 23 | * @author Alexander Makarov 24 | */ 25 | class Alert extends \yii\bootstrap\Widget 26 | { 27 | /** 28 | * @var array the alert types configuration for the flash messages. 29 | * This array is setup as $key => $value, where: 30 | * - key: the name of the session flash variable 31 | * - value: the bootstrap alert type (i.e. danger, success, info, warning) 32 | */ 33 | public $alertTypes = [ 34 | 'error' => 'alert-danger', 35 | 'danger' => 'alert-danger', 36 | 'success' => 'alert-success', 37 | 'info' => 'alert-info', 38 | 'warning' => 'alert-warning' 39 | ]; 40 | /** 41 | * @var array the options for rendering the close button tag. 42 | * Array will be passed to [[\yii\bootstrap\Alert::closeButton]]. 43 | */ 44 | public $closeButton = []; 45 | 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public function run() 51 | { 52 | $session = Yii::$app->session; 53 | $flashes = $session->getAllFlashes(); 54 | $appendClass = isset($this->options['class']) ? ' ' . $this->options['class'] : ''; 55 | 56 | foreach ($flashes as $type => $flash) { 57 | if (!isset($this->alertTypes[$type])) { 58 | continue; 59 | } 60 | 61 | foreach ((array) $flash as $i => $message) { 62 | echo \yii\bootstrap\Alert::widget([ 63 | 'body' => $message, 64 | 'closeButton' => $this->closeButton, 65 | 'options' => array_merge($this->options, [ 66 | 'id' => $this->getId() . '-' . $type . '-' . $i, 67 | 'class' => $this->alertTypes[$type] . $appendClass, 68 | ]), 69 | ]); 70 | } 71 | 72 | $session->removeFlash($type); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/backend/views/site/contact.php: -------------------------------------------------------------------------------- 1 | title = 'Contact'; 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 |
15 |

title) ?>

16 | 17 | session->hasFlash('contactFormSubmitted')): ?> 18 | 19 |
20 | Thank you for contacting us. We will respond to you as soon as possible. 21 |
22 | 23 |

24 | Note that if you turn on the Yii debugger, you should be able 25 | to view the mail message on the mail panel of the debugger. 26 | mailer->useFileTransport): ?> 27 | Because the application is in development mode, the email is not sent but saved as 28 | a file under mailer->fileTransportPath) ?>. 29 | Please configure the useFileTransport property of the mail 30 | application component to be false to enable email sending. 31 | 32 |

33 | 34 | 35 | 36 |

37 | If you have business inquiries or other questions, please fill out the following form to contact us. 38 | Thank you. 39 |

40 | 41 |
42 |
43 | 44 | 'contact-form']); ?> 45 | 46 | field($model, 'name')->textInput(['autofocus' => true]) ?> 47 | 48 | field($model, 'email') ?> 49 | 50 | field($model, 'subject') ?> 51 | 52 | field($model, 'body')->textarea(['rows' => 6]) ?> 53 | 54 | field($model, 'verifyCode')->widget(Captcha::className(), [ 55 | 'template' => '
{image}
{input}
', 56 | ]) ?> 57 | 58 |
59 | 'btn btn-primary', 'name' => 'contact-button']) ?> 60 |
61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 |
69 | -------------------------------------------------------------------------------- /common/models/search/ProductSearch.php: -------------------------------------------------------------------------------- 1 | $query, 52 | 'pagination' => Yii::$app->params['pagination'], 53 | 'sort' => [ 54 | 'defaultOrder' => [ 55 | 'created_at' => SORT_DESC, 56 | ] 57 | ], 58 | ]); 59 | 60 | $this->load($params); 61 | 62 | if (!$this->validate()) { 63 | // uncomment the following line if you do not want to return any records when validation fails 64 | // $query->where('0=1'); 65 | return $dataProvider; 66 | } 67 | 68 | // grid filtering conditions 69 | $query->andFilterWhere([ 70 | 'id' => $this->id, 71 | 'status' => $this->status, 72 | 'is_del' => $this->is_del, 73 | ]); 74 | 75 | $lCreatedAt = Helper::cuttingDateRange($this->created_at); 76 | if ($lCreatedAt !== []){ 77 | $query->andFilterWhere(['between', 'created_at', $lCreatedAt[0], $lCreatedAt[1]]); 78 | } 79 | 80 | $lUpdatedAt = Helper::cuttingDateRange($this->updated_at); 81 | if ($lUpdatedAt !== []){ 82 | $query->andFilterWhere(['between', 'updated_at', $lUpdatedAt[0], $lUpdatedAt[1]]); 83 | } 84 | 85 | $query->andFilterWhere(['like', 'name', $this->name]); 86 | 87 | return $dataProvider; 88 | } 89 | 90 | 91 | } 92 | -------------------------------------------------------------------------------- /app/backend/views/product/index.php: -------------------------------------------------------------------------------- 1 | title = '产品列表'; 12 | $this->params['breadcrumbs'][] = $this->title; 13 | ?> 14 | 15 | 16 |
17 |
18 |
19 |
20 |

title; ?>

21 |
22 |
23 |
24 | 'btn btn-primary']) ?> 25 |
26 | render('_search', ['model' => $searchModel]); ?> 27 | 28 | $dataProvider, 30 | 'filterModel' => $searchModel, 31 | 'columns' => [ 32 | ['class' => 'yii\grid\SerialColumn'], 33 | 'id', 34 | 'name', 35 | [ 36 | 'attribute'=>'status', 37 | 'value' => function($data){ 38 | return Product::enumState('status', $data->status); 39 | }, 40 | 'filter' => Product::enumState('status'), 41 | ], 42 | [ 43 | 'attribute' => 'created_at', 44 | 'format' => ['date', 'php:Y-m-d H:i:s'], 45 | 'filterType' =>GridView::FILTER_DATE_RANGE, 46 | 'filterWidgetOptions'=> Yii::$app->params['filterDateRangeOptions'], 47 | ], 48 | [ 49 | 'attribute' => 'updated_at', 50 | 'format' => ['date', 'php:Y-m-d H:i:s'], 51 | 'filterType' =>GridView::FILTER_DATE_RANGE, 52 | 'filterWidgetOptions'=> Yii::$app->params['filterDateRangeOptions'], 53 | ], 54 | [ 55 | 'header' => "操作", 56 | 'class' => 'yii\grid\ActionColumn', 57 | ], 58 | ], 59 | ]); ?> 60 |
61 |
62 |
63 |
64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /common/models/form/UserRegisterForm.php: -------------------------------------------------------------------------------- 1 | [4, 12], 'message'=>'用户名请输入长度为6-12个字符'], 25 | ['password', 'string', 'length'=>[6, 16], 'message'=>'用户名请输入长度为8-16个字符'], 26 | ['email', 'email'], 27 | ['confirm_password','compare','compareAttribute'=>'password','message'=>'两次输入密码不一致'], 28 | ['verify_code', 'captcha'], 29 | ]; 30 | } 31 | 32 | public function attributeLabels() 33 | { 34 | return [ 35 | 'username' => '用户名', 36 | 'password' => '密码', 37 | 'confirm_password' => '确认密码', 38 | 'email' => 'email', 39 | 'verify_code' => '验证码', 40 | ]; 41 | } 42 | 43 | /** 44 | * 用户注册操作 45 | */ 46 | public function register() 47 | { 48 | if (!$this->validate()) { 49 | return false; 50 | } 51 | $oqUser = User::find() 52 | ->orWhere(['username' => $this->username]) 53 | ->orWhere(['email' => $this->email]) 54 | ->one(); 55 | if ($oqUser !== null){ 56 | $this->addError('username', '用户名或邮箱已注册!!!'); 57 | return false; 58 | } 59 | 60 | $transaction = Yii::$app->db->beginTransaction(); 61 | $omUser = new User(); 62 | $omUser->username = $this->username; 63 | $omUser->generateLoginPassword($this->password); 64 | $omUser->generatePayPassword($this->password); 65 | $omUser->email = $this->email; 66 | $omUser->account = $omUser->generateAccount(); 67 | $omUser->pay_md5_key = $omUser->generatePayMd5Key(); 68 | $omUser->status = User::STATUS_REGISTER_AUDIT; 69 | 70 | $omEmailCode = new EmailCode(); 71 | if(!$omEmailCode->sendCode($this->email)){ 72 | $transaction->rollBack(); 73 | $this->addError('email', '邮箱发送失败!!!'); 74 | return false; 75 | } 76 | 77 | if ($omUser->save() === false){ 78 | $transaction->rollBack(); 79 | $this->addError('username', '注册失败,请联系管理员!!!'); 80 | return false; 81 | } 82 | 83 | $transaction->commit(); 84 | return true; 85 | } 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /app/backend/views/pay-channel/view.php: -------------------------------------------------------------------------------- 1 | title = $model->name; 11 | $this->params['breadcrumbs'][] = ['label' => '支付通道列表', 'url' => ['index']]; 12 | $this->params['breadcrumbs'][] = $this->title; 13 | \yii\web\YiiAsset::register($this); 14 | ?> 15 |
16 |
17 |

title) ?>

18 |
19 |
20 |
21 |

22 | $model->id], ['class' => 'btn btn-primary']) ?> 23 | $model->id, 26 | 'pay_channel_name'=>$model->name, 27 | ], ['class' => 'btn btn-success']) ?> 28 | $model->id], [ 29 | 'class' => 'btn btn-danger', 30 | 'data' => [ 31 | 'confirm' => 'Are you sure you want to delete this item?', 32 | 'method' => 'post', 33 | ], 34 | ]) ?> 35 |

36 | 37 | $model, 39 | 'attributes' => [ 40 | 'id', 41 | [ 42 | 'attribute' => 'product_id', 43 | 'value' => function($model){ 44 | return $model->product->name; 45 | } 46 | ], 47 | 'name', 48 | 'code', 49 | 'profit_rate', 50 | 'cost_rate', 51 | 'weight', 52 | 'request_url:url', 53 | [ 54 | 'attribute'=>'status', 55 | 'value' => function($data){ 56 | return PayChannel::enumState('status', $data->status); 57 | }, 58 | ], 59 | [ 60 | 'attribute' => 'created_at', 61 | 'format' => ['date', 'php:Y-m-d H:i:s'], 62 | ], 63 | [ 64 | 'attribute' => 'updated_at', 65 | 'format' => ['date', 'php:Y-m-d H:i:s'], 66 | ], 67 | ], 68 | ]) ?> 69 |
70 |
71 | 72 |
73 | 74 | -------------------------------------------------------------------------------- /common/models/search/PayChannelAccountSearch.php: -------------------------------------------------------------------------------- 1 | $query, 51 | 'pagination' => Yii::$app->params['pagination'], 52 | 'sort' => [ 53 | 'defaultOrder' => [ 54 | 'created_at' => SORT_DESC, 55 | ] 56 | ], 57 | ]); 58 | 59 | $this->load($params); 60 | 61 | if (!$this->validate()) { 62 | // uncomment the following line if you do not want to return any records when validation fails 63 | // $query->where('0=1'); 64 | return $dataProvider; 65 | } 66 | 67 | // grid filtering conditions 68 | $query->andFilterWhere([ 69 | 'id' => $this->id, 70 | 'pay_channel_id' => $this->pay_channel_id, 71 | 'account' => $this->account, 72 | 'status' => $this->status, 73 | 'is_del' => $this->is_del, 74 | ]); 75 | 76 | $lCreatedAt = Helper::cuttingDateRange($this->created_at); 77 | if ($lCreatedAt !== []){ 78 | $query->andFilterWhere(['between', 'created_at', $lCreatedAt[0], $lCreatedAt[1]]); 79 | } 80 | 81 | $lUpdatedAt = Helper::cuttingDateRange($this->updated_at); 82 | if ($lUpdatedAt !== []){ 83 | $query->andFilterWhere(['between', 'updated_at', $lUpdatedAt[0], $lUpdatedAt[1]]); 84 | } 85 | 86 | 87 | return $dataProvider; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/home/controllers/UserController.php: -------------------------------------------------------------------------------- 1 | [ 22 | 'class' => VerbFilter::className(), 23 | 'actions' => [ 24 | 'delete' => ['POST'], 25 | ], 26 | ], 27 | ]; 28 | } 29 | 30 | /** 31 | * 用户基础信息 32 | */ 33 | public function actionBaseInfo() 34 | { 35 | return $this->render('base-info', [ 36 | 'model' => $this->findModel(), 37 | ]); 38 | } 39 | 40 | /** 41 | * 用户支付信息 42 | */ 43 | public function actionPayInfo() 44 | { 45 | $ofUserVerifyPayPassword = new UserVerifyPayPasswordForm(); 46 | return $ofUserVerifyPayPassword->verify(function($controller){ 47 | return $controller->render('pay-info', [ 48 | 'model' => $this->findModel(), 49 | ]); 50 | },Yii::$app->request->post(), $this); 51 | } 52 | 53 | /** 54 | * 修改登录密码 55 | */ 56 | public function actionSaveLoginPassword() 57 | { 58 | $successHint = false; 59 | $ofUserSavePassword = new UserSavePasswordForm(); 60 | if ($ofUserSavePassword->load(Yii::$app->request->post()) && $ofUserSavePassword->saveLoginPassword($this->user_id)) { 61 | $successHint = '登录密码修改成功!!!'; 62 | } 63 | 64 | return $this->render('save-login-password', [ 65 | 'formValidate' => $ofUserSavePassword, 66 | 'successHint'=>$successHint, 67 | ]); 68 | } 69 | 70 | /** 71 | * 修改支付密码 72 | */ 73 | public function actionSavePayPassword() 74 | { 75 | 76 | $successHint = false; 77 | $ofUserSavePassword = new UserSavePasswordForm(); 78 | if ($ofUserSavePassword->load(Yii::$app->request->post()) && $ofUserSavePassword->savePayPassword($this->user_id)) { 79 | $successHint = '支付密码修改成功!!!'; 80 | } 81 | 82 | return $this->render('save-pay-password', [ 83 | 'formValidate' => $ofUserSavePassword, 84 | 'successHint'=>$successHint, 85 | ]); 86 | } 87 | 88 | protected function findModel() 89 | { 90 | if (($model = User::findOne($this->user_id)) !== null) { 91 | return $model; 92 | } 93 | 94 | throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.')); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /app/backend/views/pay-channel-account/view.php: -------------------------------------------------------------------------------- 1 | title = $model->account; 12 | $this->params['breadcrumbs'][] = ['label' => Yii::t('app', '支付通道列表'), 'url' => Url::to(['/pay-channel/index'])]; 13 | $this->params['breadcrumbs'][] = [ 14 | 'label' => Yii::t('app', '{pay_channel_name} 子账号列表', ['pay_channel_name'=>$model->payChannel->name]), 15 | 'url' => ['index', 'pay_channel_id'=>$model->pay_channel_id], 16 | ]; 17 | $this->params['breadcrumbs'][] = $this->title; 18 | \yii\web\YiiAsset::register($this); 19 | ?> 20 |
21 |
22 |

支付子账号列表:title) ?>

23 |
24 |
25 | 70 |
71 |
72 | -------------------------------------------------------------------------------- /app/backend/views/site/login.php: -------------------------------------------------------------------------------- 1 | title = 'Sign In'; 12 | 13 | $fieldOptions1 = [ 14 | 'options' => ['class' => 'form-group has-feedback'], 15 | 'inputTemplate' => "{input}" 16 | ]; 17 | 18 | $fieldOptions2 = [ 19 | 'options' => ['class' => 'form-group has-feedback'], 20 | 'inputTemplate' => "{input}" 21 | ]; 22 | ?> 23 | 24 | 77 | -------------------------------------------------------------------------------- /common/models/PayChannelAccount.php: -------------------------------------------------------------------------------- 1 | [self::STATUS_OFF, self::STATUS_ON]], 59 | [['account', 'appid', 'md5_key', 'private_key', 'public_key'], 'string', 'max' => 255], 60 | ]; 61 | } 62 | 63 | /** 64 | * {@inheritdoc} 65 | */ 66 | public function attributeLabels() 67 | { 68 | return [ 69 | 'id' => 'ID', 70 | 'pay_channel_id' => '通道类型', 71 | 'account' => '子账号', 72 | 'appid' => 'Appid', 73 | 'md5_key' => 'Md5秘钥', 74 | 'private_key' => '私钥', 75 | 'public_key' => '公钥', 76 | 'weight' => '权重', 77 | 'status' => '状态', 78 | 'created_at' => '创建时间', 79 | 'updated_at' => '更新时间', 80 | 'is_del' => '是否删除', 81 | ]; 82 | } 83 | 84 | public function getPayChannel(){ 85 | return $this->hasOne(PayChannel::className(), ['id' => 'pay_channel_id']); 86 | } 87 | 88 | public static function enumState($type = null, $field = null){ 89 | $lsEnum = [ 90 | 'status'=>[ 91 | self::STATUS_ON=>'开启', 92 | self::STATUS_OFF=>'关闭', 93 | ], 94 | ]; 95 | 96 | if (isset($lsEnum[$type])){ 97 | return $lsEnum[$type][$field] ?? $lsEnum[$type] ; 98 | } 99 | 100 | return $lsEnum; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /common/models/ChangeUserMoneyLog.php: -------------------------------------------------------------------------------- 1 | Yii::t('app', 'ID'), 57 | 'user_id' => Yii::t('app', '用户id'), 58 | 'change_money' => Yii::t('app', '改变金额'), 59 | 'before_money' => Yii::t('app', '改变前金额'), 60 | 'after_money' => Yii::t('app', '改变后金额'), 61 | 'type' => Yii::t('app', '类型'), 62 | 'created_at' => Yii::t('app', '创建时间'), 63 | 'updated_at' => Yii::t('app', '修改时间'), 64 | 'extra' => Yii::t('app', '扩展信息'), 65 | ]; 66 | } 67 | 68 | /** 69 | * @inheritdoc 70 | */ 71 | public function behaviors() 72 | { 73 | return [ 74 | TimestampBehavior::className(), 75 | ]; 76 | } 77 | 78 | public static function enumState($type = null, $field = null){ 79 | $lsEnum = [ 80 | 'type'=>[ 81 | self::TYPE_PAY_ORDER_CORRECTION => '支付订单校正', 82 | self::TYPE_PAY_ORDER_TURN_DOWN => '支付订单驳回', 83 | self::TYPE_PAY_ORDER_SUCCESS => '订单支付成功', 84 | self::TYPE_DRAW_MONEY_WITHHOLD => '申请提款预扣', 85 | self::TYPE_DRAW_MONEY_SUCCESS => '申请提款成功', 86 | self::TYPE_DRAW_MONEY_BACK => '申请提款退还', 87 | ], 88 | ]; 89 | 90 | if (isset($lsEnum[$type])){ 91 | return $lsEnum[$type][$field] ?? $lsEnum[$type] ; 92 | } 93 | 94 | return $lsEnum; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /app/home/controllers/DrawMoneyOrderController.php: -------------------------------------------------------------------------------- 1 | [ 20 | 'class' => VerbFilter::className(), 21 | 'actions' => [ 22 | 'delete' => ['POST'], 23 | ], 24 | ], 25 | ]; 26 | } 27 | 28 | /** 29 | * 提款申请列表 30 | */ 31 | public function actionIndex() 32 | { 33 | 34 | $lsQueryParam = Yii::$app->request->queryParams; 35 | $lsQueryParam['DrawMoneyOrderSearch']['user_id'] = $this->user_id; 36 | 37 | $searchModel = new DrawMoneyOrderSearch(); 38 | $dataProvider = $searchModel->search($lsQueryParam); 39 | 40 | return $this->render('index', [ 41 | 'searchModel' => $searchModel, 42 | 'dataProvider' => $dataProvider, 43 | ]); 44 | } 45 | 46 | /** 47 | * 提款申请详情 48 | */ 49 | public function actionView($id) 50 | { 51 | return $this->render('view', [ 52 | 'model' => $this->findModel($id), 53 | ]); 54 | } 55 | 56 | /** 57 | * 提款申请 58 | */ 59 | public function actionCreate() 60 | { 61 | $omDrawMoneyOrder = new DrawMoneyOrder(); 62 | $lsPost = Yii::$app->request->post(); 63 | if (Yii::$app->request->isPost){ 64 | $lsPost['DrawMoneyOrder']['user_id'] = $this->user_id; 65 | $lsPost['DrawMoneyOrder']['sys_order_id'] = $omDrawMoneyOrder->generateSysOrderId($this->user_id); 66 | } 67 | if ($omDrawMoneyOrder->load($lsPost) && $omDrawMoneyOrder->addApplyAndWithhold()) { 68 | return $this->redirect(['view', 'id' => $omDrawMoneyOrder->id]); 69 | } 70 | 71 | return $this->render('create', [ 72 | 'model' => $omDrawMoneyOrder, 73 | ]); 74 | } 75 | 76 | /** 77 | * 导出excel 78 | */ 79 | public function actionExport() 80 | { 81 | $lsQueryParam = Yii::$app->request->queryParams; 82 | $lsQueryParam['DrawMoneyOrderSearch']['user_id'] = $this->user_id; 83 | 84 | header('Content-Type: application/vnd.ms-excel;'); 85 | $osDrawMoneyOrder = new DrawMoneyOrderSearch(); 86 | $osDrawMoneyOrder->export($lsQueryParam); 87 | } 88 | 89 | 90 | protected function findModel($id) 91 | { 92 | if (($model = DrawMoneyOrder::findOne(['id'=>$id, 'user_id'=>$this->user_id])) !== null) { 93 | return $model; 94 | } 95 | 96 | throw new NotFoundHttpException(Yii::t('app', 'The requested page does not exist.')); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /app/home/views/draw-money-order/index.php: -------------------------------------------------------------------------------- 1 | title = Yii::t('app', '提款订单列表'); 15 | $this->params['breadcrumbs'][] = $this->title; 16 | ?> 17 | 18 | 19 |
20 |

title; ?>

21 |
22 | request->queryParams], ['class' => 'btn btn-primary']) ?> 23 |
24 | $dataProvider, 26 | 'filterModel' => $searchModel, 27 | 'columns' => [ 28 | 'sys_order_id', 29 | 'account_name', 30 | 'account_number', 31 | [ 32 | 'attribute'=>'receipt_number', 33 | 'value' => function($data) { 34 | return $data->receipt_number == ''?null : $data->receipt_number; 35 | }, 36 | ], 37 | 38 | [ 39 | 'attribute'=>'money', 40 | 'value' => function($data) { 41 | return Helper::formatMoney($data->money); 42 | }, 43 | ], 44 | [ 45 | 'attribute'=>'status', 46 | 'value' => function($data){ 47 | return DrawMoneyOrder::enumState('status', $data->status); 48 | }, 49 | 'filter' => DrawMoneyOrder::enumState('status'), 50 | ], 51 | [ 52 | 'attribute' => 'created_at', 53 | 'format' => ['date', 'php:Y-m-d H:i:s'], 54 | 'filterType' =>GridView::FILTER_DATE_RANGE, 55 | 'filterWidgetOptions'=> Yii::$app->params['filterDateRangeOptions'], 56 | ], 57 | [ 58 | 'attribute' => 'updated_at', 59 | 'format' => ['date', 'php:Y-m-d H:i:s'], 60 | 'filterType' =>GridView::FILTER_DATE_RANGE, 61 | 'filterWidgetOptions'=> Yii::$app->params['filterDateRangeOptions'], 62 | ], 63 | [ 64 | 'attribute' => 'success_at', 65 | 'value' => function($data) { 66 | return $data->receipt_number == ''?null : $data->receipt_number; 67 | }, 68 | 'filterType' =>GridView::FILTER_DATE_RANGE, 69 | 'filterWidgetOptions'=> Yii::$app->params['filterDateRangeOptions'], 70 | ], 71 | [ 72 | 'header' => "操作", 73 | 'class' => 'yii\grid\ActionColumn', 74 | 'template' => '{view}', 75 | ], 76 | ], 77 | ]); ?> 78 | 79 |
80 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | require 'fileutils' 3 | 4 | required_plugins = %w( vagrant-hostmanager vagrant-vbguest ) 5 | required_plugins.each do |plugin| 6 | exec "vagrant plugin install #{plugin}" unless Vagrant.has_plugin? plugin 7 | end 8 | 9 | domains = { 10 | app: 'yii2basic.test' 11 | } 12 | 13 | vagrantfile_dir_path = File.dirname(__FILE__) 14 | 15 | config = { 16 | local: vagrantfile_dir_path + '/vagrant/config/vagrant-local.yml', 17 | example: vagrantfile_dir_path + '/vagrant/config/vagrant-local.example.yml' 18 | } 19 | 20 | # copy config from example if local config not exists 21 | FileUtils.cp config[:example], config[:local] unless File.exist?(config[:local]) 22 | # read config 23 | options = YAML.load_file config[:local] 24 | 25 | # check github token 26 | if options['github_token'].nil? || options['github_token'].to_s.length != 40 27 | puts "You must place REAL GitHub token into configuration:\n/yii2-app-basic/vagrant/config/vagrant-local.yml" 28 | exit 29 | end 30 | 31 | # vagrant configurate 32 | Vagrant.configure(2) do |config| 33 | # select the box 34 | config.vm.box = 'bento/ubuntu-16.04' 35 | 36 | # should we ask about box updates? 37 | config.vm.box_check_update = options['box_check_update'] 38 | 39 | config.vm.provider 'virtualbox' do |vb| 40 | # machine cpus count 41 | vb.cpus = options['cpus'] 42 | # machine memory size 43 | vb.memory = options['memory'] 44 | # machine name (for VirtualBox UI) 45 | vb.name = options['machine_name'] 46 | end 47 | 48 | # machine name (for vagrant console) 49 | config.vm.define options['machine_name'] 50 | 51 | # machine name (for guest machine console) 52 | config.vm.hostname = options['machine_name'] 53 | 54 | # network settings 55 | config.vm.network 'private_network', ip: options['ip'] 56 | 57 | # sync: folder 'yii2-app-advanced' (host machine) -> folder '/app' (guest machine) 58 | config.vm.synced_folder './', '/app', owner: 'vagrant', group: 'vagrant' 59 | 60 | # disable folder '/vagrant' (guest machine) 61 | config.vm.synced_folder '.', '/vagrant', disabled: true 62 | 63 | # hosts settings (host machine) 64 | config.vm.provision :hostmanager 65 | config.hostmanager.enabled = true 66 | config.hostmanager.manage_host = true 67 | config.hostmanager.ignore_private_ip = false 68 | config.hostmanager.include_offline = true 69 | config.hostmanager.aliases = domains.values 70 | 71 | # quick fix for failed guest additions installations 72 | # config.vbguest.auto_update = false 73 | 74 | # provisioners 75 | config.vm.provision 'shell', path: './vagrant/provision/once-as-root.sh', args: [options['timezone']] 76 | config.vm.provision 'shell', path: './vagrant/provision/once-as-vagrant.sh', args: [options['github_token']], privileged: false 77 | config.vm.provision 'shell', path: './vagrant/provision/always-as-root.sh', run: 'always' 78 | 79 | # post-install message (vagrant console) 80 | config.vm.post_up_message = "App URL: http://#{domains[:app]}" 81 | end 82 | -------------------------------------------------------------------------------- /common/models/search/PayChannelSearch.php: -------------------------------------------------------------------------------- 1 | $query, 51 | 'pagination' => Yii::$app->params['pagination'], 52 | 'sort' => [ 53 | 'defaultOrder' => [ 54 | 'created_at' => SORT_DESC, 55 | ] 56 | ], 57 | ]); 58 | 59 | $this->load($params); 60 | 61 | if (!$this->validate()) { 62 | // uncomment the following line if you do not want to return any records when validation fails 63 | // $query->where('0=1'); 64 | return $dataProvider; 65 | } 66 | 67 | // grid filtering conditions 68 | $query->andFilterWhere([ 69 | 'id' => $this->id, 70 | 'product_id' => $this->product_id, 71 | 'profit_rate' => $this->profit_rate, 72 | 'cost_rate' => $this->cost_rate, 73 | 'weight' => $this->weight, 74 | 'status' => $this->status, 75 | 'is_del' => $this->is_del, 76 | ]); 77 | 78 | $lCreatedAt = Helper::cuttingDateRange($this->created_at); 79 | if ($lCreatedAt !== []){ 80 | $query->andFilterWhere(['between', 'created_at', $lCreatedAt[0], $lCreatedAt[1]]); 81 | } 82 | 83 | $lUpdatedAt = Helper::cuttingDateRange($this->updated_at); 84 | if ($lUpdatedAt !== []){ 85 | $query->andFilterWhere(['between', 'updated_at', $lUpdatedAt[0], $lUpdatedAt[1]]); 86 | } 87 | 88 | 89 | $query->andFilterWhere(['like', 'name', $this->name]) 90 | ->andFilterWhere(['like', 'code', $this->code]) 91 | ->andFilterWhere(['like', 'request_url', $this->request_url]); 92 | 93 | return $dataProvider; 94 | } 95 | } 96 | --------------------------------------------------------------------------------