Merge branch 'develop' of gitee.com:karson/fastadmin into develop

pull/406/head
Karson 2022-05-27 15:30:18 +08:00
commit 378aad4409
12 changed files with 1280 additions and 1288 deletions

View File

@ -9,12 +9,16 @@ use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use think\Db;
use think\db\exception\BindParamException;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\DbException;
use think\exception\PDOException;
use think\exception\ValidateException;
use think\response\Json;
trait Backend
{
/**
* 排除前台提交过来的字段
* @param $params
@ -24,115 +28,114 @@ trait Backend
{
if (is_array($this->excludeFields)) {
foreach ($this->excludeFields as $field) {
if (key_exists($field, $params)) {
if (array_key_exists($field, $params)) {
unset($params[$field]);
}
}
} else {
if (key_exists($this->excludeFields, $params)) {
unset($params[$this->excludeFields]);
}
} else if (array_key_exists($this->excludeFields, $params)) {
unset($params[$this->excludeFields]);
}
return $params;
}
/**
* 查看
*
* @return string|Json
* @throws \think\Exception
* @throws DbException
*/
public function index()
{
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
//如果发送的来源是Selectpage则转发到Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->where($where)
->order($sort, $order)
->paginate($limit);
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
if (false === $this->request->isAjax()) {
return $this->view->fetch();
}
return $this->view->fetch();
//如果发送的来源是 Selectpage则转发到 Selectpage
if ($this->request->request('keyField')) {
return $this->selectpage();
}
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
$list = $this->model
->where($where)
->order($sort, $order)
->paginate($limit);
$result = ['total' => $list->total(), 'rows' => $list->items()];
return json($result);
}
/**
* 回收站
*
* @return string|Json
* @throws \think\Exception
*/
public function recyclebin()
{
//设置过滤方法
$this->request->filter(['strip_tags', 'trim']);
if ($this->request->isAjax()) {
list($where, $sort, $order, $offset, $limit) = $this->buildparams();
$list = $this->model
->onlyTrashed()
->where($where)
->order($sort, $order)
->paginate($limit);
$result = array("total" => $list->total(), "rows" => $list->items());
return json($result);
if (false === $this->request->isAjax()) {
return $this->view->fetch();
}
return $this->view->fetch();
[$where, $sort, $order, $offset, $limit] = $this->buildparams();
$list = $this->model
->onlyTrashed()
->where($where)
->order($sort, $order)
->paginate($limit);
$result = ['total' => $list->total(), 'rows' => $list->items()];
return json($result);
}
/**
* 添加
*
* @return string
* @throws \think\Exception
*/
public function add()
{
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
$params = $this->preExcludeFields($params);
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
$params[$this->dataLimitField] = $this->auth->id;
}
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
$this->model->validateFailException(true)->validate($validate);
}
$result = $this->model->allowField(true)->save($params);
Db::commit();
} catch (ValidateException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success();
} else {
$this->error(__('No rows were inserted'));
}
}
if (false === $this->request->isPost()) {
return $this->view->fetch();
}
$params = $this->request->post('row/a');
if (empty($params)) {
$this->error(__('Parameter %s can not be empty', ''));
}
return $this->view->fetch();
$params = $this->preExcludeFields($params);
if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
$params[$this->dataLimitField] = $this->auth->id;
}
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
$this->model->validateFailException()->validate($validate);
}
$result = $this->model->allowField(true)->save($params);
Db::commit();
} catch (ValidateException|PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result === false) {
$this->error(__('No rows were inserted'));
}
$this->success();
}
/**
* 编辑
*
* @param $ids
* @return string
* @throws DbException
* @throws \think\Exception
*/
public function edit($ids = null)
{
@ -141,137 +144,132 @@ trait Backend
$this->error(__('No Results were found'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
if (!in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
$this->error(__('You have no permission'));
}
if ($this->request->isPost()) {
$params = $this->request->post("row/a");
if ($params) {
$params = $this->preExcludeFields($params);
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
$row->validateFailException(true)->validate($validate);
}
$result = $row->allowField(true)->save($params);
Db::commit();
} catch (ValidateException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($result !== false) {
$this->success();
} else {
$this->error(__('No rows were updated'));
}
}
if (false === $this->request->isPost()) {
$this->view->assign('row', $row);
return $this->view->fetch();
}
$params = $this->request->post('row/a');
if (empty($params)) {
$this->error(__('Parameter %s can not be empty', ''));
}
$this->view->assign("row", $row);
return $this->view->fetch();
$params = $this->preExcludeFields($params);
$result = false;
Db::startTrans();
try {
//是否采用模型验证
if ($this->modelValidate) {
$name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
$validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
$row->validateFailException()->validate($validate);
}
$result = $row->allowField(true)->save($params);
Db::commit();
} catch (ValidateException|PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if (false === $result) {
$this->error(__('No rows were updated'));
}
$this->success();
}
/**
* 删除
*
* @param $ids
* @return void
* @throws DbException
* @throws DataNotFoundException
* @throws ModelNotFoundException
*/
public function del($ids = "")
public function del($ids = null)
{
if (!$this->request->isPost()) {
if (false === $this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$list = $this->model->where($pk, 'in', $ids)->select();
$count = 0;
Db::startTrans();
try {
foreach ($list as $k => $v) {
$count += $v->delete();
}
Db::commit();
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($count) {
$this->success();
} else {
$this->error(__('No rows were deleted'));
}
$ids = $ids ?: $this->request->post("ids");
if (empty($ids)) {
$this->error(__('Parameter %s can not be empty', 'ids'));
}
$this->error(__('Parameter %s can not be empty', 'ids'));
}
/**
* 真实删除
*/
public function destroy($ids = "")
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ? $ids : $this->request->post("ids");
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
if ($ids) {
$this->model->where($pk, 'in', $ids);
}
$list = $this->model->where($pk, 'in', $ids)->select();
$count = 0;
Db::startTrans();
try {
$list = $this->model->onlyTrashed()->select();
foreach ($list as $k => $v) {
$count += $v->delete(true);
foreach ($list as $item) {
$count += $item->delete();
}
Db::commit();
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
} catch (PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($count) {
$this->success();
} else {
$this->error(__('No rows were deleted'));
}
$this->error(__('Parameter %s can not be empty', 'ids'));
$this->error(__('No rows were deleted'));
}
/**
* 真实删除
*
* @param $ids
* @return void
*/
public function destroy($ids = null)
{
if (false === $this->request->isPost()) {
$this->error(__("Invalid parameters"));
}
$ids = $ids ?: $this->request->post('ids');
if (empty($ids)) {
$this->error(__('Parameter %s can not be empty', 'ids'));
}
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$this->model->where($pk, 'in', $ids);
$count = 0;
Db::startTrans();
try {
$list = $this->model->onlyTrashed()->select();
foreach ($list as $item) {
$count += $item->delete(true);
}
Db::commit();
} catch (PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($count) {
$this->success();
}
$this->error(__('No rows were deleted'));
}
/**
* 还原
*
* @param $ids
* @return void
*/
public function restore($ids = "")
public function restore($ids = null)
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
if (false === $this->request->isPost()) {
$this->error(__('Invalid parameters'));
}
$ids = $ids ? $ids : $this->request->post("ids");
$ids = $ids ?: $this->request->post('ids');
$pk = $this->model->getPk();
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
@ -284,14 +282,11 @@ trait Backend
Db::startTrans();
try {
$list = $this->model->onlyTrashed()->select();
foreach ($list as $index => $item) {
foreach ($list as $item) {
$count += $item->restore();
}
Db::commit();
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
} catch (PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
@ -303,52 +298,56 @@ trait Backend
/**
* 批量更新
*
* @param $ids
* @return void
*/
public function multi($ids = "")
public function multi($ids = null)
{
if (!$this->request->isPost()) {
$this->error(__("Invalid parameters"));
if (false === $this->request->isPost()) {
$this->error(__('Invalid parameters'));
}
$ids = $ids ? $ids : $this->request->post("ids");
if ($ids) {
if ($this->request->has('params')) {
parse_str($this->request->post("params"), $values);
$values = $this->auth->isSuperAdmin() ? $values : array_intersect_key($values, array_flip(is_array($this->multiFields) ? $this->multiFields : explode(',', $this->multiFields)));
if ($values) {
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$count = 0;
Db::startTrans();
try {
$list = $this->model->where($this->model->getPk(), 'in', $ids)->select();
foreach ($list as $index => $item) {
$count += $item->allowField(true)->isUpdate(true)->save($values);
}
Db::commit();
} catch (PDOException $e) {
Db::rollback();
$this->error($e->getMessage());
} catch (Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
if ($count) {
$this->success();
} else {
$this->error(__('No rows were updated'));
}
} else {
$this->error(__('You have no permission'));
}
$ids = $ids ?: $this->request->post('ids');
if (empty($ids)) {
$this->error(__('Parameter %s can not be empty', 'ids'));
}
if (false === $this->request->has('params')) {
$this->error(__('No rows were updated'));
}
parse_str($this->request->post('params'), $values);
$values = $this->auth->isSuperAdmin() ? $values : array_intersect_key($values, array_flip(is_array($this->multiFields) ? $this->multiFields : explode(',', $this->multiFields)));
if (empty($values)) {
$this->error(__('You have no permission'));
}
$adminIds = $this->getDataLimitAdminIds();
if (is_array($adminIds)) {
$this->model->where($this->dataLimitField, 'in', $adminIds);
}
$count = 0;
Db::startTrans();
try {
$list = $this->model->where($this->model->getPk(), 'in', $ids)->select();
foreach ($list as $item) {
$count += $item->allowField(true)->isUpdate(true)->save($values);
}
Db::commit();
} catch (PDOException|Exception $e) {
Db::rollback();
$this->error($e->getMessage());
}
$this->error(__('Parameter %s can not be empty', 'ids'));
if ($count) {
$this->success();
}
$this->error(__('No rows were updated'));
}
/**
* 导入
*
* @return void
* @throws PDOException
* @throws BindParamException
*/
protected function import()
{
@ -368,12 +367,12 @@ trait Backend
if ($ext === 'csv') {
$file = fopen($filePath, 'r');
$filePath = tempnam(sys_get_temp_dir(), 'import_csv');
$fp = fopen($filePath, "w");
$fp = fopen($filePath, 'w');
$n = 0;
while ($line = fgets($file)) {
$line = rtrim($line, "\n\r\0");
$encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
if ($encoding != 'utf-8') {
if ($encoding !== 'utf-8') {
$line = mb_convert_encoding($line, 'utf-8', $encoding);
}
if ($n == 0 || preg_match('/^".*"$/', $line)) {

View File

@ -7,7 +7,7 @@ return [
'Sign up successful' => '注册成功',
'Username can not be empty' => '用户名不能为空',
'Username must be 3 to 30 characters' => '用户名必须3-30个字符',
'Username must be 6 to 30 characters' => '用户名必须3-30个字符',
'Username must be 6 to 30 characters' => '用户名必须6-30个字符',
'Password can not be empty' => '密码不能为空',
'Password must be 6 to 30 characters' => '密码必须6-30个字符',
'Mobile is incorrect' => '手机格式不正确',

View File

@ -1,11 +1,11 @@
<!--@formatter:off-->
{if "[type]" == 'email'}
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_ems_correct')}, event=[event], email:#email)" />
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});digits;remote({:url('api/validate/check_ems_correct')}, event=[event], email:#email)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:url('api/ems/send')}" data-type="email" data-event="[event]">发送验证码</a>
</span>
{elseif "[type]" == 'mobile'/}
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_sms_correct')}, event=[event], mobile:#mobile)" />
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});digits;remote({:url('api/validate/check_sms_correct')}, event=[event], mobile:#mobile)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:url('api/sms/send')}" data-type="mobile" data-event="[event]">发送验证码</a>
</span>

View File

@ -69,7 +69,7 @@
<label for="captcha" class="control-label col-xs-12 col-sm-3">{:__('Captcha')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_ems_correct')}, event=resetpwd, email:#email)"/>
<input type="text" name="captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});digits;remote({:url('api/validate/check_ems_correct')}, event=resetpwd, email:#email)"/>
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-primary btn-captcha" data-url="{:url('api/ems/send')}" data-type="email" data-event="resetpwd">{:__('Send verification code')}</a>
</span>

View File

@ -121,7 +121,7 @@
<label class="control-label col-xs-12 col-sm-3">{:__('Captcha')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input type="text" name="captcha" id="email-captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_ems_correct')}, event=changeemail, email:#email)" />
<input type="text" name="captcha" id="email-captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});digits;remote({:url('api/validate/check_ems_correct')}, event=changeemail, email:#email)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:url('api/ems/send')}" data-type="email" data-event="changeemail">获取验证码</a>
</span>
@ -155,7 +155,7 @@
<label for="mobile-captcha" class="control-label col-xs-12 col-sm-3">{:__('Captcha')}:</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<input type="text" name="captcha" id="mobile-captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});integer[+];remote({:url('api/validate/check_sms_correct')}, event=changemobile, mobile:#mobile)" />
<input type="text" name="captcha" id="mobile-captcha" class="form-control" data-rule="required;length({$Think.config.captcha.length});digits;remote({:url('api/validate/check_sms_correct')}, event=changemobile, mobile:#mobile)" />
<span class="input-group-btn" style="padding:0;border:none;">
<a href="javascript:;" class="btn btn-info btn-captcha" data-url="{:url('api/sms/send')}" data-type="mobile" data-event="changemobile">获取验证码</a>
</span>

View File

@ -38,7 +38,7 @@
"repositories": [
{
"type": "git",
"url": "https://gitee.com/karson/framework"
"url": "https://gitee.com/fastadminnet/framework.git"
}
]
}

View File

@ -8,45 +8,45 @@ use ArrayAccess;
* 表单元素生成
* @class Form
* @package fast
* @method string token() static 生成Token
* @method string label(string $name, string $value = null, array $options = []) static label标签
* @method string input($type, $name, string $value = null, array $options = []) static 按类型生成文本框
* @method string text(string $name, string $value = null, array $options = []) static 普通文本框
* @method string password(string $name, array $options = []) static 密码文本框
* @method string hidden(string $name, string $value = null, array $options = []) static 隐藏文本框
* @method string email(string $name, string $value = null, array $options = []) static Email文本框
* @method string url(string $name, string $value = null, array $options = []) static URL文本框
* @method string file(string $name, array $options = []) static 文件上传组件
* @method string textarea(string $name, string $value = null, array $options = []) static 多行文本框
* @method string editor(string $name, string $value = null, array $options = []) static 富文本编辑器
* @method string select(string $name, array $list = [], string $selected = null, array $options = []) static 下拉列表组件
* @method string selects(string $name, array $list = [], string $selected = null, array $options = []) static 下拉列表组件(多选)
* @method string selectpicker(string $name, array $list = [], string $selected = null, array $options = []) static 下拉列表组件(友好)
* @method string selectpickers(string $name, array $list = [], string $selected = null, array $options = []) static 下拉列表组件(友好)(多选)
* @method string selectpage(string $name, string $value, string $url, string $field = null, string $primaryKey = null, array $options = []) static 动态下拉列表组件
* @method string selectpages(string $name, string $value, string $url, string $field = null, string $primaryKey = null, array $options = []) static 动态下拉列表组件(多选)
* @method string citypicker(string $name, string $value, array $options = []) static 城市选择组件
* @method string switcher(string $name, string $value, array $options = []) static 切换组件
* @method string datepicker(string $name, string $value, array $options = []) static 日期选择组件
* @method string timepicker(string $name, string $value, array $options = []) static 时间选择组件
* @method string datetimepicker(string $name, string $value, array $options = []) static 日期时间选择组件
* @method string daterange(string $name, string $value, array $options = []) static 日期区间组件
* @method string timerange(string $name, string $value, array $options = []) static 时间区间组件
* @method string datetimerange(string $name, string $value, array $options = []) static 日期时间区间组件
* @method string fieldlist(string $name, string $value, string $title = null, string $template = null, array $options = []) static 字段列表组件
* @method string cxselect(string $url, array $names = [], array $values = [], array $options = []) static 联动组件
* @method string selectRange(string $name, string $begin, string $end, string $selected = null, array $options = []) static 选择数字区间
* @method string selectYear(string $name, string $begin, string $end, string $selected = null, array $options = []) static 选择年
* @method string selectMonth(string $name, string $selected = null, array $options = [], string $format = '%m') static 选择月
* @method string checkbox(string $name, string $value = '1', string $checked = null, array $options = []) static 单个复选框
* @method string checkboxs(string $name, array $list = [], string $checked = null, array $options = []) static 一组复选框
* @method string radio(string $name, string $value = null, string $checked = null, array $options = [])) static 单个单选框
* @method string radios(string $name, array $list = [], string $checked = null, array $options = [])) static 一组单选框
* @method string image(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) static 上传图片组件
* @method string images(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) static 上传图片组件(多图)
* @method string upload(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) static 上传文件组件
* @method string uploads(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) static 上传文件组件(多文件)
* @method string button(string $value = null, array $options = []) static 表单button
* @method static string token() 生成Token
* @method static string label(string $name, string $value = null, array $options = []) label标签
* @method static string input($type, $name, string $value = null, array $options = []) 按类型生成文本框
* @method static string text(string $name, string $value = null, array $options = []) 普通文本框
* @method static string password(string $name, array $options = []) 密码文本框
* @method static string hidden(string $name, string $value = null, array $options = []) 隐藏文本框
* @method static string email(string $name, string $value = null, array $options = []) Email文本框
* @method static string url(string $name, string $value = null, array $options = []) URL文本框
* @method static string file(string $name, array $options = []) 文件上传组件
* @method static string textarea(string $name, string $value = null, array $options = []) 多行文本框
* @method static string editor(string $name, string $value = null, array $options = []) 富文本编辑器
* @method static string select(string $name, array $list = [], string $selected = null, array $options = []) 下拉列表组件
* @method static string selects(string $name, array $list = [], string $selected = null, array $options = []) 下拉列表组件(多选)
* @method static string selectpicker(string $name, array $list = [], string $selected = null, array $options = []) 下拉列表组件(友好)
* @method static string selectpickers(string $name, array $list = [], string $selected = null, array $options = []) 下拉列表组件(友好)(多选)
* @method static string selectpage(string $name, string $value, string $url, string $field = null, string $primaryKey = null, array $options = []) 动态下拉列表组件
* @method static string selectpages(string $name, string $value, string $url, string $field = null, string $primaryKey = null, array $options = []) 动态下拉列表组件(多选)
* @method static string citypicker(string $name, string $value, array $options = []) 城市选择组件
* @method static string switcher(string $name, string $value, array $options = []) 切换组件
* @method static string datepicker(string $name, string $value, array $options = []) 日期选择组件
* @method static string timepicker(string $name, string $value, array $options = []) 时间选择组件
* @method static string datetimepicker(string $name, string $value, array $options = []) 日期时间选择组件
* @method static string daterange(string $name, string $value, array $options = []) 日期区间组件
* @method static string timerange(string $name, string $value, array $options = []) 时间区间组件
* @method static string datetimerange(string $name, string $value, array $options = []) 日期时间区间组件
* @method static string fieldlist(string $name, string $value, string $title = null, string $template = null, array $options = []) 字段列表组件
* @method static string cxselect(string $url, array $names = [], array $values = [], array $options = []) 联动组件
* @method static string selectRange(string $name, string $begin, string $end, string $selected = null, array $options = []) 选择数字区间
* @method static string selectYear(string $name, string $begin, string $end, string $selected = null, array $options = []) 选择年
* @method static string selectMonth(string $name, string $selected = null, array $options = [], string $format = '%m') 选择月
* @method static string checkbox(string $name, string $value = '1', string $checked = null, array $options = []) 单个复选框
* @method static string checkboxs(string $name, array $list = [], string $checked = null, array $options = []) 一组复选框
* @method static string radio(string $name, string $value = null, string $checked = null, array $options = [])) 单个单选框
* @method static string radios(string $name, array $list = [], string $checked = null, array $options = [])) 一组单选框
* @method static string image(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) 上传图片组件
* @method static string images(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) 上传图片组件(多图)
* @method static string upload(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) 上传文件组件
* @method static string uploads(string $name = null, string $value, array $inputAttr = [], array $uploadAttr = [], array $chooseAttr = [], array $previewAttr = []) 上传文件组件(多文件)
* @method static string button(string $value = null, array $options = []) 表单button
*/
class Form
{

View File

@ -68,13 +68,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
});
});
//当表格分页变更时
table.on('page-change.bs.table', function (e, page, pagesize) {
if (!isNaN(pagesize)) {
localStorage.setItem("pagesize-addon", pagesize);
}
});
Template.helper("Moment", Moment);
Template.helper("addons", Config['addons']);
@ -90,6 +83,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
// 初始化表格
table.bootstrapTable({
url: $.fn.bootstrapTable.defaults.extend.index_url,
pageSize: 50,
queryParams: function (params) {
var userinfo = Controller.api.userinfo.get();
$.extend(params, {
@ -181,7 +175,6 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function
commonSearch: true,
searchFormVisible: true,
searchFormTemplate: 'searchformtpl',
pageSize: localStorage.getItem('pagesize-addon') || 50,
});
// 为表格绑定事件

File diff suppressed because it is too large Load Diff

View File

@ -11607,7 +11607,7 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
},
ignoreColumn: [0, 'operate'] //默认不导出第一列(checkbox)与操作(operate)列
},
pageSize: localStorage.getItem("pagesize") || 10,
pageSize: localStorage.getItem('page-size') || 10,
pageList: [10, 15, 20, 25, 50, 'All'],
pagination: true,
clickToSelect: true, //是否启用点击选中
@ -11771,12 +11771,6 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
table.on('refresh.bs.table', function (e, settings, data) {
$(Table.config.refreshbtn, toolbar).find(".fa").addClass("fa-spin");
});
//当表格分页变更时
table.on('page-change.bs.table', function (e, page, pagesize) {
if (!isNaN(pagesize)) {
localStorage.setItem("pagesize", pagesize);
}
});
//当执行搜索时
table.on('search.bs.table common-search.bs.table', function (e, settings, data) {
table.trigger("uncheckbox");
@ -12121,6 +12115,12 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
Table.list[id] = table;
return table;
},
// 设置全局分页的单页显示数
pageSize: function (pageSize) {
if (!isNaN(pageSize)) {
localStorage.setItem('page-size', pageSize);
}
},
// 批量操作请求
multi: function (action, ids, table, element) {
var options = table.bootstrapTable('getOptions');
@ -12563,387 +12563,387 @@ define('table',['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstr
return Table;
});
// jQuery List DragSort v0.5.2
// Website: http://dragsort.codeplex.com/
// License: http://dragsort.codeplex.com/license
(function($) {
$.fn.dragsort = function(options) {
if (options == "destroy") {
$(this.selector).trigger("dragsort-uninit");
return;
}
var opts = $.extend({}, $.fn.dragsort.defaults, options);
var lists = [];
var list = null, lastPos = null;
this.each(function(i, cont) {
//if list container is table, the browser automatically wraps rows in tbody if not specified so change list container to tbody so that children returns rows as user expected
if ($(cont).is("table") && $(cont).children().size() == 1 && $(cont).children().is("tbody"))
cont = $(cont).children().get(0);
var newList = {
draggedItem: null,
placeHolderItem: null,
pos: null,
offset: null,
offsetLimit: null,
scroll: null,
container: cont,
init: function() {
//set options to default values if not set
opts.tagName = opts.tagName == "" ? ($(this.container).children().size() == 0 ? "li" : $(this.container).children().get(0).tagName.toLowerCase()) : opts.tagName;
if (opts.itemSelector == "")
opts.itemSelector = opts.tagName;
if (opts.dragSelector == "")
opts.dragSelector = opts.tagName;
if (opts.placeHolderTemplate == "")
opts.placeHolderTemplate = "<" + opts.tagName + ">&nbsp;</" + opts.tagName + ">";
//listidx allows reference back to correct list variable instance
$(this.container).attr("data-listidx", i).mousedown(this.grabItem).bind("dragsort-uninit", this.uninit);
this.styleDragHandlers(true);
},
uninit: function() {
var list = lists[$(this).attr("data-listidx")];
$(list.container).unbind("mousedown", list.grabItem).unbind("dragsort-uninit");
list.styleDragHandlers(false);
},
getItems: function() {
return $(this.container).children(opts.itemSelector);
},
styleDragHandlers: function(cursor) {
this.getItems().map(function() { return $(this).is(opts.dragSelector) ? this : $(this).find(opts.dragSelector).get(); }).css("cursor", cursor ? "pointer" : "");
},
grabItem: function(e) {
var list = lists[$(this).attr("data-listidx")];
var item = $(e.target).closest("[data-listidx] > " + opts.tagName).get(0);
var insideMoveableItem = list.getItems().filter(function() { return this == item; }).size() > 0;
//if not left click or if clicked on excluded element (e.g. text box) or not a moveable list item return
if (e.which != 1 || $(e.target).is(opts.dragSelectorExclude) || $(e.target).closest(opts.dragSelectorExclude).size() > 0 || !insideMoveableItem)
return;
//prevents selection, stops issue on Fx where dragging hyperlink doesn't work and on IE where it triggers mousemove even though mouse hasn't moved,
//does also stop being able to click text boxes hence dragging on text boxes by default is disabled in dragSelectorExclude
//e.preventDefault();
//change cursor to move while dragging
var dragHandle = e.target;
while (!$(dragHandle).is(opts.dragSelector)) {
if (dragHandle == this) return;
dragHandle = dragHandle.parentNode;
}
$(dragHandle).attr("data-cursor", $(dragHandle).css("cursor"));
$(dragHandle).css("cursor", "move");
//on mousedown wait for movement of mouse before triggering dragsort script (dragStart) to allow clicking of hyperlinks to work
var listElem = this;
var trigger = function() {
list.dragStart.call(listElem, e);
$(list.container).unbind("mousemove", trigger);
};
$(list.container).mousemove(trigger).mouseup(function() { $(list.container).unbind("mousemove", trigger); $(dragHandle).css("cursor", $(dragHandle).attr("data-cursor")); });
},
dragStart: function(e) {
if (list != null && list.draggedItem != null)
list.dropItem();
list = lists[$(this).attr("data-listidx")];
list.draggedItem = $(e.target).closest("[data-listidx] > " + opts.tagName)
//record current position so on dragend we know if the dragged item changed position or not, not using getItems to allow dragsort to restore dragged item to original location in relation to fixed items
list.draggedItem.attr("data-origpos", $(this).attr("data-listidx") + "-" + $(list.container).children().index(list.draggedItem));
//calculate mouse offset relative to draggedItem
var mt = parseInt(list.draggedItem.css("marginTop"));
var ml = parseInt(list.draggedItem.css("marginLeft"));
list.offset = list.draggedItem.offset();
list.offset.top = e.pageY - list.offset.top + (isNaN(mt) ? 0 : mt) - 1;
list.offset.left = e.pageX - list.offset.left + (isNaN(ml) ? 0 : ml) - 1;
//calculate box the dragged item can't be dragged outside of
if (!opts.dragBetween) {
var containerHeight = $(list.container).outerHeight() == 0 ? Math.max(1, Math.round(0.5 + list.getItems().size() * list.draggedItem.outerWidth() / $(list.container).outerWidth())) * list.draggedItem.outerHeight() : $(list.container).outerHeight();
list.offsetLimit = $(list.container).offset();
list.offsetLimit.right = list.offsetLimit.left + $(list.container).outerWidth() - list.draggedItem.outerWidth();
list.offsetLimit.bottom = list.offsetLimit.top + containerHeight - list.draggedItem.outerHeight();
}
//create placeholder item
var h = list.draggedItem.height();
var w = list.draggedItem.width();
if (opts.tagName == "tr") {
list.draggedItem.children().each(function() { $(this).width($(this).width()); });
list.placeHolderItem = list.draggedItem.clone().attr("data-placeholder", true);
list.draggedItem.after(list.placeHolderItem);
//list.placeHolderItem.children().each(function() { $(this).css({ borderWidth:0, width: $(this).width() + 1, height: $(this).height() + 1 }).html("&nbsp;"); });
list.placeHolderItem.children().each(function() { $(this).html("&nbsp;"); });
} else {
list.draggedItem.after(opts.placeHolderTemplate);
list.placeHolderItem = list.draggedItem.next().css({ height: h, width: w }).attr("data-placeholder", true);
}
if (opts.tagName == "td") {
var listTable = list.draggedItem.closest("table").get(0);
$("<table id='" + listTable.id + "' style='border-width: 0px;' class='dragSortItem " + listTable.className + "'><tr></tr></table>").appendTo("body").children().append(list.draggedItem);
}
//style draggedItem while dragging
var orig = list.draggedItem.attr("style");
list.draggedItem.attr("data-origstyle", orig ? orig : "");
list.draggedItem.css({ position: "absolute", opacity: 0.8, "z-index": 999, height: h, width: w });
//auto-scroll setup
list.scroll = { moveX: 0, moveY: 0, maxX: $(document).width() - $(window).width(), maxY: $(document).height() - $(window).height() };
list.scroll.scrollY = window.setInterval(function() {
if (opts.scrollContainer != window) {
$(opts.scrollContainer).scrollTop($(opts.scrollContainer).scrollTop() + list.scroll.moveY);
return;
}
var t = $(opts.scrollContainer).scrollTop();
if (list.scroll.moveY > 0 && t < list.scroll.maxY || list.scroll.moveY < 0 && t > 0) {
$(opts.scrollContainer).scrollTop(t + list.scroll.moveY);
list.draggedItem.css("top", list.draggedItem.offset().top + list.scroll.moveY + 1);
}
}, 10);
list.scroll.scrollX = window.setInterval(function() {
if (opts.scrollContainer != window) {
$(opts.scrollContainer).scrollLeft($(opts.scrollContainer).scrollLeft() + list.scroll.moveX);
return;
}
var l = $(opts.scrollContainer).scrollLeft();
if (list.scroll.moveX > 0 && l < list.scroll.maxX || list.scroll.moveX < 0 && l > 0) {
$(opts.scrollContainer).scrollLeft(l + list.scroll.moveX);
list.draggedItem.css("left", list.draggedItem.offset().left + list.scroll.moveX + 1);
}
}, 10);
//misc
$(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
list.setPos(e.pageX, e.pageY);
$(document).bind("mousemove", list.swapItems);
$(document).bind("mouseup", list.dropItem);
if (opts.scrollContainer != window)
$(window).bind("wheel", list.wheel);
},
//set position of draggedItem
setPos: function(x, y) {
//remove mouse offset so mouse cursor remains in same place on draggedItem instead of top left corner
var top = y - this.offset.top;
var left = x - this.offset.left;
//limit top, left to within box draggedItem can't be dragged outside of
if (!opts.dragBetween) {
top = Math.min(this.offsetLimit.bottom, Math.max(top, this.offsetLimit.top));
left = Math.min(this.offsetLimit.right, Math.max(left, this.offsetLimit.left));
}
//adjust top & left calculations to parent offset
var parent = this.draggedItem.offsetParent().not("body").offset(); //offsetParent returns body even when it's static, if not static offset is only factoring margin
if (parent != null) {
top -= parent.top;
left -= parent.left;
}
//set x or y auto-scroll amount
if (opts.scrollContainer == window) {
y -= $(window).scrollTop();
x -= $(window).scrollLeft();
y = Math.max(0, y - $(window).height() + 5) + Math.min(0, y - 5);
x = Math.max(0, x - $(window).width() + 5) + Math.min(0, x - 5);
} else {
var cont = $(opts.scrollContainer);
var offset = cont.offset();
y = Math.max(0, y - cont.height() - offset.top) + Math.min(0, y - offset.top);
x = Math.max(0, x - cont.width() - offset.left) + Math.min(0, x - offset.left);
}
list.scroll.moveX = x == 0 ? 0 : x * opts.scrollSpeed / Math.abs(x);
list.scroll.moveY = y == 0 ? 0 : y * opts.scrollSpeed / Math.abs(y);
//move draggedItem to new mouse cursor location
this.draggedItem.css({ top: top, left: left });
},
//if scroll container is a div allow mouse wheel to scroll div instead of window when mouse is hovering over
wheel: function(e) {
if (list && opts.scrollContainer != window) {
var cont = $(opts.scrollContainer);
var offset = cont.offset();
e = e.originalEvent;
if (e.clientX > offset.left && e.clientX < offset.left + cont.width() && e.clientY > offset.top && e.clientY < offset.top + cont.height()) {
var deltaY = (e.deltaMode == 0 ? 1 : 10) * e.deltaY;
cont.scrollTop(cont.scrollTop() + deltaY);
e.preventDefault();
}
}
},
//build a table recording all the positions of the moveable list items
buildPositionTable: function() {
var pos = [];
this.getItems().not([list.draggedItem[0], list.placeHolderItem[0]]).each(function(i) {
var loc = $(this).offset();
loc.right = loc.left + $(this).outerWidth();
loc.bottom = loc.top + $(this).outerHeight();
loc.elm = this;
pos[i] = loc;
});
this.pos = pos;
},
dropItem: function() {
if (list.draggedItem == null)
return;
//list.draggedItem.attr("style", "") doesn't work on IE8 and jQuery 1.5 or lower
//list.draggedItem.removeAttr("style") doesn't work on chrome and jQuery 1.6 (works jQuery 1.5 or lower)
var orig = list.draggedItem.attr("data-origstyle");
list.draggedItem.attr("style", orig);
if (orig == "")
list.draggedItem.removeAttr("style");
list.draggedItem.removeAttr("data-origstyle");
list.styleDragHandlers(true);
list.placeHolderItem.before(list.draggedItem);
list.placeHolderItem.remove();
$("[data-droptarget], .dragSortItem").remove();
window.clearInterval(list.scroll.scrollY);
window.clearInterval(list.scroll.scrollX);
//if position changed call dragEnd
if (list.draggedItem.attr("data-origpos") != $(lists).index(list) + "-" + $(list.container).children().index(list.draggedItem))
if (opts.dragEnd.apply(list.draggedItem) == false) { //if dragEnd returns false revert order
var pos = list.draggedItem.attr("data-origpos").split('-');
var nextItem = $(lists[pos[0]].container).children().not(list.draggedItem).eq(pos[1]);
if (nextItem.size() > 0)
nextItem.before(list.draggedItem);
else if (pos[1] == 0) //was the only item in list
$(lists[pos[0]].container).prepend(list.draggedItem);
else //was the last item in list
$(lists[pos[0]].container).append(list.draggedItem);
}
list.draggedItem.removeAttr("data-origpos");
list.draggedItem = null;
$(document).unbind("mousemove", list.swapItems);
$(document).unbind("mouseup", list.dropItem);
if (opts.scrollContainer != window)
$(window).unbind("wheel", list.wheel);
return false;
},
//swap the draggedItem (represented visually by placeholder) with the list item the it has been dragged on top of
swapItems: function(e) {
if (list.draggedItem == null)
return false;
//move draggedItem to mouse location
list.setPos(e.pageX, e.pageY);
//retrieve list and item position mouse cursor is over
var ei = list.findPos(e.pageX, e.pageY);
var nlist = list;
for (var i = 0; ei == -1 && opts.dragBetween && i < lists.length; i++) {
ei = lists[i].findPos(e.pageX, e.pageY);
nlist = lists[i];
}
//if not over another moveable list item return
if (ei == -1)
return false;
//save fixed items locations
var children = function() { return $(nlist.container).children().not(nlist.draggedItem); };
var fixed = children().not(opts.itemSelector).each(function(i) { this.idx = children().index(this); });
//if moving draggedItem up or left place placeHolder before list item the dragged item is hovering over otherwise place it after
if (lastPos == null || lastPos.top > list.draggedItem.offset().top || lastPos.left > list.draggedItem.offset().left)
$(nlist.pos[ei].elm).before(list.placeHolderItem);
else
$(nlist.pos[ei].elm).after(list.placeHolderItem);
//restore fixed items location
fixed.each(function() {
var elm = children().eq(this.idx).get(0);
if (this != elm && children().index(this) < this.idx)
$(this).insertAfter(elm);
else if (this != elm)
$(this).insertBefore(elm);
});
//misc
$(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
lastPos = list.draggedItem.offset();
return false;
},
//returns the index of the list item the mouse is over
findPos: function(x, y) {
for (var i = 0; i < this.pos.length; i++) {
if (this.pos[i].left < x && this.pos[i].right > x && this.pos[i].top < y && this.pos[i].bottom > y)
return i;
}
return -1;
},
//create drop targets which are placeholders at the end of other lists to allow dragging straight to the last position
createDropTargets: function() {
if (!opts.dragBetween)
return;
$(lists).each(function() {
var ph = $(this.container).find("[data-placeholder]");
var dt = $(this.container).find("[data-droptarget]");
if (ph.size() > 0 && dt.size() > 0)
dt.remove();
else if (ph.size() == 0 && dt.size() == 0) {
if (opts.tagName == "td")
$(opts.placeHolderTemplate).attr("data-droptarget", true).appendTo(this.container);
else
//list.placeHolderItem.clone().removeAttr("data-placeholder") crashes in IE7 and jquery 1.5.1 (doesn't in jquery 1.4.2 or IE8)
$(this.container).append(list.placeHolderItem.removeAttr("data-placeholder").clone().attr("data-droptarget", true));
list.placeHolderItem.attr("data-placeholder", true);
}
});
}
};
newList.init();
lists.push(newList);
});
return this;
};
$.fn.dragsort.defaults = {
tagName:"",
itemSelector: "",
dragSelector: "",
dragSelectorExclude: "input, textarea",
dragEnd: function() { },
dragBetween: false,
placeHolderTemplate: "",
scrollContainer: window,
scrollSpeed: 5
};
})(jQuery);
// jQuery List DragSort v0.5.2
// Website: http://dragsort.codeplex.com/
// License: http://dragsort.codeplex.com/license
(function($) {
$.fn.dragsort = function(options) {
if (options == "destroy") {
$(this.selector).trigger("dragsort-uninit");
return;
}
var opts = $.extend({}, $.fn.dragsort.defaults, options);
var lists = [];
var list = null, lastPos = null;
this.each(function(i, cont) {
//if list container is table, the browser automatically wraps rows in tbody if not specified so change list container to tbody so that children returns rows as user expected
if ($(cont).is("table") && $(cont).children().size() == 1 && $(cont).children().is("tbody"))
cont = $(cont).children().get(0);
var newList = {
draggedItem: null,
placeHolderItem: null,
pos: null,
offset: null,
offsetLimit: null,
scroll: null,
container: cont,
init: function() {
//set options to default values if not set
opts.tagName = opts.tagName == "" ? ($(this.container).children().size() == 0 ? "li" : $(this.container).children().get(0).tagName.toLowerCase()) : opts.tagName;
if (opts.itemSelector == "")
opts.itemSelector = opts.tagName;
if (opts.dragSelector == "")
opts.dragSelector = opts.tagName;
if (opts.placeHolderTemplate == "")
opts.placeHolderTemplate = "<" + opts.tagName + ">&nbsp;</" + opts.tagName + ">";
//listidx allows reference back to correct list variable instance
$(this.container).attr("data-listidx", i).mousedown(this.grabItem).bind("dragsort-uninit", this.uninit);
this.styleDragHandlers(true);
},
uninit: function() {
var list = lists[$(this).attr("data-listidx")];
$(list.container).unbind("mousedown", list.grabItem).unbind("dragsort-uninit");
list.styleDragHandlers(false);
},
getItems: function() {
return $(this.container).children(opts.itemSelector);
},
styleDragHandlers: function(cursor) {
this.getItems().map(function() { return $(this).is(opts.dragSelector) ? this : $(this).find(opts.dragSelector).get(); }).css("cursor", cursor ? "pointer" : "");
},
grabItem: function(e) {
var list = lists[$(this).attr("data-listidx")];
var item = $(e.target).closest("[data-listidx] > " + opts.tagName).get(0);
var insideMoveableItem = list.getItems().filter(function() { return this == item; }).size() > 0;
//if not left click or if clicked on excluded element (e.g. text box) or not a moveable list item return
if (e.which != 1 || $(e.target).is(opts.dragSelectorExclude) || $(e.target).closest(opts.dragSelectorExclude).size() > 0 || !insideMoveableItem)
return;
//prevents selection, stops issue on Fx where dragging hyperlink doesn't work and on IE where it triggers mousemove even though mouse hasn't moved,
//does also stop being able to click text boxes hence dragging on text boxes by default is disabled in dragSelectorExclude
//e.preventDefault();
//change cursor to move while dragging
var dragHandle = e.target;
while (!$(dragHandle).is(opts.dragSelector)) {
if (dragHandle == this) return;
dragHandle = dragHandle.parentNode;
}
$(dragHandle).attr("data-cursor", $(dragHandle).css("cursor"));
$(dragHandle).css("cursor", "move");
//on mousedown wait for movement of mouse before triggering dragsort script (dragStart) to allow clicking of hyperlinks to work
var listElem = this;
var trigger = function() {
list.dragStart.call(listElem, e);
$(list.container).unbind("mousemove", trigger);
};
$(list.container).mousemove(trigger).mouseup(function() { $(list.container).unbind("mousemove", trigger); $(dragHandle).css("cursor", $(dragHandle).attr("data-cursor")); });
},
dragStart: function(e) {
if (list != null && list.draggedItem != null)
list.dropItem();
list = lists[$(this).attr("data-listidx")];
list.draggedItem = $(e.target).closest("[data-listidx] > " + opts.tagName)
//record current position so on dragend we know if the dragged item changed position or not, not using getItems to allow dragsort to restore dragged item to original location in relation to fixed items
list.draggedItem.attr("data-origpos", $(this).attr("data-listidx") + "-" + $(list.container).children().index(list.draggedItem));
//calculate mouse offset relative to draggedItem
var mt = parseInt(list.draggedItem.css("marginTop"));
var ml = parseInt(list.draggedItem.css("marginLeft"));
list.offset = list.draggedItem.offset();
list.offset.top = e.pageY - list.offset.top + (isNaN(mt) ? 0 : mt) - 1;
list.offset.left = e.pageX - list.offset.left + (isNaN(ml) ? 0 : ml) - 1;
//calculate box the dragged item can't be dragged outside of
if (!opts.dragBetween) {
var containerHeight = $(list.container).outerHeight() == 0 ? Math.max(1, Math.round(0.5 + list.getItems().size() * list.draggedItem.outerWidth() / $(list.container).outerWidth())) * list.draggedItem.outerHeight() : $(list.container).outerHeight();
list.offsetLimit = $(list.container).offset();
list.offsetLimit.right = list.offsetLimit.left + $(list.container).outerWidth() - list.draggedItem.outerWidth();
list.offsetLimit.bottom = list.offsetLimit.top + containerHeight - list.draggedItem.outerHeight();
}
//create placeholder item
var h = list.draggedItem.height();
var w = list.draggedItem.width();
if (opts.tagName == "tr") {
list.draggedItem.children().each(function() { $(this).width($(this).width()); });
list.placeHolderItem = list.draggedItem.clone().attr("data-placeholder", true);
list.draggedItem.after(list.placeHolderItem);
//list.placeHolderItem.children().each(function() { $(this).css({ borderWidth:0, width: $(this).width() + 1, height: $(this).height() + 1 }).html("&nbsp;"); });
list.placeHolderItem.children().each(function() { $(this).html("&nbsp;"); });
} else {
list.draggedItem.after(opts.placeHolderTemplate);
list.placeHolderItem = list.draggedItem.next().css({ height: h, width: w }).attr("data-placeholder", true);
}
if (opts.tagName == "td") {
var listTable = list.draggedItem.closest("table").get(0);
$("<table id='" + listTable.id + "' style='border-width: 0px;' class='dragSortItem " + listTable.className + "'><tr></tr></table>").appendTo("body").children().append(list.draggedItem);
}
//style draggedItem while dragging
var orig = list.draggedItem.attr("style");
list.draggedItem.attr("data-origstyle", orig ? orig : "");
list.draggedItem.css({ position: "absolute", opacity: 0.8, "z-index": 999, height: h, width: w });
//auto-scroll setup
list.scroll = { moveX: 0, moveY: 0, maxX: $(document).width() - $(window).width(), maxY: $(document).height() - $(window).height() };
list.scroll.scrollY = window.setInterval(function() {
if (opts.scrollContainer != window) {
$(opts.scrollContainer).scrollTop($(opts.scrollContainer).scrollTop() + list.scroll.moveY);
return;
}
var t = $(opts.scrollContainer).scrollTop();
if (list.scroll.moveY > 0 && t < list.scroll.maxY || list.scroll.moveY < 0 && t > 0) {
$(opts.scrollContainer).scrollTop(t + list.scroll.moveY);
list.draggedItem.css("top", list.draggedItem.offset().top + list.scroll.moveY + 1);
}
}, 10);
list.scroll.scrollX = window.setInterval(function() {
if (opts.scrollContainer != window) {
$(opts.scrollContainer).scrollLeft($(opts.scrollContainer).scrollLeft() + list.scroll.moveX);
return;
}
var l = $(opts.scrollContainer).scrollLeft();
if (list.scroll.moveX > 0 && l < list.scroll.maxX || list.scroll.moveX < 0 && l > 0) {
$(opts.scrollContainer).scrollLeft(l + list.scroll.moveX);
list.draggedItem.css("left", list.draggedItem.offset().left + list.scroll.moveX + 1);
}
}, 10);
//misc
$(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
list.setPos(e.pageX, e.pageY);
$(document).bind("mousemove", list.swapItems);
$(document).bind("mouseup", list.dropItem);
if (opts.scrollContainer != window)
$(window).bind("wheel", list.wheel);
},
//set position of draggedItem
setPos: function(x, y) {
//remove mouse offset so mouse cursor remains in same place on draggedItem instead of top left corner
var top = y - this.offset.top;
var left = x - this.offset.left;
//limit top, left to within box draggedItem can't be dragged outside of
if (!opts.dragBetween) {
top = Math.min(this.offsetLimit.bottom, Math.max(top, this.offsetLimit.top));
left = Math.min(this.offsetLimit.right, Math.max(left, this.offsetLimit.left));
}
//adjust top & left calculations to parent offset
var parent = this.draggedItem.offsetParent().not("body").offset(); //offsetParent returns body even when it's static, if not static offset is only factoring margin
if (parent != null) {
top -= parent.top;
left -= parent.left;
}
//set x or y auto-scroll amount
if (opts.scrollContainer == window) {
y -= $(window).scrollTop();
x -= $(window).scrollLeft();
y = Math.max(0, y - $(window).height() + 5) + Math.min(0, y - 5);
x = Math.max(0, x - $(window).width() + 5) + Math.min(0, x - 5);
} else {
var cont = $(opts.scrollContainer);
var offset = cont.offset();
y = Math.max(0, y - cont.height() - offset.top) + Math.min(0, y - offset.top);
x = Math.max(0, x - cont.width() - offset.left) + Math.min(0, x - offset.left);
}
list.scroll.moveX = x == 0 ? 0 : x * opts.scrollSpeed / Math.abs(x);
list.scroll.moveY = y == 0 ? 0 : y * opts.scrollSpeed / Math.abs(y);
//move draggedItem to new mouse cursor location
this.draggedItem.css({ top: top, left: left });
},
//if scroll container is a div allow mouse wheel to scroll div instead of window when mouse is hovering over
wheel: function(e) {
if (list && opts.scrollContainer != window) {
var cont = $(opts.scrollContainer);
var offset = cont.offset();
e = e.originalEvent;
if (e.clientX > offset.left && e.clientX < offset.left + cont.width() && e.clientY > offset.top && e.clientY < offset.top + cont.height()) {
var deltaY = (e.deltaMode == 0 ? 1 : 10) * e.deltaY;
cont.scrollTop(cont.scrollTop() + deltaY);
e.preventDefault();
}
}
},
//build a table recording all the positions of the moveable list items
buildPositionTable: function() {
var pos = [];
this.getItems().not([list.draggedItem[0], list.placeHolderItem[0]]).each(function(i) {
var loc = $(this).offset();
loc.right = loc.left + $(this).outerWidth();
loc.bottom = loc.top + $(this).outerHeight();
loc.elm = this;
pos[i] = loc;
});
this.pos = pos;
},
dropItem: function() {
if (list.draggedItem == null)
return;
//list.draggedItem.attr("style", "") doesn't work on IE8 and jQuery 1.5 or lower
//list.draggedItem.removeAttr("style") doesn't work on chrome and jQuery 1.6 (works jQuery 1.5 or lower)
var orig = list.draggedItem.attr("data-origstyle");
list.draggedItem.attr("style", orig);
if (orig == "")
list.draggedItem.removeAttr("style");
list.draggedItem.removeAttr("data-origstyle");
list.styleDragHandlers(true);
list.placeHolderItem.before(list.draggedItem);
list.placeHolderItem.remove();
$("[data-droptarget], .dragSortItem").remove();
window.clearInterval(list.scroll.scrollY);
window.clearInterval(list.scroll.scrollX);
//if position changed call dragEnd
if (list.draggedItem.attr("data-origpos") != $(lists).index(list) + "-" + $(list.container).children().index(list.draggedItem))
if (opts.dragEnd.apply(list.draggedItem) == false) { //if dragEnd returns false revert order
var pos = list.draggedItem.attr("data-origpos").split('-');
var nextItem = $(lists[pos[0]].container).children().not(list.draggedItem).eq(pos[1]);
if (nextItem.size() > 0)
nextItem.before(list.draggedItem);
else if (pos[1] == 0) //was the only item in list
$(lists[pos[0]].container).prepend(list.draggedItem);
else //was the last item in list
$(lists[pos[0]].container).append(list.draggedItem);
}
list.draggedItem.removeAttr("data-origpos");
list.draggedItem = null;
$(document).unbind("mousemove", list.swapItems);
$(document).unbind("mouseup", list.dropItem);
if (opts.scrollContainer != window)
$(window).unbind("wheel", list.wheel);
return false;
},
//swap the draggedItem (represented visually by placeholder) with the list item the it has been dragged on top of
swapItems: function(e) {
if (list.draggedItem == null)
return false;
//move draggedItem to mouse location
list.setPos(e.pageX, e.pageY);
//retrieve list and item position mouse cursor is over
var ei = list.findPos(e.pageX, e.pageY);
var nlist = list;
for (var i = 0; ei == -1 && opts.dragBetween && i < lists.length; i++) {
ei = lists[i].findPos(e.pageX, e.pageY);
nlist = lists[i];
}
//if not over another moveable list item return
if (ei == -1)
return false;
//save fixed items locations
var children = function() { return $(nlist.container).children().not(nlist.draggedItem); };
var fixed = children().not(opts.itemSelector).each(function(i) { this.idx = children().index(this); });
//if moving draggedItem up or left place placeHolder before list item the dragged item is hovering over otherwise place it after
if (lastPos == null || lastPos.top > list.draggedItem.offset().top || lastPos.left > list.draggedItem.offset().left)
$(nlist.pos[ei].elm).before(list.placeHolderItem);
else
$(nlist.pos[ei].elm).after(list.placeHolderItem);
//restore fixed items location
fixed.each(function() {
var elm = children().eq(this.idx).get(0);
if (this != elm && children().index(this) < this.idx)
$(this).insertAfter(elm);
else if (this != elm)
$(this).insertBefore(elm);
});
//misc
$(lists).each(function(i, l) { l.createDropTargets(); l.buildPositionTable(); });
lastPos = list.draggedItem.offset();
return false;
},
//returns the index of the list item the mouse is over
findPos: function(x, y) {
for (var i = 0; i < this.pos.length; i++) {
if (this.pos[i].left < x && this.pos[i].right > x && this.pos[i].top < y && this.pos[i].bottom > y)
return i;
}
return -1;
},
//create drop targets which are placeholders at the end of other lists to allow dragging straight to the last position
createDropTargets: function() {
if (!opts.dragBetween)
return;
$(lists).each(function() {
var ph = $(this.container).find("[data-placeholder]");
var dt = $(this.container).find("[data-droptarget]");
if (ph.size() > 0 && dt.size() > 0)
dt.remove();
else if (ph.size() == 0 && dt.size() == 0) {
if (opts.tagName == "td")
$(opts.placeHolderTemplate).attr("data-droptarget", true).appendTo(this.container);
else
//list.placeHolderItem.clone().removeAttr("data-placeholder") crashes in IE7 and jquery 1.5.1 (doesn't in jquery 1.4.2 or IE8)
$(this.container).append(list.placeHolderItem.removeAttr("data-placeholder").clone().attr("data-droptarget", true));
list.placeHolderItem.attr("data-placeholder", true);
}
});
}
};
newList.init();
lists.push(newList);
});
return this;
};
$.fn.dragsort.defaults = {
tagName:"",
itemSelector: "",
dragSelector: "",
dragSelectorExclude: "input, textarea",
dragEnd: function() { },
dragBetween: false,
placeHolderTemplate: "",
scrollContainer: window,
scrollSpeed: 5
};
})(jQuery);
define("dragsort", function(){});

View File

@ -26,7 +26,7 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
},
ignoreColumn: [0, 'operate'] //默认不导出第一列(checkbox)与操作(operate)列
},
pageSize: localStorage.getItem("pagesize") || 10,
pageSize: localStorage.getItem('page-size') || 10,
pageList: [10, 15, 20, 25, 50, 'All'],
pagination: true,
clickToSelect: true, //是否启用点击选中
@ -190,12 +190,6 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
table.on('refresh.bs.table', function (e, settings, data) {
$(Table.config.refreshbtn, toolbar).find(".fa").addClass("fa-spin");
});
//当表格分页变更时
table.on('page-change.bs.table', function (e, page, pagesize) {
if (!isNaN(pagesize)) {
localStorage.setItem("pagesize", pagesize);
}
});
//当执行搜索时
table.on('search.bs.table common-search.bs.table', function (e, settings, data) {
table.trigger("uncheckbox");
@ -540,6 +534,12 @@ define(['jquery', 'bootstrap', 'moment', 'moment/locale/zh-cn', 'bootstrap-table
Table.list[id] = table;
return table;
},
// 设置全局分页的单页显示数
pageSize: function (pageSize) {
if (!isNaN(pageSize)) {
localStorage.setItem('page-size', pageSize);
}
},
// 批量操作请求
multi: function (action, ids, table, element) {
var options = table.bootstrapTable('getOptions');

2
think
View File

@ -14,4 +14,4 @@
define('APP_PATH', __DIR__ . '/application/');
// 加载框架引导文件
require './thinkphp/console.php';
require __DIR__ . '/thinkphp/console.php';