mirror of https://gitee.com/karson/fastadmin.git
Compare commits
6 Commits
0265c0b8ad
...
211a54b4c3
| Author | SHA1 | Date |
|---|---|---|
|
|
211a54b4c3 | |
|
|
4e48b3a736 | |
|
|
6ceb59b9f1 | |
|
|
7754cf4c3c | |
|
|
d6ef94c573 | |
|
|
5595954d6d |
|
|
@ -36,7 +36,7 @@ module.exports = function (grunt) {
|
|||
var matches = content.match(pattern);
|
||||
if (matches) {
|
||||
if (type === 'js') {
|
||||
var data = matches[1].replaceAll(/(urlArgs|baseUrl):(.*)\n/gi, '');
|
||||
var data = matches[1].replace(/(urlArgs|baseUrl):[^\r\n]*[\r\n]*/gi, '');
|
||||
const parse = require('parse-config-file'), fs = require('fs');
|
||||
require('jsonminify');
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace app\admin\controller;
|
||||
|
||||
use app\admin\model\AdminLog;
|
||||
use app\common\controller\Backend;
|
||||
use app\common\exception\UploadException;
|
||||
use app\common\library\Upload;
|
||||
|
|
@ -73,6 +74,9 @@ class Ajax extends Backend
|
|||
//必须还原upload配置,否则分片及cdnurl函数计算错误
|
||||
Config::load(APP_PATH . 'extra/upload.php', 'upload');
|
||||
|
||||
//自定义日志标题
|
||||
AdminLog::setTitle(__('Upload'));
|
||||
|
||||
$chunkid = $this->request->post("chunkid");
|
||||
if ($chunkid) {
|
||||
if (!Config::get('upload.chunking')) {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ class Attachment extends Backend
|
|||
->order($sort, $order)
|
||||
->paginate($limit);
|
||||
|
||||
$cdnurl = preg_replace("/\/(\w+)\.php$/i", '', $this->request->root());
|
||||
$cdnurl = preg_replace("/\/(\w+)\.php$/i", '', $this->request->root(true));
|
||||
foreach ($list as $k => &$v) {
|
||||
$v['fullurl'] = ($v['storage'] == 'local' ? $cdnurl : $this->view->config['upload']['cdnurl']) . $v['url'];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ return [
|
|||
'All' => '全部',
|
||||
'Detail' => '详情',
|
||||
'Multi' => '批量更新',
|
||||
'Dragsort' => '排序',
|
||||
'Setting' => '配置',
|
||||
'Move' => '移动',
|
||||
'Name' => '名称',
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class AdminLog extends Model
|
|||
//忽略的链接正则列表
|
||||
protected static $ignoreRegex = [
|
||||
'/^(.*)\/(selectpage|index)$/i',
|
||||
'/^(.*)\/addon\/get_table_list$/i',
|
||||
];
|
||||
|
||||
public static function setTitle($title)
|
||||
|
|
@ -69,14 +70,7 @@ class AdminLog extends Model
|
|||
$content = self::getPureContent($content);
|
||||
}
|
||||
$title = $title ?: self::$title;
|
||||
if (!$title) {
|
||||
$title = [];
|
||||
$breadcrumb = Auth::instance()->getBreadcrumb($path);
|
||||
foreach ($breadcrumb as $k => $v) {
|
||||
$title[] = $v['title'];
|
||||
}
|
||||
$title = implode(' / ', $title);
|
||||
}
|
||||
$title = $title ?: implode(' / ', array_column(Auth::instance()->getBreadcrumb($path), 'title'));
|
||||
self::create([
|
||||
'title' => $title,
|
||||
'content' => !is_scalar($content) ? json_encode($content, JSON_UNESCAPED_UNICODE) : $content,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<title>{$title|default=''}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="referrer" content="never">
|
||||
<meta name="referrer" content="no-referrer">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
|
||||
<link rel="shortcut icon" href="__CDN__/assets/img/favicon.ico" />
|
||||
|
|
|
|||
|
|
@ -102,6 +102,11 @@ class Backend extends Controller
|
|||
*/
|
||||
protected $excludeFields = "";
|
||||
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
protected $dragsortFields = 'weigh';
|
||||
|
||||
/**
|
||||
* 导入文件首行类型
|
||||
* 支持comment/name
|
||||
|
|
|
|||
|
|
@ -133,52 +133,51 @@ class Auth
|
|||
*/
|
||||
public function register($username, $password, $email = '', $mobile = '', $extend = [])
|
||||
{
|
||||
// 检测用户名、昵称、邮箱、手机号是否存在
|
||||
if (User::getByUsername($username)) {
|
||||
$this->setError('Username already exist');
|
||||
return false;
|
||||
}
|
||||
if (User::getByNickname($username)) {
|
||||
$this->setError('Nickname already exist');
|
||||
return false;
|
||||
}
|
||||
if ($email && User::getByEmail($email)) {
|
||||
$this->setError('Email already exist');
|
||||
return false;
|
||||
}
|
||||
if ($mobile && User::getByMobile($mobile)) {
|
||||
$this->setError('Mobile already exist');
|
||||
return false;
|
||||
}
|
||||
|
||||
$ip = request()->ip();
|
||||
$time = time();
|
||||
|
||||
$data = [
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'email' => $email,
|
||||
'mobile' => $mobile,
|
||||
'level' => 1,
|
||||
'score' => 0,
|
||||
'avatar' => '',
|
||||
];
|
||||
$params = array_merge($data, [
|
||||
'nickname' => preg_match("/^1[3-9]{1}\d{9}$/", $username) ? substr_replace($username, '****', 3, 4) : $username,
|
||||
'salt' => Random::alnum(),
|
||||
'jointime' => $time,
|
||||
'joinip' => $ip,
|
||||
'logintime' => $time,
|
||||
'loginip' => $ip,
|
||||
'prevtime' => $time,
|
||||
'status' => 'normal'
|
||||
]);
|
||||
$params['password'] = $this->getEncryptPassword($password, $params['salt']);
|
||||
$params = array_merge($params, $extend);
|
||||
|
||||
//账号注册时需要开启事务,避免出现垃圾数据
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 检测用户名、邮箱、手机号是否存在
|
||||
if ($username && User::checkExists('username', $username)) {
|
||||
$this->setError('Username already exist');
|
||||
Db::rollback();
|
||||
return false;
|
||||
}
|
||||
if ($email && User::checkExists('email', $email)) {
|
||||
$this->setError('Email already exist');
|
||||
Db::rollback();
|
||||
return false;
|
||||
}
|
||||
if ($mobile && User::checkExists('mobile', $mobile)) {
|
||||
$this->setError('Mobile already exist');
|
||||
Db::rollback();
|
||||
return false;
|
||||
}
|
||||
|
||||
$ip = request()->ip();
|
||||
$time = time();
|
||||
|
||||
$data = [
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
'email' => $email,
|
||||
'mobile' => $mobile,
|
||||
'level' => 1,
|
||||
'score' => 0,
|
||||
'avatar' => '',
|
||||
];
|
||||
$params = array_merge($data, [
|
||||
'nickname' => preg_match("/^1[3-9]{1}\d{9}$/", $username) ? substr_replace($username, '****', 3, 4) : $username,
|
||||
'salt' => Random::alnum(),
|
||||
'jointime' => $time,
|
||||
'joinip' => $ip,
|
||||
'logintime' => $time,
|
||||
'loginip' => $ip,
|
||||
'prevtime' => $time,
|
||||
'status' => 'normal'
|
||||
]);
|
||||
$params['password'] = $this->getEncryptPassword($password, $params['salt']);
|
||||
$params = array_merge($params, $extend);
|
||||
|
||||
$user = User::create($params, true);
|
||||
|
||||
$this->_user = User::get($user->id);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,16 @@ class User extends Model
|
|||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断指定字段的值是否存在
|
||||
* @param string $field 字段名
|
||||
* @param string $value 字段值
|
||||
*/
|
||||
public static function checkExists($field, $value)
|
||||
{
|
||||
return self::lock(true)->where($field, $value)->find();
|
||||
}
|
||||
|
||||
/**
|
||||
* 变更会员余额
|
||||
* @param int $money 余额
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ return [
|
|||
'loginip_check' => true,
|
||||
//登录页默认背景图
|
||||
'login_background' => "",
|
||||
//是否启用简洁导航
|
||||
//是否启用简洁导航,如同时启用多级菜单导航,简洁导航将失效
|
||||
'simplenav' => false,
|
||||
//是否启用多级菜单导航
|
||||
'multiplenav' => false,
|
||||
|
|
|
|||
|
|
@ -224,9 +224,9 @@ class User extends Frontend
|
|||
//如果已经有账号则直接登录
|
||||
$ret = $this->auth->direct($user->id);
|
||||
} else {
|
||||
$ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
|
||||
//如果是手机号首次注册则直接设定为已验证
|
||||
$this->auth->getUser()->save(['verification' => ['email' => 0, 'mobile' => 1]]);
|
||||
$username = \fast\Random::username();
|
||||
$nickname = '用户' . substr($mobile, -4);
|
||||
$ret = $this->auth->register($username, Random::alnum(), '', $mobile, ['nickname' => $nickname, 'verification' => ['mobile' => 1]]);
|
||||
}
|
||||
if ($ret) {
|
||||
Sms::flush($mobile, 'mobilelogin');
|
||||
|
|
@ -321,6 +321,9 @@ class User extends Frontend
|
|||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 附件管理
|
||||
*/
|
||||
public function attachment()
|
||||
{
|
||||
//设置过滤方法
|
||||
|
|
@ -388,6 +391,9 @@ class User extends Frontend
|
|||
return $this->view->fetch();
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户协议
|
||||
*/
|
||||
public function agreement()
|
||||
{
|
||||
$this->view->assign('title', __('User agreement'));
|
||||
|
|
|
|||
|
|
@ -89,6 +89,15 @@ class Random
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机用户名
|
||||
* @return string
|
||||
*/
|
||||
public static function username(): string
|
||||
{
|
||||
return 'user_'.bin2hex(random_bytes(8)) . substr(uniqid(), -8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全球唯一标识
|
||||
* @return string
|
||||
|
|
|
|||
|
|
@ -18,11 +18,45 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
|||
exportTypes: ['json', 'xml', 'csv', 'txt', 'doc', 'excel'],
|
||||
exportOptions: {
|
||||
fileName: 'export_' + Moment().format("YYYY-MM-DD"),
|
||||
preventInjection: false,
|
||||
htmlContent: false,
|
||||
mso: {
|
||||
onMsoNumberFormat: function (cell, row, col) {
|
||||
return !isNaN($(cell).text()) ? '\\@' : '';
|
||||
},
|
||||
var text = $(cell).text().trim();
|
||||
return text !== '' && !isNaN(text) ? '\\@' : '';
|
||||
}
|
||||
},
|
||||
onCellHtmlData: function (cell, row, col, html) {
|
||||
var text = cell.text();
|
||||
|
||||
var path = location.pathname.match(/\/[^\/]+/)[0];
|
||||
path = path.indexOf(".php") > -1 ? path : '';
|
||||
if (cell.is("th")) {
|
||||
return text;
|
||||
} else if ($("input", cell).length > 0) {
|
||||
var inputArr = [];
|
||||
$("input", cell).each(function (key, item) {
|
||||
inputArr.push($(item).val());
|
||||
});
|
||||
return inputArr.join(",");
|
||||
} else if ($(">a", cell).length > 0) {
|
||||
var anchorArr = [];
|
||||
$(">a", cell).each(function (key, item) {
|
||||
if (html.match(/ajax\/icon\?suffix=/)) {
|
||||
anchorArr.push($(item).attr("href"));
|
||||
} else if ($(item).find("i.fa-toggle-on").length > 0) {
|
||||
anchorArr.push($(item).data("value"));
|
||||
} else {
|
||||
if ($(">img", item).length > 0 && !$.fn.bootstrapTable.defaults.exportOptions.htmlContent) {
|
||||
anchorArr.push($(">img", item).prop("src").replace(new RegExp(path, "g"), ''));
|
||||
} else {
|
||||
anchorArr.push($(item).html().replace(new RegExp(path, "g"), ''));
|
||||
}
|
||||
}
|
||||
});
|
||||
return anchorArr.join(",");
|
||||
} else {
|
||||
return html.replace(new RegExp(path, "g"), '');
|
||||
}
|
||||
},
|
||||
ignoreColumn: [0, 'operate'] //默认不导出第一列(checkbox)与操作(operate)列
|
||||
},
|
||||
|
|
@ -828,7 +862,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
|
|||
if (typeof this.disable !== "undefined") {
|
||||
disable = typeof this.disable === "function" ? this.disable.call(this, value, row, index) : this.disable;
|
||||
}
|
||||
return "<a href='javascript:;' data-toggle='tooltip' title='" + __('Click to toggle') + "' class='btn-change " + (disable ? 'btn disabled no-padding' : '') + "' data-index='" + index + "' data-id='"
|
||||
return "<a href='javascript:;' data-toggle='tooltip' data-value='" + value + "' title='" + __('Click to toggle') + "' class='btn-change " + (disable ? 'btn disabled no-padding' : '') + "' data-index='" + index + "' data-id='"
|
||||
+ row[pk] + "' " + (url ? "data-url='" + url + "'" : "") + (confirm ? "data-confirm='" + confirm + "'" : "") + " data-params='" + this.field + "=" + (value == yes ? no : yes) + "'><i class='fa fa-toggle-on text-success text-" + color + " " + (value == yes ? '' : 'fa-flip-horizontal text-gray') + " fa-2x'></i></a>";
|
||||
},
|
||||
url: function (value, row, index) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue