Commit b160b83a authored by 汪波's avatar 汪波

Merge remote-tracking branch 'origin/dev' into dev

parents 2b8166af 9a739163
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace common\libs; namespace common\libs;
use GuzzleHttp\Exception\ClientException;
use Yii; use Yii;
use \GuzzleHttp\Client; use \GuzzleHttp\Client;
...@@ -57,8 +58,8 @@ class Message ...@@ -57,8 +58,8 @@ class Message
} catch (ClientException $e) { } catch (ClientException $e) {
$response = $e->getResponse(); $response = $e->getResponse();
} catch (\Exception $e) { } catch (\Exception $e) {
throw $e;
Yii::getLogger()->log($e, Logger::LEVEL_ERROR, 'Message'); Yii::getLogger()->log($e, Logger::LEVEL_ERROR, 'Message');
throw $e;
} }
$return = new \SimpleXMLElement($response->getBody()->getContents()); $return = new \SimpleXMLElement($response->getBody()->getContents());
if ((string)$return->returnstatus !== 'Success') { if ((string)$return->returnstatus !== 'Success') {
......
...@@ -30,6 +30,7 @@ class Utils ...@@ -30,6 +30,7 @@ class Utils
* @param bool $status * @param bool $status
* @param null $messgae * @param null $messgae
* @param null $data * @param null $data
* @throws
*/ */
public static function ajaxResponse($status = TRUE, $messgae = NULL, $data = NULL) public static function ajaxResponse($status = TRUE, $messgae = NULL, $data = NULL)
{ {
...@@ -40,6 +41,9 @@ class Utils ...@@ -40,6 +41,9 @@ class Utils
'data' => $data, 'data' => $data,
'message' => $messgae 'message' => $messgae
]; ];
$response->send();
throw new ExitException();
} }
/** /**
...@@ -85,11 +89,15 @@ class Utils ...@@ -85,11 +89,15 @@ class Utils
*/ */
public static function showWarn($message) public static function showWarn($message)
{ {
\Yii::$app->controller->layout = 'blank'; $response = \Yii::$app->response;
\Yii::$app->response->data = \Yii::$app->controller->render('@app/views/site/warn', [ $controller = \Yii::$app->controller;
$controller->layout = 'blank';
$response->data = $controller->render('@app/views/site/warn', [
'message' => $message 'message' => $message
]); ]);
\Yii::$app->response->send(); $response->send();
throw new ExitException(); throw new ExitException();
} }
......
...@@ -6,6 +6,7 @@ use Yii; ...@@ -6,6 +6,7 @@ use Yii;
use yii\behaviors\TimestampBehavior; use yii\behaviors\TimestampBehavior;
use yii\data\Pagination; use yii\data\Pagination;
use yii\helpers\HtmlPurifier; use yii\helpers\HtmlPurifier;
use yii\helpers\Url;
use yii\redis\ActiveRecord; use yii\redis\ActiveRecord;
/** /**
...@@ -231,4 +232,9 @@ class Course extends \yii\db\ActiveRecord ...@@ -231,4 +232,9 @@ class Course extends \yii\db\ActiveRecord
return self::find()->where($where)->sum('comment_count'); return self::find()->where($where)->sum('comment_count');
} }
public static function url($courseId, $schema=false)
{
return Url::to(['home/video', 'courseId'=>$courseId], $schema);
}
} }
<?php
namespace common\models;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
/**
* This is the model class for table "settle_account_weixin".
*
* @property integer $user_id
* @property string $open_id
* @property string $nickname
* @property string $headimgurl
* @property string $access_token
* @property string $refresh_token
* @property integer $expires
* @property integer $created_at
* @property integer $updated_at
*/
class SettleAccountWeixin extends ActiveRecord
{
const HEAD_SIZE_ORG = 0;
const HEAD_SIZE_S = 46;
const HEAD_SIZE_M = 64;
const HEAD_SIZE_L = 96;
const HEAD_SIZE_XL = 132;
/**
* @inheritdoc
*/
public static function tableName()
{
return 'settle_account_weixin';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['user_id', 'open_id', 'nickname', 'headimgurl', 'access_token', 'refresh_token', 'expires'], 'required'],
[['user_id', 'expires', 'created_at', 'updated_at'], 'integer'],
[['open_id'], 'string', 'max' => 28],
[['headimgurl', 'access_token', 'refresh_token'], 'string', 'max' => 255],
[['open_id'], 'unique'],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'user_id' => 'User ID',
'open_id' => 'Open ID',
'headimgurl' => 'Headimgurl',
'access_token' => 'Access Token',
'refresh_token' => 'Refresh Token',
'expires' => 'Expires',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
/**
* @inheritdoc
*/
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
]
]
];
}
/**
* 获取不同尺寸的微信头像
*
* @param string $headImgUrl
* @param int $size
* @return string
*/
public static function headResize($headImgUrl, $size=self::HEAD_SIZE_ORG)
{
return $size == self::HEAD_SIZE_ORG ? $headImgUrl : substr_replace($headImgUrl, $size, -1);
}
}
<?php
namespace common\models;
use Yii;
/**
* This is the model class for table "settle_orders".
*
* @property integer $id
* @property integer $user_id
* @property string $type
* @property string $out_trade_no
* @property string $trade_no
* @property string $amount
* @property integer $income_id_min
* @property integer $income_id_max
* @property integer $status
* @property integer $created_at
* @property integer $updated_at
*/
class SettleOrders extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'settle_orders';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['user_id', 'type', 'out_trade_no', 'trade_no', 'amount', 'income_id_min', 'income_id_max', 'created_at', 'updated_at'], 'required'],
[['user_id', 'income_id_min', 'income_id_max', 'status', 'created_at', 'updated_at'], 'integer'],
[['type'], 'string'],
[['amount'], 'number'],
[['out_trade_no', 'trade_no'], 'string', 'max' => 50],
[['out_trade_no'], 'unique'],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'user_id' => 'User ID',
'type' => 'Type',
'out_trade_no' => 'Out Trade No',
'trade_no' => 'Trade No',
'amount' => 'Amount',
'income_id_min' => 'Income Id Min',
'income_id_max' => 'Income Id Max',
'status' => 'Status',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
}
...@@ -45,8 +45,10 @@ class Teacher extends ActiveRecord ...@@ -45,8 +45,10 @@ class Teacher extends ActiveRecord
[['name', 'class_id'], 'required'], [['name', 'class_id'], 'required'],
[['user_id', 'created_at', 'updated_at'], 'integer'], [['user_id', 'created_at', 'updated_at'], 'integer'],
[['intro'], 'string'], [['intro'], 'string'],
[['intro'], 'default', 'value'=>''],
[['name'], 'string', 'min'=>2, 'max' => 64], [['name'], 'string', 'min'=>2, 'max' => 64],
[['avatar'], 'string', 'max' => 100], [['avatar'], 'string', 'max' => 100],
[['avatar'], 'default', 'value' => ''],
]; ];
} }
......
...@@ -29,8 +29,6 @@ class m160927_122057_income_init extends Migration ...@@ -29,8 +29,6 @@ class m160927_122057_income_init extends Migration
public function down() public function down()
{ {
echo "m160927_113951_winxin_init cannot be reverted.\n";
$this->dropTable($this->table); $this->dropTable($this->table);
} }
......
...@@ -19,7 +19,7 @@ class m160927_122231_orders_init extends Migration ...@@ -19,7 +19,7 @@ class m160927_122231_orders_init extends Migration
'user_id' => $this->integer()->notNull()->unsigned(), 'user_id' => $this->integer()->notNull()->unsigned(),
'course_id' => $this->integer()->notNull()->unsigned(), 'course_id' => $this->integer()->notNull()->unsigned(),
'number' => $this->string(32)->notNull(), 'number' => $this->string(32)->notNull(),
'credit' => $this->decimal(6,2)-unsigned()->notNull()->comment('消费'), 'credit' => $this->decimal(6,2)->unsigned()->notNull()->comment('消费'),
'status' => $this->smallInteger()->notNull()->defaultValue(0)->unsigned()->comment('0 未支付 1 已支付'), 'status' => $this->smallInteger()->notNull()->defaultValue(0)->unsigned()->comment('0 未支付 1 已支付'),
'pay_order' => $this->string(64)->notNull()->comment('第三方支付订单'), 'pay_order' => $this->string(64)->notNull()->comment('第三方支付订单'),
'created_at' => $this->integer()->notNull(), 'created_at' => $this->integer()->notNull(),
......
<?php
use yii\db\Migration;
class m161020_033512_settle_account_weixin_init extends Migration
{
public $table = '{{%settle_account_weixin}}';
public function up()
{
$this->createTable($this->table, [
'`user_id` int(10) UNSIGNED NOT NULL PRIMARY KEY',
'open_id' => $this->char(28),
'`nickname` varchar(30) CHARACTER SET utf8mb4 NOT NULL',
'headimgurl' => $this->string(255),
'access_token' => $this->string(255),
'refresh_token' => $this->string(255),
'expires' => $this->integer(10)->unsigned(),
'created_at' => $this->integer(10)->unsigned()->notNull(),
'updated_at' => $this->integer(10)->unsigned()->notNull(),
]);
$this->addCommentOnTable($this->table, '结算微信帐户');
$this->createIndex('open_id', $this->table, 'open_id', true);
}
public function down()
{
$this->dropTable($this->table);
}
/*
// Use safeUp/safeDown to run migration code within a transaction
public function safeUp()
{
}
public function safeDown()
{
}
*/
}
<?php
use yii\db\Migration;
class m161020_033521_settle_orders_init extends Migration
{
public $table = '{{%settle_orders}}';
public function up()
{
$this->createTable($this->table, [
'id' => $this->primaryKey(10)->unsigned(),
'user_id' => $this->integer(10)->unsigned()->notNull(),
'`type` enum(\'weixin\',\'alipay\') NOT NULL COMMENT \'结算类型\'',
'out_trade_no' => $this->string(50)->comment('本地订单编号'),
'trade_no' => $this->string(50)->comment('支付平台订单编号'),
'amount' => $this->decimal(8, 2)->unsigned()->comment('结算金额'),
'income_id_min' => $this->integer(10)->unsigned()->comment('结算的收记录范围最小id'),
'income_id_max' => $this->integer(10)->unsigned()->comment('结算的收记录范围最大id'),
'`status` TINYINT(1) NOT NULL DEFAULT \'0\' COMMENT \'订单状态:0 未支付,1 已支付, 2 支付失败\'',
'created_at' => $this->integer(10)->unsigned()->notNull(),
'updated_at' => $this->integer(10)->unsigned()->notNull(),
]);
$this->addCommentOnTable($this->table, '结算记录表');
$this->createIndex('out_trade_no', $this->table, 'out_trade_no', true);
$this->createIndex('user_id', $this->table, 'user_id');
$this->createIndex('status', $this->table, 'status');
}
public function down()
{
$this->dropTable($this->table);
}
/*
// Use safeUp/safeDown to run migration code within a transaction
public function safeUp()
{
}
public function safeDown()
{
}
*/
}
...@@ -3,4 +3,5 @@ return [ ...@@ -3,4 +3,5 @@ return [
'adminEmail' => 'admin@example.com', 'adminEmail' => 'admin@example.com',
'signup.msg' => '您正在注册云涯,验证码: xxxxxx,2小时内有效', 'signup.msg' => '您正在注册云涯,验证码: xxxxxx,2小时内有效',
'resetpassword.msg' => '您正在找回密码,验证码: xxxxxx,2小时内有效', 'resetpassword.msg' => '您正在找回密码,验证码: xxxxxx,2小时内有效',
'settle.weixin.unbind.msg' => '您正在删除已绑定的结算微信,验证码: {code},2小时内有效'
]; ];
...@@ -90,7 +90,7 @@ class ClassesInfoController extends \yii\web\Controller ...@@ -90,7 +90,7 @@ class ClassesInfoController extends \yii\web\Controller
if (!$agreement) { if (!$agreement) {
$model->addError('agreement', '必须同意使用协议'); $model->addError('agreement', '必须同意使用协议');
} elseif ($model->validate() && $model->save()) { } elseif ($model->validate() && $model->save()) {
return $this->redirect('/classes-info'); return $this->render('@app/views/site/success', ['message'=>'您已成功提交课堂申请,我们将尽快为您审核通过。']);
} }
} }
......
...@@ -12,6 +12,7 @@ use frontend\components\ClassesFilter; ...@@ -12,6 +12,7 @@ use frontend\components\ClassesFilter;
use Qiniu\Storage\BucketManager; use Qiniu\Storage\BucketManager;
use Yii; use Yii;
use yii\filters\AccessControl; use yii\filters\AccessControl;
use yii\web\NotFoundHttpException;
use yii\web\Response; use yii\web\Response;
use yii\web\UploadedFile; use yii\web\UploadedFile;
...@@ -51,17 +52,16 @@ class MyCourseController extends \yii\web\Controller ...@@ -51,17 +52,16 @@ class MyCourseController extends \yii\web\Controller
*/ */
public function actionIndex() public function actionIndex()
{ {
$list = Course::getCourseListsByClassId($this->classStatus['id'], null, 6, null); $list = Course::getCourseListsByClassId($this->classStatus['id'], null, 12, null);
return $this->render('index', ['list'=>$list['data'], 'pagination'=>$list['pagination']]); return $this->render('index', ['list'=>$list['data'], 'pagination'=>$list['pagination']]);
} }
/** /**
* 发布课程 * 发布课程
* *
* @param int $id
* @return string * @return string
*/ */
public function actionPublish($id=0) public function actionPublish()
{ {
/* @var \common\components\Qiniu $qiniu */ /* @var \common\components\Qiniu $qiniu */
$qiniu = Yii::$app->qiniu; $qiniu = Yii::$app->qiniu;
...@@ -79,6 +79,29 @@ class MyCourseController extends \yii\web\Controller ...@@ -79,6 +79,29 @@ class MyCourseController extends \yii\web\Controller
return $this->render('publish', compact('thumbToken', 'videoToken')); return $this->render('publish', compact('thumbToken', 'videoToken'));
} }
/**
* 编辑课程信息
*
* @param int $id
* @return string
* @throws NotFoundHttpException
*/
public function actionEdit($id=0)
{
$course = Course::findOne(['id'=>$id, 'user_id'=>Yii::$app->user->getId()]);
if (!$course) {
throw new NotFoundHttpException('视频不存在!');
}
$lesson = Courseware::findOne(['course_id'=>$course->id]);
$teacherIds = CourseTeacher::findAll(['course_id'=>$course->id]);
$thumbToken = '';
return $this->render('edit', compact('course', 'lesson', 'teacherIds', 'thumbToken'));
}
/** /**
* 提交并保存课程 * 提交并保存课程
*/ */
...@@ -89,6 +112,8 @@ class MyCourseController extends \yii\web\Controller ...@@ -89,6 +112,8 @@ class MyCourseController extends \yii\web\Controller
$userId = Yii::$app->user->identity->getId(); $userId = Yii::$app->user->identity->getId();
$classId = $this->classStatus['id']; $classId = $this->classStatus['id'];
//验证临时ID //验证临时ID
$tmpId = $request->post('tmp'); $tmpId = $request->post('tmp');
...@@ -100,7 +125,7 @@ class MyCourseController extends \yii\web\Controller ...@@ -100,7 +125,7 @@ class MyCourseController extends \yii\web\Controller
//课程数据 //课程数据
$courseData = [ $courseData = [
'user_id' => $userId, 'user_id' => $userId,
'classed_id' => $classId 'class_id' => $classId
]; ];
foreach (['name', 'teacher', 'price', 'free_time', 'intro', 'preview'=>'preview_pic', 'recommend'] as $postKey => $key) { foreach (['name', 'teacher', 'price', 'free_time', 'intro', 'preview'=>'preview_pic', 'recommend'] as $postKey => $key) {
......
...@@ -2,8 +2,12 @@ ...@@ -2,8 +2,12 @@
namespace frontend\controllers; namespace frontend\controllers;
use common\libs\ApiWeixin;
use common\libs\Message;
use common\libs\OAuthException;
use common\libs\Utils; use common\libs\Utils;
use common\models\Income; use common\models\Income;
use common\models\SettleAccountWeixin;
use dosamigos\qrcode\lib\Enum; use dosamigos\qrcode\lib\Enum;
use frontend\components\ClassesFilter; use frontend\components\ClassesFilter;
use Yii; use Yii;
...@@ -31,7 +35,7 @@ class MyIncomeController extends \yii\web\Controller ...@@ -31,7 +35,7 @@ class MyIncomeController extends \yii\web\Controller
'roles' => ['@'] 'roles' => ['@']
] ]
], ],
'except' => ['weixin-bind', 'weixin-callback'] 'except' => ['wxbind-request', 'wxbind-callback']
], ],
'classes' => [ 'classes' => [
'class' => ClassesFilter::className() 'class' => ClassesFilter::className()
...@@ -50,10 +54,15 @@ class MyIncomeController extends \yii\web\Controller ...@@ -50,10 +54,15 @@ class MyIncomeController extends \yii\web\Controller
$settled = Income::getMoneyTotal($uid, Income::STATUS_IS_SETTLED); $settled = Income::getMoneyTotal($uid, Income::STATUS_IS_SETTLED);
$notSettled = Income::getMoneyTotal($uid, Income::STATUS_NOT_SETTLED); $notSettled = Income::getMoneyTotal($uid, Income::STATUS_NOT_SETTLED);
$account = SettleAccountWeixin::findOne(['user_id'=>$uid]);
return $this->render('index', $ret + compact('settled', 'notSettled')); return $this->render('index', $ret + compact('settled', 'notSettled', 'account'));
} }
/**
* 输出绑定微信的二维码图片
*/
public function actionWxbindQrcode() public function actionWxbindQrcode()
{ {
//生成随机的 key 防止被猜测到 //生成随机的 key 防止被猜测到
...@@ -64,7 +73,7 @@ class MyIncomeController extends \yii\web\Controller ...@@ -64,7 +73,7 @@ class MyIncomeController extends \yii\web\Controller
'uid' => Yii::$app->user->getId() 'uid' => Yii::$app->user->getId()
])); ]));
$url = Url::to(['my-income/weixin-bind', 'key'=>$key], true); $url = Url::to(['my-income/weixin-bind-request', 'key'=>$key], true);
//输出二维码图像 //输出二维码图像
$response = Yii::$app->response; $response = Yii::$app->response;
...@@ -74,7 +83,26 @@ class MyIncomeController extends \yii\web\Controller ...@@ -74,7 +83,26 @@ class MyIncomeController extends \yii\web\Controller
7, 2, false, Enum::QR_FORMAT_JPG); 7, 2, false, Enum::QR_FORMAT_JPG);
} }
public function actionWeixinBind() /**
* 返回当前绑定微信的状态,用于检查微博是否绑定
*/
public function actionCheckBindStatus()
{
$account = SettleAccountWeixin::findOne(['user_id'=>Yii::$app->user->getId()]);
if ($account) {
Utils::ajaxResponse(true);
} else {
Utils::ajaxResponse(false);
}
}
/**
* 发起微信授权请求跳转
*
* @return Response
*/
public function actionWxbindRequest()
{ {
$key = Yii::$app->request->get('key', ''); $key = Yii::$app->request->get('key', '');
...@@ -82,23 +110,176 @@ class MyIncomeController extends \yii\web\Controller ...@@ -82,23 +110,176 @@ class MyIncomeController extends \yii\web\Controller
Utils::showWarn('参数缺失!'); Utils::showWarn('参数缺失!');
} }
$data = Yii::$app->redis->get('yy_wxbind_'.$key); $data = $this->getBindKeyData($key);
if (!$data) { if (!$data) {
Utils::showWarn('该地址已失效,请刷新页面后重新扫描!'); Utils::showWarn('该地址已失效,请刷新页面后重新扫描!');
} }
$data = unserialize($data); $callbackUrl = Url::to(['my-income/wxbind-callback'], true);
$callbackUrl = Url::to(['my-income/weixin-callback'], true); $wx = new ApiWeixin();
$url = $wx->getAuthorizeURLWrapped($callbackUrl, $key);
$wx = new \common\libs\ApiWeixin(); return $this->redirect($url);
echo $wx->getAuthorizeURLWrapped($callbackUrl, $key);
} }
public function actionWeixinCallback() /**
* 微信授权回调
*/
public function actionWxbindCallback()
{
$code = Yii::$app->request->get('code');
$state = Yii::$app->request->get('state');
//$redirect = Yii::$app->request->get('redirect');
$data = $this->getBindKeyData($state);
if (!$data) {
Utils::showWarn('该地址已失效,请刷新页面后重新扫描!');
}
//拒绝授权后,code 参数为空
if (!$code) {
Utils::showWarn('您已经取消了授权,绑定失败!');
}
$wx = new ApiWeixin();
try {
$token = $wx->getAccessToken('code', array('code' => $code));
} catch (OAuthException $e) {
Yii::warning('my-income/wxbind-callback/getAccessTokenError: '.$e->getMessage());
Utils::showWarn('登录失败,请重试!');
}
if (!is_array($token)) {
Utils::showWarn('绑定失败,未获取到任何授权信息!');
}
if (isset($token['errcode'])) {
Utils::showWarn("绑定失败:{$token['errmsg']}!");
}
$userInfo = $wx->userInfo($token['openid']);
if (!$userInfo || isset($userInfo['errcode'])) {
Yii::warning('my-income/wxbind-callback/getUserInfoError: '.(is_array($userInfo) ? $userInfo['errmsg'] : ''));
Utils::showWarn("获取用户信息失败,请稍候重试!");
}
$account = SettleAccountWeixin::findOne(['open_id'=>$token['openid']]);
if ($account && $account['user_id'] != $data['uid']) {
Utils::showWarn('您的帐号已经绑定了其它的结算微信,如需更换请先取消帐号与微信的绑定再试!');
}
$model = new SettleAccountWeixin();
$model->user_id = $data['uid'];
$model->open_id = $token['openid'];
$model->nickname = $userInfo['nickname']; //头像尺寸 0、46、64、96、132
$model->headimgurl = $userInfo['headimgurl'];
$model->access_token = $token['access_token'];
$model->refresh_token = $token['refresh_token'];
$model->expires = $token['expires_in'] + time();
if ($model->save()) {
return $this->render('@app/views/site/success', [
'message' => '成功绑定结算微信!'
]);
} else {
Utils::showWarn('绑定失败:'.Utils::fetchErrorFirst($model->errors));
}
}
/**
* 发送取消绑定验证码
*
* @throws \Exception
* @throws \yii\base\ExitException
*/
public function actionSendUnbindCode()
{ {
if (!Yii::$app->request->getIsPost()) {
Utils::ajaxResponse(false, '请求错误');
}
$session = Yii::$app->session;
$k = 'wxunbind_verify_code';
$data = $session->get($k);
if ($data && time() - $data['sendtime'] < 60) {
Utils::ajaxResponse(false, '您发送的太频繁,请稍候再试。');
}
$data = [
'code' => Utils::randomNumber(6),
'sendtime' => time()
];
$session->set($k, $data);
$number = Yii::$app->user->identity->telephone;
$template = Yii::$app->params['settle.weixin.unbind.msg'];
$sms = new Message();
$sms->send($number, str_replace('{code}', $data['code'], $template));
Utils::ajaxResponse(true, 'send success');
}
/**
* 解除绑定
*/
public function actionWeixinUnbind()
{
$session = Yii::$app->session;
$uid = Yii::$app->user->getId();
$vcode = Yii::$app->request->post('vcode');
$k = 'wxunbind_verify_code';
$data = $session->get($k);
//验证有效时间
if (!$data || time() - $data['sendtime'] > 3600 * 2) {
$session->remove($k);
Utils::ajaxResponse(false, '验证码已经失效,请重新发送!');
}
//验证是否错误次数过多
$redis = Yii::$app->redis;
$rk = 'yy_wxunbind_failed_'.$uid;
$failedTimes = (int)$redis->get($rk);
if ($failedTimes >= 5) {
Utils::ajaxResponse(false, '您的错误次数过多,请稍候再试!');
}
if ($vcode != $data['code']) {
$redis->setex($rk, 600, ++$failedTimes);
Utils::ajaxResponse(false, '验证码错误!');
}
//删除绑定的微信
$account = SettleAccountWeixin::findOne(['user_id'=>$uid]);
$account && $account->delete();
$session->remove($k);
Utils::ajaxResponse(true);
} }
/**
* 获取绑定key中的数据
*
* @param string $key
* @return array|null
*/
private function getBindKeyData($key)
{
$data = Yii::$app->redis->get('yy_wxbind_'.$key);
return $data ? unserialize($data) : null;
}
} }
<?php
/**
* @var $this yii\web\View
* @var $course \common\models\Course
* @var $lesson \common\models\Courseware
* @var $teacherIds [\common\models\CourseTeacher]
*/
use frontend\assets\AppAsset;
$this->title = '编辑课程信息';
//AppAsset::addScript($this, '@web/assets/single-lib/plupload/plupload.full.min.js');
AppAsset::addScript($this, '@web/assets/course_publish.js');
AppAsset::addCss($this, '@web/assets/css/course_publish.css');
?>
<div class="send-class" id="publishMain" xmlns:v-el="http://www.w3.org/1999/xhtml">
<div class="tit">编辑课程信息</div>
<form method="post" name="coursePublish">
<div class="cls-part">
<div class="tit">标题</div>
<input type="text" name="name" class="input-r-control" placeholder="请输入课程标题,20 个汉字以内..." value="<?=$course->name?>">
</div>
<div class="cls-part teacher-list">
<div class="tit">讲师</div>
<div class="checkbox" v-cloak>
<label v-for="(index, item) in teachers" :class="{'m-l-10':index!=0}">
<input name="teacher[]" type="checkbox" value="{{item.id}}" v-model="checkedTeachers">{{item.name}}
</label>
<div class="d-i-b" v-if="atState">
<input type="text" class="input-r-control reset-input" placeholder="请输入讲师名称" v-model="addTeacherName" v-el:tni>
<button type="button" class="btn btn-nobg" @click="addTeacher">保存</button>
</div>
<span class="m-l-10" v-if="!atState"><a href="javascript:;" @click="addTeacher">+ 添加讲师</a></span>
</div>
</div>
<div class="cls-part">
<div class="tit">上传视频</div>
</div>
<div class="cls-part">
<div class="tit">规则设定</div>
<div class="clearfix">
<div class="checkbox rules-set fl">
<label class="clearfix">
<!--<input name="vip_price" type="checkbox" class="fl" value="1">--><span>会员价</span> <input type="text" name="price" class="input-r-control text-center" value="0"> <span>元</span>
</label>
</div>
<div class="checkbox rules-set m-l-20 fl">
<label class="clearfix">
<!--<input name="free_time" type="checkbox" class="fl">--><span>免费试看</span> <input type="text" name="free_time" class="input-r-control text-center" value="0"> <span>分钟</span>
</label>
</div>
</div>
</div>
<div class="cls-part">
<div class="tit">课程介绍</div>
<div class="cls-intro-textarea">
<textarea name="intro" class="input-r-control" placeholder="请输入课程介绍..." id="introEditor"><?=\yii\helpers\Html::encode($course->intro)?></textarea>
</div>
</div>
<div class="cls-part">
<div class="tit">缩略图 <small>建议尺寸:900像素 * 500像素</small></div>
<thumb-upload uptoken="<?=$thumbToken?>"></thumb-upload>
</div>
<div class="cls-part p-b-20">
<div class="tit">课程属性</div>
<div class="checkbox">
<label>
<input type="checkbox" name="recommend" value="1">推荐课程
</label>
</div>
</div>
<input type="hidden" name="tmp" value="{{tmp}}" />
<input type="hidden" name="vuid" value="{{vuid}}" />
<input type="hidden" name="preview" value="{{previewKey}}" />
<div class="btn-box text-center" style="border-top: 1px solid #e7e7e7; margin-top: 10px; ">
<button type="button" class="btn btn-nobg">取消</button>
<button type="submit" class="btn btn-save m-l-10">保存</button>
</div>
</form>
</div>
\ No newline at end of file
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* @var $list array * @var $list array
* @var $pagination yii\data\Pagination * @var $pagination yii\data\Pagination
*/ */
use common\models\Course;
use yii\helpers\Url; use yii\helpers\Url;
use yii\widgets\LinkPager; use yii\widgets\LinkPager;
...@@ -21,7 +22,7 @@ $qiniu = \Yii::$app->qiniu; ...@@ -21,7 +22,7 @@ $qiniu = \Yii::$app->qiniu;
<div class="video-img-box"> <div class="video-img-box">
<a href="<?=Url::to(['video/index', 'id'=>$course['id']])?>" target="_blank"><img src="<?=$qiniu->getUrl('public', $course['preview_pic'])?>-m.preview"></a> <a href="<?=Url::to(['video/index', 'id'=>$course['id']])?>" target="_blank"><img src="<?=$qiniu->getUrl('public', $course['preview_pic'])?>-m.preview"></a>
<div class="video-list-cnt"> <div class="video-list-cnt">
<div class="tit"><a href="<?=Url::to(['video/index', 'id'=>$course['id']])?>" target="_blank"><?=$course['name']?></a></div> <div class="tit"><a href="<?=Course::url($course['id'])?>" target="_blank"><?=$course['name']?></a></div>
<?php if ($course['teachers']) { ?> <?php if ($course['teachers']) { ?>
<div class="teacher">讲师:<?=join(', ', array_column($course['teachers'], 'name'))?></div> <div class="teacher">讲师:<?=join(', ', array_column($course['teachers'], 'name'))?></div>
<?php } ?> <?php } ?>
...@@ -30,7 +31,7 @@ $qiniu = \Yii::$app->qiniu; ...@@ -30,7 +31,7 @@ $qiniu = \Yii::$app->qiniu;
<div class="outline"> <div class="outline">
<span><?=$course['play_count']?> 次播放</span> · <span><?=$course['comment_count']?> 次评论</span> · <span><?=$course['favorite_count']?> 收藏</span> <span><?=$course['play_count']?> 次播放</span> · <span><?=$course['comment_count']?> 次评论</span> · <span><?=$course['favorite_count']?> 收藏</span>
</div> </div>
<!--<div class="edit"><a href="<?=Url::to(['my-course/publish', 'id'=>$course['id']])?>"><i class="icon-mode_edit"></i></a></div>--> <div class="edit"><a href="<?=Url::to(['my-course/edit', 'id'=>$course['id']])?>" title="编辑课程信息"><i class="icon-mode_edit"></i></a></div>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -3,9 +3,12 @@ ...@@ -3,9 +3,12 @@
* @var $this yii\web\View * @var $this yii\web\View
* @var $data array * @var $data array
* @var $pagination \yii\data\Pagination * @var $pagination \yii\data\Pagination
* @var $account array
*/ */
use common\models\SettleAccountWeixin;
use frontend\assets\AppAsset; use frontend\assets\AppAsset;
use yii\helpers\Html;
$this->title = '知识有价'; $this->title = '知识有价';
...@@ -14,7 +17,15 @@ AppAsset::addScript($this, '@web/assets/my_income.js'); ...@@ -14,7 +17,15 @@ AppAsset::addScript($this, '@web/assets/my_income.js');
<div class="buy-recode-top"> <div class="buy-recode-top">
<div class="col-md-4"> <div class="col-md-4">
<h3>结算微信</h3> <h3>结算微信</h3>
<button type="button" class="btn btn-save" @click="bindWeixinClick">绑定</button> <?php if ($account) { ?>
<div class="clearfix">
<div class="band-wx-info pull-left"><img src="<?=SettleAccountWeixin::headResize($account['headimgurl'], SettleAccountWeixin::HEAD_SIZE_S)?>">
<span><?=Html::encode($account['nickname'])?></span></div>
<button class="btn btn-default pull-left" @click="weixinUnbindClick">取消绑定</button>
</div>
<?php } else { ?>
<button type="button" class="btn btn-save" @click="weixinBindClick">绑定</button>
<?php } ?>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<h3>已结算</h3> <h3>已结算</h3>
...@@ -46,7 +57,7 @@ AppAsset::addScript($this, '@web/assets/my_income.js'); ...@@ -46,7 +57,7 @@ AppAsset::addScript($this, '@web/assets/my_income.js');
<?=date('Y-m-d H:i', $row['order']['updated_at'])?> <?=date('Y-m-d H:i', $row['order']['updated_at'])?>
</td> </td>
<td><?=$row['order']['user']['telephone']?> / <?=$row['order']['user']['username']?></td> <td><?=$row['order']['user']['telephone']?> / <?=$row['order']['user']['username']?></td>
<td>《<?=$row['order']['course']['name']?>》</td> <td>《<a href="<?=\common\models\Course::url($row['order']['course_id'])?>" target="_blank"><?=$row['order']['course']['name']?></a>》</td>
<td>¥<?=$row['order']['credit']?></td> <td>¥<?=$row['order']['credit']?></td>
<td><?=($row['status'] ? '已结算' : '未结算')?></td> <td><?=($row['status'] ? '已结算' : '未结算')?></td>
</tr> </tr>
...@@ -58,4 +69,5 @@ AppAsset::addScript($this, '@web/assets/my_income.js'); ...@@ -58,4 +69,5 @@ AppAsset::addScript($this, '@web/assets/my_income.js');
<?=\yii\widgets\LinkPager::widget(['pagination'=>$pagination])?> <?=\yii\widgets\LinkPager::widget(['pagination'=>$pagination])?>
</div> </div>
</div> </div>
</div> </div>
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: pader
* Date: 2016/10/20
* Time: 19:02
*/
use frontend\assets\AppAsset;
AppAsset::register($this);
AppAsset::addCss($this, '@web/assets/css/style.css');
\Yii::$app->controller->layout = 'blank';
$css = <<<CSS
.sus-tips {
position: absolute;
left: 50%;
top: 50%;
margin-top: -105px;
margin-left: -200px;
width: 400px;
padding: 40px;
text-align: center;
background-color: #fff;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0,0,0,.05);
}
.sus-tips i {
display: inline-block;
width: 60px;
height: 60px;
font-size: 30px;
text-align: center;
line-height: 60px;
border-radius: 100%;
background-color:#24cf5f ;
color: #fff;
}
.sus-tips p {
padding: 40px 0 0;
color: #24cf5f;
font-size: 14px;
}
CSS;
$this->registerCss($css);
$this->title = '提示';
?>
<div class="sus-tips">
<i class="glyphicon glyphicon-ok"></i>
<p><?=$message?></p>
</div>
\ No newline at end of file
<?php
/**
* @var $message string
*/
$css = <<<CSS
html {
background-color: #f7f7f7;
}
.danger-tip {
text-align: center;
background-color: #f7f7f7;
margin-top: 200px;
}
.danger-tip img {
width: 150px;
}
.danger-tip h3 {
font-size: 24px;
}
.danger-tip p {
width: 400px;
font-size: 14px;
color: #999;
margin: 20px auto;
text-align: left;
background-color: #fff;
border-radius: 5px;
padding: 20px;
border-left:3px solid #ccc;
}
CSS;
$this->registerCss($css);
$this->title = '提示';
?>
<div class="danger-tip">
<img src="<?=\frontend\assets\AppAsset::getStaticUrl('img/no-connection.gif')?>">
<h3>提示信息</h3>
<p><?=$message?></p>
<button type="button" class="btn btn-default" onclick="history.back()">返回</button>
</div>
\ No newline at end of file
<template>
<form method="post" style="padding:20px;width:300px;">
<div class="v-code-box input-wrapper">
<input type="text" name="vcode" class="input-r-control" placeholder="请输入短信验证码">
<button type="button" class="btn btn-nobg" @click="getVerifyCode" :disabled="getDisabled">{{getText}}</button>
<!--<span class="tip-vcode">验证码错误</span>-->
</div>
<div class="v-code-foot">
<button type="submit" class="btn btn-success">解除绑定</button>
</div>
</form>
</template>
<script>
var defaultGetText = "获取验证码";
var timerId = null;
export default{
data() {
return {
getDisabled: false,
getText: defaultGetText
}
},
methods: {
getVerifyCode() {
this.getDisabled = true;
this.getText = "发送中..";
var self = this;
$.post("/my-income/send-unbind-code", {_:Math.random()}, function(t) {
if (t.status) {
var timeout = 120;
self.getText = "已发送(" + timeout + ")";
timerId = setInterval(function() {
--timeout;
if (timeout == 0) {
clearInterval(timerId);
self.getText = defaultGetText;
self.getDisabled = false;
} else {
self.getText = "已发送(" + timeout + ")";
}
}, 1000);
} else {
layer.msg(t.message);
self.getDisabled = false;
self.getText = defaultGetText;
}
}, "json");
}
},
ready() {
var self = this;
var form = this.$el;
$(form).submit(function() {
if ($.trim(form.vcode.value) == "") {
form.vcode.focus();
return false;
}
$.post("/my-income/weixin-unbind", $(form).serialize(), function(t) {
if (t.status) {
$(".v-code-box", form).remove();
$("button[type='submit']", form).text('成功解绑结算微信');
self.getText = defaultGetText;
clearInterval(timerId);
setTimeout(function() {
location.reload();
}, 2000);
} else {
layer.msg(t.message);
form.vcode.value = "";
form.vcode.focus();
}
}, "json");
return false;
});
}
}
</script>
var Vue = require('vue'); var Vue = require('vue');
var layer = require('layer-js'); var layer = require('layer-js');
var unbindForm = require('./components/unbind-form.vue');
/**
* 检查绑定状态,如绑定成功则刷新页面,否则一直检查
*
* @param callback
* @returns {number}
*/
function loopCheckBindStatus(callback) {
return setTimeout(function() {
$.getJSON("/my-income/check-bind-status", function(t) {
if (t.status) {
location.reload();
} else {
var id = loopCheckBindStatus(callback);
callback(id);
}
});
}, 3200);
}
var vm = new Vue({ var vm = new Vue({
el: ".buy-recode-top", el: ".buy-recode-top",
methods: { methods: {
bindWeixinClick: function() { weixinBindClick: function() {
var idx = layer.open({ var idx = layer.open({
type: 1, type: 1,
title: "绑定微信", title: "绑定微信",
...@@ -12,7 +32,30 @@ var vm = new Vue({ ...@@ -12,7 +32,30 @@ var vm = new Vue({
area: ['320px', '380px'], area: ['320px', '380px'],
cancel: function(idx) { cancel: function(idx) {
layer.close(idx); layer.close(idx);
this.content.show(); //this.content.show();
clearTimeout(timerId);
}
});
var timerId = loopCheckBindStatus(function(id) {
timerId = id;
});
},
weixinUnbindClick: function() {
layer.open({
type: 1,
//shift: 0,
title: "解绑结算微信",
id: 'layerContent',
content: '<unbind-form></unbind-form>',
area: ['300px', '180px']
});
new Vue({
el: '#layerContent',
components:{
unbindForm: unbindForm
} }
}); });
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment