1
0
mirror of https://gitee.com/koogua/course-tencent-cloud.git synced 2025-06-26 12:23:06 +08:00

Merge branch 'develop' into demo

This commit is contained in:
xiaochong0302 2020-09-17 21:31:48 +08:00
commit 2b749c7d5c
494 changed files with 3898 additions and 3459 deletions

2
.gitignore vendored
View File

@ -4,6 +4,8 @@
/config/xs.course.ini
/config/xs.group.ini
/config/xs.user.ini
/config/alipay/*.crt
/config/wxpay/*.pem
/public/robots.txt
/public/sitemap.xml
*KgTest*

View File

@ -4,22 +4,28 @@
酷瓜云课堂,依托腾讯云基础服务架构,采用 C 扩展框架 Phalcon 开发,致力网络教育软件。
#### 系统功能
都有些什么功能?我也不想写一大堆,自己体验吧!
帐号100015@163.com / 123456 (前后台通用)
PS**系统后台已禁止提交并隐藏私人配置**
- [前台演示](https://ctc.koogua.com)
- [后台演示](https://ctc.koogua.com/admin)
帐号100015@163.com / 123456 (前后台通用,请不要修改密码)
友情提示:
- 系统配置低1核 1G 1M 跑多个容器),手下留情
- 课程数据来源于网络(无实质内容),切莫购买
- 管理后台已禁止提交(私密配置已过滤)
#### 项目组件
- 后台框架:[phalcon 3.4.5](https://phalcon.io)
- 前端框架:[layui 2.5.6](https://layui.com) [layim 3.9.5](https://www.layui.com/layim)(已授权)
- 全文检索:[xunsearch 1.4.9](http://www.xunsearch.com)
- 即时通讯:[workerman 3.5.22](https://workerman.net)
- 其它依赖:[php7.3](https://php.net) [mysql5.7](https://mysql.com) [redis5.0](https://redis.io)
- 基础依赖:[php7.3](https://php.net) [mysql5.7](https://mysql.com) [redis5.0](https://redis.io)
#### 使用协议
@ -32,32 +38,7 @@ PS**系统后台已禁止提交并隐藏私人配置**
#### 安装指南
- [运行环境搭建](https://gitee.com/koogua/course-tencent-cloud-docker)
- [系统服务配置](https://gitee.com/koogua/course-tencent-cloud/wikis/服务配置)
#### 会推出商业服务吗?
- 如果不符合您对“开源”的认知,请移步其它同类产品,毕竟同类“免费”产品也很多。
- 如果“开源”版本不能满足您的需求,或者您希望有更好的支持,商业服务是不错的选择。
我们为用户提供的服务包括:
- 系统安装
- 系统定制
- 企业会员
#### 会有阿里云版吗?
阿里云版规划中,之前阿里云服务过期未续费,所以腾讯云版本先出。
#### 代码有加密吗?
所有代码都公开授权代码除外例如layim没有所谓的商业版和付费插件。
#### 通过这个项目能学到什么?
1. 项目规划phalcon实战缓存JWT即时通讯全文检索
2. docker操作docker服务编排supervisordevops
3. gitlinuxphpmysqlredisnginx
- [系统服务配置](https://gitee.com/koogua/course-tencent-cloud/wikis)
#### 开发计划
@ -73,7 +54,29 @@ PS**系统后台已禁止提交并隐藏私人配置**
#### 加入我们
这是我的创业项目,个人能力和精力有限,要兼顾产品规划以及开发,还要处理除报税记账之外的所有琐碎事情。
目前在南山科技园某个众创空间,希望有能独挡一面的**深圳前端同学**加入我们。
这是一个创业项目,个人能力和精力有限,要兼顾产品规划以及开发,还要处理很多琐碎事情。目前在南山科技园某个众创空间,希望有 **深圳前端同学** 加入我们。
联系邮箱76632555@qq.com
#### 通过这个项目能学到什么?
- 项目规划phalcon缓存JWT即时通讯全文检索
- dockersupervisordevops
- gitlinuxphpmysqlredisnginx
#### 有阿里云版吗?
阿里云版规划中,之前阿里云服务过期未续费,所以腾讯云版本先出。
#### 代码有加密吗?
所有代码都公开授权代码除外例如layim没有所谓的商业版和付费插件。
#### 有商业服务吗?
生存是一个问题,生存才能发展,我们为用户提供的服务包括:
- 系统安装
- 系统定制
- 企业授权

View File

@ -7,7 +7,7 @@ use App\Models\Course as CourseModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class CourseCatalog extends Builder
class CourseChapterList extends Builder
{
/**

View File

@ -15,7 +15,7 @@ abstract class Cache extends Component
public function __construct()
{
$this->cache = $this->getDI()->get('cache');
$this->cache = $this->getDI()->getShared('cache');
}
/**

View File

@ -20,7 +20,7 @@ abstract class Counter extends Component
public function __construct()
{
$this->cache = $this->getDI()->get('cache');
$this->cache = $this->getDI()->getShared('cache');
$this->redis = $this->cache->getRedis();
}

View File

@ -2,9 +2,9 @@
namespace App\Caches;
use App\Builders\CourseCatalog as CourseCatalogBuilder;
use App\Builders\CourseChapterList as CourseChapterListBuilder;
class CourseCatalog extends Cache
class CourseChapterList extends Cache
{
protected $lifetime = 7 * 86400;
@ -16,12 +16,12 @@ class CourseCatalog extends Cache
public function getKey($id = null)
{
return "course_catalog:{$id}";
return "course_chapter_list:{$id}";
}
public function getContent($id = null)
{
$builder = new CourseCatalogBuilder();
$builder = new CourseChapterListBuilder();
$list = $builder->handle($id);

View File

@ -1,72 +0,0 @@
<?php
namespace App\Caches;
use App\Models\Carousel as CarouselModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class IndexCarouselList extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'index_carousel_list';
}
public function getContent($id = null)
{
$limit = 5;
$carousels = $this->findCarousels($limit);
if ($carousels->count() == 0) {
return [];
}
return $this->handleContent($carousels);
}
/**
* @param CarouselModel[] $carousels
* @return array
*/
protected function handleContent($carousels)
{
$result = [];
foreach ($carousels as $carousel) {
$result[] = [
'id' => $carousel->id,
'title' => $carousel->title,
'cover' => $carousel->cover,
'style' => $carousel->style,
'target' => $carousel->target,
'content' => $carousel->content,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CarouselModel[]
*/
public function findCarousels($limit = 5)
{
return CarouselModel::query()
->where('published = 1')
->orderBy('priority ASC')
->limit($limit)
->execute();
}
}

View File

@ -30,7 +30,7 @@ class IndexFreeCourseList extends Cache
{
$categoryLimit = 5;
$courseLimit = 10;
$courseLimit = 8;
$categories = $this->findCategories($categoryLimit);
@ -100,7 +100,7 @@ class IndexFreeCourseList extends Cache
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCategoryCourses($categoryId, $limit = 10)
protected function findCategoryCourses($categoryId, $limit = 8)
{
$categoryService = new CategoryService();

View File

@ -30,7 +30,7 @@ class IndexNewCourseList extends Cache
{
$categoryLimit = 5;
$courseLimit = 10;
$courseLimit = 8;
$categories = $this->findCategories($categoryLimit);
@ -100,7 +100,7 @@ class IndexNewCourseList extends Cache
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCategoryCourses($categoryId, $limit = 10)
protected function findCategoryCourses($categoryId, $limit = 8)
{
$categoryService = new CategoryService();

View File

@ -0,0 +1,70 @@
<?php
namespace App\Caches;
use App\Models\Course as CourseModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
/**
* 简版免费课程
*/
class IndexSimpleFreeCourseList extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'index_simple_free_course_list';
}
public function getContent($id = null)
{
$limit = 8;
$courses = $this->findCourses($limit);
if ($courses->count() == 0) {
return [];
}
$result = [];
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'model' => $course->model,
'level' => $course->level,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCourses($limit = 8)
{
return CourseModel::query()
->where('published = 1')
->andWhere('market_price = 0')
->orderBy('score DESC')
->limit($limit)
->execute();
}
}

View File

@ -0,0 +1,69 @@
<?php
namespace App\Caches;
use App\Models\Course as CourseModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
/**
* 简版新上课程
*/
class IndexSimpleNewCourseList extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'index_simple_new_course_list';
}
public function getContent($id = null)
{
$limit = 8;
$courses = $this->findCourses($limit);
if ($courses->count() == 0) {
return [];
}
$result = [];
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'model' => $course->model,
'level' => $course->level,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCourses($limit = 8)
{
return CourseModel::query()
->where('published = 1')
->orderBy('id DESC')
->limit($limit)
->execute();
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace App\Caches;
use App\Models\Course as CourseModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
/**
* 简版会员课程
*/
class IndexSimpleVipCourseList extends Cache
{
protected $lifetime = 1 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'index_simple_vip_course_list';
}
public function getContent($id = null)
{
$limit = 8;
$courses = $this->findCourses($limit);
if ($courses->count() == 0) {
return [];
}
$result = [];
foreach ($courses as $course) {
$result[] = [
'id' => $course->id,
'title' => $course->title,
'cover' => $course->cover,
'market_price' => $course->market_price,
'vip_price' => $course->vip_price,
'model' => $course->model,
'level' => $course->level,
'user_count' => $course->user_count,
'lesson_count' => $course->lesson_count,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCourses($limit = 8)
{
return CourseModel::query()
->where('published = 1')
->andWhere('vip_price >= 0')
->orderBy('score DESC')
->limit($limit)
->execute();
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Caches;
use App\Models\Slide as SlideModel;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
class IndexSlideList extends Cache
{
protected $lifetime = 365 * 86400;
public function getLifetime()
{
return $this->lifetime;
}
public function getKey($id = null)
{
return 'index_slide_list';
}
public function getContent($id = null)
{
$limit = 5;
$slides = $this->findSlides($limit);
if ($slides->count() == 0) {
return [];
}
return $this->handleContent($slides);
}
/**
* @param SlideModel[] $slides
* @return array
*/
protected function handleContent($slides)
{
$result = [];
foreach ($slides as $slide) {
$result[] = [
'id' => $slide->id,
'title' => $slide->title,
'cover' => $slide->cover,
'target' => $slide->target,
'content' => $slide->content,
];
}
return $result;
}
/**
* @param int $limit
* @return ResultsetInterface|Resultset|SlideModel[]
*/
public function findSlides($limit = 5)
{
return SlideModel::query()
->where('published = 1')
->orderBy('priority ASC')
->limit($limit)
->execute();
}
}

View File

@ -30,7 +30,7 @@ class IndexVipCourseList extends Cache
{
$categoryLimit = 5;
$courseLimit = 10;
$courseLimit = 8;
$categories = $this->findCategories($categoryLimit);
@ -100,7 +100,7 @@ class IndexVipCourseList extends Cache
* @param int $limit
* @return ResultsetInterface|Resultset|CourseModel[]
*/
protected function findCategoryCourses($categoryId, $limit = 10)
protected function findCategoryCourses($categoryId, $limit = 8)
{
$categoryService = new CategoryService();

View File

@ -2,8 +2,6 @@
namespace App\Console\Tasks;
use Phalcon\Cli\Task;
class CleanLogTask extends Task
{
@ -15,8 +13,8 @@ class CleanLogTask extends Task
$this->cleanSqlLog();
$this->cleanListenerLog();
$this->cleanCaptchaLog();
$this->cleanMailerLog();
$this->cleanSmserLog();
$this->cleanMailLog();
$this->cleanSmsLog();
$this->cleanVodLog();
$this->cleanLiveLog();
$this->cleanStorageLog();
@ -101,17 +99,17 @@ class CleanLogTask extends Task
/**
* 清理短信服务日志
*/
protected function cleanSmserLog()
protected function cleanSmsLog()
{
$this->cleanLog('smser', 7);
$this->cleanLog('sms', 7);
}
/**
* 清理邮件服务日志
*/
protected function cleanMailerLog()
protected function cleanMailLog()
{
$this->cleanLog('mailer', 7);
$this->cleanLog('mail', 7);
}
/**
@ -165,9 +163,9 @@ class CleanLogTask extends Task
if (strtotime($today) - strtotime($date) >= $keepDays * 86400) {
$deleted = unlink($file);
if ($deleted) {
echo "Delete {$file} success" . PHP_EOL;
echo "delete {$file} success" . PHP_EOL;
} else {
echo "Delete {$file} failed" . PHP_EOL;
echo "delete {$file} failed" . PHP_EOL;
}
}
}

View File

@ -2,20 +2,14 @@
namespace App\Console\Tasks;
use App\Library\Cache\Backend\Redis as RedisCache;
use Phalcon\Cli\Task;
use Phalcon\Config;
class CleanSessionTask extends Task
{
public function mainAction()
{
$config = $this->getConfig();
$cache = $this->getCache();
$redis = $cache->getRedis();
$redis = $this->getRedis();
$redis->select($config->path('session.db'));
@ -47,24 +41,4 @@ class CleanSessionTask extends Task
return $cache->queryKeys('_PHCR', $limit);
}
protected function getConfig()
{
/**
* @var Config $config
*/
$config = $this->getDI()->get('config');
return $config;
}
protected function getCache()
{
/**
* @var RedisCache $cache
*/
$cache = $this->getDI()->get('cache');
return $cache;
}
}

View File

@ -3,7 +3,6 @@
namespace App\Console\Tasks;
use App\Models\Order as OrderModel;
use Phalcon\Cli\Task;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;

View File

@ -5,7 +5,6 @@ namespace App\Console\Tasks;
use App\Models\Trade as TradeModel;
use App\Services\Pay\Alipay as AlipayService;
use App\Services\Pay\Wxpay as WxpayService;
use Phalcon\Cli\Task;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;

View File

@ -5,7 +5,6 @@ namespace App\Console\Tasks;
use App\Models\Course as CourseModel;
use App\Services\Search\CourseDocument;
use App\Services\Search\CourseSearcher;
use Phalcon\Cli\Task;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -24,7 +23,7 @@ class CourseIndexTask extends Task
$query = $params[0] ?? null;
if (!$query) {
exit("please special a query word" . PHP_EOL);
exit('please special a query word' . PHP_EOL);
}
$result = $this->searchCourses($query);
@ -61,11 +60,11 @@ class CourseIndexTask extends Task
$index = $handler->getXS()->getIndex();
echo "start clean index" . PHP_EOL;
echo 'start clean index' . PHP_EOL;
$index->clean();
echo "end clean index" . PHP_EOL;
echo 'end clean index' . PHP_EOL;
}
/**
@ -75,9 +74,7 @@ class CourseIndexTask extends Task
{
$courses = $this->findCourses();
if ($courses->count() == 0) {
return;
}
if ($courses->count() == 0) return;
$handler = new CourseSearcher();
@ -85,7 +82,7 @@ class CourseIndexTask extends Task
$index = $handler->getXS()->getIndex();
echo "start rebuild index" . PHP_EOL;
echo 'start rebuild index' . PHP_EOL;
$index->beginRebuild();
@ -96,7 +93,7 @@ class CourseIndexTask extends Task
$index->endRebuild();
echo "end rebuild index" . PHP_EOL;
echo 'end rebuild index' . PHP_EOL;
}
/**

View File

@ -9,7 +9,7 @@ use App\Models\Task as TaskModel;
use App\Models\Trade as TradeModel;
use App\Repos\Order as OrderRepo;
use App\Repos\User as UserRepo;
use App\Services\Smser\Order as OrderSmser;
use App\Services\Sms\Order as OrderSms;
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -74,7 +74,6 @@ class DeliverTask extends Task
$task->update();
$logger->info('Order Process Exception ' . kg_json_encode([
'line' => $e->getLine(),
'code' => $e->getCode(),
'message' => $e->getMessage(),
'task' => $task->toArray(),
@ -165,9 +164,9 @@ class DeliverTask extends Task
protected function handleOrderNotice(OrderModel $order)
{
$smser = new OrderSmser();
$sms = new OrderSms();
$smser->handle($order);
$sms->handle($order);
}
protected function handleOrderRefund(OrderModel $order)

View File

@ -5,7 +5,6 @@ namespace App\Console\Tasks;
use App\Models\ImGroup as GroupModel;
use App\Services\Search\GroupDocument;
use App\Services\Search\GroupSearcher;
use Phalcon\Cli\Task;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -24,7 +23,7 @@ class GroupIndexTask extends Task
$query = $params[0] ?? null;
if (!$query) {
exit("please special a query word" . PHP_EOL);
exit('please special a query word' . PHP_EOL);
}
$result = $this->searchGroups($query);
@ -61,11 +60,11 @@ class GroupIndexTask extends Task
$index = $handler->getXS()->getIndex();
echo "start clean index" . PHP_EOL;
echo 'start clean index' . PHP_EOL;
$index->clean();
echo "end clean index" . PHP_EOL;
echo 'end clean index' . PHP_EOL;
}
/**
@ -75,9 +74,7 @@ class GroupIndexTask extends Task
{
$groups = $this->findGroups();
if ($groups->count() == 0) {
return;
}
if ($groups->count() == 0) return;
$handler = new GroupSearcher();
@ -85,7 +82,7 @@ class GroupIndexTask extends Task
$index = $handler->getXS()->getIndex();
echo "start rebuild index" . PHP_EOL;
echo 'start rebuild index' . PHP_EOL;
$index->beginRebuild();
@ -96,7 +93,7 @@ class GroupIndexTask extends Task
$index->endRebuild();
echo "end rebuild index" . PHP_EOL;
echo 'end rebuild index' . PHP_EOL;
}
/**

View File

@ -2,54 +2,42 @@
namespace App\Console\Tasks;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Models\CourseUser as CourseUserModel;
use App\Repos\Chapter as ChapterRepo;
use App\Services\LiveNotify as LiveNotifyService;
use App\Services\Smser\Live as LiveSmser;
use Phalcon\Cli\Task;
use App\Services\Sms\Live as LiveSms;
class LiveNotifyTask extends Task
{
/**
* @var RedisCache
*/
protected $cache;
/**
* @var \Redis
*/
protected $redis;
public function mainAction()
{
$this->cache = $this->getDI()->get('cache');
$cache = $this->getCache();
$this->redis = $this->cache->getRedis();
$redis = $this->getRedis();
$service = new LiveNotifyService();
$key = $service->getNotifyKey();
$chapterIds = $this->redis->sMembers($key);
$chapterIds = $redis->sMembers($key);
if (!$chapterIds) return;
$sentKey = $service->getSentNotifyKey();
$sentChapterIds = $this->redis->sMembers($sentKey);
$sentChapterIds = $redis->sMembers($sentKey);
foreach ($chapterIds as $chapterId) {
if (!in_array($chapterId, $sentChapterIds)) {
$this->sendNotification($chapterId);
} else {
$this->redis->sAdd($sentKey, $chapterId);
$redis->sAdd($sentKey, $chapterId);
}
}
if ($this->redis->sCard($sentKey) == 1) {
$this->redis->expire($sentKey, 86400);
if ($redis->sCard($sentKey) == 1) {
$redis->expire($sentKey, 86400);
}
}
@ -65,18 +53,15 @@ class LiveNotifyTask extends Task
if (!$targetUserIds) return;
$smser = new LiveSmser();
$sms = new LiveSms();
foreach ($targetUserIds as $userId) {
$smser->handle($chapterId, $userId, $chapterLive->start_time);
$sms->handle($chapterId, $userId, $chapterLive->start_time);
}
}
protected function findTargetUserIds($courseId)
{
/**
* 只给付费和vip用户发通知
*/
$sourceTypes = [
CourseUserModel::SOURCE_CHARGE,
CourseUserModel::SOURCE_VIP,
@ -88,11 +73,11 @@ class LiveNotifyTask extends Task
->inWhere('source_type', $sourceTypes)
->execute();
if ($rows->count() > 0) {
return kg_array_column($rows->toArray(), 'user_id');
if ($rows->count() == 0) {
return [];
}
return [];
return kg_array_column($rows->toArray(), 'user_id');
}
}

View File

@ -2,149 +2,31 @@
namespace App\Console\Tasks;
use App\Caches\Setting as SettingCache;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Models\Setting as SettingModel;
use Phalcon\Cli\Task;
use Phalcon\Config;
use App\Caches\IndexFreeCourseList as IndexFreeCourseListCache;
use App\Caches\IndexNewCourseList as IndexNewCourseListCache;
use App\Caches\IndexVipCourseList as IndexVipCourseListCache;
class MaintainTask extends Task
{
public function mainAction()
public function rebuildIndexCourseCacheAction($params)
{
$this->resetSettingAction();
$this->resetAnnotationAction();
$this->resetMetadataAction();
$this->resetVoltAction();
}
$section = $params[0] ?? null;
/**
* 重置设置
*
* @command: php console.php maintain reset_setting
*/
public function resetSettingAction()
{
echo "start reset setting..." . PHP_EOL;
$rows = SettingModel::query()->columns('section')->distinct(true)->execute();
foreach ($rows as $row) {
$cache = new SettingCache();
$cache->rebuild($row->section);
if (!$section || $section == 'new_course') {
$cache = new IndexNewCourseListCache();
$cache->rebuild();
}
echo "end reset setting..." . PHP_EOL;
}
/**
* 重置注解
*
* @command: php console.php maintain reset_annotation
*/
public function resetAnnotationAction()
{
$config = $this->getConfig();
$cache = $this->getCache();
$redis = $cache->getRedis();
$dbIndex = $config->path('annotation.db');
$statsKey = $config->path('annotation.statsKey');
$redis->select($dbIndex);
$keys = $redis->sMembers($statsKey);
echo "start reset annotation..." . PHP_EOL;
if (count($keys) > 0) {
$keys = $this->handlePhKeys($keys);
$redis->del(...$keys);
$redis->del($statsKey);
if (!$section || $section == 'free_course') {
$cache = new IndexFreeCourseListCache();
$cache->rebuild();
}
echo "end reset annotation..." . PHP_EOL;
}
/**
* 重置元数据
*
* @command: php console.php maintain reset_metadata
*/
public function resetMetadataAction()
{
$config = $this->getConfig();
$cache = $this->getCache();
$redis = $cache->getRedis();
$dbIndex = $config->path('metadata.db');
$statsKey = $config->path('metadata.statsKey');
$redis->select($dbIndex);
$keys = $redis->sMembers($statsKey);
echo "start reset metadata..." . PHP_EOL;
if (count($keys) > 0) {
$keys = $this->handlePhKeys($keys);
$redis->del(...$keys);
$redis->del($statsKey);
if (!$section || $section == 'vip_course') {
$cache = new IndexVipCourseListCache();
$cache->rebuild();
}
echo "start reset metadata..." . PHP_EOL;
}
/**
* 重置模板
*
* @command: php console.php maintain reset_volt
*/
public function resetVoltAction()
{
echo "start reset volt..." . PHP_EOL;
$dir = cache_path('volt');
foreach (scandir($dir) as $file) {
if (strpos($file, '.php')) {
unlink($dir . '/' . $file);
}
}
echo "end reset volt..." . PHP_EOL;
}
protected function getConfig()
{
/**
* @var Config $config
*/
$config = $this->getDI()->get('config');
return $config;
}
protected function getCache()
{
/**
* @var RedisCache $cache
*/
$cache = $this->getDI()->get('cache');
return $cache;
}
protected function handlePhKeys($keys)
{
return array_map(function ($key) {
return "_PHCR{$key}";
}, $keys);
}
}

View File

@ -13,7 +13,7 @@ use App\Repos\Trade as TradeRepo;
use App\Repos\User as UserRepo;
use App\Services\Pay\Alipay as AlipayService;
use App\Services\Pay\Wxpay as WxpayService;
use App\Services\Smser\Refund as RefundSmser;
use App\Services\Sms\Refund as RefundSms;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -111,7 +111,6 @@ class RefundTask extends Task
$task->update();
$logger->info('Refund Task Exception ' . kg_json_encode([
'line' => $e->getLine(),
'code' => $e->getCode(),
'message' => $e->getMessage(),
'task' => $task->toArray(),
@ -284,9 +283,9 @@ class RefundTask extends Task
*/
protected function handleRefundNotice(RefundModel $refund)
{
$smser = new RefundSmser();
$sms = new RefundSms();
$smser->handle($refund);
$sms->handle($refund);
}
/**

View File

@ -3,7 +3,6 @@
namespace App\Console\Tasks;
use App\Models\User as UserModel;
use Phalcon\Cli\Task;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;

View File

@ -49,9 +49,9 @@ class SiteMapTask extends Task
{
$service = new AppService();
$settings = $service->getSectionSettings('site');
$settings = $service->getSettings('site');
return $settings['base_url'] ?? '';
return $settings['url'] ?? '';
}
protected function addIndex()
@ -62,7 +62,7 @@ class SiteMapTask extends Task
protected function addCourses()
{
/**
* @var Resultset $courses
* @var Resultset|CourseModel[] $courses
*/
$courses = CourseModel::query()->where('published = 1')->execute();

View File

@ -2,39 +2,23 @@
namespace App\Console\Tasks;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Repos\Course as CourseRepo;
use App\Services\Search\CourseDocument;
use App\Services\Search\CourseSearcher;
use App\Services\Syncer\CourseIndex as CourseIndexSyncer;
use App\Services\Sync\CourseIndex as CourseIndexSync;
class SyncCourseIndexTask extends Task
{
/**
* @var RedisCache
*/
protected $cache;
/**
* @var \Redis
*/
protected $redis;
public function mainAction()
{
$this->cache = $this->getDI()->get('cache');
$cache = $this->getCache();
$this->redis = $this->cache->getRedis();
$redis = $this->getRedis();
$this->rebuild();
}
protected function rebuild()
{
$key = $this->getSyncKey();
$courseIds = $this->redis->sRandMember($key, 1000);
$courseIds = $redis->sRandMember($key, 1000);
if (!$courseIds) return;
@ -42,9 +26,7 @@ class SyncCourseIndexTask extends Task
$courses = $courseRepo->findByIds($courseIds);
if ($courses->count() == 0) {
return;
}
if ($courses->count() == 0) return;
$document = new CourseDocument();
@ -67,14 +49,14 @@ class SyncCourseIndexTask extends Task
$index->closeBuffer();
$this->redis->sRem($key, ...$courseIds);
$redis->sRem($key, ...$courseIds);
}
protected function getSyncKey()
{
$syncer = new CourseIndexSyncer();
$sync = new CourseIndexSync();
return $syncer->getSyncKey();
return $sync->getSyncKey();
}
}

View File

@ -2,39 +2,23 @@
namespace App\Console\Tasks;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Repos\ImGroup as GroupRepo;
use App\Services\Search\GroupDocument;
use App\Services\Search\GroupSearcher;
use App\Services\Syncer\GroupIndex as GroupIndexSyncer;
use App\Services\Sync\GroupIndex as GroupIndexSync;
class SyncGroupIndexTask extends Task
{
/**
* @var RedisCache
*/
protected $cache;
/**
* @var \Redis
*/
protected $redis;
public function mainAction()
{
$this->cache = $this->getDI()->get('cache');
$cache = $this->getCache();
$this->redis = $this->cache->getRedis();
$redis = $this->getRedis();
$this->rebuild();
}
protected function rebuild()
{
$key = $this->getSyncKey();
$groupIds = $this->redis->sRandMember($key, 1000);
$groupIds = $redis->sRandMember($key, 1000);
if (!$groupIds) return;
@ -42,9 +26,7 @@ class SyncGroupIndexTask extends Task
$groups = $groupRepo->findByIds($groupIds);
if ($groups->count() == 0) {
return;
}
if ($groups->count() == 0) return;
$document = new GroupDocument();
@ -67,14 +49,14 @@ class SyncGroupIndexTask extends Task
$index->closeBuffer();
$this->redis->sRem($key, ...$groupIds);
$redis->sRem($key, ...$groupIds);
}
protected function getSyncKey()
{
$syncer = new GroupIndexSyncer();
$sync = new GroupIndexSync();
return $syncer->getSyncKey();
return $sync->getSyncKey();
}
}

View File

@ -2,7 +2,6 @@
namespace App\Console\Tasks;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Models\Course as CourseModel;
use App\Models\Learning as LearningModel;
use App\Repos\Chapter as ChapterRepo;
@ -10,43 +9,32 @@ use App\Repos\ChapterUser as ChapterUserRepo;
use App\Repos\Course as CourseRepo;
use App\Repos\CourseUser as CourseUserRepo;
use App\Repos\Learning as LearningRepo;
use App\Services\Syncer\Learning as LearningSyncer;
use Phalcon\Cli\Task;
use App\Services\Sync\Learning as LearningSync;
class SyncLearningTask extends Task
{
/**
* @var RedisCache
*/
protected $cache;
/**
* @var \Redis
*/
protected $redis;
public function mainAction()
{
$this->cache = $this->getDI()->get('cache');
$cache = $this->getCache();
$this->redis = $this->cache->getRedis();
$redis = $this->getRedis();
$syncer = new LearningSyncer();
$sync = new LearningSync();
$syncKey = $syncer->getSyncKey();
$syncKey = $sync->getSyncKey();
$requestIds = $this->redis->sMembers($syncKey);
$requestIds = $redis->sMembers($syncKey);
if (!$requestIds) return;
foreach ($requestIds as $requestId) {
$itemKey = $syncer->getItemKey($requestId);
$itemKey = $sync->getItemKey($requestId);
$this->handleLearning($itemKey);
$this->redis->sRem($syncKey, $requestId);
$redis->sRem($syncKey, $requestId);
}
}
@ -153,15 +141,11 @@ class SyncLearningTask extends Task
$courseLessons = $courseRepo->findLessons($learning->course_id);
if ($courseLessons->count() == 0) {
return;
}
if ($courseLessons->count() == 0) return;
$userLearnings = $courseRepo->findUserLearnings($learning->course_id, $learning->user_id, $learning->plan_id);
if ($userLearnings->count() == 0) {
return;
}
if ($userLearnings->count() == 0) return;
$consumedUserLearnings = [];
@ -171,9 +155,7 @@ class SyncLearningTask extends Task
}
}
if (count($consumedUserLearnings) == 0) {
return;
}
if (count($consumedUserLearnings) == 0) return;
$duration = 0;

View File

@ -2,39 +2,23 @@
namespace App\Console\Tasks;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Repos\User as UserRepo;
use App\Services\Search\UserDocument;
use App\Services\Search\UserSearcher;
use App\Services\Syncer\UserIndex as UserIndexSyncer;
use App\Services\Sync\UserIndex as UserIndexSync;
class SyncUserIndexTask extends Task
{
/**
* @var RedisCache
*/
protected $cache;
/**
* @var \Redis
*/
protected $redis;
public function mainAction()
{
$this->cache = $this->getDI()->get('cache');
$cache = $this->getCache();
$this->redis = $this->cache->getRedis();
$redis = $this->getRedis();
$this->rebuild();
}
protected function rebuild()
{
$key = $this->getSyncKey();
$userIds = $this->redis->sRandMember($key, 1000);
$userIds = $redis->sRandMember($key, 1000);
if (!$userIds) return;
@ -42,9 +26,7 @@ class SyncUserIndexTask extends Task
$users = $userRepo->findByIds($userIds);
if ($users->count() == 0) {
return;
}
if ($users->count() == 0) return;
$document = new UserDocument();
@ -67,14 +49,14 @@ class SyncUserIndexTask extends Task
$index->closeBuffer();
$this->redis->sRem($key, ...$userIds);
$redis->sRem($key, ...$userIds);
}
protected function getSyncKey()
{
$syncer = new UserIndexSyncer();
$sync = new UserIndexSync();
return $syncer->getSyncKey();
return $sync->getSyncKey();
}
}

View File

@ -2,14 +2,46 @@
namespace App\Console\Tasks;
use App\Library\Logger;
use App\Library\Cache\Backend\Redis as RedisCache;
use App\Library\Logger as AppLogger;
use Phalcon\Config as PhConfig;
use Phalcon\Logger\Adapter\File as PhLogger;
class Task extends \Phalcon\Cli\Task
{
/**
* @return PhConfig
*/
public function getConfig()
{
return $this->getDI()->getShared('config');
}
/**
* @return RedisCache
*/
public function getCache()
{
return $this->getDI()->getShared('cache');
}
/**
* @return \Redis
*/
public function getRedis()
{
return $this->getCache()->getRedis();
}
/**
* @param null $channel
* @return PhLogger
*/
public function getLogger($channel = null)
{
$logger = new Logger();
$logger = new AppLogger();
return $logger->getInstance($channel);
}

View File

@ -3,7 +3,6 @@
namespace App\Console\Tasks;
use App\Models\User as UserModel;
use Phalcon\Cli\Task;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -14,13 +13,10 @@ class UnlockUserTask extends Task
{
$users = $this->findUsers();
if ($users->count() == 0) {
return;
}
if ($users->count() == 0) return;
foreach ($users as $user) {
$user->locked = 0;
$user->update();
$user->update(['locked' => 0]);
}
}

View File

@ -0,0 +1,127 @@
<?php
namespace App\Console\Tasks;
use App\Caches\Setting as SettingCache;
use App\Models\Setting as SettingModel;
class UpgradeTask extends Task
{
public function mainAction()
{
$this->resetSettingAction();
$this->resetAnnotationAction();
$this->resetMetadataAction();
$this->resetVoltAction();
}
/**
* 重置系统设置
*
* @command: php console.php upgrade reset_setting
*/
public function resetSettingAction()
{
echo "start reset setting..." . PHP_EOL;
$rows = SettingModel::query()->columns('section')->distinct(true)->execute();
foreach ($rows as $row) {
$cache = new SettingCache();
$cache->rebuild($row->section);
}
echo "end reset setting..." . PHP_EOL;
}
/**
* 重置注解
*
* @command: php console.php upgrade reset_annotation
*/
public function resetAnnotationAction()
{
$config = $this->getConfig();
$cache = $this->getCache();
$redis = $this->getRedis();
$dbIndex = $config->path('annotation.db');
$statsKey = $config->path('annotation.statsKey');
$redis->select($dbIndex);
$keys = $redis->sMembers($statsKey);
echo "start reset annotation..." . PHP_EOL;
if (count($keys) > 0) {
$keys = $this->handlePhKeys($keys);
$redis->del(...$keys);
$redis->del($statsKey);
}
echo "end reset annotation..." . PHP_EOL;
}
/**
* 重置元数据
*
* @command: php console.php upgrade reset_metadata
*/
public function resetMetadataAction()
{
$config = $this->getConfig();
$cache = $this->getCache();
$redis = $this->getRedis();
$dbIndex = $config->path('metadata.db');
$statsKey = $config->path('metadata.statsKey');
$redis->select($dbIndex);
$keys = $redis->sMembers($statsKey);
echo "start reset metadata..." . PHP_EOL;
if (count($keys) > 0) {
$keys = $this->handlePhKeys($keys);
$redis->del(...$keys);
$redis->del($statsKey);
}
echo "start reset metadata..." . PHP_EOL;
}
/**
* 重置模板
*
* @command: php console.php upgrade reset_volt
*/
public function resetVoltAction()
{
echo "start reset volt..." . PHP_EOL;
$dir = cache_path('volt');
foreach (scandir($dir) as $file) {
if (strpos($file, '.php')) {
unlink($dir . '/' . $file);
}
}
echo "end reset volt..." . PHP_EOL;
}
protected function handlePhKeys($keys)
{
return array_map(function ($key) {
return "_PHCR{$key}";
}, $keys);
}
}

View File

@ -5,7 +5,6 @@ namespace App\Console\Tasks;
use App\Models\User as UserModel;
use App\Services\Search\UserDocument;
use App\Services\Search\UserSearcher;
use Phalcon\Cli\Task;
use Phalcon\Mvc\Model\Resultset;
use Phalcon\Mvc\Model\ResultsetInterface;
@ -24,7 +23,7 @@ class UserIndexTask extends Task
$query = $params[0] ?? null;
if (!$query) {
exit("please special a query word" . PHP_EOL);
exit('please special a query word' . PHP_EOL);
}
$result = $this->searchUsers($query);
@ -61,11 +60,11 @@ class UserIndexTask extends Task
$index = $handler->getXS()->getIndex();
echo "start clean index" . PHP_EOL;
echo 'start clean index' . PHP_EOL;
$index->clean();
echo "end clean index" . PHP_EOL;
echo 'end clean index' . PHP_EOL;
}
/**
@ -75,9 +74,7 @@ class UserIndexTask extends Task
{
$users = $this->findUsers();
if ($users->count() == 0) {
return;
}
if ($users->count() == 0) return;
$handler = new UserSearcher();
@ -85,7 +82,7 @@ class UserIndexTask extends Task
$index = $handler->getXS()->getIndex();
echo "start rebuild index" . PHP_EOL;
echo 'start rebuild index' . PHP_EOL;
$index->beginRebuild();
@ -96,7 +93,7 @@ class UserIndexTask extends Task
$index->endRebuild();
echo "end rebuild index" . PHP_EOL;
echo 'end rebuild index' . PHP_EOL;
}
/**

View File

@ -6,7 +6,6 @@ use App\Models\Chapter as ChapterModel;
use App\Repos\Chapter as ChapterRepo;
use App\Services\CourseStat as CourseStatService;
use App\Services\Vod as VodService;
use Phalcon\Cli\Task;
class VodEventTask extends Task
{

View File

@ -35,24 +35,24 @@ class ChapterController extends Controller
*/
public function addAction()
{
$courseId = $this->request->getQuery('course_id');
$parentId = $this->request->getQuery('parent_id');
$type = $this->request->getQuery('type');
$courseId = $this->request->getQuery('course_id', 'int');
$parentId = $this->request->getQuery('parent_id', 'int');
$type = $this->request->getQuery('type', 'string', 'chapter');
$courseService = new CourseService();
$course = $courseService->getCourse($courseId);
$chapters = $courseService->getChapters($courseId);
$this->view->pick('chapter/add_chapter');
if ($type == 'lesson') {
$this->view->pick('chapter/add_lesson');
}
$this->view->setVar('course', $course);
$this->view->setVar('parent_id', $parentId);
$this->view->setVar('chapters', $chapters);
if ($type == 'chapter') {
$this->view->pick('chapter/add_chapter');
} else {
$this->view->pick('chapter/add_lesson');
}
}
/**
@ -89,11 +89,12 @@ class ChapterController extends Controller
$chapter = $chapterService->getChapter($id);
$course = $courseService->getCourse($chapter->course_id);
$this->view->setVar('chapter', $chapter);
$this->view->setVar('course', $course);
$this->view->pick('chapter/edit_chapter');
if ($chapter->parent_id > 0) {
$this->view->pick('chapter/edit_lesson');
switch ($course->model) {
case CourseModel::MODEL_VOD:
$vod = $contentService->getChapterVod($chapter->id);
@ -110,12 +111,10 @@ class ChapterController extends Controller
$this->view->setVar('read', $read);
break;
}
$this->view->pick('chapter/edit_lesson');
} else {
$this->view->pick('chapter/edit_chapter');
}
$this->view->setVar('chapter', $chapter);
$this->view->setVar('course', $course);
}
/**

View File

@ -43,7 +43,7 @@ class PublicController extends \Phalcon\Mvc\Controller
*/
public function ip2regionAction()
{
$ip = $this->request->getQuery('ip', 'trim');
$ip = $this->request->getQuery('ip', 'string');
$region = kg_ip2region($ip);

View File

@ -48,7 +48,7 @@ class SessionController extends \Phalcon\Mvc\Controller
$settingService = new SettingService();
$captcha = $settingService->getSectionSettings('captcha');
$captcha = $settingService->getSettings('captcha');
$this->view->pick('public/login');
$this->view->setVar('app_info', $appInfo);

View File

@ -29,7 +29,7 @@ class SettingController extends Controller
} else {
$site = $settingService->getSectionSettings($section);
$site = $settingService->getSettings($section);
$site['url'] = $site['url'] ?: kg_site_url();
@ -56,7 +56,7 @@ class SettingController extends Controller
} else {
$secret = $settingService->getSectionSettings($section);
$secret = $settingService->getSettings($section);
$this->view->setVar('secret', $secret);
}
@ -81,7 +81,7 @@ class SettingController extends Controller
} else {
$cos = $settingService->getSectionSettings($section);
$cos = $settingService->getSettings($section);
$this->view->setVar('cos', $cos);
}
@ -106,7 +106,7 @@ class SettingController extends Controller
} else {
$vod = $settingService->getSectionSettings($section);
$vod = $settingService->getSettings($section);
$this->view->setVar('vod', $vod);
}
@ -121,7 +121,7 @@ class SettingController extends Controller
if ($this->request->isPost()) {
$section = $this->request->getPost('section');
$section = $this->request->getPost('section', 'string');
$data = $this->request->getPost();
@ -150,7 +150,7 @@ class SettingController extends Controller
if ($this->request->isPost()) {
$section = $this->request->getPost('section');
$section = $this->request->getPost('section', 'string');
$data = $this->request->getPost();
@ -169,11 +169,11 @@ class SettingController extends Controller
}
/**
* @Route("/smser", name="admin.setting.smser")
* @Route("/sms", name="admin.setting.sms")
*/
public function smserAction()
public function smsAction()
{
$section = 'smser';
$section = 'sms';
$settingService = new SettingService();
@ -181,24 +181,24 @@ class SettingController extends Controller
$data = $this->request->getPost();
$settingService->updateSmserSettings($section, $data);
$settingService->updateSmsSettings($section, $data);
return $this->jsonSuccess(['msg' => '更新配置成功']);
} else {
$smser = $settingService->getSectionSettings($section);
$sms = $settingService->getSettings($section);
$this->view->setVar('smser', $smser);
$this->view->setVar('sms', $sms);
}
}
/**
* @Route("/mailer", name="admin.setting.mailer")
* @Route("/mail", name="admin.setting.mail")
*/
public function mailerAction()
public function mailAction()
{
$section = 'mailer';
$section = 'mail';
$settingService = new SettingService();
@ -212,9 +212,9 @@ class SettingController extends Controller
} else {
$mailer = $settingService->getSectionSettings($section);
$mail = $settingService->getSettings($section);
$this->view->setVar('mailer', $mailer);
$this->view->setVar('mail', $mail);
}
}
@ -242,7 +242,7 @@ class SettingController extends Controller
} else {
$captcha = $settingService->getSectionSettings($section);
$captcha = $settingService->getSettings($section);
$this->view->setVar('captcha', $captcha);
}
@ -257,7 +257,7 @@ class SettingController extends Controller
if ($this->request->isPost()) {
$data = $this->request->getPost('vip');
$data = $this->request->getPost('vip', 'string');
$settingService->updateVipSettings($data);
@ -280,7 +280,7 @@ class SettingController extends Controller
if ($this->request->isPost()) {
$section = $this->request->getPost('section');
$section = $this->request->getPost('section', 'string');
$data = $this->request->getPost();
@ -290,8 +290,8 @@ class SettingController extends Controller
} else {
$main = $settingService->getSectionSettings('im.main');
$cs = $settingService->getSectionSettings('im.cs');
$main = $settingService->getSettings('im.main');
$cs = $settingService->getSettings('im.cs');
$this->view->setVar('main', $main);
$this->view->setVar('cs', $cs);

View File

@ -2,28 +2,28 @@
namespace App\Http\Admin\Controllers;
use App\Http\Admin\Services\Carousel as CarouselService;
use App\Http\Admin\Services\Slide as SlideService;
/**
* @RoutePrefix("/admin/carousel")
* @RoutePrefix("/admin/slide")
*/
class CarouselController extends Controller
class SlideController extends Controller
{
/**
* @Get("/list", name="admin.carousel.list")
* @Get("/list", name="admin.slide.list")
*/
public function listAction()
{
$carouselService = new CarouselService();
$slideService = new SlideService();
$pager = $carouselService->getCarousels();
$pager = $slideService->getSlides();
$this->view->setVar('pager', $pager);
}
/**
* @Get("/add", name="admin.carousel.add")
* @Get("/add", name="admin.slide.add")
*/
public function addAction()
{
@ -31,17 +31,17 @@ class CarouselController extends Controller
}
/**
* @Post("/create", name="admin.carousel.create")
* @Post("/create", name="admin.slide.create")
*/
public function createAction()
{
$carouselService = new CarouselService();
$slideService = new SlideService();
$carousel = $carouselService->createCarousel();
$slide = $slideService->createSlide();
$location = $this->url->get([
'for' => 'admin.carousel.edit',
'id' => $carousel->id,
'for' => 'admin.slide.edit',
'id' => $slide->id,
]);
$content = [
@ -53,27 +53,27 @@ class CarouselController extends Controller
}
/**
* @Get("/{id:[0-9]+}/edit", name="admin.carousel.edit")
* @Get("/{id:[0-9]+}/edit", name="admin.slide.edit")
*/
public function editAction($id)
{
$carouselService = new CarouselService();
$slideService = new SlideService();
$carousel = $carouselService->getCarousel($id);
$slide = $slideService->getSlide($id);
$this->view->setVar('carousel', $carousel);
$this->view->setVar('slide', $slide);
}
/**
* @Post("/{id:[0-9]+}/update", name="admin.carousel.update")
* @Post("/{id:[0-9]+}/update", name="admin.slide.update")
*/
public function updateAction($id)
{
$carouselService = new CarouselService();
$slideService = new SlideService();
$carouselService->updateCarousel($id);
$slideService->updateSlide($id);
$location = $this->url->get(['for' => 'admin.carousel.list']);
$location = $this->url->get(['for' => 'admin.slide.list']);
$content = [
'location' => $location,
@ -84,13 +84,13 @@ class CarouselController extends Controller
}
/**
* @Post("/{id:[0-9]+}/delete", name="admin.carousel.delete")
* @Post("/{id:[0-9]+}/delete", name="admin.slide.delete")
*/
public function deleteAction($id)
{
$carouselService = new CarouselService();
$slideService = new SlideService();
$carouselService->deleteCarousel($id);
$slideService->deleteSlide($id);
$location = $this->request->getHTTPReferer();
@ -103,13 +103,13 @@ class CarouselController extends Controller
}
/**
* @Post("/{id:[0-9]+}/restore", name="admin.carousel.restore")
* @Post("/{id:[0-9]+}/restore", name="admin.slide.restore")
*/
public function restoreAction($id)
{
$carouselService = new CarouselService();
$slideService = new SlideService();
$carouselService->restoreCarousel($id);
$slideService->restoreSlide($id);
$location = $this->request->getHTTPReferer();

View File

@ -84,7 +84,7 @@ class StudentController extends Controller
*/
public function editAction()
{
$relationId = $this->request->getQuery('relation_id');
$relationId = $this->request->getQuery('relation_id', 'int');
$studentService = new StudentService();

View File

@ -7,11 +7,10 @@ use App\Http\Admin\Services\Setting as SettingService;
use App\Http\Admin\Services\WxpayTest as WxpayTestService;
use App\Services\Captcha as CaptchaService;
use App\Services\Live as LiveService;
use App\Services\Mailer\Test as TestMailerService;
use App\Services\Mail\Test as TestMailService;
use App\Services\MyStorage as StorageService;
use App\Services\Smser\Test as TestSmserService;
use App\Services\Sms\Test as TestSmsService;
use App\Services\Vod as VodService;
use Phalcon\Mvc\View;
/**
* @RoutePrefix("/admin/test")
@ -60,14 +59,14 @@ class TestController extends Controller
*/
public function livePushAction()
{
$streamName = $this->request->getQuery('stream');
$streamName = $this->request->getQuery('stream', 'string');
$liveService = new LiveService();
$pushUrl = $liveService->getPushUrl($streamName);
$qrcode = $this->url->get(
['for' => 'desktop.qrcode'],
['for' => 'home.qrcode'],
['text' => urlencode($pushUrl)]
);
@ -92,21 +91,20 @@ class TestController extends Controller
$pullUrls = $liveService->getPullUrls('test');
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->pick('public/live_player');
$this->view->setVar('pull_urls', $pullUrls);
}
/**
* @Post("/smser", name="admin.test.smser")
* @Post("/sms", name="admin.test.sms")
*/
public function smserAction()
public function smsAction()
{
$phone = $this->request->getPost('phone');
$phone = $this->request->getPost('phone', 'string');
$smserService = new TestSmserService();
$smsService = new TestSmsService();
$response = $smserService->handle($phone);
$response = $smsService->handle($phone);
if ($response) {
return $this->jsonSuccess(['msg' => '发送短信成功,请到收件箱确认']);
@ -116,15 +114,15 @@ class TestController extends Controller
}
/**
* @Post("/mailer", name="admin.test.mailer")
* @Post("/mail", name="admin.test.mail")
*/
public function mailerAction()
public function mailAction()
{
$email = $this->request->getPost('email');
$email = $this->request->getPost('email', 'string');
$mailerService = new TestMailerService();
$mailService = new TestMailService();
$result = $mailerService->handle($email);
$result = $mailService->handle($email);
if ($result) {
return $this->jsonSuccess(['msg' => '发送邮件成功,请到收件箱确认']);
@ -166,7 +164,7 @@ class TestController extends Controller
$this->db->begin();
$order = $alipayTestService->createOrder();
$order = $alipayTestService->createAlipayOrder();
$trade = $alipayTestService->createTrade($order);
$qrcode = $alipayTestService->scan($trade);
@ -190,7 +188,7 @@ class TestController extends Controller
$this->db->begin();
$order = $wxpayTestService->createOrder();
$order = $wxpayTestService->createWxpayOrder();
$trade = $wxpayTestService->createTrade($order);
$qrcode = $wxpayTestService->scan($trade);
@ -210,7 +208,7 @@ class TestController extends Controller
*/
public function alipayStatusAction()
{
$sn = $this->request->getQuery('sn');
$sn = $this->request->getQuery('sn', 'string');
$alipayTestService = new AlipayTestService();
@ -224,7 +222,7 @@ class TestController extends Controller
*/
public function wxpayStatusAction()
{
$sn = $this->request->getQuery('sn');
$sn = $this->request->getQuery('sn', 'string');
$wxpayTestService = new WxpayTestService();

View File

@ -70,13 +70,16 @@ class TradeController extends Controller
{
$tradeService = new TradeService();
$tradeService->refundTrade($id);
$refund = $tradeService->refundTrade($id);
$location = $this->request->getHTTPReferer();
$location = $this->url->get([
'for' => 'admin.refund.show',
'id' => $refund->id,
]);
$content = [
'location' => $location,
'msg' => '申请退款成功,请到退款管理中审核确认',
'msg' => '申请退款成功',
];
return $this->jsonSuccess($content);

View File

@ -53,13 +53,13 @@ class UploadController extends Controller
}
/**
* @Post("/editor/img", name="admin.upload.editor_img")
* @Post("/content/img", name="admin.upload.content_img")
*/
public function uploadEditorImageAction()
public function uploadContentImageAction()
{
$service = new StorageService();
$file = $service->uploadEditorImage();
$file = $service->uploadContentImage();
if ($file) {
return $this->jsonSuccess([

View File

@ -3,7 +3,6 @@
namespace App\Http\Admin\Controllers;
use App\Services\Vod as VodService;
use Phalcon\Mvc\View;
/**
* @RoutePrefix("/admin/vod")
@ -28,13 +27,12 @@ class VodController extends Controller
*/
public function playerAction()
{
$chapterId = $this->request->getQuery('chapter_id');
$playUrl = $this->request->getQuery('play_url');
$chapterId = $this->request->getQuery('chapter_id', 'int');
$playUrl = $this->request->getQuery('play_url', 'string');
$this->view->setRenderLevel(View::LEVEL_ACTION_VIEW);
$this->view->pick('public/vod_player');
$this->view->setVar('chapter_id', $chapterId);
$this->view->setVar('play_url', urldecode($playUrl));
$this->view->setVar('play_url', $playUrl);
}
}

View File

@ -20,7 +20,7 @@ class AlipayTest extends PayTest
if ($code) {
$codeUrl = $this->url->get(
['for' => 'desktop.qrcode'],
['for' => 'home.qrcode'],
['text' => urlencode($code)]
);
}

View File

@ -385,25 +385,25 @@ class AuthNode extends Service
'id' => '2-5-1',
'title' => '轮播列表',
'type' => 'menu',
'route' => 'admin.carousel.list',
'route' => 'admin.slide.list',
],
[
'id' => '2-5-2',
'title' => '添加轮播',
'type' => 'menu',
'route' => 'admin.carousel.add',
'route' => 'admin.slide.add',
],
[
'id' => '2-5-3',
'title' => '编辑轮播',
'type' => 'button',
'route' => 'admin.carousel.edit',
'route' => 'admin.slide.edit',
],
[
'id' => '2-5-4',
'title' => '删除轮播',
'type' => 'button',
'route' => 'admin.carousel.delete',
'route' => 'admin.slide.delete',
],
],
],
@ -675,13 +675,13 @@ class AuthNode extends Service
'id' => '5-1-6',
'title' => '短信设置',
'type' => 'menu',
'route' => 'admin.setting.smser',
'route' => 'admin.setting.sms',
],
[
'id' => '5-1-7',
'title' => '邮件设置',
'type' => 'menu',
'route' => 'admin.setting.mailer',
'route' => 'admin.setting.mail',
],
[
'id' => '5-1-8',

View File

@ -3,7 +3,7 @@
namespace App\Http\Admin\Services;
use App\Caches\Chapter as ChapterCache;
use App\Caches\CourseCatalog as CourseCatalogCache;
use App\Caches\CourseChapterList as CatalogCache;
use App\Models\Chapter as ChapterModel;
use App\Models\ChapterLive as ChapterLiveModel;
use App\Models\ChapterRead as ChapterReadModel;
@ -249,7 +249,7 @@ class Chapter extends Service
protected function rebuildCatalogCache(ChapterModel $chapter)
{
$cache = new CourseCatalogCache();
$cache = new CatalogCache();
$cache->rebuild($chapter->course_id);
}

View File

@ -2,6 +2,7 @@
namespace App\Http\Admin\Services;
use App\Caches\CourseChapterList as CatalogCache;
use App\Library\Utils\Word as WordUtil;
use App\Models\Chapter as ChapterModel;
use App\Models\Course as CourseModel;
@ -63,6 +64,8 @@ class ChapterContent extends Service
$this->updateChapterRead($chapter);
break;
}
$this->rebuildCatalogCache($chapter);
}
protected function updateChapterVod(ChapterModel $chapter)
@ -166,4 +169,11 @@ class ChapterContent extends Service
$courseStats->updateReadAttrs($chapter->course_id);
}
protected function rebuildCatalogCache(ChapterModel $chapter)
{
$cache = new CatalogCache();
$cache->rebuild($chapter->course_id);
}
}

View File

@ -21,7 +21,7 @@ use App\Repos\CourseCategory as CourseCategoryRepo;
use App\Repos\CourseRelated as CourseRelatedRepo;
use App\Repos\CourseUser as CourseUserRepo;
use App\Repos\User as UserRepo;
use App\Services\Syncer\CourseIndex as CourseIndexSyncer;
use App\Services\Sync\CourseIndex as CourseIndexSync;
use App\Validators\Course as CourseValidator;
class Course extends Service
@ -363,9 +363,9 @@ class Course extends Service
protected function rebuildCourseIndex(CourseModel $course)
{
$syncer = new CourseIndexSyncer();
$sync = new CourseIndexSync();
$syncer->addItem($course->id);
$sync->addItem($course->id);
}
protected function saveTeachers(CourseModel $course, $teacherIds)

View File

@ -15,11 +15,11 @@ abstract class PayTest extends Service
protected $channel;
/**
* 创建订单
* 创建支付宝订单
*
* @return OrderModel
*/
public function createOrder()
public function createAlipayOrder()
{
/**
* @var AdminAuth $auth
@ -30,8 +30,45 @@ abstract class PayTest extends Service
$order = new OrderModel();
$order->subject = '测试 - 支付测试0.01元';
$order->amount = 0.01;
$order->subject = '测试 - 支付测试3.01元';
$order->amount = 3.01;
$order->owner_id = $authUser['id'];
$order->item_type = OrderModel::ITEM_TEST;
$order->create();
return $order;
}
/**
* 创建微信订单
*
* @return OrderModel
*/
public function createWxpayOrder()
{
/**
* @var AdminAuth $auth
*/
$auth = $this->getDI()->get('auth');
$authUser = $auth->getAuthInfo();
$config = $this->getConfig();
$order = new OrderModel();
/**
* 微信沙箱环境金额不能自定义,只能是测试用例值(沙吊的不行)
*/
if ($config->get('env') == ENV_DEV) {
$order->subject = '测试 - 支付测试3.01元';
$order->amount = 3.01;
} else {
$order->subject = '测试 - 支付测试0.01元';
$order->amount = 0.01;
}
$order->owner_id = $authUser['id'];
$order->item_type = OrderModel::ITEM_TEST;

View File

@ -24,7 +24,7 @@ class Session extends Service
$currentUser = $this->getCurrentUser();
if ($currentUser->id > 0) {
$this->response->redirect(['for' => 'desktop.index']);
$this->response->redirect(['for' => 'home.index']);
}
$post = $this->request->getPost();
@ -33,7 +33,7 @@ class Session extends Service
$user = $accountValidator->checkAdminLogin($post['account'], $post['password']);
$captchaSettings = $this->getSectionSettings('captcha');
$captchaSettings = $this->getSettings('captcha');
/**
* 验证码是一次性的,放到最后检查,减少第三方调用

View File

@ -11,18 +11,18 @@ class Setting extends Service
public function getAlipaySettings()
{
$alipay = $this->getSectionSettings('pay.alipay');
$alipay = $this->getSettings('pay.alipay');
$alipay['notify_url'] = $alipay['notify_url'] ?: kg_full_url(['for' => 'desktop.alipay_notify']);
$alipay['notify_url'] = $alipay['notify_url'] ?: kg_full_url(['for' => 'home.alipay_notify']);
return $alipay;
}
public function getWxpaySettings()
{
$wxpay = $this->getSectionSettings('pay.wxpay');
$wxpay = $this->getSettings('pay.wxpay');
$wxpay['notify_url'] = $wxpay['notify_url'] ?: kg_full_url(['for' => 'desktop.wxpay_notify']);
$wxpay['notify_url'] = $wxpay['notify_url'] ?: kg_full_url(['for' => 'home.wxpay_notify']);
return $wxpay;
}
@ -36,20 +36,20 @@ class Setting extends Service
public function getLiveSettings($section)
{
$result = $this->getSectionSettings($section);
$result = $this->getSettings($section);
if ($section == 'live.notify') {
$result['stream_begin_url'] = $result['stream_begin_url'] ?: kg_full_url(['for' => 'desktop.live_notify'], ['action' => 'streamBegin']);
$result['stream_end_url'] = $result['stream_end_url'] ?: kg_full_url(['for' => 'desktop.live_notify'], ['action' => 'streamEnd']);
$result['record_url'] = $result['record_url'] ?: kg_full_url(['for' => 'desktop.live_notify'], ['action' => 'record']);
$result['snapshot_url'] = $result['snapshot_url'] ?: kg_full_url(['for' => 'desktop.live_notify'], ['action' => 'snapshot']);
$result['porn_url'] = $result['porn_url'] ?: kg_full_url(['for' => 'desktop.live_notify'], ['action' => 'porn']);
$result['stream_begin_url'] = $result['stream_begin_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'streamBegin']);
$result['stream_end_url'] = $result['stream_end_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'streamEnd']);
$result['record_url'] = $result['record_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'record']);
$result['snapshot_url'] = $result['snapshot_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'snapshot']);
$result['porn_url'] = $result['porn_url'] ?: kg_full_url(['for' => 'home.live_notify'], ['action' => 'porn']);
}
return $result;
}
public function getSectionSettings($section)
public function getSettings($section)
{
$settingsRepo = new SettingRepo();
@ -119,7 +119,7 @@ class Setting extends Service
$this->updateSectionSettings($section, $settings);
}
public function updateSmserSettings($section, $settings)
public function updateSmsSettings($section, $settings)
{
$settings['template'] = kg_json_encode($settings['template']);

View File

@ -2,16 +2,16 @@
namespace App\Http\Admin\Services;
use App\Caches\IndexCarouselList as IndexCarouselListCache;
use App\Caches\IndexSlideList as IndexSlideListCache;
use App\Library\Paginator\Query as PagerQuery;
use App\Models\Carousel as CarouselModel;
use App\Repos\Carousel as CarouselRepo;
use App\Validators\Carousel as CarouselValidator;
use App\Models\Slide as SlideModel;
use App\Repos\Slide as SlideRepo;
use App\Validators\Slide as SlideValidator;
class Carousel extends Service
class Slide extends Service
{
public function getCarousels()
public function getSlides()
{
$pagerQuery = new PagerQuery();
@ -23,55 +23,55 @@ class Carousel extends Service
$page = $pagerQuery->getPage();
$limit = $pagerQuery->getLimit();
$carouselRepo = new CarouselRepo();
$slideRepo = new SlideRepo();
return $carouselRepo->paginate($params, $sort, $page, $limit);
return $slideRepo->paginate($params, $sort, $page, $limit);
}
public function getCarousel($id)
public function getSlide($id)
{
return $this->findOrFail($id);
}
public function createCarousel()
public function createSlide()
{
$post = $this->request->getPost();
$validator = new CarouselValidator();
$validator = new SlideValidator();
$data['title'] = $validator->checkTitle($post['title']);
$data['target'] = $validator->checkTarget($post['target']);
if ($post['target'] == CarouselModel::TARGET_COURSE) {
if ($post['target'] == SlideModel::TARGET_COURSE) {
$course = $validator->checkCourse($post['content']);
$data['content'] = $course->id;
$data['cover'] = $course->cover;
$data['summary'] = $course->summary;
} elseif ($post['target'] == CarouselModel::TARGET_PAGE) {
} elseif ($post['target'] == SlideModel::TARGET_PAGE) {
$page = $validator->checkPage($post['content']);
$data['content'] = $page->id;
} elseif ($post['target'] == CarouselModel::TARGET_LINK) {
} elseif ($post['target'] == SlideModel::TARGET_LINK) {
$data['content'] = $validator->checkLink($post['content']);
}
$data['priority'] = 20;
$carousel = new CarouselModel();
$slide = new SlideModel();
$carousel->create($data);
$slide->create($data);
$this->rebuildCarouselCache();
$this->rebuildSlideCache();
return $carousel;
return $slide;
}
public function updateCarousel($id)
public function updateSlide($id)
{
$carousel = $this->findOrFail($id);
$slide = $this->findOrFail($id);
$post = $this->request->getPost();
$validator = new CarouselValidator();
$validator = new SlideValidator();
$data = [];
@ -87,18 +87,14 @@ class Carousel extends Service
$data['cover'] = $validator->checkCover($post['cover']);
}
if (isset($post['style']['bg_color'])) {
$data['style']['bg_color'] = $validator->checkBgColor($post['style']['bg_color']);
}
if (isset($post['content'])) {
if ($carousel->target == CarouselModel::TARGET_COURSE) {
if ($slide->target == SlideModel::TARGET_COURSE) {
$course = $validator->checkCourse($post['content']);
$data['content'] = $course->id;
} elseif ($carousel->target == CarouselModel::TARGET_PAGE) {
} elseif ($slide->target == SlideModel::TARGET_PAGE) {
$page = $validator->checkPage($post['content']);
$data['content'] = $page->id;
} elseif ($carousel->target == CarouselModel::TARGET_LINK) {
} elseif ($slide->target == SlideModel::TARGET_LINK) {
$data['content'] = $validator->checkLink($post['content']);
}
}
@ -111,51 +107,51 @@ class Carousel extends Service
$data['published'] = $validator->checkPublishStatus($post['published']);
}
$carousel->update($data);
$slide->update($data);
$this->rebuildCarouselCache();
$this->rebuildSlideCache();
return $carousel;
return $slide;
}
public function deleteCarousel($id)
public function deleteSlide($id)
{
$carousel = $this->findOrFail($id);
$slide = $this->findOrFail($id);
$carousel->deleted = 1;
$slide->deleted = 1;
$carousel->update();
$slide->update();
$this->rebuildCarouselCache();
$this->rebuildSlideCache();
return $carousel;
return $slide;
}
public function restoreCarousel($id)
public function restoreSlide($id)
{
$carousel = $this->findOrFail($id);
$slide = $this->findOrFail($id);
$carousel->deleted = 0;
$slide->deleted = 0;
$carousel->update();
$slide->update();
$this->rebuildCarouselCache();
$this->rebuildSlideCache();
return $carousel;
return $slide;
}
protected function rebuildCarouselCache()
protected function rebuildSlideCache()
{
$cache = new IndexCarouselListCache();
$cache = new IndexSlideListCache();
$cache->rebuild();
}
protected function findOrFail($id)
{
$validator = new CarouselValidator();
$validator = new SlideValidator();
return $validator->checkCarousel($id);
return $validator->checkSlide($id);
}
}

View File

@ -101,7 +101,7 @@ class Trade extends Service
$refund->create();
return $trade;
return $refund;
}
protected function findOrFail($id)

View File

@ -2,7 +2,7 @@
{% block content %}
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.carousel.create'}) }}">
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.slide.create'}) }}">
<fieldset class="layui-elem-field layui-field-title">
<legend>添加轮播</legend>
</fieldset>
@ -15,9 +15,9 @@
<div class="layui-form-item">
<label class="layui-form-label">目标类型</label>
<div class="layui-input-block">
<input type="radio" name="target" value="course" title="课程" lay-filter="target" checked="checked">
<input type="radio" name="target" value="page" title="单页" lay-filter="target">
<input type="radio" name="target" value="link" title="链接" lay-filter="target">
<input type="radio" name="target" value="1" title="课程" lay-filter="target" checked="checked">
<input type="radio" name="target" value="2" title="单页" lay-filter="target">
<input type="radio" name="target" value="3" title="链接" lay-filter="target">
</div>
</div>
<div class="layui-form-item">

View File

@ -3,67 +3,58 @@
{% block content %}
{%- macro content_label(target) %}
{% if target == 'course' %}
{% if target == 1 %}
课程编号
{% elseif target == 'page' %}
{% elseif target == 2 %}
单页编号
{% elseif target == 'link' %}
{% elseif target == 3 %}
链接地址
{% endif %}
{%- endmacro %}
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.carousel.update','id':carousel.id}) }}">
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.slide.update','id':slide.id}) }}">
<fieldset class="layui-elem-field layui-field-title">
<legend>编辑轮播</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label">封面</label>
<div class="layui-input-inline">
<img id="img-cover" class="kg-cover" src="{{ carousel.cover }}">
<input type="hidden" name="cover" value="{{ carousel.cover }}">
<img id="img-cover" class="kg-cover" src="{{ slide.cover }}">
<input type="hidden" name="cover" value="{{ slide.cover }}">
</div>
<div class="layui-input-inline" style="padding-top:35px;">
<button id="change-cover" class="layui-btn layui-btn-sm" type="button">更换</button>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">背景色</label>
<div class="layui-input-inline">
<input class="layui-input" type="text" name="style[bg_color]" value="{{ carousel.style['bg_color'] }}" lay-verify="required">
</div>
<div class="layui-inline">
<div id="style-bg-color"></div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">标题</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="title" value="{{ carousel.title }}" lay-verify="required">
<input class="layui-input" type="text" name="title" value="{{ slide.title }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">概要</label>
<div class="layui-input-block">
<textarea class="layui-textarea" name="summary">{{ carousel.summary }}</textarea>
<input class="layui-input" type="text" name="summary" value="{{ slide.summary }}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{{ content_label(carousel.target) }}</label>
<label class="layui-form-label">{{ content_label(slide.target) }}</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="content" value="{{ carousel.content }}" lay-verify="required">
<input class="layui-input" type="text" name="content" value="{{ slide.content }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">排序</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="priority" value="{{ carousel.priority }}" lay-verify="number">
<input class="layui-input" type="text" name="priority" value="{{ slide.priority }}" lay-verify="number">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">发布</label>
<div class="layui-input-block">
<input type="radio" name="published" value="1" title="是" {% if carousel.published == 1 %}checked{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if carousel.published == 0 %}checked{% endif %}>
<input type="radio" name="published" value="1" title="是" {% if slide.published == 1 %}checked="checked"{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if slide.published == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
@ -82,27 +73,3 @@
{{ js_include('admin/js/cover.upload.js') }}
{% endblock %}
{% block inline_js %}
<script>
layui.use(['jquery', 'colorpicker'], function () {
var $ = layui.jquery;
var colorPicker = layui.colorpicker;
colorPicker.render({
elem: '#style-bg-color',
color: '{{ carousel.style['bg_color'] }}',
predefine: true,
change: function (color) {
$('input[name="style[bg_color]"]').val(color);
}
});
});
</script>
{% endblock %}

View File

@ -3,17 +3,15 @@
{% block content %}
{%- macro target_info(value) %}
{% if value == 'course' %}
{% if value == 1 %}
<span class="layui-badge layui-bg-green">课程</span>
{% elseif value == 'page' %}
{% elseif value == 2 %}
<span class="layui-badge layui-bg-blue">单页</span>
{% elseif value == 'link' %}
<span class="layui-badge layui-bg-orange">链接</span>
{% elseif value == 3 %}
<span class="layui-badge layui-bg-gray">链接</span>
{% endif %}
{%- endmacro %}
{% set add_url = url({'for':'admin.carousel.add'}) %}
<div class="kg-nav">
<div class="kg-nav-left">
<span class="layui-breadcrumb">
@ -43,16 +41,16 @@
</thead>
<tbody>
{% for item in pager.items %}
{% set edit_url = url({'for':'admin.carousel.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.carousel.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.carousel.delete','id':item.id}) %}
{% set restore_url = url({'for':'admin.carousel.restore','id':item.id}) %}
{% set edit_url = url({'for':'admin.slide.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.slide.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.slide.delete','id':item.id}) %}
{% set restore_url = url({'for':'admin.slide.restore','id':item.id}) %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.title }}</td>
<td><a href="{{ edit_url }}">{{ item.title }}</a></td>
<td>{{ target_info(item.target) }}</td>
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td>
<td><input type="checkbox" name="published" value="1" lay-filter="published" lay-skin="switch" lay-text="是|否" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-filter="published" lay-skin="switch" lay-text="是|否" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm"> 操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -21,8 +21,8 @@
<div class="layui-form-item">
<label class="layui-form-label">发布</label>
<div class="layui-input-block">
<input type="radio" name="published" value="1" title="是" {% if category.published == 1 %}checked{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if category.published == 0 %}checked{% endif %}>
<input type="radio" name="published" value="1" title="是" {% if category.published == 1 %}checked="checked"{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if category.published == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">

View File

@ -61,7 +61,7 @@
<td><span class="layui-badge layui-bg-gray">{{ item.level }}</span></td>
<td><span class="layui-badge layui-bg-gray">{{ item.child_count }}</span></td>
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -41,7 +41,7 @@
{% block link_css %}
{% if chapter.model == '3' %}
{% if chapter.model == 3 %}
{{ css_link('https://cdn.jsdelivr.net/npm/vditor/dist/index.css', false) }}
{% endif %}
@ -49,12 +49,12 @@
{% block include_js %}
{% if chapter.model == '3' %}
{% if chapter.model == 3 %}
{{ js_include('https://cdn.jsdelivr.net/npm/vditor/dist/index.min.js', false) }}
{{ js_include('admin/js/vditor.js') }}
{% elseif chapter.model == '1' %}
{% elseif chapter.model == 1 %}
{{ js_include('lib/vod-js-sdk-v6.min.js') }}
{{ js_include('lib/clipboard.min.js') }}

View File

@ -42,7 +42,7 @@
</thead>
<tbody>
{% for item in lessons %}
{% set preview_url = url({'for':'desktop.chapter.show','id':item.id}) %}
{% set preview_url = url({'for':'home.chapter.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.chapter.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.chapter.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.chapter.delete','id':item.id}) %}
@ -56,8 +56,8 @@
<td>{{ live_time_info(item.attrs) }}</td>
<td>{{ live_status_info(item.attrs['stream']['status']) }}</td>
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td>
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="free" data-url="{{ update_url }}" {% if item.free == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="free" data-url="{{ update_url }}" {% if item.free == 1 %}checked="checked"{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -21,7 +21,7 @@
</thead>
<tbody>
{% for item in lessons %}
{% set preview_url = url({'for':'desktop.chapter.show','id':item.id}) %}
{% set preview_url = url({'for':'home.chapter.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.chapter.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.chapter.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.chapter.delete','id':item.id}) %}
@ -34,8 +34,8 @@
</td>
<td><span class="layui-badge layui-bg-gray">{{ item.attrs['word_count'] }}</span></td>
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td>
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="free" data-url="{{ update_url }}" {% if item.free == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="free" data-url="{{ update_url }}" {% if item.free == 1 %}checked="checked"{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -37,7 +37,7 @@
</thead>
<tbody>
{% for item in lessons %}
{% set preview_url = url({'for':'desktop.chapter.show','id':item.id}) %}
{% set preview_url = url({'for':'home.chapter.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.chapter.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.chapter.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.chapter.delete','id':item.id}) %}
@ -51,8 +51,8 @@
<td>{{ file_status(item.attrs['file']['status']) }}</td>
<td>{{ item.attrs['duration']|duration }}</td>
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td>
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="free" data-url="{{ update_url }}" {% if item.free == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="free" value="1" lay-skin="switch" lay-text="是|否" lay-filter="free" data-url="{{ update_url }}" {% if item.free == 1 %}checked="checked"{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -57,7 +57,7 @@
<p>编号:{{ item.owner.id }}</p>
</td>
<td>{{ date('Y-m-d H:i:s',item.create_time) }}</td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -30,10 +30,10 @@
<div class="layui-form-item">
<label class="layui-form-label">难度</label>
<div class="layui-input-block">
<input type="radio" name="level" value="1" title="入门" {% if course.level == '1' %}checked{% endif %}>
<input type="radio" name="level" value="2" title="初级" {% if course.level == '2' %}checked{% endif %}>
<input type="radio" name="level" value="3" title="中级" {% if course.level == '3' %}checked{% endif %}>
<input type="radio" name="level" value="4" title="高级" {% if course.level == '4' %}checked{% endif %}>
<input type="radio" name="level" value="1" title="入门" {% if course.level == '1' %}checked="checked"{% endif %}>
<input type="radio" name="level" value="2" title="初级" {% if course.level == '2' %}checked="checked"{% endif %}>
<input type="radio" name="level" value="3" title="中级" {% if course.level == '3' %}checked="checked"{% endif %}>
<input type="radio" name="level" value="4" title="高级" {% if course.level == '4' %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">

View File

@ -69,7 +69,7 @@
</thead>
<tbody>
{% for item in pager.items %}
{% set preview_url = url({'for':'desktop.course.show','id':item.id}) %}
{% set preview_url = url({'for':'home.course.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.course.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.course.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.course.delete','id':item.id}) %}
@ -97,7 +97,7 @@
<p>市场:{{ '¥%0.2f'|format(item.market_price) }}</p>
<p>会员:{{ '¥%0.2f'|format(item.vip_price) }}</p>
</td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -39,8 +39,8 @@
<div class="layui-form-item">
<label class="layui-form-label">发布</label>
<div class="layui-input-block">
<input type="radio" name="published" value="1" title="是" {% if help.published == 1 %}checked{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if help.published == 0 %}checked{% endif %}>
<input type="radio" name="published" value="1" title="是" {% if help.published == 1 %}checked="checked"{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if help.published == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">

View File

@ -32,7 +32,7 @@
<tbody>
{% for item in helps %}
{% set list_url = url({'for':'admin.help.list'},{'category_id':item.category.id}) %}
{% set preview_url = url({'for':'desktop.help.show','id':item.id}) %}
{% set preview_url = url({'for':'home.help.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.help.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.help.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.help.delete','id':item.id}) %}
@ -42,7 +42,7 @@
<td><a href="{{ edit_url }}">{{ item.title }}</a></td>
<td><a href="{{ list_url }}">{{ item.category.name }}</a></td>
<td class="center"><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td>
<td class="center"><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td class="center"><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -37,8 +37,8 @@
<div class="layui-form-item">
<label class="layui-form-label">发布</label>
<div class="layui-input-block">
<input type="radio" name="published" value="1" title="是" {% if group.published == 1 %}checked{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if group.published == 0 %}checked{% endif %}>
<input type="radio" name="published" value="1" title="是" {% if group.published == 1 %}checked="checked"{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if group.published == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">

View File

@ -49,7 +49,7 @@
</thead>
<tbody>
{% for item in pager.items %}
{% set preview_url = url({'for':'desktop.group.show','id':item.id}) %}
{% set preview_url = url({'for':'home.group.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.group.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.group.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.group.delete','id':item.id}) %}
@ -59,7 +59,7 @@
<td><a href="{{ edit_url }}">{{ item.name }}</a> {{ type_info(item.type) }}</td>
<td>{{ owner_info(item.owner) }}</td>
<td><span class="layui-badge layui-bg-gray">{{ item.user_count }}</span></td>
<td><input type="checkbox" name="published" value="1" lay-filter="published" lay-skin="switch" lay-text="是|否" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-filter="published" lay-skin="switch" lay-text="是|否" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -28,13 +28,13 @@
<li class="layui-nav-item">
<a href="javascript:">{{ auth_user.name }}</a>
<dl class="layui-nav-child">
<dd><a href="{{ url({'for':'desktop.my.profile'}) }}" target="_blank">基本资料</a></dd>
<dd><a href="{{ url({'for':'desktop.my.account'}) }}" target="_blank">安全设置</a></dd>
<dd><a href="{{ url({'for':'home.uc.profile'}) }}" target="_blank">基本资料</a></dd>
<dd><a href="{{ url({'for':'home.uc.account'}) }}" target="_blank">安全设置</a></dd>
<dd><a href="{{ url({'for':'admin.logout'}) }}">退出登录</a></dd>
</dl>
</li>
<li class="layui-nav-item">
<a href="{{ url({'for':'desktop.index'}) }}" target="_blank">前台</a>
<a href="{{ url({'for':'home.index'}) }}" target="_blank">前台</a>
</li>
</ul>
</div>

View File

@ -19,7 +19,7 @@
<td>获取渠道</td>
<td>
<a href="https://gitee.com/koogua/course-tencent-cloud" target="_blank">Gitee</a>&nbsp;
<a href="https://github.com/koogua/course-tencent-cloud" target="_blank">Github</a>
<a href="https://github.com/xiaochong0302/course-tencent-cloud" target="_blank">Github</a>
</td>
</tr>
</tbody>

View File

@ -27,22 +27,22 @@
<div class="layui-form-item">
<label class="layui-form-label">位置</label>
<div class="layui-input-block">
<input type="radio" name="position" value="top" title="顶部" {% if nav.position == 1 %}checked{% endif %}>
<input type="radio" name="position" value="bottom" title="底部" {% if nav.position == 2 %}checked{% endif %}>
<input type="radio" name="position" value="1" title="顶部" {% if nav.position == 1 %}checked="checked"{% endif %}>
<input type="radio" name="position" value="2" title="底部" {% if nav.position == 2 %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">目标</label>
<div class="layui-input-block">
<input type="radio" name="target" value="_blank" title="新窗口" {% if nav.target == '_blank' %}checked{% endif %}>
<input type="radio" name="target" value="_self" title="原窗口" {% if nav.target == '_self' %}checked{% endif %}>
<input type="radio" name="target" value="_blank" title="新窗口" {% if nav.target == '_blank' %}checked="checked"{% endif %}>
<input type="radio" name="target" value="_self" title="原窗口" {% if nav.target == '_self' %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">发布</label>
<div class="layui-input-block">
<input type="radio" name="published" value="1" title="是" {% if nav.published == 1 %}checked{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if nav.published == 0 %}checked{% endif %}>
<input type="radio" name="published" value="1" title="是" {% if nav.published == 1 %}checked="checked"{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if nav.published == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">

View File

@ -82,7 +82,7 @@
<td>{{ position_info(item.position) }}</td>
<td>{{ target_info(item.target) }}</td>
<td><input class="layui-input kg-priority" type="text" name="priority" title="数值越小排序越靠前" value="{{ item.priority }}" data-url="{{ update_url }}"></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <span class="layui-icon layui-icon-triangle-d"></span></button>

View File

@ -1,12 +1,12 @@
{%- macro item_info(order) %}
{% if order.item_type == '1' %}
{% if order.item_type == 1 %}
{% set course = order.item_info['course'] %}
<div class="kg-order-item">
<p>课程名称:{{ course['title'] }}</p>
<p>市场价格:{{ '¥%0.2f'|format(course['market_price']) }},会员价格:{{ '¥%0.2f'|format(course['vip_price']) }}</p>
<p>学习期限:{{ date('Y-m-d H:i:s',course['study_expiry_time']) }},退款期限:{{ date('Y-m-d H:i:s',course['refund_expiry_time']) }}</p>
</div>
{% elseif order.item_type == '2' %}
{% elseif order.item_type == 2 %}
{% set courses = order.item_info['courses'] %}
{% for course in courses %}
<div class="kg-order-item">
@ -15,20 +15,20 @@
<p>学习期限:{{ date('Y-m-d H:i:s',course['study_expiry_time']) }},退款期限:{{ date('Y-m-d H:i:s',course['refund_expiry_time']) }}</p>
</div>
{% endfor %}
{% elseif order.item_type == '3' %}
{% elseif order.item_type == 3 %}
{% set course = order.item_info['course'] %}
{% set reward = order.item_info['reward'] %}
<div class="kg-order-item">
<p>商品名称:{{ order.subject }}</p>
<p>商品价格:{{ '¥%0.2f'|format(order.amount) }}</p>
</div>
{% elseif order.item_type == '4' %}
{% elseif order.item_type == 4 %}
{% set vip = order.item_info['vip'] %}
<div class="kg-order-item">
<p>商品名称:{{ order.subject }}</p>
<p>商品价格:{{ '¥%0.2f'|format(order.amount) }}</p>
</div>
{% elseif order.item_type == '99' %}
{% elseif order.item_type == 99 %}
<div class="kg-order-item">
<p>商品名称:{{ order.subject }}</p>
<p>商品价格:{{ '¥%0.2f'|format(order.amount) }}</p>

View File

@ -12,7 +12,7 @@
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{% if account.phone %} {{ account.phone }} {% else %} 未知 {% endif %}</td>
<td>{% if account.email %} {{ account.email }} {% else %} 未知 {% endif %}</td>
<td>{{ account.phone }}</td>
<td>{{ account.email }}</td>
</tr>
</table>

View File

@ -43,7 +43,7 @@
<td><span class="layui-badge layui-bg-gray">{{ item.course_count }}</span></td>
<td>{{ '¥%0.2f'|format(item.market_price) }}</td>
<td>{{ '¥%0.2f'|format(item.vip_price) }}</td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -22,8 +22,8 @@
<div class="layui-form-item">
<label class="layui-form-label">发布</label>
<div class="layui-input-block">
<input type="radio" name="published" value="1" title="是" {% if page.published == 1 %}checked{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if page.published == 0 %}checked{% endif %}>
<input type="radio" name="published" value="1" title="是" {% if page.published == 1 %}checked="checked"{% endif %}>
<input type="radio" name="published" value="0" title="否" {% if page.published == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">

View File

@ -31,7 +31,7 @@
</thead>
<tbody>
{% for item in pager.items %}
{% set preview_url = url({'for':'desktop.page.show','id':item.id}) %}
{% set preview_url = url({'for':'home.page.show','id':item.id}) %}
{% set edit_url = url({'for':'admin.page.edit','id':item.id}) %}
{% set update_url = url({'for':'admin.page.update','id':item.id}) %}
{% set delete_url = url({'for':'admin.page.delete','id':item.id}) %}
@ -40,7 +40,7 @@
<td><a href="{{ edit_url }}">{{ item.title }}</a></td>
<td>{{ date('Y-m-d H:i',item.create_time) }}</td>
<td>{{ date('Y-m-d H:i',item.update_time) }}</td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}>
</td>
<td class="center">
<div class="layui-dropdown">

View File

@ -19,6 +19,6 @@
{% block link_css %}
{{ css_link("desktop/css/error.css") }}
{{ css_link("home/css/error.css") }}
{% endblock %}

View File

@ -1,70 +1,56 @@
<!DOCTYPE html>
<html lang="zh-Hans-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>视频直播</title>
<script src="https://imgcache.qq.com/open/qcloud/video/vcplayer/TcPlayer-2.3.2.js"></script>
{% extends 'templates/main.volt' %}
{% block content %}
<div id="player"></div>
{% endblock %}
{% block inline_css %}
<style>
html, body {
margin: 0;
.kg-body {
padding: 0;
}
</style>
</head>
<body>
<div id="player"></div>
</body>
</html>
<script>
{% endblock %}
var playUrls = JSON.parse('{{ pull_urls|json_encode }}');
{% block inline_js %}
var options = {
live: true,
autoplay: true,
h5_flv: true,
width: 720,
height: 405
};
<script src="https://imgcache.qq.com/open/qcloud/video/vcplayer/TcPlayer-2.3.3.js"></script>
if (playUrls.rtmp && playUrls.rtmp.od) {
options.rtmp = playUrls.rtmp.od;
}
<script>
if (playUrls.rtmp && playUrls.rtmp.hd) {
options.rtmp_hd = playUrls.rtmp.hd;
}
layui.use(['jquery'], function () {
if (playUrls.rtmp && playUrls.rtmp.sd) {
options.rtmp_sd = playUrls.rtmp.sd;
}
var $ = layui.jquery;
if (playUrls.flv && playUrls.flv.od) {
options.flv = playUrls.flv.od;
}
var options = {
live: true,
autoplay: true,
h5_flv: true,
width: 720,
height: 405
};
if (playUrls.flv && playUrls.flv.hd) {
options.flv_hd = playUrls.flv.hd;
}
var playUrls = JSON.parse('{{ pull_urls|json_encode }}');
var formats = ['rtmp', 'flv', 'm3u8'];
var rates = ['od', 'hd', 'sd'];
if (playUrls.flv && playUrls.flv.sd) {
options.flv_sd = playUrls.flv.sd;
}
$.each(formats, function (i, format) {
$.each(rates, function (k, rate) {
if (playUrls.hasOwnProperty(format) && playUrls[format].hasOwnProperty(rate)) {
var key = k === 0 ? format : format + '_' + rate;
options[key] = playUrls[format][rate];
}
});
});
if (playUrls.m3u8 && playUrls.m3u8.od) {
options.m3u8 = playUrls.m3u8.od;
}
new TcPlayer('player', options);
if (playUrls.m3u8 && playUrls.m3u8.hd) {
options.m3u8_hd = playUrls.m3u8.hd;
}
});
if (playUrls.m3u8 && playUrls.m3u8.sd) {
options.m3u8_sd = playUrls.m3u8.sd;
}
</script>
var player = new TcPlayer('player', options);
</script>
{% endblock %}

View File

@ -26,7 +26,7 @@
{% endif %}
<div class="layui-form-item">
<div class="layui-input-block">
{% set disabled = captcha.enabled ? 'disabled' : '' %}
{% set disabled = captcha.enabled ? 'disabled="disabled"' : '' %}
<button id="submit-btn" class="layui-btn layui-btn-fluid layui-btn-disabled" {{ disabled }} lay-submit="true" lay-filter="go">立即登录</button>
<input type="hidden" name="ticket">
<input type="hidden" name="rand">
@ -71,7 +71,7 @@
var $ = layui.jquery;
var captcha = new TencentCaptcha(
new TencentCaptcha(
$('#captcha-btn')[0],
$('#captcha-btn').data('app-id'),
function (res) {

View File

@ -1,31 +1,38 @@
<!DOCTYPE html>
<html lang="zh-Hans-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>视频点播</title>
<script src="https://imgcache.qq.com/open/qcloud/video/vcplayer/TcPlayer-2.3.2.js"></script>
{% extends 'templates/main.volt' %}
{% block content %}
<div id="player"></div>
{% endblock %}
{% block inline_css %}
<style>
html, body {
margin: 0;
.kg-body {
padding: 0;
}
</style>
</head>
<body>
<div id="player"></div>
</body>
</html>
<script>
{% endblock %}
var playUrl = '{{ play_url }}';
{% block inline_js %}
var player = new TcPlayer('player', {
m3u8: playUrl,
autoplay: false,
width: 720,
height: 405
});
<script src="https://imgcache.qq.com/open/qcloud/video/vcplayer/TcPlayer-2.3.3.js"></script>
</script>
<script>
layui.use(['jquery'], function () {
new TcPlayer('player', {
m3u8: '{{ play_url }}',
autoplay: false,
width: 720,
height: 405
});
});
</script>
{% endblock %}

View File

@ -26,6 +26,7 @@
<input type="radio" name="status" value="3" title="已审核">
<input type="radio" name="status" value="4" title="已拒绝">
<input type="radio" name="status" value="5" title="已完成">
<input type="radio" name="status" value="6" title="已失败">
</div>
</div>
<div class="layui-form-item">

View File

@ -39,7 +39,7 @@
<br>
{% if refund.status == 'pending' %}
{% if refund.status == 1 %}
<form class="layui-form kg-form" method="POST" action="{{ refund_review_url }}">
<fieldset class="layui-elem-field layui-field-title">
<legend>审核退款</legend>

View File

@ -54,7 +54,7 @@
<p>昵称:<a href="{{ list_by_owner_url }}">{{ item.owner.name }}</a></p>
<p>编号:{{ item.owner.id }}</p>
</td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked{% endif %}></td>
<td><input type="checkbox" name="published" value="1" lay-skin="switch" lay-text="是|否" lay-filter="published" data-url="{{ update_url }}" {% if item.published == 1 %}checked="checked"{% endif %}></td>
<td class="center">
<div class="layui-dropdown">
<button class="layui-btn layui-btn-sm">操作 <i class="layui-icon layui-icon-triangle-d"></i></button>

View File

@ -31,7 +31,7 @@
<td width="15%">{{ level2.title }}</td>
<td>
{% for level3 in level2.children %}
<input type="checkbox" name="routes[]" title="{{ level3.title }}" value="{{ level3.route }}" {% if level3.route in role.routes %}checked{% endif %}>
<input type="checkbox" name="routes[]" title="{{ level3.title }}" value="{{ level3.route }}" {% if level3.route in role.routes %}checked="checked"{% endif %}>
{% endfor %}
</td>
</tr>

View File

@ -2,8 +2,8 @@
<div class="layui-form-item">
<label class="layui-form-label">开启服务</label>
<div class="layui-input-block">
<input type="radio" name="enabled" value="1" title="是" lay-filter="status" {% if cs.enabled == 1 %}checked{% endif %}>
<input type="radio" name="enabled" value="0" title="否" lay-filter="status" {% if cs.enabled == 0 %}checked{% endif %}>
<input type="radio" name="enabled" value="1" title="是" lay-filter="status" {% if cs.enabled == 1 %}checked="checked"{% endif %}>
<input type="radio" name="enabled" value="0" title="否" lay-filter="status" {% if cs.enabled == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">

View File

@ -14,29 +14,29 @@
<div class="layui-form-item">
<label class="layui-form-label">开启图片上传</label>
<div class="layui-input-block">
<input type="radio" name="upload_img_enabled" value="1" title="是" {% if main.upload_img_enabled == "1" %}checked{% endif %}>
<input type="radio" name="upload_img_enabled" value="0" title="否" {% if main.upload_img_enabled == "0" %}checked{% endif %}>
<input type="radio" name="upload_img_enabled" value="1" title="是" {% if main.upload_img_enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="upload_img_enabled" value="0" title="否" {% if main.upload_img_enabled == "0" %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">开启文件上传</label>
<div class="layui-input-block">
<input type="radio" name="upload_file_enabled" value="1" title="是" {% if main.upload_file_enabled == "1" %}checked{% endif %}>
<input type="radio" name="upload_file_enabled" value="0" title="否" {% if main.upload_file_enabled == "0" %}checked{% endif %}>
<input type="radio" name="upload_file_enabled" value="1" title="是" {% if main.upload_file_enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="upload_file_enabled" value="0" title="否" {% if main.upload_file_enabled == "0" %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">开启音频栏</label>
<div class="layui-input-block">
<input type="radio" name="tool_audio_enabled" value="1" title="是" {% if main.tool_audio_enabled == "1" %}checked{% endif %}>
<input type="radio" name="tool_audio_enabled" value="0" title="否" {% if main.tool_audio_enabled == "0" %}checked{% endif %}>
<input type="radio" name="tool_audio_enabled" value="1" title="是" {% if main.tool_audio_enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="tool_audio_enabled" value="0" title="否" {% if main.tool_audio_enabled == "0" %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">开启视频栏</label>
<div class="layui-input-block">
<input type="radio" name="tool_video_enabled" value="1" title="是" {% if main.tool_video_enabled == "1" %}checked{% endif %}>
<input type="radio" name="tool_video_enabled" value="0" title="否" {% if main.tool_video_enabled == "0" %}checked{% endif %}>
<input type="radio" name="tool_video_enabled" value="1" title="是" {% if main.tool_video_enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="tool_video_enabled" value="0" title="否" {% if main.tool_video_enabled == "0" %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">

View File

@ -40,7 +40,7 @@
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
<input type="hidden" name="section" value="notify">
<input type="hidden" name="section" value="live.notify">
</div>
</div>
</form>

View File

@ -8,8 +8,8 @@
<div class="layui-form-item">
<label class="layui-form-label">拉流协议</label>
<div class="layui-input-block">
<input type="radio" name="protocol" value="http" title="HTTP" {% if pull.protocol == "http" %}checked{% endif %}>
<input type="radio" name="protocol" value="https" title="HTTPS" {% if pull.protocol == "https" %}checked{% endif %}>
<input type="radio" name="protocol" value="http" title="HTTP" {% if pull.protocol == "http" %}checked="checked"{% endif %}>
<input type="radio" name="protocol" value="https" title="HTTPS" {% if pull.protocol == "https" %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
@ -24,8 +24,8 @@
<div class="layui-form-item">
<label class="layui-form-label">开启鉴权</label>
<div class="layui-input-block">
<input type="radio" name="auth_enabled" value="1" title="是" lay-filter="pull_auth_enabled" {% if pull.auth_enabled == 1 %}checked{% endif %}>
<input type="radio" name="auth_enabled" value="0" title="否" lay-filter="pull_auth_enabled" {% if pull.auth_enabled == 0 %}checked{% endif %}>
<input type="radio" name="auth_enabled" value="1" title="是" lay-filter="pull_auth_enabled" {% if pull.auth_enabled == 1 %}checked="checked"{% endif %}>
<input type="radio" name="auth_enabled" value="0" title="否" lay-filter="pull_auth_enabled" {% if pull.auth_enabled == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div id="pull-auth-block" style="{{ pull_auth_display }}">
@ -48,8 +48,8 @@
<div class="layui-form-item">
<label class="layui-form-label">开启转码</label>
<div class="layui-input-block">
<input type="radio" name="trans_enabled" value="1" title="是" lay-filter="pull_trans_enabled" {% if pull.trans_enabled == 1 %}checked{% endif %}>
<input type="radio" name="trans_enabled" value="0" title="否" lay-filter="pull_trans_enabled" {% if pull.trans_enabled == 0 %}checked{% endif %}>
<input type="radio" name="trans_enabled" value="1" title="是" lay-filter="pull_trans_enabled" {% if pull.trans_enabled == 1 %}checked="checked"{% endif %}>
<input type="radio" name="trans_enabled" value="0" title="否" lay-filter="pull_trans_enabled" {% if pull.trans_enabled == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div id="pull-trans-tpl-block" style="{{ pull_trans_tpl_display }}">
@ -97,7 +97,7 @@
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
<input type="hidden" name="section" value="pull">
<input type="hidden" name="section" value="live.pull">
</div>
</div>
</form>

View File

@ -16,8 +16,8 @@
<div class="layui-form-item">
<label class="layui-form-label">开启鉴权</label>
<div class="layui-input-block">
<input type="radio" name="auth_enabled" value="1" title="是" lay-filter="push_auth_enabled" {% if push.auth_enabled == 1 %}checked{% endif %}>
<input type="radio" name="auth_enabled" value="0" title="否" lay-filter="push_auth_enabled" {% if push.auth_enabled == 0 %}checked{% endif %}>
<input type="radio" name="auth_enabled" value="1" title="是" lay-filter="push_auth_enabled" {% if push.auth_enabled == 1 %}checked="checked"{% endif %}>
<input type="radio" name="auth_enabled" value="0" title="否" lay-filter="push_auth_enabled" {% if push.auth_enabled == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div id="push-auth-block" style="{{ push_auth_display }}">
@ -39,7 +39,7 @@
<div class="layui-input-block">
<button class="layui-btn" lay-submit="true" lay-filter="go">提交</button>
<button type="button" class="kg-back layui-btn layui-btn-primary">返回</button>
<input type="hidden" name="section" value="push">
<input type="hidden" name="section" value="live.push">
</div>
</div>
</form>

View File

@ -17,7 +17,7 @@
<div class="layui-form-item">
<label class="layui-form-label">推流地址</label>
<div class="layui-input-inline" style="width:350px;">
<input id="tc1" class="layui-input" type="text" name="obs.fms_url" value="{{ obs.fms_url }}" readonly="readonly">
<input id="tc1" class="layui-input" type="text" name="obs_fms_url" value="{{ obs.fms_url }}" readonly="readonly">
</div>
<div class="layui-input-inline" style="width:100px;">
<span class="kg-copy layui-btn" data-clipboard-target="#tc1">复制</span>

View File

@ -2,60 +2,60 @@
{% block content %}
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.mailer'}) }}">
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.mail'}) }}">
<fieldset class="layui-elem-field layui-field-title">
<legend>邮件配置</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label">发送邮箱</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="smtp_from_email" value="{{ mailer.smtp_from_email }}">
<input class="layui-input" type="text" name="smtp_from_email" value="{{ mail.smtp_from_email }}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">发送人</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="smtp_from_name" value="{{ mailer.smtp_from_name }}">
<input class="layui-input" type="text" name="smtp_from_name" value="{{ mail.smtp_from_name }}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SMTP服务器</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="smtp_host" value="{{ mailer.smtp_host }}">
<input class="layui-input" type="text" name="smtp_host" value="{{ mail.smtp_host }}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SMTP端口号</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="smtp_port" value="{{ mailer.smtp_port }}">
<input class="layui-input" type="text" name="smtp_port" value="{{ mail.smtp_port }}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">加密类型</label>
<div class="layui-input-block">
<input type="radio" name="smtp_encryption" value="ssl" title="SSL" {% if mailer.smtp_encryption == "ssl" %}checked{% endif %}>
<input type="radio" name="smtp_encryption" value="tls" title="TLS" {% if mailer.smtp_encryption == "tls" %}checked{% endif %}>
<input type="radio" name="smtp_encryption" value="" title="不加密" {% if mailer.smtp_encryption == "" %}checked{% endif %}>
<input type="radio" name="smtp_encryption" value="ssl" title="SSL" {% if mail.smtp_encryption == "ssl" %}checked="checked"{% endif %}>
<input type="radio" name="smtp_encryption" value="tls" title="TLS" {% if mail.smtp_encryption == "tls" %}checked="checked"{% endif %}>
<input type="radio" name="smtp_encryption" value="" title="不加密" {% if mail.smtp_encryption == "" %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">账户验证</label>
<div class="layui-input-block">
<input type="radio" name="smtp_authentication" value="1" title="是" lay-filter="smtp_auth" {% if mailer.smtp_authentication == "1" %}checked{% endif %}>
<input type="radio" name="smtp_authentication" value="0" title="否" lay-filter="smtp_auth" {% if mailer.smtp_authentication == "0" %}checked{% endif %}>
<input type="radio" name="smtp_auth_enabled" value="1" title="是" lay-filter="smtp_auth_enabled" {% if mail.smtp_auth_enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="smtp_auth_enabled" value="0" title="否" lay-filter="smtp_auth_enabled" {% if mail.smtp_auth_enabled == "0" %}checked="checked"{% endif %}>
</div>
</div>
<div id="smtp-auth-block">
<div class="layui-form-item">
<label class="layui-form-label">SMTP帐号</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="smtp_username" value="{{ mailer.smtp_username }}">
<input class="layui-input" type="text" name="smtp_username" value="{{ mail.smtp_username }}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">SMTP密码</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="smtp_password" value="{{ mailer.smtp_password }}">
<input class="layui-input" type="text" name="smtp_password" value="{{ mail.smtp_password }}">
</div>
</div>
</div>
@ -68,7 +68,7 @@
</div>
</form>
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.test.mailer'}) }}">
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.test.mail'}) }}">
<fieldset class="layui-elem-field layui-field-title">
<legend>邮件测试</legend>
</fieldset>
@ -98,7 +98,7 @@
var $ = layui.jquery;
var form = layui.form;
form.on('radio(smtp_auth)', function (data) {
form.on('radio(smtp_auth_enabled)', function (data) {
var block = $('#smtp-auth-block');
if (data.value === '1') {
block.show();

View File

@ -2,8 +2,8 @@
<div class="layui-form-item">
<label class="layui-form-label">开启支付</label>
<div class="layui-input-block">
<input type="radio" name="enabled" value="1" title="是" {% if alipay.enabled == "1" %}checked{% endif %}>
<input type="radio" name="enabled" value="0" title="否" {% if alipay.enabled == "0" %}checked{% endif %}>
<input type="radio" name="enabled" value="1" title="是" {% if alipay.enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="enabled" value="0" title="否" {% if alipay.enabled == "0" %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">

View File

@ -2,24 +2,24 @@
<div class="layui-form-item">
<label class="layui-form-label">开启支付</label>
<div class="layui-input-block">
<input type="radio" name="enabled" value="1" title="是" {% if wxpay.enabled == "1" %}checked{% endif %}>
<input type="radio" name="enabled" value="0" title="否" {% if wxpay.enabled == "0" %}checked{% endif %}>
<input type="radio" name="enabled" value="1" title="是" {% if wxpay.enabled == "1" %}checked="checked"{% endif %}>
<input type="radio" name="enabled" value="0" title="否" {% if wxpay.enabled == "0" %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">App ID</label>
<label class="layui-form-label">公众号ID</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="app_id" value="{{ wxpay.app_id }}" lay-verify="required">
<input class="layui-input" type="text" name="mp_app_id" value="{{ wxpay.mp_app_id }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Mch ID</label>
<label class="layui-form-label">商户号ID</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="mch_id" value="{{ wxpay.mch_id }}" lay-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">Private Key</label>
<label class="layui-form-label">API密钥</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="key" value="{{ wxpay.key }}" lay-verify="required">
</div>
@ -40,6 +40,9 @@
</div>
</form>
{% set subject = config.get('env') == 'dev' ? '支付测试3.01元' : '支付测试0.01元' %}
{% set total_amount = config.get('env') == 'dev' ? 3.01 : 0.01 %}
<form class="layui-form kg-form">
<fieldset class="layui-elem-field layui-field-title">
<legend>支付测试</legend>
@ -47,13 +50,13 @@
<div class="layui-form-item">
<label class="layui-form-label">支付项目</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="subject" value="支付测试0.01元" readonly="readonly">
<input class="layui-input" type="text" name="subject" value="{{ subject }}" readonly="readonly">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">支付金额</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="total_amount" value="0.01" readonly="readonly">
<input class="layui-input" type="text" name="total_amount" value="{{ total_amount }}" readonly="readonly">
</div>
</div>
<div class="layui-form-item">

View File

@ -2,7 +2,8 @@
{% block content %}
{% set closed_tips_display = site.enabled == 0 ? 'display:block' : 'display:none' %}
{% set closed_tips_display = site.status == 'closed' ? 'display:block' : 'display:none' %}
{% set analytics_script_display = site.analytics_enabled == 1 ? 'display:block' : 'display:none' %}
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.site'}) }}">
<fieldset class="layui-elem-field layui-field-title">
@ -11,8 +12,8 @@
<div class="layui-form-item">
<label class="layui-form-label">站点状态</label>
<div class="layui-input-block">
<input type="radio" name="enabled" value="1" title="正常" lay-filter="status" {% if site.enabled == 1 %}checked{% endif %}>
<input type="radio" name="enabled" value="0" title="关闭" lay-filter="status" {% if site.enabled == 0 %}checked{% endif %}>
<input type="radio" name="status" value="normal" title="正常" lay-filter="status" {% if site.status == 'normal' %}checked="checked"{% endif %}>
<input type="radio" name="status" value="closed" title="关闭" lay-filter="status" {% if site.status == 'closed' %}checked="checked"{% endif %}>
</div>
</div>
<div id="closed-tips-block" style="{{ closed_tips_display }}">
@ -23,6 +24,13 @@
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">首页版式</label>
<div class="layui-input-block">
<input type="radio" name="index_tpl" value="simple" title="简洁" {% if site.index_tpl == 'simple' %}checked="checked"{% endif %}>
<input type="radio" name="index_tpl" value="full" title="丰富" {% if site.index_tpl == 'full' %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">网站名称</label>
<div class="layui-input-block">
@ -82,9 +90,18 @@
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">站点统计</label>
<label class="layui-form-label">开启统计</label>
<div class="layui-input-block">
<textarea name="analytics" class="layui-textarea" placeholder="使用百度统计等第三方统计分析站点流量">{{ site.analytics }}</textarea>
<input type="radio" name="analytics_enabled" value="1" title="是" lay-filter="analytics_enabled" {% if site.analytics_enabled == 1 %}checked="checked"{% endif %}>
<input type="radio" name="analytics_enabled" value="0" title="否" lay-filter="analytics_enabled" {% if site.analytics_enabled == 0 %}checked="checked"{% endif %}>
</div>
</div>
<div id="analytics-script-block" style="{{ analytics_script_display }}">
<div class="layui-form-item">
<label class="layui-form-label">统计代码</label>
<div class="layui-input-block">
<textarea name="analytics_script" class="layui-textarea" placeholder="使用百度统计等第三方统计分析站点流量">{{ site.analytics_script }}</textarea>
</div>
</div>
</div>
<div class="layui-form-item">
@ -110,7 +127,16 @@
form.on('radio(status)', function (data) {
var block = $('#closed-tips-block');
if (data.value === '0') {
if (data.value === 'closed') {
block.show();
} else {
block.hide();
}
});
form.on('radio(analytics_enabled)', function (data) {
var block = $('#analytics-script-block');
if (data.value === '1') {
block.show();
} else {
block.hide();

View File

@ -2,28 +2,28 @@
{% block content %}
{% set template = smser.template|json_decode %}
{% set template = sms.template|json_decode %}
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.smser'}) }}">
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.setting.sms'}) }}">
<fieldset class="layui-elem-field layui-field-title">
<legend>基础配置</legend>
</fieldset>
<div class="layui-form-item">
<label class="layui-form-label">App ID</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="app_id" value="{{ smser.app_id }}" layui-verify="required">
<input class="layui-input" type="text" name="app_id" value="{{ sms.app_id }}" layui-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">App Key</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="app_key" value="{{ smser.app_key }}" layui-verify="required">
<input class="layui-input" type="text" name="app_key" value="{{ sms.app_key }}" layui-verify="required">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">内容签名</label>
<div class="layui-input-block">
<input class="layui-input" type="text" name="signature" placeholder="注意使用的是签名内容而非签名ID" value="{{ smser.signature }}" layui-verify="required">
<input class="layui-input" type="text" name="signature" placeholder="注意使用的是签名内容而非签名ID" value="{{ sms.signature }}" layui-verify="required">
</div>
</div>
<fieldset class="layui-elem-field layui-field-title">
@ -80,7 +80,7 @@
</div>
</form>
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.test.smser'}) }}">
<form class="layui-form kg-form" method="POST" action="{{ url({'for':'admin.test.sms'}) }}">
<fieldset class="layui-elem-field layui-field-title">
<legend>短信测试</legend>
</fieldset>

View File

@ -21,8 +21,8 @@
<div class="layui-form-item">
<label class="layui-form-label">访问协议</label>
<div class="layui-input-block">
<input type="radio" name="protocol" value="http" title="HTTP" {% if cos.protocol == "http" %}checked{% endif %}>
<input type="radio" name="protocol" value="https" title="HTTPS" {% if cos.protocol == "https" %}checked{% endif %}>
<input type="radio" name="protocol" value="http" title="HTTP" {% if cos.protocol == "http" %}checked="checked"{% endif %}>
<input type="radio" name="protocol" value="https" title="HTTPS" {% if cos.protocol == "https" %}checked="checked"{% endif %}>
</div>
</div>
<div class="layui-form-item">
@ -56,7 +56,7 @@
<td>mageMogr2/thumbnail/270x/interlace/0</td>
</tr>
<tr>
<td>carousel_1100</td>
<td>slide_1100</td>
<td>imageMogr2/thumbnail/1100x/interlace/0</td>
</tr>
</tbody>

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