功能更新

This commit is contained in:
2020-03-30 21:16:28 +08:00
parent b16e4ab920
commit f31f3b99fa
23 changed files with 464 additions and 230 deletions

View File

@@ -9,7 +9,7 @@
// 应用公共文件
use think\facade\Session;
define("SENTCMS_VERSION", '4.0.20200217');
define("SENTCMS_VERSION", '4.x');
/**
*
@@ -28,6 +28,16 @@ function form($field = [], $data = []) {
return \app\http\form\Form::render($field, $data);
}
/**
* 广告位广告
* @param string $name 广告位名称
* @param array $param 参数
* @return mixed
*/
function ad($name, $param = []){
return '';
}
function parse_field_bind(){
}

View File

@@ -14,6 +14,7 @@ use think\facade\View;
use think\facade\Cache;
use think\Validate;
use app\model\Config;
use think\facade\Route;
class Base {

View File

@@ -6,9 +6,10 @@
// +----------------------------------------------------------------------
// | Author: molong <molong@tensent.cn> <http://www.tensent.cn>
// +----------------------------------------------------------------------
namespace app\controller\admin;
use app\model\Attribute as AttributeModel;
/**
* @title 字段管理
* @description 字段管理
@@ -16,32 +17,32 @@ namespace app\controller\admin;
class Attribute extends Base {
//保存的Model句柄
protected $model;
protected $attr;
// protected $model;
// protected $attr;
//初始化
public function _initialize() {
parent::_initialize();
public function initialize() {
parent::initialize();
$this->getContentMenu();
$this->model = model('Attribute');
//遍历属性列表
foreach (get_attribute_type() as $key => $value) {
$this->attr[$key] = $value[0];
}
$this->validate_rule = array(
0 => '请选择',
'regex' => '正则验证',
'function' => '函数验证',
'unique' => '唯一验证',
'length' => '长度验证',
'in' => '验证在范围内',
'notin' => '验证不在范围内',
'between' => '区间验证',
'notbetween' => '不在区间验证',
);
$this->auto_type = array(0 => '请选择', 'function' => '函数', 'field' => '字段', 'string' => '字符串');
$this->the_time = array(0 => '请选择', '3' => '始 终', '1' => '新 增', '2' => '编 辑');
$this->field = $this->getField();
// $this->model = model('Attribute');
// //遍历属性列表
// foreach (get_attribute_type() as $key => $value) {
// $this->attr[$key] = $value[0];
// }
// $this->validate_rule = array(
// 0 => '请选择',
// 'regex' => '正则验证',
// 'function' => '函数验证',
// 'unique' => '唯一验证',
// 'length' => '长度验证',
// 'in' => '验证在范围内',
// 'notin' => '验证不在范围内',
// 'between' => '区间验证',
// 'notbetween' => '不在区间验证',
// );
// $this->auto_type = array(0 => '请选择', 'function' => '函数', 'field' => '字段', 'string' => '字符串');
// $this->the_time = array(0 => '请选择', '3' => '始 终', '1' => '新 增', '2' => '编 辑');
// $this->field = $this->getField();
}
/**
@@ -52,17 +53,13 @@ class Attribute extends Base {
if (!$model_id) {
return $this->error('非法操作!');
}
$list = model('Attribute')->where('model_id', $model_id)->order('id desc')->paginate(25, false, array(
'query' => $this->request->param(),
));
$list = AttributeModel::where('model_id', $model_id)->order('id desc')->paginate($this->request->pageConfig);
$data = array(
$this->data = array(
'list' => $list,
'model_id' => $model_id,
'page' => $list->render(),
);
$this->assign($data);
$this->setMeta('字段管理');
return $this->fetch();
}

View File

@@ -9,9 +9,12 @@
namespace app\controller\admin;
use app\model\Menu;
use app\model\Model;
use app\model\AuthGroup;
use think\facade\View;
use \app\model\Form;
use \app\controller\Base as BaseC;
use think\facade\Route;
class Base extends BaseC {
@@ -190,28 +193,26 @@ class Base extends BaseC {
}
protected function getContentMenu() {
$model = \think\facade\Loader::model('Model');
$list = array();
$map = array(
'status' => array('gt', 0),
);
$list = $model::where($map)->field("name,id,title,icon,'' as 'style'")->select();
$list = [];
$menu = [];
$map[] = ['status', '>', 0];
$list = Model::where($map)->field("name,id,title,icon,'' as 'style'")->select();
//判断是否有模型权限
$models = AuthGroup::getAuthModels(session('user_auth.uid'));
$models = AuthGroup::getAuthModels(session('userInfo.uid'));
foreach ($list as $key => $value) {
if (IS_ROOT || in_array($value['id'], $models)) {
if ('/admin/content/index' == $this->request->path() && input('model_id') == $value['id']) {
if ('/admin/content/index' == $this->request->url() && input('model_id') == $value['id']) {
$value['style'] = "active";
}
$value['url'] = "/admin/content/index?model_id=" . $value['id'];
$value['url'] = "/admin/".$value['name']."/index";
$value['title'] = $value['title'] . "管理";
$value['icon'] = $value['icon'] ? $value['icon'] : 'file';
$menu[] = $value;
}
}
if (!empty($menu)) {
$this->assign('extend_menu', array('内容管理' => $menu));
View::assign('extend_menu', array('内容管理' => $menu));
}
}

View File

@@ -19,8 +19,8 @@ use app\model\Model;
*/
class Category extends Base {
public function _initialize() {
parent::_initialize();
public function initialize() {
parent::initialize();
$this->getContentMenu();
}

View File

@@ -69,7 +69,7 @@ class Config extends Base {
ConfigM::update(['value' => $value], ['name' => $key]);
}
//清除db_config_data缓存
cache('system_config_data', null);
Cache::pull('system_config_data');
return $this->success("更新成功!");
} else {
$list = $config->where(array('status' => 1, 'group' => $id))->field('id,name,title,extra,value,remark,type')->order('sort')->select();
@@ -91,7 +91,7 @@ class Config extends Base {
if ($data) {
$result = ConfigM::create($data);
if (false !== $result) {
Cache::pull('db_config_data');
Cache::pull('system_config_data');
return $this->success('新增成功', url('/admin/config/index'));
} else {
return $this->error('新增失败');
@@ -115,8 +115,7 @@ class Config extends Base {
if ($data) {
$result = ConfigM::update($data, array('id' => $data['id']));
if (false !== $result) {
Cache::pull('db_config_data');
//记录行为
Cache::pull('system_config_data');
return $this->success('更新成功', Cookie('__forward__'));
} else {
return $this->error('更新失败!');
@@ -148,7 +147,7 @@ class Config extends Base {
$Config->where($map)->setField('value', $value);
}
}
cache('db_config_data', null);
Cache::pull('system_config_data');
return $this->success('保存成功!');
}
@@ -165,9 +164,7 @@ class Config extends Base {
$map = array('id' => array('in', $id));
if (db('Config')->where($map)->delete()) {
cache('DB_CONFIG_DATA', null);
//记录行为
action_log('update_config', 'config', $id, session('user_auth.uid'));
Cache::pull('system_config_data');
return $this->success('删除成功');
} else {
return $this->error('删除失败!');
@@ -213,9 +210,9 @@ class Config extends Base {
* @title 主题选择
*/
public function themes(ConfigM $config) {
$list = $config->getThemesList();
$pc = config('system_config.pc_themes');
$mobile = config('system_config.mobile_themes');
$list = $config->getThemesList($this->request);
$pc = config('config.pc_themes');
$mobile = config('config.mobile_themes');
$this->data = array(
'pc' => $pc,
@@ -231,9 +228,9 @@ class Config extends Base {
* @return json
*/
public function setthemes($name, $id) {
$result = db('Config')->where('name', $name . '_themes')->setField('value', $id);
$result = ConfigM::where('name', $name . '_themes')->setField('value', $id);
if (false !== $result) {
\think\Cache::clear();
Cache::pull('system_config_data');
return $this->success('设置成功!');
} else {
return $this->error('设置失败!');

View File

@@ -13,22 +13,10 @@ namespace app\controller\admin;
* @title 内容管理
*/
class Content extends Base {
public function _initialize() {
parent::_initialize();
public function initialize() {
parent::initialize();
$this->getContentMenu();
$this->model_id = $model_id = $this->request->param('model_id');
$list = db('Model')->column('*', 'id');
if (empty($list[$model_id])) {
return $this->error("无此模型!");
} else {
$this->modelInfo = $list[$model_id];
$this->model = M($this->modelInfo['name']);
}
$this->assign('model_id', $model_id);
$this->assign('model_list', $list);
}
/**

View File

@@ -26,7 +26,7 @@ class Database extends Base {
/* 数据还原 */
case 'import':
//列出备份文件列表
$path = \think\facade\Cache::get('system_config_data.data_backup_path');
$path = $this->app->getRuntimePath() . DIRECTORY_SEPARATOR . 'backup';
if (!is_dir($path)) {
mkdir($path, 0755, true);
}
@@ -83,7 +83,7 @@ class Database extends Base {
*/
public function optimize($tables = null) {
if ($tables) {
$Db = \think\Db::connect();
$Db = \think\facade\Db::connect();
if (is_array($tables)) {
$tables = implode('`,`', $tables);
$list = $Db->query("OPTIMIZE TABLE `{$tables}`");
@@ -112,7 +112,7 @@ class Database extends Base {
*/
public function repair($tables = null) {
if ($tables) {
$Db = \think\Db::connect();
$Db = \think\facade\Db::connect();
if (is_array($tables)) {
$tables = implode('`,`', $tables);
$list = $Db->query("REPAIR TABLE `{$tables}`");
@@ -142,7 +142,7 @@ class Database extends Base {
public function del($time = 0) {
if ($time) {
$name = date('Ymd-His', $time) . '-*.sql*';
$path = realpath(config('DATA_BACKUP_PATH')) . DIRECTORY_SEPARATOR . $name;
$path = $this->app->getRuntimePath() . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . $name;
array_map("unlink", glob($path));
if (count(glob($path))) {
return $this->error('备份文件删除失败,请检查权限!');
@@ -163,7 +163,7 @@ class Database extends Base {
public function export($tables = null, $id = null, $start = null) {
if ($this->request->isPost() && !empty($tables) && is_array($tables)) {
//初始化
$path = config('data_backup_path');
$path = $this->app->getRuntimePath() . DIRECTORY_SEPARATOR . 'backup';
if (!is_dir($path)) {
mkdir($path, 0755, true);
}
@@ -236,7 +236,7 @@ class Database extends Base {
//初始化
//获取备份文件信息
$name = date('Ymd-His', $time) . '-*.sql*';
$path = realpath(config('data_backup_path')) . DIRECTORY_SEPARATOR . $name;
$path = $this->app->getRuntimePath() . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . $name;
$files = glob($path);
$list = array();
foreach ($files as $name) {
@@ -257,7 +257,7 @@ class Database extends Base {
} elseif (is_numeric($part) && is_numeric($start)) {
$list = session('backup_list');
$db = new \com\Database($list[$part], array('path' => realpath(config('data_backup_path')) . DIRECTORY_SEPARATOR, 'compress' => $list[$part][2]));
$db = new \com\Database($list[$part], array('path' => $this->app->getRuntimePath() . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR, 'compress' => $list[$part][2]));
$start = $db->import($start);

View File

@@ -15,8 +15,8 @@ use app\model\Model as ModelM;
*/
class Model extends Base {
public function _initialize() {
parent::_initialize();
public function initialize() {
parent::initialize();
$this->getContentMenu();
}

View File

@@ -40,19 +40,17 @@ class Seo extends Base {
public function add() {
if ($this->request->isPost()) {
$data = $this->request->post();
$result = $this->seo->save($data);
$result = SeoRule::create($data);
if ($result) {
return $this->success("添加成功!");
} else {
return $this->error("添加失败!");
}
} else {
$data = array(
'keyList' => $this->seo->keyList,
$this->data = array(
'keyList' => SeoRule::$keyList,
);
$this->assign($data);
$this->setMeta("添加规则");
return $this->fetch('public/edit');
return $this->fetch('admin/public/edit');
}
}
@@ -62,22 +60,24 @@ class Seo extends Base {
public function edit($id = null) {
if ($this->request->isPost()) {
$data = $this->request->post();
$result = $this->seo->save($data, array('id' => $data['id']));
$result = SeoRule::update($data, array('id' => $data['id']));
if (false !== $result) {
return $this->success("修改成功!");
} else {
return $this->error("修改失败!");
}
} else {
$id = input('id', '', 'trim,intval');
$info = $this->seo->where(array('id' => $id))->find();
$data = array(
$id = $this->request->param('id', 0);
if (!$id) {
return $this->error("非法操作!");
}
$info = SeoRule::find($id);
$this->data = array(
'info' => $info,
'keyList' => $this->seo->keyList,
'keyList' => SeoRule::$keyList,
);
$this->assign($data);
$this->setMeta("编辑规则");
return $this->fetch('public/edit');
return $this->fetch('admin/public/edit');
}
}
@@ -85,11 +85,20 @@ class Seo extends Base {
* @title 删除SEO
*/
public function del() {
$id = $this->getArrayParam('id');
$id = $this->request->param('id');
if (empty($id)) {
return $this->error("非法操作!");
}
$result = $this->seo->where(array('id' => array('IN', $id)))->delete();
if (is_array($id)) {
$map[] = ['id', 'IN', $id];
}else{
$map[] = ['id', '=', $id];
}
$result = SeoRule::where($map)->delete();
if ($result) {
return $this->success("删除成功!");
} else {
@@ -117,19 +126,19 @@ class Seo extends Base {
*/
public function addrewrite() {
if ($this->request->isPost()) {
$result = model('Rewrite')->change();
$data = $this->request->param();
$result = Rewrite::create($data);
if (false != $result) {
return $this->success("添加成功!", url('admin/seo/rewrite'));
return $this->success("添加成功!", url('/admin/seo/rewrite'));
} else {
return $this->error(model('Rewrite')->getError());
return $this->error('添加失败!');
}
} else {
$data = array(
'keyList' => $this->rewrite->keyList,
$this->data = array(
'keyList' => Rewrite::$keyList,
);
$this->assign($data);
$this->setMeta("添加路由规则");
return $this->fetch('public/edit');
return $this->fetch('admin/public/edit');
}
}
@@ -138,22 +147,22 @@ class Seo extends Base {
*/
public function editrewrite() {
if ($this->request->isPost()) {
$result = model('Rewrite')->change();
$data = $this->request->param();
$result = Rewrite::update($data, ['id' => $data['id']]);
if (false != $result) {
return $this->success("更新成功!", url('admin/seo/rewrite'));
return $this->success("更新成功!", url('/admin/seo/rewrite'));
} else {
return $this->error(model('Rewrite')->getError());
return $this->error('更新失败!');
}
} else {
$id = input('id', '', 'trim,intval');
$info = db('Rewrite')->where(array('id' => $id))->find();
$data = array(
$id = $this->request->param('id');
$info = Rewrite::find($id);
$this->data = array(
'info' => $info,
'keyList' => $this->rewrite->keyList,
'keyList' => Rewrite::$keyList,
);
$this->assign($data);
$this->setMeta("编辑路由规则");
return $this->fetch('public/edit');
return $this->fetch('admin/public/edit');
}
}
@@ -161,11 +170,20 @@ class Seo extends Base {
* @title 删除静态规则
*/
public function delrewrite() {
$id = $this->getArrayParam('id');
$id = $this->request->param('id');
if (empty($id)) {
return $this->error("非法操作!");
}
$result = db('Rewrite')->where(array('id' => array('IN', $id)))->delete();
if (is_array($id)) {
$map[] = ['id', 'IN', $id];
}else{
$map[] = ['id', '=', $id];
}
$result = Rewrite::where($map)->delete();
if ($result) {
return $this->success("删除成功!");
} else {

View File

@@ -17,4 +17,8 @@ class Index extends Base {
public function index() {
return $this->fetch();
}
public function ad(){
return $this->fetch('ad');
}
}

View File

@@ -6,9 +6,10 @@
// +----------------------------------------------------------------------
// | Author: molong <molong@tensent.cn> <http://www.tensent.cn>
// +----------------------------------------------------------------------
namespace app\model;
use think\facade\Config;
/**
* 设置模型
*/
@@ -18,88 +19,65 @@ class Attribute extends \think\Model {
'id' => 'integer',
);
// protected static function init() {
// self::afterInsert(function ($data) {
// if ($data['model_id']) {
// $name = db('Model')->where('id', $data['model_id'])->value('name');
// $db = new \com\Datatable();
// $attr = $data->toArray();
// $model_attr = array(
// 'model_id' => $data['model_id'],
// 'attr_id' => $data->id,
// 'group_id' => 0,
// 'is_add_table' => 1,
// 'is_show' => $data['is_show'],
// 'is_must' => $data['is_must'],
// 'sort' => 0,
// );
// $attr['after'] = db('Attribute')->where('name', '<>', $data['name'])->where('model_id', $data['model_id'])->order('id desc')->value('name');
// return $db->columField(strtolower($name), $attr)->query();
// }
// });
// self::beforeUpdate(function ($data) {
// $attr = $data->toArray();
// $attr['action'] = 'CHANGE';
// $attr['oldname'] = db('Attribute')->where('id', $attr['id'])->value('name');
// if ($attr['id']) {
// $name = db('Model')->where('id', $attr['model_id'])->value('name');
// $db = new \com\Datatable();
// return $db->columField(strtolower($name), $attr)->query();
// } else {
// return false;
// }
// });
// }
protected static function onAfterInsert($model){
// if ($data['model_id']) {
// $name = db('Model')->where('id', $data['model_id'])->value('name');
// $db = new \com\Datatable();
// $attr = $data->toArray();
// $model_attr = array(
// 'model_id' => $data['model_id'],
// 'attr_id' => $data->id,
// 'group_id' => 0,
// 'is_add_table' => 1,
// 'is_show' => $data['is_show'],
// 'is_must' => $data['is_must'],
// 'sort' => 0,
// );
// $attr['after'] = db('Attribute')->where('name', '<>', $data['name'])->where('model_id', $data['model_id'])->order('id desc')->value('name');
// return $db->columField(strtolower($name), $attr)->query();
// }
}
protected static function onAfterUpdate($model){
// $attr = $data->toArray();
// $attr['action'] = 'CHANGE';
// $attr['oldname'] = db('Attribute')->where('id', $attr['id'])->value('name');
// if ($attr['id']) {
// $name = db('Model')->where('id', $attr['model_id'])->value('name');
// $db = new \com\Datatable();
// return $db->columField(strtolower($name), $attr)->query();
// } else {
// return false;
// }
}
protected static function onAfterDelete($model){
$tablename = strtolower($tablename);
//删除模型表中字段
$db = new \com\Datatable();
if (!$db->CheckField($tablename, $info['name'])) {
return true;
}
$result = $db->delField($tablename, $info['name'])->query();
}
protected function getTypeTextAttr($value, $data) {
$type = config('config_type_list');
$type_text = explode(',', $type[$data['type']]);
return $type_text[0];
}
public function getFieldlist($map, $index = 'id') {
$list = array();
$row = db('Attribute')->field('*,remark as help,type,extra as "option",model_id')->where($map)->order('group_id asc, sort asc')->select();
foreach ($row as $key => $value) {
if (in_array($value['type'], array('checkbox', 'radio', 'select', 'bool'))) {
$value['option'] = parse_field_attr($value['extra']);
} elseif ($value['type'] == 'bind') {
$extra = parse_field_bind($value['extra'], '', $value['model_id']);
$option = array();
foreach ($extra as $k => $v) {
$option[$v['id']] = $v['title_show'];
}
$value['option'] = $option;
}
$list[$value['id']] = $value;
$config_type_list = Config::get('config.config_type_list');
$type = [];
foreach ($config_type_list as $key => $value) {
$type[$value['key']] = $value['label'];
}
return $list;
return isset($type[$data['type']]) ? $type[$data['type']] : '';
}
public function del($id, $model_id) {
$map['id'] = $id;
$info = $this->find($id);
$tablename = db('Model')->where(array('id' => $model_id))->value('name');
protected function getOptionAttr($value, $data){
if ($data == '') {
return [];
}
if (in_array($data['type'], ['checkbox', 'radio', 'select', 'bool'])) {
# code...
}elseif($data['type'] == 'bind'){
//先删除字段表内的数据
$result = $this->where($map)->delete();
if ($result) {
$tablename = strtolower($tablename);
//删除模型表中字段
$db = new \com\Datatable();
if (!$db->CheckField($tablename, $info['name'])) {
return true;
}
$result = $db->delField($tablename, $info['name'])->query();
if ($result) {
return true;
} else {
$this->error = "删除失败!";
return false;
}
} else {
$this->error = "删除失败!";
return false;
}
}
}

View File

@@ -23,4 +23,6 @@ class AuthGroup extends Model{
['name'=>'description', 'title'=>'分组描述', 'type'=>'textarea', 'help'=>'', 'option'=>''],
['name'=>'status', 'title'=>'状态', 'type'=>'select', 'help'=>'', 'option'=> [['key' => 0, 'label' => '禁用'],['key' => 1, 'label' => '启用']]],
];
public static function getAuthModels($uid){}
}

View File

@@ -83,10 +83,34 @@ class Config extends Model {
return $data;
}
public function getThemesList(){
public function getThemesList($request){
return [
'pc' => [],
'mobile' => []
'pc' => $this->getList('pc'),
'mobile' => $this->getList('mobile')
];
}
protected function getList($type){
$tempPath = app()->getRootPath() . 'public' . DIRECTORY_SEPARATOR . 'template' . DIRECTORY_SEPARATOR;
$file = opendir($tempPath);
$list = [];
while (false !== ($filename = readdir($file))) {
if (!in_array($filename, array('.', '..'))) {
$files = $tempPath . $filename . '/info.php';
if (is_file($files)) {
$info = include($files);
if (isset($info['type']) && $info['type'] == $type) {
$info['id'] = $filename;
$preview = '/template/' . $filename . '/' . $info['preview'];
$info['preview'] = is_file($tempPath . $preview) ? $preview : '/static/common/images/default.png';
$list[] = $info;
}else{
continue;
}
}
}
}
return $list;
}
}

View File

@@ -16,7 +16,7 @@ class Rewrite extends \think\Model {
protected $autoWriteTimestamp = true;
public $keyList = array(
public static $keyList = array(
array('name' => 'id', 'title' => '标识', 'type' => 'hidden'),
array('name' => 'rule', 'title' => '规则名称', 'type' => 'text', 'option' => '', 'help' => '规则名称,方便记忆'),
array('name' => 'url', 'title' => '规则地址', 'type' => 'text', 'option' => '', 'help' => '规则地址'),

View File

@@ -14,18 +14,18 @@ namespace app\model;
*/
class SeoRule extends \think\Model {
public $keyList = array(
array('name' => 'id', 'title' => '标识', 'type' => 'hidden'),
array('name' => 'title', 'title' => '规则名称', 'type' => 'text', 'option' => '', 'help' => '规则名称,方便记忆'),
array('name' => 'app', 'title' => '模块名', 'type' => 'select', 'option' => array('*' => '-所有模块-', 'index' => '前台模块', 'user' => '用户中心'), 'help' => '不选表示所有模块'),
array('name' => 'controller', 'title' => '控制器', 'type' => 'text', 'option' => '', 'help' => '不填表示所有控制器'),
array('name' => 'action', 'title' => '方法', 'type' => 'text', 'option' => '', 'help' => '不填表示所有方法'),
array('name' => 'seo_title', 'title' => 'SEO标题', 'type' => 'text', 'option' => '', 'help' => '不填表示使用默认'),
array('name' => 'seo_keywords', 'title' => 'SEO关键字', 'type' => 'text', 'option' => '', 'help' => '不填表示使用默认'),
array('name' => 'seo_description', 'title' => 'SEO描述', 'type' => 'text', 'option' => '', 'help' => '不填表示使用默认'),
array('name' => 'status', 'title' => '状态', 'type' => 'select', 'option' => array('0' => '禁用', '1' => '启用'), 'help' => ''),
array('name' => 'sort', 'title' => '排序', 'type' => 'text', 'option' => '', 'help' => ''),
);
public static $keyList = [
['name' => 'id', 'title' => '标识', 'type' => 'hidden'],
['name' => 'title', 'title' => '规则名称', 'type' => 'text', 'option' => '', 'help' => '规则名称,方便记忆'],
['name' => 'app', 'title' => '模块名', 'type' => 'select', 'option' => [['key'=>'*', 'label' => '-所有模块-'], ['key'=>'index', 'label' => '前台模块'], ['key'=>'user', 'label' => '用户中心']], 'help' => '不选表示所有模块'],
['name' => 'controller', 'title' => '控制器', 'type' => 'text', 'option' => '', 'help' => '不填表示所有控制器'],
['name' => 'action', 'title' => '方法', 'type' => 'text', 'option' => '', 'help' => '不填表示所有方法'],
['name' => 'seo_title', 'title' => 'SEO标题', 'type' => 'text', 'option' => '', 'help' => '不填表示使用默认'],
['name' => 'seo_keywords', 'title' => 'SEO关键字', 'type' => 'text', 'option' => '', 'help' => '不填表示使用默认'],
['name' => 'seo_description', 'title' => 'SEO描述', 'type' => 'text', 'option' => '', 'help' => '不填表示使用默认'],
['name' => 'status', 'title' => '状态', 'type' => 'select', 'option' => [['key'=>'0', 'label' => '禁用'], ['key'=>'1', 'label' => '启用']], 'help' => ''],
['name' => 'sort', 'title' => '排序', 'type' => 'text', 'option' => '', 'help' => ''],
];
protected function setAppAttr($value) {
return $value ? $value : '*';

214
extend/com/Database.php Normal file
View File

@@ -0,0 +1,214 @@
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://www.zjzit.cn>
// +----------------------------------------------------------------------
namespace com;
use think\facade\Config;
use think\facade\Db;
//数据导出模型
class Database{
/**
* 文件指针
* @var resource
*/
private $fp;
/**
* 备份文件信息 part - 卷号name - 文件名
* @var array
*/
private $file;
/**
* 当前打开文件大小
* @var integer
*/
private $size = 0;
/**
* 备份配置
* @var integer
*/
private $config;
/**
* 数据库备份构造方法
* @param array $file 备份或还原的文件信息
* @param array $config 备份配置信息
* @param string $type 执行类型export - 备份数据, import - 还原数据
*/
public function __construct($file, $config, $type = 'export'){
$this->file = $file;
$this->config = $config;
}
/**
* 打开一个卷,用于写入数据
* @param integer $size 写入数据的大小
*/
private function open($size){
if($this->fp){
$this->size += $size;
if($this->size > $this->config['part']){
$this->config['compress'] ? @gzclose($this->fp) : @fclose($this->fp);
$this->fp = null;
$this->file['part']++;
session('backup_file', $this->file);
$this->create();
}
} else {
$backuppath = $this->config['path'];
$filename = "{$backuppath}{$this->file['name']}-{$this->file['part']}.sql";
if($this->config['compress']){
$filename = "{$filename}.gz";
$this->fp = @gzopen($filename, "a{$this->config['level']}");
} else {
$this->fp = @fopen($filename, 'a');
}
$this->size = filesize($filename) + $size;
}
}
/**
* 写入初始数据
* @return boolean true - 写入成功false - 写入失败
*/
public function create(){
$sql = "-- -----------------------------\n";
$sql .= "-- SentCMS MySQL Data Transfer \n";
$sql .= "-- \n";
$sql .= "-- Host : " . config('database.hostname') . "\n";
$sql .= "-- Port : " . config('database.hostport') . "\n";
$sql .= "-- Database : " . config('database.database') . "\n";
$sql .= "-- \n";
$sql .= "-- Part : #{$this->file['part']}\n";
$sql .= "-- Date : " . date("Y-m-d H:i:s") . "\n";
$sql .= "-- -----------------------------\n\n";
$sql .= "SET FOREIGN_KEY_CHECKS = 0;\n\n";
return $this->write($sql);
}
/**
* 写入SQL语句
* @param string $sql 要写入的SQL语句
* @return boolean true - 写入成功false - 写入失败!
*/
private function write($sql){
$size = strlen($sql);
//由于压缩原因无法计算出压缩后的长度这里假设压缩率为50%
//一般情况压缩率都会高于50%
$size = $this->config['compress'] ? $size / 2 : $size;
$this->open($size);
return $this->config['compress'] ? @gzwrite($this->fp, $sql) : @fwrite($this->fp, $sql);
}
/**
* 备份表结构
* @param string $table 表名
* @param integer $start 起始行数
* @return boolean false - 备份失败
*/
public function backup($table, $start){
//创建DB对象
$db = Db::connect();
//备份表结构
if(0 == $start){
$result = $db->query("SHOW CREATE TABLE `{$table}`");
$sql = "\n";
$sql .= "-- -----------------------------\n";
$sql .= "-- Table structure for `{$table}`\n";
$sql .= "-- -----------------------------\n";
$sql .= "DROP TABLE IF EXISTS `{$table}`;\n";
$sql .= trim($result[0]['Create Table']) . ";\n\n";
if(false === $this->write($sql)){
return false;
}
}
//数据总数
$result = $db->query("SELECT COUNT(*) AS count FROM `{$table}`");
$count = $result['0']['count'];
//备份表数据
if($count){
//写入数据注释
if(0 == $start){
$sql = "-- -----------------------------\n";
$sql .= "-- Records of `{$table}`\n";
$sql .= "-- -----------------------------\n";
$this->write($sql);
}
//备份数据记录
$result = $db->query("SELECT * FROM `{$table}` LIMIT {$start}, 1000");
foreach ($result as $row) {
$row = array_map('addslashes', $row);
$sql = "INSERT INTO `{$table}` VALUES ('" . str_replace(array("\r","\n"),array('\r','\n'),implode("', '", $row)) . "');\n";
if(false === $this->write($sql)){
return false;
}
}
//还有更多数据
if($count > $start + 1000){
return array($start + 1000, $count);
}
}
//备份下一表
return 0;
}
public function import($start){
//还原数据
$db = Db::connect();
if($this->config['compress']){
$gz = gzopen($this->file[1], 'r');
$size = 0;
} else {
$size = filesize($this->file[1]);
$gz = fopen($this->file[1], 'r');
}
$sql = '';
if($start){
$this->config['compress'] ? gzseek($gz, $start) : fseek($gz, $start);
}
for($i = 0; $i < 1000; $i++){
$sql .= $this->config['compress'] ? gzgets($gz) : fgets($gz);
if(preg_match('/.*;$/', trim($sql))){
if(false !== $db->execute($sql)){
$start += strlen($sql);
} else {
return false;
}
$sql = '';
} elseif ($this->config['compress'] ? gzeof($gz) : feof($gz)) {
return 0;
}
}
return array($start, $size);
}
/**
* 析构方法,用于关闭文件资源
*/
public function __destruct(){
//$this->config['compress'] ? @gzclose($this->fp) : @fclose($this->fp);
}
}

View File

@@ -27,7 +27,7 @@ html, body {background-color: #fff; color: #636b6f; font-family: 'Raleway', sans
<div class="title m-b-md">
SentCMS网站管理系统
</div>
{:ad('index', [])}
<div class="links">
<a href="https://www.kancloud.cn/tensent/sentcms3/169624" target="_blank">文档</a>
<a href="https://www.tensent.cn" target="_blank">资讯</a>

View File

@@ -21,14 +21,14 @@
{volist name="list['pc']" id="item"}
<div class="col-sm-4 col-md-3">
<div class="thumbnail">
<img src="{$item['img']}" alt="{$item['name']}" class="img-rounded">
<img src="{$item['preview']}" alt="{$item['name']}" class="img-rounded">
<div class="caption">
<h4>{$item['name']}</h4>
<p class="text-right">
{if $pc == $item['id']}
<button class="btn btn-danger btn-block" disabled>已启用</button>
{else/}
<a href="{:url('admin/config/setthemes?name=pc&id='.$item['id'])}" class="btn btn-primary btn-block ajax-get">启用</a>
<a href="{:url('/admin/config/setthemes', ['name'=>'pc', 'id'=> $item['id']])}" class="btn btn-primary btn-block ajax-get">启用</a>
{/if}
</p>
</div>
@@ -42,14 +42,14 @@
{volist name="list['mobile']" id="item"}
<div class="col-sm-4 col-md-3">
<div class="thumbnail">
<img src="{$item['img']}" alt="{$item['name']}" class="img-rounded">
<img src="{$item['preview']}" alt="{$item['name']}" class="img-rounded">
<div class="caption">
<h4>{$item['name']}</h4>
<p class="text-right">
{if $mobile == $item['id']}
<button class="btn btn-danger btn-block" disabled>已启用</button>
{else/}
<a href="{:url('admin/config/setthemes?name=mobile&id='.$item['id'])}" class="btn btn-primary btn-block ajax-get">启用</a>
<a href="{:url('/admin/config/setthemes', ['name'=>'mobile', 'id'=> $item['id']])}" class="btn btn-primary btn-block ajax-get">启用</a>
{/if}
</p>
</div>

View File

@@ -8,12 +8,12 @@
</div>
<div class="pull-right">
<a id="export" class="btn btn-primary" href="javascript:;" autocomplete="off">立即备份</a>
<a id="optimize" class="btn btn-success" href="{:url('optimize')}">优化表</a>
<a id="repair" class="btn btn-warning" href="{:url('repair')}">修复表</a>
<a id="optimize" class="btn btn-success" href="{:url('/admin/database/optimize')}">优化表</a>
<a id="repair" class="btn btn-warning" href="{:url('/admin/database/repair')}">修复表</a>
</div>
</header>
<div class="main-box-body clearfix">
<form id="export-form" method="post" action="{:url('export')}">
<form id="export-form" method="post" action="{:url('/admin/database/export')}">
<div class="table-responsive clearfix">
<table class="table table-striped">
<thead>
@@ -39,9 +39,9 @@
<td>{$table.create_time}</td>
<td class="info">未备份</td>
<td class="action">
<a class="ajax-get no-refresh" href="{:url('optimize?tables='.$table['name'])}">优化表</a>
<a class="ajax-get no-refresh" href="{:url('/admin/database/optimize', ['tables' => $table['name']])}">优化表</a>
&nbsp;
<a class="ajax-get no-refresh" href="{:url('repair?tables='.$table['name'])}">修复表</a>
<a class="ajax-get no-refresh" href="{:url('/admin/database/repair', ['tables' => $table['name']])}">修复表</a>
</td>
</tr>
{/volist}

View File

@@ -29,16 +29,16 @@
<tbody>
{volist name="list" id="data"}
<tr>
<td>{$data.time|date='Ymd-His',###}</td>
<td>{$data.time}</td>
<td>{$data.part}</td>
<td>{$data.compress}</td>
<td>{$data.size|format_bytes}</td>
<td>{$key}</td>
<td>-</td>
<td class="action">
<a class="db-import" href="{:url('import?time='.$data['time'])}">还原</a>
<a class="db-import" href="{:url('/admin/database/import', ['time' => $data['time']])}">还原</a>
&nbsp;
<a class="ajax-get confirm" href="{:url('del?time='.$data['time'])}">删除</a>
<a class="ajax-get confirm" href="{:url('/admin/database/del', ['time' => $data['time']])}">删除</a>
</td>
</tr>
{/volist}

View File

@@ -9,8 +9,8 @@
<h2>{$meta_title}</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="{:url('add')}">新 增</a>
<button class="btn btn-danger ajax-post confirm" url="{:url('del')}" target-form="ids">删 除</button>
<a class="btn btn-primary" href="{:url('/admin/seo/add')}">新 增</a>
<button class="btn btn-danger ajax-post confirm" url="{:url('/admin/seo/del')}" target-form="ids">删 除</button>
</div>
</header>
<div class="main-box-body clearfix">
@@ -37,8 +37,8 @@
<td>{$item['sort']}</td>
<td>{$item['seo_title']}</td>
<td>
<a href="{:url('edit?id='.$item['id'])}">编辑</a>
<a href="{:url('del?id='.$item['id'])}" class="confirm ajax-get">删除</a>
<a href="{:url('/admin/seo/edit', ['id'=> $item['id']])}">编辑</a>
<a href="{:url('/admin/seo/del', ['id'=> $item['id']])}" class="confirm ajax-get">删除</a>
</td>
</tr>
{/volist}

View File

@@ -9,8 +9,8 @@
<h2>{$meta_title}</h2>
</div>
<div class="pull-right">
<a class="btn btn-primary" href="{:url('addrewrite')}">新 增</a>
<button class="btn btn-danger ajax-post confirm" url="{:url('delrewrite')}" target-form="ids">删 除</button>
<a class="btn btn-primary" href="{:url('/admin/seo/addrewrite')}">新 增</a>
<button class="btn btn-danger ajax-post confirm" url="{:url('/admin/seo/delrewrite')}" target-form="ids">删 除</button>
</div>
</header>
<div class="main-box-body clearfix">
@@ -33,8 +33,8 @@
<td>{$item['rule']}</td>
<td>{$item['url']}</td>
<td>
<a href="{:url('editrewrite?id='.$item['id'])}">编辑</a>
<a href="{:url('delrewrite?id='.$item['id'])}" class="confirm ajax-get">删除</a>
<a href="{:url('/admin/seo/editrewrite', ['id' => $item['id']])}">编辑</a>
<a href="{:url('/admin/seo/delrewrite', ['id' => $item['id']])}" class="confirm ajax-get">删除</a>
</td>
</tr>
{/volist}