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 |
17 | = $this->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 |
17 | = $this->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 |
= Html::encode($this->title) ?>
15 |
16 |
17 | = nl2br(Html::encode($message)) ?>
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 |
= Html::encode($this->title) ?>
17 | = DetailView::widget([
18 | 'model' => $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 |
13 |
14 |
17 | = $this->render('_form', [
18 | 'model' => $model,
19 | ]) ?>
20 |
21 |
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 |
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 |
18 | = $this->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 |
19 | = $this->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 | = Html::csrfMetaTags() ?>
17 | = Html::encode($this->title) ?>
18 | head() ?>
19 |
20 |
21 |
22 | beginBody() ?>
23 |
24 | = $content ?>
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 | = $content ?>
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 |
20 | = $this->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 |
20 | = $this->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 | = $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
17 |
18 | = $form->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 | = $form->field($model, 'username')->textInput(['maxlength' => true,'readonly'=>'true']) ?>
18 |
19 | = $form->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 |
13 | 'horizontal']); ?>
14 | errorSummary($formValidate); ?>
15 |
16 | = $form->field($formValidate, 'password')->passwordInput() ?>
17 |
21 |
22 |
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 |
21 |
22 |
账号激活成功
23 |
24 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/home/views/product/index.php:
--------------------------------------------------------------------------------
1 | title = Yii::t('app', '产品列表');
10 | $this->params['breadcrumbs'][] = $this->title;
11 | ?>
12 |
13 |
14 |
= Html::encode($this->title) ?>
15 |
16 |
17 |
18 |
19 |
20 | | 产品名称 |
21 | 费率(单位:千分之一) |
22 |
23 | foreach ($lsProduct as $k => $v):?>
24 |
25 |
26 | | = $v['name'];?> |
27 | = $v['min_cost_rate'];?>~= $v['max_cost_rate'];?> |
28 |
29 | endforeach; ?>
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/backend/views/product/_search.php:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 | ['index'],
15 | 'method' => 'get',
16 | ]); ?>
17 |
18 | = $form->field($model, 'id') ?>
19 |
20 | = $form->field($model, 'name') ?>
21 |
22 | = $form->field($model, 'status') ?>
23 |
24 | = $form->field($model, 'created_at') ?>
25 |
26 | = $form->field($model, 'updated_at') ?>
27 |
28 | field($model, 'is_del') ?>
29 |
30 |
31 | = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
32 | = Html::resetButton('Reset', ['class' => 'btn btn-outline-secondary']) ?>
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/app/home/views/draw-money-order/create.php:
--------------------------------------------------------------------------------
1 | title = Yii::t('app', '提款申请');
9 | $this->params['breadcrumbs'][] = $this->title;
10 | ?>
11 |
12 |
13 |
= Html::encode($this->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 |
21 |
22 |
25 | = $this->render('_form', [
26 | 'model' => $model,
27 | ]) ?>
28 |
29 |
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 |
12 |
13 | ['index'],
15 | 'method' => 'get',
16 | 'options' => [
17 | 'data-pjax' => 1
18 | ],
19 | ]); ?>
20 |
21 | = $form->field($model, 'id') ?>
22 |
23 | = $form->field($model, 'username') ?>
24 |
25 | = $form->field($model, 'auth_key') ?>
26 |
27 | = $form->field($model, 'password_hash') ?>
28 |
29 | = $form->field($model, 'password_reset_token') ?>
30 |
31 | field($model, 'email') ?>
32 |
33 | field($model, 'money') ?>
34 |
35 | field($model, 'status') ?>
36 |
37 | field($model, 'created_at') ?>
38 |
39 | field($model, 'updated_at') ?>
40 |
41 |
42 | = Html::submitButton(Yii::t('app', 'Search'), ['class' => 'btn btn-primary']) ?>
43 | = Html::resetButton(Yii::t('app', 'Reset'), ['class' => 'btn btn-outline-secondary']) ?>
44 |
45 |
46 |
47 |
48 |
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 |
= Html::encode($this->title) ?>
17 |
18 |
19 | = Html::a(Yii::t('app', 'Update'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
20 | = Html::a(Yii::t('app', 'Delete'), ['delete', 'id' => $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 | = DetailView::widget([
30 | 'model' => $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 |
12 |
13 | ['index'],
15 | 'method' => 'get',
16 | 'options' => [
17 | 'data-pjax' => 1
18 | ],
19 | ]); ?>
20 |
21 | = $form->field($model, 'id') ?>
22 |
23 | = $form->field($model, 'product_id') ?>
24 |
25 | = $form->field($model, 'name') ?>
26 |
27 | = $form->field($model, 'code') ?>
28 |
29 | = $form->field($model, 'rate') ?>
30 |
31 | field($model, 'cost') ?>
32 |
33 | field($model, 'weight') ?>
34 |
35 | field($model, 'request_url') ?>
36 |
37 | field($model, 'status') ?>
38 |
39 | field($model, 'created_at') ?>
40 |
41 | field($model, 'updated_at') ?>
42 |
43 | field($model, 'is_del') ?>
44 |
45 |
46 | = Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
47 | = Html::resetButton('Reset', ['class' => 'btn btn-outline-secondary']) ?>
48 |
49 |
50 |
51 |
52 |
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 |
= $name ?>
19 |
20 |
21 | = nl2br(Html::encode($message)) ?>
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 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/backend/views/pay-channel-account/_form.php:
--------------------------------------------------------------------------------
1 |
13 | 'horizontal']); ?>
14 | errorSummary($model); ?>
15 |
16 |
17 |
18 | = $form->field($model, 'account')->textInput(['maxlength' => true]) ?>
19 |
20 | = $form->field($model, 'appid')->textInput(['maxlength' => true]) ?>
21 |
22 | = $form->field($model, 'md5_key')->textInput(['maxlength' => true]) ?>
23 |
24 | = $form->field($model, 'private_key')->textInput(['maxlength' => true]) ?>
25 |
26 | = $form->field($model, 'public_key')->textInput(['maxlength' => true]) ?>
27 |
28 | = $form->field($model, 'weight')->Input('number') ?>
29 |
30 | = $form->field($model, 'status')->dropDownList(
31 | PayChannelAccount::enumState('status')
32 | ) ?>
33 |
34 |
35 |
36 |
37 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/backend/views/pay-channel-account/_search.php:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 | ['index'],
15 | 'method' => 'get',
16 | 'options' => [
17 | 'data-pjax' => 1
18 | ],
19 | ]); ?>
20 |
21 | = $form->field($model, 'id') ?>
22 |
23 | = $form->field($model, 'channel_id') ?>
24 |
25 | = $form->field($model, 'account') ?>
26 |
27 | = $form->field($model, 'appid') ?>
28 |
29 | = $form->field($model, 'md5_key') ?>
30 |
31 | field($model, 'private_key') ?>
32 |
33 | field($model, 'public_key') ?>
34 |
35 | field($model, 'weight') ?>
36 |
37 | field($model, 'status') ?>
38 |
39 | field($model, 'created_at') ?>
40 |
41 | field($model, 'updated_at') ?>
42 |
43 | field($model, 'is_del') ?>
44 |
45 |
46 | = Html::submitButton(Yii::t('app', 'Search'), ['class' => 'btn btn-primary']) ?>
47 | = Html::resetButton(Yii::t('app', 'Reset'), ['class' => 'btn btn-outline-secondary']) ?>
48 |
49 |
50 |
51 |
52 |
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 |
19 |
20 | = GridView::widget([
21 | 'dataProvider' => $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 |
= Html::encode($this->title) ?>
17 | if( $successHint === false ):?>
18 |
19 |
35 | else: ?>
36 |
37 |
= $successHint; ?>
38 |
39 |
42 |
43 |
44 | endif; ?>
45 |
46 |
--------------------------------------------------------------------------------
/app/backend/views/site/index.php:
--------------------------------------------------------------------------------
1 | title = '服务器信息';
6 | ?>
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
欢迎回来
23 | = $oqAdmin->username; ?>!
24 |
25 |
上次登录IP:= $oqAdmin->pre_login_ip; ?>
26 |
上次登录时间:= date('Y-m-d H:i:s', $oqAdmin->pre_login_at); ?>
27 |
28 |
29 |
30 |
31 |
32 | foreach($lAppInfo as $k=>$v):?>
33 |
34 | | = $k ?> |
35 | = $v?> |
36 |
37 | endforeach;?>
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 |
= Html::encode($this->title) ?>
19 | = DetailView::widget([
20 | 'model' => $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 | = $form->field($model, 'product_id')->dropDownList(
22 | ArrayHelper::merge([''=>'请选择'], $omProduct->getIdToNameList(Product::DEL_STATE_NO))
23 | ) ?>
24 |
25 | = $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
26 |
27 | = $form->field($model, 'code')->textInput(['maxlength' => true]) ?>
28 |
29 | = $form->field($model, 'profit_rate')->Input('number') ?>
30 |
31 | = $form->field($model, 'cost_rate')->Input('number') ?>
32 |
33 | = $form->field($model, 'weight')->Input('number') ?>
34 |
35 | = $form->field($model, 'request_url')->textInput(['maxlength' => true]) ?>
36 |
37 | = $form->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 | = $form->field($model, 'user_id')->textInput(['disabled'=>true]) ?>
23 |
24 | = $form->field($model, 'sys_order_id')->textInput(['disabled'=>true]) ?>
25 |
26 | = $form->field($model, 'account_name')->textInput(['disabled'=>true]) ?>
27 |
28 | = $form->field($model, 'account_number')->textInput(['disabled'=>true]) ?>
29 |
30 | = $form->field($model, 'money')->textInput(['value'=>Helper::formatMoney($model->money),'disabled'=>true]) ?>
31 |
32 | = $form->field($model, 'receipt_number')->textInput(['maxlength' => true]) ?>
33 |
34 | = $form->field($model, 'remark')->textInput(['maxlength' => true]) ?>
35 |
36 | = $form->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 |
= Html::encode($this->title) ?>
18 | = DetailView::widget([
19 | 'model' => $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 |
= Html::encode($this->title) ?>
17 | if( $successHint === false ):?>
18 |
19 |
35 | else: ?>
36 |
37 |
= $successHint; ?>
38 |
39 |
40 | =Html::beginForm(['/site/logout'], 'post');?>
41 | =Html::submitButton('注销,重新登录',
42 | ['class' => 'btn btn-lg btn-primary',
43 | 'style'=> 'font-size: 16px']
44 | );?>
45 | =Html::endForm();?>
46 |
47 |
48 |
49 | endif; ?>
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 | = Html::csrfMetaTags() ?>
37 | = Html::encode($this->title) ?>
38 | head() ?>
39 |
40 |
41 | beginBody() ?>
42 |
43 |
44 | = $this->render(
45 | 'header.php',
46 | ['directoryAsset' => $directoryAsset]
47 | ) ?>
48 |
49 | = $this->render(
50 | 'left.php',
51 | ['directoryAsset' => $directoryAsset]
52 | )
53 | ?>
54 |
55 | = $this->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 |
20 |
21 |
22 |
23 | = Html::a('更改', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
24 | = Html::a('删除', ['delete', 'id' => $model->id], [
25 | 'class' => 'btn btn-danger',
26 | 'data' => [
27 | 'confirm' => '您确定要删除此项目吗?',
28 | 'method' => 'post',
29 | ],
30 | ]) ?>
31 |
32 |
33 | = DetailView::widget([
34 | 'model' => $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 |
21 |
22 | 'horizontal']); ?>
23 | errorSummary($model); ?>
24 |
25 |
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 |
= Html::encode($this->title) ?>
20 | = DetailView::widget([
21 | 'model' => $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 |
= Html::encode($this->title) ?>
18 |
19 | = Html::a('导出订单excel', ['export',Yii::$app->request->queryParams], ['class' => 'btn btn-primary']) ?>
20 |
21 | = GridView::widget([
22 | 'dataProvider' => $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 | if( $registerHint === false ):?>
20 | $this->render('/_form_error_alert',['formValidate'=>$formValidate])?>
21 |
22 |
23 |
24 |
25 |
26 |
= Html::encode($this->title) ?>
27 |
28 |
29 |
30 |
31 | = $form->field($formValidate, 'email') ?>
32 |
33 | = $form->field($formValidate, 'username') ?>
34 |
35 | = $form->field($formValidate, 'password')->passwordInput() ?>
36 |
37 | = $form->field($formValidate, 'confirm_password')->passwordInput() ?>
38 | = $form
39 | ->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' => "
",
48 | ]) ?>
49 | = Html::submitButton( '注册', ['class' => 'btn btn-success btn-block']) ?>
50 |
51 |
52 |
53 |
54 |
55 | = Html::a('已经注册?立即登录!', ['/site/login']) ?>
56 |
57 |
58 |
59 | else: ?>
60 | = Alert::widget([
61 | 'options' => ['class' => 'alert-dismissible alert-success'],
62 | 'body' => $registerHint
63 | ]) ?>
64 |
65 | endif; ?>
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 |
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 |
22 |
23 |
24 | = Html::a('新增产品', ['create'], ['class' => 'btn btn-primary']) ?>
25 |
26 | render('_search', ['model' => $searchModel]); ?>
27 |
28 | = GridView::widget([
29 | 'dataProvider' => $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 |
19 |
20 |
21 |
22 | = Html::a('更新', ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
23 | = Html::a('子账号列表', [
24 | '/pay-channel-account/index',
25 | 'pay_channel_id'=>$model->id,
26 | 'pay_channel_name'=>$model->name,
27 | ], ['class' => 'btn btn-success']) ?>
28 | = Html::a('删除', ['delete', 'id' => $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 | = DetailView::widget([
38 | 'model' => $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 |
24 |
25 |
26 |
27 | = Html::a(Yii::t('app', '更新'), ['update', 'id' => $model->id], ['class' => 'btn btn-primary']) ?>
28 | = Html::a(Yii::t('app', '删除'), ['delete', 'id' => $model->id], [
29 | 'class' => 'btn btn-danger',
30 | 'data' => [
31 | 'confirm' => Yii::t('app', 'Are you sure you want to delete this item?'),
32 | 'method' => 'post',
33 | ],
34 | ]) ?>
35 |
36 |
37 | = DetailView::widget([
38 | 'model' => $model,
39 | 'attributes' => [
40 | [
41 | 'attribute' => 'pay_channel_id',
42 | 'value' => function($model){
43 | return $model->payChannel->name;
44 | }
45 | ],
46 | 'account',
47 | 'appid',
48 | 'md5_key',
49 | 'private_key',
50 | 'public_key',
51 | 'weight',
52 | [
53 | 'attribute'=>'status',
54 | 'value' => function($data){
55 | return PayChannelAccount::enumState('status', $data->status);
56 | },
57 | ],
58 | [
59 | 'attribute' => 'created_at',
60 | 'format' => ['date', 'php:Y-m-d H:i:s'],
61 | ],
62 | [
63 | 'attribute' => 'updated_at',
64 | 'format' => ['date', 'php:Y-m-d H:i:s'],
65 | ],
66 | ],
67 | ]) ?>
68 |
69 |
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 |
25 |
28 |
29 |
30 |
Sign in to start your session
31 |
32 | 'login-form', 'enableClientValidation' => false]); ?>
33 |
34 | = $form
35 | ->field($formValidate, 'username', $fieldOptions1)
36 | ->label(false)
37 | ->textInput(['placeholder' => $formValidate->getAttributeLabel('username')]) ?>
38 |
39 | = $form
40 | ->field($formValidate, 'password', $fieldOptions2)
41 | ->label(false)
42 | ->passwordInput(['placeholder' => $formValidate->getAttributeLabel('password')]) ?>
43 |
44 | = $form
45 | ->field($formValidate, 'verify_code')
46 | ->label(false)
47 | ->widget(Captcha::className(), [
48 | 'captchaAction'=>Url::to('site/captcha'),
49 | 'imageOptions'=>[
50 | 'title'=>'换一个',
51 | 'alt'=>'换一个',
52 | ],
53 | 'options' => ['placeholder' => $formValidate->getAttributeLabel('verify_code')],
54 | 'template' => '
',
55 | ]) ?>
56 |
57 |
58 | = $form->field($formValidate, 'remember_me')->checkbox() ?>
59 |
60 |
61 |
62 | = Html::submitButton('Sign in', ['class' => 'btn btn-primary btn-block btn-flat', 'name' => 'login-button']) ?>
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
For learning only, no business activities
73 |
74 |
75 |
76 |
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 |
= $this->title; ?>
21 |
22 | = Html::a('导出订单excel', ['export',Yii::$app->request->queryParams], ['class' => 'btn btn-primary']) ?>
23 |
24 | = GridView::widget([
25 | 'dataProvider' => $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 |
--------------------------------------------------------------------------------