Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ed8237a00 | ||
|
|
216ca6e697 | ||
|
|
969a7a5ce5 | ||
|
|
5593a20009 | ||
|
|
8a33a4fed3 | ||
|
|
a4e8a86045 | ||
|
|
61e622d2ad | ||
|
|
1b3265aeb5 | ||
|
|
e1c0f6c881 | ||
|
|
3891cf8898 | ||
|
|
4ade618657 | ||
|
|
e7253e7de0 | ||
|
|
063108a846 | ||
|
|
f41943320b | ||
|
|
1f0064743e | ||
|
|
115573a88c | ||
|
|
253379f0c6 | ||
|
|
9a0ff912b5 | ||
|
|
517fd191d3 | ||
|
|
d1dfa8b49b | ||
|
|
c819751a66 | ||
|
|
3a2ee69d0f | ||
|
|
d513177c74 | ||
|
|
0705b9a38d | ||
|
|
feb26660e8 | ||
|
|
b8ccf1542b | ||
|
|
74122885f1 | ||
|
|
f5813dec99 | ||
|
|
db0ac015f0 | ||
|
|
bdabac7cff | ||
|
|
bd9cb6a3af | ||
|
|
3aaf030b89 | ||
|
|
16975c4ee8 | ||
|
|
666598cd30 | ||
|
|
b9f764e4d0 | ||
|
|
bc03616e43 | ||
|
|
8aba56c8c2 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,4 +9,4 @@ Thumbs.db
|
||||
/vendor
|
||||
/.settings
|
||||
/.buildpath
|
||||
/.project
|
||||
/.project
|
||||
|
||||
@@ -109,24 +109,21 @@ class Ajax extends AdminController
|
||||
*/
|
||||
public function getUploadFiles(Request $request): Json
|
||||
{
|
||||
$get = $request->get();
|
||||
$page = !empty($get['page']) ? $get['page'] : 1;
|
||||
$limit = !empty($get['limit']) ? $get['limit'] : 10;
|
||||
$title = !empty($get['title']) ? $get['title'] : null;
|
||||
$this->model = new SystemUploadfile();
|
||||
$count = $this->model
|
||||
->where(function (Query $query) use ($title) {
|
||||
!empty($title) && $query->where('original_name', 'like', "%{$title}%");
|
||||
})
|
||||
$get = $request->get();
|
||||
$page = !empty($get['page']) ? $get['page'] : 1;
|
||||
$limit = !empty($get['limit']) ? $get['limit'] : 10;
|
||||
$title = !empty($get['title']) ? $get['title'] : null;
|
||||
$count = SystemUploadfile::where(function(Query $query) use ($title) {
|
||||
!empty($title) && $query->where('original_name', 'like', "%{$title}%");
|
||||
})
|
||||
->count();
|
||||
$list = $this->model
|
||||
->where(function (Query $query) use ($title) {
|
||||
!empty($title) && $query->where('original_name', 'like', "%{$title}%");
|
||||
})
|
||||
$list = SystemUploadfile::where(function(Query $query) use ($title) {
|
||||
!empty($title) && $query->where('original_name', 'like', "%{$title}%");
|
||||
})
|
||||
->page($page, $limit)
|
||||
->order($this->sort)
|
||||
->select()->toArray();
|
||||
$data = [
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
@@ -149,7 +146,7 @@ class Ajax extends AdminController
|
||||
$upload_allow_size = $uploadConfig['upload_allow_size'];
|
||||
$_upload_allow_ext = explode(',', $uploadConfig['upload_allow_ext']);
|
||||
$upload_allow_ext = [];
|
||||
array_map(function ($value) use (&$upload_allow_ext) {
|
||||
array_map(function($value) use (&$upload_allow_ext) {
|
||||
$upload_allow_ext[] = '.' . $value;
|
||||
}, $_upload_allow_ext);
|
||||
$config = [
|
||||
|
||||
@@ -109,7 +109,7 @@ class Index extends AdminController
|
||||
|
||||
try {
|
||||
$save = $row->save([
|
||||
'password' => password($post['password']),
|
||||
'password' => password_hash($post['password'], PASSWORD_DEFAULT),
|
||||
]);
|
||||
}catch (Exception $e) {
|
||||
$this->error('保存失败');
|
||||
|
||||
@@ -53,7 +53,7 @@ class Login extends AdminController
|
||||
if (empty($admin)) {
|
||||
$this->error('用户不存在');
|
||||
}
|
||||
if (password($post['password']) != $admin->password) {
|
||||
if (!password_verify($post['password'], $admin->password)) {
|
||||
$this->error('密码输入有误');
|
||||
}
|
||||
if ($admin->status == 0) {
|
||||
|
||||
@@ -15,7 +15,7 @@ class Cate extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new MallCate();
|
||||
self::$model = MallCate::class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,8 +24,8 @@ class Goods extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new MallGoods();
|
||||
$this->assign('cate', (new MallCate())->column('title', 'id'));
|
||||
self::$model = new MallGoods();
|
||||
$this->assign('cate', MallCate::column('title', 'id'));
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
@@ -34,8 +34,8 @@ class Goods extends AdminController
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) return $this->selectList();
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
$count = $this->model->where($where)->count();
|
||||
$list = $this->model->with(['cate'])->where($where)->page($page, $limit)->order($this->sort)->select()->toArray();
|
||||
$count = self::$model::where($where)->count();
|
||||
$list = self::$model::with(['cate'])->where($where)->page($page, $limit)->order($this->sort)->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
@@ -50,7 +50,7 @@ class Goods extends AdminController
|
||||
#[NodeAnnotation(title: '入库', auth: true)]
|
||||
public function stock(Request $request, $id): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
|
||||
@@ -24,8 +24,8 @@ class Admin extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemAdmin();
|
||||
$this->assign('auth_list', $this->model->getAuthList());
|
||||
self::$model = SystemAdmin::class;
|
||||
$this->assign('auth_list', self::$model::getAuthList());
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
@@ -36,11 +36,8 @@ class Admin extends AdminController
|
||||
return $this->selectList();
|
||||
}
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
$count = $this->model
|
||||
->where($where)
|
||||
->count();
|
||||
$list = $this->model
|
||||
->withoutField('password')
|
||||
$count = self::$model::where($where)->count();
|
||||
$list = self::$model::withoutField('password')
|
||||
->where($where)
|
||||
->page($page, $limit)
|
||||
->order($this->sort)
|
||||
@@ -68,7 +65,7 @@ class Admin extends AdminController
|
||||
if (empty($post['password'])) $post['password'] = '123456';
|
||||
$post['password'] = password($post['password']);
|
||||
try {
|
||||
$save = $this->model->save($post);
|
||||
$save = self::$model::create($post);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败' . $e->getMessage());
|
||||
}
|
||||
@@ -80,7 +77,7 @@ class Admin extends AdminController
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
public function edit(Request $request, $id = 0): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
@@ -103,7 +100,7 @@ class Admin extends AdminController
|
||||
#[NodeAnnotation(title: '设置密码', auth: true)]
|
||||
public function password(Request $request, $id): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isAjax()) {
|
||||
$post = $request->post();
|
||||
@@ -124,7 +121,6 @@ class Admin extends AdminController
|
||||
}
|
||||
$save ? $this->success('保存成功') : $this->error('保存失败');
|
||||
}
|
||||
$row->auth_ids = explode(',', $row->auth_ids ?: '');
|
||||
$this->assign('row', $row);
|
||||
return $this->fetch();
|
||||
}
|
||||
@@ -134,7 +130,7 @@ class Admin extends AdminController
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$id = $request->param('id');
|
||||
$row = $this->model->whereIn('id', $id)->select();
|
||||
$row = self::$model::whereIn('id', $id)->select();
|
||||
$row->isEmpty() && $this->error('数据不存在');
|
||||
$id == AdminConstant::SUPER_ADMIN_ID && $this->error('超级管理员不允许修改');
|
||||
if (is_array($id)) {
|
||||
@@ -167,7 +163,7 @@ class Admin extends AdminController
|
||||
if ($post['id'] == AdminConstant::SUPER_ADMIN_ID && $post['field'] == 'status') {
|
||||
$this->error('超级管理员状态不允许修改');
|
||||
}
|
||||
$row = $this->model->find($post['id']);
|
||||
$row = self::$model::find($post['id']);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
try {
|
||||
$row->save([
|
||||
|
||||
@@ -23,16 +23,16 @@ class Auth extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemAuth();
|
||||
self::$model = SystemAuth::class;
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '授权', auth: true)]
|
||||
public function authorize(Request $request, $id): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isAjax()) {
|
||||
$list = $this->model->getAuthorizeNodeListByAdminId($id);
|
||||
$list = self::$model::getAuthorizeNodeListByAdminId($id);
|
||||
$this->success('获取成功', $list);
|
||||
}
|
||||
$this->assign('row', $row);
|
||||
@@ -46,7 +46,7 @@ class Auth extends AdminController
|
||||
$id = $request->post('id');
|
||||
$node = $request->post('node', "[]");
|
||||
$node = json_decode($node, true);
|
||||
$row = $this->model->find($id);
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
try {
|
||||
$authNode = new SystemAuthNode();
|
||||
|
||||
@@ -9,6 +9,7 @@ use app\admin\service\annotation\ControllerAnnotation;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\App;
|
||||
use think\facade\Cache;
|
||||
use think\response\Json;
|
||||
|
||||
#[ControllerAnnotation(title: '系统配置管理')]
|
||||
@@ -18,7 +19,7 @@ class Config extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemConfig();
|
||||
self::$model = SystemConfig::class;
|
||||
$this->assign('upload_types', config('admin.upload_types'));
|
||||
$this->assign('editor_types', config('admin.editor_types'));
|
||||
}
|
||||
@@ -41,20 +42,21 @@ class Config extends AdminController
|
||||
if ($group == 'upload') {
|
||||
$upload_types = config('admin.upload_types');
|
||||
// 兼容旧版本
|
||||
$this->model->removeOption()->where('name', 'upload_allow_type')->update(['value' => implode(',', array_keys($upload_types))]);
|
||||
self::$model::where('name', 'upload_allow_type')->update(['value' => implode(',', array_keys($upload_types))]);
|
||||
}
|
||||
foreach ($post as $key => $val) {
|
||||
if (in_array($key, $notAddFields)) continue;
|
||||
if ($this->model->removeOption()->where('name', $key)->count()) {
|
||||
$this->model->removeOption()->where('name', $key)->update(['value' => $val,]);
|
||||
if (self::$model::where('name', $key)->count()) {
|
||||
self::$model::where('name', $key)->update(['value' => $val,]);
|
||||
}else {
|
||||
$this->model->create(
|
||||
self::$model::create(
|
||||
[
|
||||
'name' => $key,
|
||||
'value' => $val,
|
||||
'group' => $group,
|
||||
]);
|
||||
}
|
||||
if (Cache::has($key)) Cache::set($key, $val);
|
||||
}
|
||||
TriggerService::updateMenu();
|
||||
TriggerService::updateSysConfig();
|
||||
|
||||
@@ -22,7 +22,7 @@ class Log extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemLog();
|
||||
self::$model = SystemLog::class;
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
@@ -34,7 +34,7 @@ class Log extends AdminController
|
||||
}
|
||||
[$page, $limit, $where, $excludeFields] = $this->buildTableParams(['month']);
|
||||
$month = !empty($excludeFields['month']) ? date('Ym', strtotime($excludeFields['month'])) : date('Ym');
|
||||
$model = $this->model->setSuffix("_$month")->with('admin')->where($where);
|
||||
$model = (new self::$model)->setSuffix("_$month")->with('admin')->where($where);
|
||||
try {
|
||||
$count = $model->count();
|
||||
$list = $model->page($page, $limit)->order($this->sort)->select();
|
||||
@@ -54,14 +54,14 @@ class Log extends AdminController
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '导出', auth: true)]
|
||||
public function export(): bool
|
||||
public function export()
|
||||
{
|
||||
if (env('EASYADMIN.IS_DEMO', false)) {
|
||||
$this->error('演示环境下不允许操作');
|
||||
}
|
||||
[$page, $limit, $where, $excludeFields] = $this->buildTableParams(['month']);
|
||||
$month = !empty($excludeFields['month']) ? date('Ym', strtotime($excludeFields['month'])) : date('Ym');
|
||||
$tableName = $this->model->setSuffix("_$month")->getName();
|
||||
$tableName = (new self::$model)->setSuffix("_$month")->getName();
|
||||
$tableName = CommonTool::humpToLine(lcfirst($tableName));
|
||||
$prefix = config('database.connections.mysql.prefix');
|
||||
$dbList = Db::query("show full columns from {$prefix}{$tableName}");
|
||||
@@ -72,10 +72,9 @@ class Log extends AdminController
|
||||
$header[] = [$comment, $vo['Field']];
|
||||
}
|
||||
}
|
||||
$model = $this->model->setSuffix("_$month")->with('admin')->where($where);
|
||||
$model = (new self::$model)->setSuffix("_$month")->with('admin')->where($where);
|
||||
try {
|
||||
$list = $model
|
||||
->where($where)
|
||||
->limit(10000)
|
||||
->order('id', 'desc')
|
||||
->select()
|
||||
@@ -84,11 +83,10 @@ class Log extends AdminController
|
||||
$vo['content'] = json_encode($vo['content'], JSON_UNESCAPED_UNICODE);
|
||||
$vo['response'] = json_encode($vo['response'], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
}catch (PDOException|DbException $exception) {
|
||||
exportExcel($header, $list, '操作日志');
|
||||
}catch (\Throwable $exception) {
|
||||
$this->error($exception->getMessage());
|
||||
}
|
||||
$fileName = time();
|
||||
return Excel::exportData($list, $header, $fileName, 'xlsx');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class Menu extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemMenu();
|
||||
self::$model = SystemMenu::class;
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
@@ -35,8 +35,8 @@ class Menu extends AdminController
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
$count = $this->model->count();
|
||||
$list = $this->model->order($this->sort)->select()->toArray();
|
||||
$count = self::$model::count();
|
||||
$list = self::$model::order($this->sort)->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
@@ -52,7 +52,7 @@ class Menu extends AdminController
|
||||
public function add(Request $request): string
|
||||
{
|
||||
$id = $request->param('id');
|
||||
$homeId = $this->model->where(['pid' => MenuConstant::HOME_PID,])->value('id');
|
||||
$homeId = self::$model::where(['pid' => MenuConstant::HOME_PID,])->value('id');
|
||||
if ($id == $homeId) {
|
||||
$this->error('首页不能添加子菜单');
|
||||
}
|
||||
@@ -65,7 +65,7 @@ class Menu extends AdminController
|
||||
];
|
||||
$this->validate($post, $rule);
|
||||
try {
|
||||
$save = $this->model->save($post);
|
||||
$save = self::$model::create($post);
|
||||
}catch (\Exception $e) {
|
||||
$this->error('保存失败');
|
||||
}
|
||||
@@ -76,7 +76,7 @@ class Menu extends AdminController
|
||||
$this->error('保存失败');
|
||||
}
|
||||
}
|
||||
$pidMenuList = $this->model->getPidMenuList();
|
||||
$pidMenuList = self::$model::getPidMenuList();
|
||||
$this->assign('id', $id);
|
||||
$this->assign('pidMenuList', $pidMenuList);
|
||||
return $this->fetch();
|
||||
@@ -85,7 +85,7 @@ class Menu extends AdminController
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
public function edit(Request $request, $id = 0): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
@@ -108,7 +108,7 @@ class Menu extends AdminController
|
||||
$this->error('保存失败');
|
||||
}
|
||||
}
|
||||
$pidMenuList = $this->model->getPidMenuList();
|
||||
$pidMenuList = self::$model::getPidMenuList();
|
||||
$this->assign([
|
||||
'id' => $id,
|
||||
'pidMenuList' => $pidMenuList,
|
||||
@@ -122,7 +122,7 @@ class Menu extends AdminController
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$id = $request->param('id');
|
||||
$row = $this->model->whereIn('id', $id)->select();
|
||||
$row = self::$model::whereIn('id', $id)->select();
|
||||
empty($row) && $this->error('数据不存在');
|
||||
try {
|
||||
$save = $row->delete();
|
||||
@@ -148,17 +148,16 @@ class Menu extends AdminController
|
||||
'value|值' => 'require',
|
||||
];
|
||||
$this->validate($post, $rule);
|
||||
$row = $this->model->find($post['id']);
|
||||
$row = self::$model::find($post['id']);
|
||||
if (!$row) {
|
||||
$this->error('数据不存在');
|
||||
}
|
||||
if (!in_array($post['field'], $this->allowModifyFields)) {
|
||||
$this->error('该字段不允许修改:' . $post['field']);
|
||||
}
|
||||
$homeId = $this->model
|
||||
->where([
|
||||
'pid' => MenuConstant::HOME_PID,
|
||||
])
|
||||
$homeId = self::$model::where([
|
||||
'pid' => MenuConstant::HOME_PID,
|
||||
])
|
||||
->value('id');
|
||||
if ($post['id'] == $homeId && $post['field'] == 'status') {
|
||||
$this->error('首页状态不允许关闭');
|
||||
|
||||
@@ -22,7 +22,7 @@ class Node extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemNode();
|
||||
self::$model = SystemNode::class;
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
@@ -32,10 +32,8 @@ class Node extends AdminController
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
$count = $this->model
|
||||
->count();
|
||||
$list = $this->model
|
||||
->getNodeTreeList();
|
||||
$count = self::$model::count();
|
||||
$list = self::$model::getNodeTreeList();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
@@ -54,15 +52,14 @@ class Node extends AdminController
|
||||
$this->checkPostRequest();
|
||||
$nodeList = (new NodeService())->getNodeList();
|
||||
empty($nodeList) && $this->error('暂无需要更新的系统节点');
|
||||
$model = new SystemNode();
|
||||
|
||||
try {
|
||||
if ($force == 1) {
|
||||
$updateNodeList = $model->removeOption()->whereIn('node', array_column($nodeList, 'node'))->select();
|
||||
$updateNodeList = self::$model::whereIn('node', array_column($nodeList, 'node'))->select();
|
||||
$formatNodeList = array_format_key($nodeList, 'node');
|
||||
foreach ($updateNodeList as $vo) {
|
||||
isset($formatNodeList[$vo['node']])
|
||||
&& $model->removeOption()->where('id', $vo['id'])->update(
|
||||
&& self::$model::where('id', $vo['id'])->update(
|
||||
[
|
||||
'title' => $formatNodeList[$vo['node']]['title'],
|
||||
'is_auth' => $formatNodeList[$vo['node']]['is_auth'],
|
||||
@@ -70,7 +67,7 @@ class Node extends AdminController
|
||||
);
|
||||
}
|
||||
}
|
||||
$existNodeList = $model->removeOption()->field('node,title,type,is_auth')->select();
|
||||
$existNodeList = self::$model::field('node,title,type,is_auth')->select();
|
||||
foreach ($nodeList as $key => $vo) {
|
||||
foreach ($existNodeList as $v) {
|
||||
if ($vo['node'] == $v->node) {
|
||||
@@ -80,7 +77,7 @@ class Node extends AdminController
|
||||
}
|
||||
}
|
||||
if (!empty($nodeList)) {
|
||||
$model->saveAll($nodeList);
|
||||
(new self::$model)->saveAll($nodeList);
|
||||
TriggerService::updateNode();
|
||||
}
|
||||
}catch (\Exception $e) {
|
||||
@@ -94,12 +91,11 @@ class Node extends AdminController
|
||||
{
|
||||
$this->checkPostRequest();
|
||||
$nodeList = (new NodeService())->getNodeList();
|
||||
$model = new SystemNode();
|
||||
try {
|
||||
$existNodeList = $model->field('id,node,title,type,is_auth')->select()->toArray();
|
||||
$existNodeList = self::$model::field('id,node,title,type,is_auth')->select()->toArray();
|
||||
$formatNodeList = array_format_key($nodeList, 'node');
|
||||
foreach ($existNodeList as $vo) {
|
||||
!isset($formatNodeList[$vo['node']]) && $model->where('id', $vo['id'])->delete();
|
||||
!isset($formatNodeList[$vo['node']]) && self::$model::where('id', $vo['id'])->delete();
|
||||
}
|
||||
TriggerService::updateNode();
|
||||
}catch (\Exception $e) {
|
||||
|
||||
@@ -21,7 +21,7 @@ class Quick extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemQuick();
|
||||
self::$model = SystemQuick::class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ class Uploadfile extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new SystemUploadfile();
|
||||
self::$model = SystemUploadfile::class;
|
||||
$this->assign('upload_types', config('admin.upload_types'));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,15 +22,15 @@ class SystemAdmin extends TimeModel
|
||||
],
|
||||
];
|
||||
|
||||
public function getAuthIdsAttr($value): array
|
||||
public static function getAuthIdsAttr($value): array
|
||||
{
|
||||
if (!$value) return [];
|
||||
return explode(',', $value);
|
||||
}
|
||||
|
||||
public function getAuthList(): array
|
||||
public static function getAuthList(): array
|
||||
{
|
||||
return (new SystemAuth())->removeOption()->where('status', 1)->column('title', 'id');
|
||||
return SystemAuth::where('status', 1)->column('title', 'id');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,13 +25,13 @@ class SystemAuth extends TimeModel
|
||||
* @throws DbException
|
||||
* @throws ModelNotFoundException
|
||||
*/
|
||||
public function getAuthorizeNodeListByAdminId($authId): array
|
||||
public static function getAuthorizeNodeListByAdminId($authId): array
|
||||
{
|
||||
$checkNodeList = (new SystemAuthNode())
|
||||
->where('auth_id', $authId)
|
||||
->column('node_id');
|
||||
$systemNode = new SystemNode();
|
||||
$nodeList = $systemNode
|
||||
$nodeList = $systemNode
|
||||
->where('is_auth', 1)
|
||||
->field('id,node,title,type,is_auth')
|
||||
->select()
|
||||
|
||||
@@ -23,14 +23,14 @@ class SystemMenu extends TimeModel
|
||||
* @throws DbException
|
||||
* @throws DataNotFoundException
|
||||
*/
|
||||
public function getPidMenuList(): array
|
||||
public static function getPidMenuList(): array
|
||||
{
|
||||
$list = $this->removeOption()->field('id,pid,title')->where([
|
||||
$list = self::field('id,pid,title')->where([
|
||||
['pid', '<>', MenuConstant::HOME_PID],
|
||||
['status', '=', 1],
|
||||
])->select()->toArray();
|
||||
|
||||
$pidMenuList = $this->buildPidMenu(0, $list);
|
||||
$pidMenuList = self::buildPidMenu(0, $list);
|
||||
return array_merge([[
|
||||
'id' => 0,
|
||||
'pid' => 0,
|
||||
@@ -38,7 +38,7 @@ class SystemMenu extends TimeModel
|
||||
]], $pidMenuList);
|
||||
}
|
||||
|
||||
protected function buildPidMenu($pid, $list, $level = 0): array
|
||||
protected static function buildPidMenu($pid, $list, $level = 0): array
|
||||
{
|
||||
$newList = [];
|
||||
foreach ($list as $vo) {
|
||||
@@ -57,7 +57,7 @@ class SystemMenu extends TimeModel
|
||||
$vo['title'] = $markString . $vo['title'];
|
||||
}
|
||||
$newList[] = $vo;
|
||||
$childList = $this->buildPidMenu($vo['id'], $list, $level);
|
||||
$childList = self::buildPidMenu($vo['id'], $list, $level);
|
||||
!empty($childList) && $newList = array_merge($newList, $childList);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@ use app\common\model\TimeModel;
|
||||
class SystemNode extends TimeModel
|
||||
{
|
||||
|
||||
public function getNodeTreeList(): array
|
||||
public static function getNodeTreeList(): array
|
||||
{
|
||||
$list = $this->removeOption()->select()->toArray();
|
||||
return $this->buildNodeTree($list);
|
||||
$list = self::select()->toArray();
|
||||
return self::buildNodeTree($list);
|
||||
}
|
||||
|
||||
protected function buildNodeTree($list): array
|
||||
protected static function buildNodeTree($list): array
|
||||
{
|
||||
$newList = [];
|
||||
$repeatString = " ";
|
||||
|
||||
@@ -9,11 +9,10 @@ class ConfigService
|
||||
|
||||
public static function getVersion()
|
||||
{
|
||||
$version = cache('version');
|
||||
$version = cache('site_version');
|
||||
if (empty($version)) {
|
||||
$version = sysConfig('site', 'site_version');
|
||||
cache('site_version', $version);
|
||||
Cache::set('version', $version, 3600);
|
||||
}
|
||||
return $version;
|
||||
}
|
||||
|
||||
@@ -355,6 +355,7 @@ class BuildCurd
|
||||
if (!empty($bindSelectField) && !in_array($bindSelectField, array_column($columns, 'Field'))) {
|
||||
throw new TableException("关联表{$relationTable}不存在该字段: {$bindSelectField}");
|
||||
}
|
||||
$onlyFields = [];
|
||||
foreach ($columns as $vo) {
|
||||
if (empty($primaryKey) && $vo['Key'] == 'PRI') {
|
||||
$primaryKey = $vo['Field'];
|
||||
@@ -362,6 +363,7 @@ class BuildCurd
|
||||
if (!empty($onlyShowFields) && !in_array($vo['Field'], $onlyShowFields)) {
|
||||
continue;
|
||||
}
|
||||
if (!empty($onlyShowFields)) $onlyFields[] = $vo['Field'];
|
||||
$colum = [
|
||||
'type' => $vo['Type'],
|
||||
'comment' => $vo['Comment'],
|
||||
@@ -388,6 +390,7 @@ class BuildCurd
|
||||
'bindSelectField' => $bindSelectField,
|
||||
'delete' => $delete,
|
||||
'tableColumns' => $formatColumns,
|
||||
'onlyFields' => $onlyFields,
|
||||
];
|
||||
if (!empty($bindSelectField)) {
|
||||
$relationArray = explode('\\', $modelFilename);
|
||||
@@ -1038,7 +1041,7 @@ class BuildCurd
|
||||
$relationCode = '';
|
||||
foreach ($this->relationArray as $key => $val) {
|
||||
$relation = CommonTool::lineToHump($key);
|
||||
$relationCode = "->withJoin('{$relation}', 'LEFT')\r";
|
||||
$relationCode = "withJoin('{$relation}', 'LEFT')";
|
||||
if (!empty($val['bindSelectField']) && !empty($val['primaryKey'])) {
|
||||
$constructRelation = '$notes["' . lcfirst($val['foreignKey']) . '"] = \app\admin\model\\' . $val['modelFilename'] . '::column("' . $val['bindSelectField'] . '", "' . $val['primaryKey'] . '");';
|
||||
}
|
||||
@@ -1092,16 +1095,17 @@ class BuildCurd
|
||||
$relationList = '';
|
||||
if (!empty($this->relationArray)) {
|
||||
foreach ($this->relationArray as $key => $val) {
|
||||
$relation = CommonTool::lineToHump($key);
|
||||
// $relationCode = CommonTool::replaceTemplate(
|
||||
// $this->getTemplate("model{$this->DS}relation"),
|
||||
// [
|
||||
// 'relationMethod' => $relation,
|
||||
// 'relationModel' => "\app\admin\model\\{$val['modelFilename']}",
|
||||
// 'foreignKey' => $val['foreignKey'],
|
||||
// 'primaryKey' => $val['primaryKey'],
|
||||
// ]);
|
||||
// $relationList .= $relationCode;
|
||||
$relation = CommonTool::lineToHump($key);
|
||||
$relationCode = CommonTool::replaceTemplate(
|
||||
$this->getTemplate("model{$this->DS}relation"),
|
||||
[
|
||||
'relationMethod' => $relation,
|
||||
'relationModel' => "{$val['modelFilename']}::class",
|
||||
'foreignKey' => $val['foreignKey'],
|
||||
'primaryKey' => $val['primaryKey'],
|
||||
'relationFields' => empty($val['onlyFields']) ? "" : "->field('{$val['primaryKey']}," . implode(',', $val['onlyFields']) . "')",
|
||||
]);
|
||||
$relationList .= $relationCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1343,6 +1347,15 @@ class BuildCurd
|
||||
);
|
||||
$this->fileList[$viewEditFile] = $viewEditValue;
|
||||
|
||||
$viewRecycleFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}recycle.html";
|
||||
$viewRecycleValue = CommonTool::replaceTemplate(
|
||||
$this->getTemplate("view{$this->DS}recycle"),
|
||||
[
|
||||
'controllerUrl' => $this->controllerUrl,
|
||||
'notesScript' => $this->formatNotesScript(),
|
||||
]
|
||||
);
|
||||
$this->fileList[$viewRecycleFile] = $viewRecycleValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1363,7 +1376,7 @@ class BuildCurd
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.image}";
|
||||
} elseif ($val['formType'] == 'datetime') {
|
||||
$templateValue = "{field: '{$field}', search: 'range', title: '{$val['comment']}'}";
|
||||
} elseif ($val['formType'] == 'images') {
|
||||
} elseif ($val['formType'] == 'images') {
|
||||
continue;
|
||||
} elseif ($val['formType'] == 'file') {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.url}";
|
||||
@@ -1390,13 +1403,12 @@ class BuildCurd
|
||||
} else {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
|
||||
}
|
||||
|
||||
$indexCols .= $this->formatColsRow("{$templateValue},\r");
|
||||
}
|
||||
|
||||
// 关联表
|
||||
foreach ($this->relationArray as $table => $tableVal) {
|
||||
$table = CommonTool::lineToHump($table);
|
||||
$table = CommonTool::humpToLine($table);
|
||||
foreach ($tableVal['tableColumns'] as $field => $val) {
|
||||
if ($val['formType'] == 'image') {
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.image}";
|
||||
@@ -1417,20 +1429,22 @@ class BuildCurd
|
||||
} elseif (in_array($field, $this->sortFields)) {
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', edit: 'text'}";
|
||||
} else {
|
||||
$templateValue = "";
|
||||
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}'}";
|
||||
}
|
||||
|
||||
if ($templateValue) $indexCols .= $this->formatColsRow("{$templateValue},\r");
|
||||
}
|
||||
}
|
||||
|
||||
$indexCols .= $this->formatColsRow("{width: 250, title: '操作', templet: ea.table.tool},\r");
|
||||
$recycleCols = $indexCols;
|
||||
$indexCols .= $this->formatColsRow("{width: 250, title: '操作', templet: ea.table.tool},\r");
|
||||
|
||||
$jsValue = CommonTool::replaceTemplate(
|
||||
$this->getTemplate("static{$this->DS}js"),
|
||||
[
|
||||
'controllerUrl' => $this->controllerUrl,
|
||||
'indexCols' => $indexCols,
|
||||
'recycleCols' => $recycleCols,
|
||||
]
|
||||
);
|
||||
$this->fileList[$jsFile] = $jsValue;
|
||||
|
||||
@@ -16,9 +16,10 @@ class {{controllerName}} extends AdminController
|
||||
public function __construct(App $app)
|
||||
{
|
||||
parent::__construct($app);
|
||||
$this->model = new {{modelFilename}}();
|
||||
$this->notes = $notes = $this->model->notes;
|
||||
self::$model = new {{modelFilename}}();
|
||||
$notes = self::$model::$notes;
|
||||
{{constructRelation}}
|
||||
$this->notes =$notes;
|
||||
$this->assign(compact('notes'));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
#[NodeAnnotation(title: '列表', auth: true)]
|
||||
public function index(\app\Request $request): \think\response\Json|string
|
||||
{
|
||||
if ($request->isAjax()) {
|
||||
if (input('selectFields')) {
|
||||
return $this->selectList();
|
||||
}
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
$count = self::$model::where($where)->{{relationIndexMethod}}->count();
|
||||
$list = self::$model::where($where)->{{relationIndexMethod}}->page($page, $limit)->order($this->sort)->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
return $this->fetch();
|
||||
}
|
||||
@@ -7,12 +7,17 @@ use app\common\model\TimeModel;
|
||||
class {{modelName}} extends TimeModel
|
||||
{
|
||||
|
||||
protected $name = "{{table}}";
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return [
|
||||
'name' => "{{table}}",
|
||||
'table' => "{{prefix_table}}",
|
||||
'deleteTime' => {{deleteTime}},
|
||||
];
|
||||
}
|
||||
|
||||
protected $table = "{{prefix_table}}";
|
||||
public static array $notes = {{selectArrays}};
|
||||
|
||||
protected $deleteTime = {{deleteTime}};
|
||||
|
||||
public array $notes = {{selectArrays}};
|
||||
{{relationList}}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
public function {{relationMethod}}()
|
||||
{
|
||||
return $this->belongsTo('{{relationModel}}', '{{foreignKey}}', '{{primaryKey}}');
|
||||
return $this->belongsTo({{relationModel}}, '{{foreignKey}}', '{{primaryKey}}'){{relationFields}};
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
delete_url: '{{controllerUrl}}/delete',
|
||||
export_url: '{{controllerUrl}}/export',
|
||||
modify_url: '{{controllerUrl}}/modify',
|
||||
recycle_url: '{{controllerUrl}}/recycle',
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -29,5 +30,62 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
edit: function () {
|
||||
ea.listen();
|
||||
},
|
||||
recycle: function () {
|
||||
init.index_url = init.recycle_url;
|
||||
ea.table.render({
|
||||
init: init,
|
||||
toolbar: ['refresh',
|
||||
[{
|
||||
class: 'layui-btn layui-btn-sm',
|
||||
method: 'get',
|
||||
field: 'id',
|
||||
icon: 'fa fa-refresh',
|
||||
text: '全部恢复',
|
||||
title: '确定恢复?',
|
||||
auth: 'recycle',
|
||||
url: init.recycle_url + '?type=restore',
|
||||
checkbox: true
|
||||
}, {
|
||||
class: 'layui-btn layui-btn-danger layui-btn-sm',
|
||||
method: 'get',
|
||||
field: 'id',
|
||||
icon: 'fa fa-delete',
|
||||
text: '彻底删除',
|
||||
title: '确定彻底删除?',
|
||||
auth: 'recycle',
|
||||
url: init.recycle_url + '?type=delete',
|
||||
checkbox: true
|
||||
}], 'export',
|
||||
],
|
||||
cols: [[
|
||||
{{recycleCols}}
|
||||
{
|
||||
width: 250,
|
||||
title: '操作',
|
||||
templet: ea.table.tool,
|
||||
operat: [
|
||||
[{
|
||||
title: '确认恢复?',
|
||||
text: '恢复数据',
|
||||
filed: 'id',
|
||||
url: init.recycle_url + '?type=restore',
|
||||
method: 'get',
|
||||
auth: 'recycle',
|
||||
class: 'layui-btn layui-btn-xs layui-btn-success',
|
||||
}, {
|
||||
title: '想好了吗?',
|
||||
text: '彻底删除',
|
||||
filed: 'id',
|
||||
method: 'get',
|
||||
url: init.recycle_url + '?type=delete',
|
||||
auth: 'recycle',
|
||||
class: 'layui-btn layui-btn-xs layui-btn-normal layui-bg-red',
|
||||
}]]
|
||||
}
|
||||
]],
|
||||
});
|
||||
|
||||
ea.listen();
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -4,6 +4,7 @@
|
||||
data-auth-add="{:auth('{{controllerUrl}}/add')}"
|
||||
data-auth-edit="{:auth('{{controllerUrl}}/edit')}"
|
||||
data-auth-delete="{:auth('{{controllerUrl}}/delete')}"
|
||||
data-auth-recycle="{:auth('{{controllerUrl}}/recycle')}"
|
||||
lay-filter="currentTable">
|
||||
<!-- searchTableShow="false" 隐藏搜索框 -->
|
||||
</table>
|
||||
|
||||
13
app/admin/service/curd/templates/view/recycle.code
Normal file
13
app/admin/service/curd/templates/view/recycle.code
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="currentTable" class="layui-table layui-hide"
|
||||
data-auth-recycle="{:auth('{{controllerUrl}}/recycle')}"
|
||||
lay-filter="currentTable">
|
||||
<!-- searchTableShow="false" 隐藏搜索框 -->
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{{notesScript}}
|
||||
</script>
|
||||
@@ -100,6 +100,9 @@ class CommonTool
|
||||
{
|
||||
$arrayString = str_replace('array (', '[', $arrayString);
|
||||
$arrayString = str_replace(')', ']', $arrayString);
|
||||
$arrayString = str_replace('=>
|
||||
[', '=> [', $arrayString);
|
||||
return $arrayString;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace app\admin\traits;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\admin\service\tool\CommonTool;
|
||||
use app\Request;
|
||||
use jianyan\excel\Excel;
|
||||
use think\db\exception\PDOException;
|
||||
use think\facade\Db;
|
||||
use think\response\Json;
|
||||
|
||||
@@ -25,8 +25,8 @@ trait Curd
|
||||
return $this->selectList();
|
||||
}
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
$count = $this->model->where($where)->count();
|
||||
$list = $this->model->where($where)->page($page, $limit)->order($this->sort)->select()->toArray();
|
||||
$count = self::$model::where($where)->count();
|
||||
$list = self::$model::where($where)->page($page, $limit)->order($this->sort)->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
@@ -46,8 +46,8 @@ trait Curd
|
||||
$rule = [];
|
||||
$this->validate($post, $rule);
|
||||
try {
|
||||
Db::transaction(function () use ($post, &$save) {
|
||||
$save = $this->model->save($post);
|
||||
Db::transaction(function() use ($post, &$save) {
|
||||
$save = self::$model::create($post);
|
||||
});
|
||||
}catch (\Exception $e) {
|
||||
$this->error('新增失败:' . $e->getMessage());
|
||||
@@ -60,14 +60,14 @@ trait Curd
|
||||
#[NodeAnnotation(title: '编辑', auth: true)]
|
||||
public function edit(Request $request, $id = 0): string
|
||||
{
|
||||
$row = $this->model->find($id);
|
||||
$row = self::$model::find($id);
|
||||
empty($row) && $this->error('数据不存在');
|
||||
if ($request->isPost()) {
|
||||
$post = $request->post();
|
||||
$rule = [];
|
||||
$this->validate($post, $rule);
|
||||
try {
|
||||
Db::transaction(function () use ($post, $row, &$save) {
|
||||
Db::transaction(function() use ($post, $row, &$save) {
|
||||
$save = $row->save($post);
|
||||
});
|
||||
}catch (\Exception $e) {
|
||||
@@ -85,7 +85,7 @@ trait Curd
|
||||
// 如果不是id作为主键 请在对应的控制器中覆盖重写
|
||||
$id = $request->param('id', []);
|
||||
$this->checkPostRequest();
|
||||
$row = $this->model->whereIn('id', $id)->select();
|
||||
$row = self::$model::whereIn('id', $id)->select();
|
||||
$row->isEmpty() && $this->error('数据不存在');
|
||||
try {
|
||||
$save = $row->delete();
|
||||
@@ -102,7 +102,7 @@ trait Curd
|
||||
$this->error('演示环境下不允许操作');
|
||||
}
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
$tableName = $this->model->getName();
|
||||
$tableName = (new self::$model)->getName();
|
||||
$tableName = CommonTool::humpToLine(lcfirst($tableName));
|
||||
$prefix = config('database.connections.mysql.prefix');
|
||||
$dbList = Db::query("show full columns from {$prefix}{$tableName}");
|
||||
@@ -113,14 +113,16 @@ trait Curd
|
||||
$header[] = [$comment, $vo['Field']];
|
||||
}
|
||||
}
|
||||
$list = $this->model
|
||||
->where($where)
|
||||
$list = self::$model::where($where)
|
||||
->limit(100000)
|
||||
->order('id', 'desc')
|
||||
->order($this->sort)
|
||||
->select()
|
||||
->toArray();
|
||||
$fileName = time();
|
||||
return Excel::exportData($list, $header, $fileName, 'xlsx');
|
||||
try {
|
||||
exportExcel($header, $list);
|
||||
}catch (\Throwable $exception) {
|
||||
$this->error('导出失败: ' . $exception->getMessage() . PHP_EOL . $exception->getFile() . PHP_EOL . $exception->getLine());
|
||||
}
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '属性修改', auth: true)]
|
||||
@@ -134,7 +136,7 @@ trait Curd
|
||||
'value|值' => 'require',
|
||||
];
|
||||
$this->validate($post, $rule);
|
||||
$row = $this->model->find($post['id']);
|
||||
$row = self::$model::find($post['id']);
|
||||
if (!$row) {
|
||||
$this->error('数据不存在');
|
||||
}
|
||||
@@ -142,7 +144,7 @@ trait Curd
|
||||
$this->error('该字段不允许修改:' . $post['field']);
|
||||
}
|
||||
try {
|
||||
Db::transaction(function () use ($post, $row) {
|
||||
Db::transaction(function() use ($post, $row) {
|
||||
$row->save([
|
||||
$post['field'] => $post['value'],
|
||||
]);
|
||||
@@ -153,4 +155,49 @@ trait Curd
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '回收站', auth: true)]
|
||||
public function recycle(Request $request): Json|string
|
||||
{
|
||||
if (!$request->isAjax()) {
|
||||
return $this->fetch();
|
||||
}
|
||||
$id = $request->param('id', []);
|
||||
$type = $request->param('type', '');
|
||||
$deleteTimeField = (new self::$model)->getOption('deleteTime'); // 获取软删除字段
|
||||
$defaultErrorMsg = 'Model 中未设置软删除 deleteTime 对应字段 或 数据表中不存在该字段';
|
||||
if (!$deleteTimeField) $this->success($defaultErrorMsg);
|
||||
switch ($type) {
|
||||
case 'restore':
|
||||
self::$model::withTrashed()->whereIn('id', $id)->strict(false)->update([$deleteTimeField => null, 'update_time' => time()]);
|
||||
$this->success('success');
|
||||
break;
|
||||
case 'delete':
|
||||
self::$model::destroy($id, true);
|
||||
$this->success('success');
|
||||
break;
|
||||
default:
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
try {
|
||||
$count = self::$model::withTrashed()->where($where)->whereNotNull($deleteTimeField)->count();
|
||||
$list = self::$model::withTrashed()->where($where)->page($page, $limit)->order($this->sort)->whereNotNull($deleteTimeField)->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
$error = $e->getMessage();
|
||||
if ($e instanceof PDOException) $error .= '<br>' . $defaultErrorMsg;
|
||||
$data = [
|
||||
'code' => -1,
|
||||
'msg' => $error,
|
||||
'count' => 0,
|
||||
'data' => [],
|
||||
];
|
||||
}
|
||||
return json($data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="head_img" class="layui-input layui-col-xs6" lay-reqtext="请上传用户头像" placeholder="请上传用户头像" value="{$row.head_img|default=''}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="head_img" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn" data-upload="head_img" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_head_img" data-upload-select="head_img" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<li class="layui-nav-item mobile layui-hide-xs" lay-unselect>
|
||||
<a href="javascript:;" data-check-screen="full"><i class="fa fa-arrows-alt"></i></a>
|
||||
</li>
|
||||
<li class="layui-nav-item" lay-unselect>
|
||||
<li class="layui-nav-item mobile layui-hide-xs" lay-unselect>
|
||||
<div class="layui-form ws-header-theme" lay-filter="header-theme">
|
||||
<input type="checkbox" name="theme-mode" lay-filter="header-theme-mode" lay-skin="switch">
|
||||
<div lay-checkbox>
|
||||
@@ -91,8 +91,8 @@
|
||||
<div class="layuimini-site-mobile"><i class="layui-icon"></i></div>
|
||||
|
||||
<div class="layui-body">
|
||||
<div class="layuimini-tab layui-tab-rollTool layui-tab" lay-filter="layuiminiTab" lay-allowclose="true">
|
||||
<ul class="layui-tab-title">
|
||||
<div class="layuimini-tab layui-tabs-rollTool layui-tabs" lay-filter="layuiminiTab" id="layuiminiTab">
|
||||
<ul class="layui-tabs-header">
|
||||
<li class="layui-this" id="layuiminiHomeTabId" lay-id=""></li>
|
||||
</ul>
|
||||
<div class="layui-tab-control">
|
||||
@@ -111,8 +111,8 @@
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
<div class="layui-tab-content">
|
||||
<div id="layuiminiHomeTabIframe" class="layui-tab-item layui-show"></div>
|
||||
<div class="layui-tabs-body">
|
||||
<div id="layuiminiHomeTabIframe" class="layui-tab-item layui-tabs-item layui-show"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
<span class="layui-badge layui-bg-cyan pull-right ">实时</span>
|
||||
<div class="panel-content">
|
||||
<h5>用户统计</h5>
|
||||
<h1>1234</h1>
|
||||
<h6>当前分类总记录数</h6>
|
||||
<h2>1234</h2>
|
||||
<h6>记录数</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,8 +28,8 @@
|
||||
<span class="layui-badge layui-bg-purple pull-right ">实时</span>
|
||||
<div class="panel-content">
|
||||
<h5>商品统计</h5>
|
||||
<h1>1234</h1>
|
||||
<h6>当前分类总记录数</h6>
|
||||
<h2>1234</h2>
|
||||
<h6>记录数</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -40,8 +40,8 @@
|
||||
<span class="layui-badge layui-bg-orange pull-right ">实时</span>
|
||||
<div class="panel-content">
|
||||
<h5>浏览统计</h5>
|
||||
<h1>1234</h1>
|
||||
<h6>当前分类总记录数</h6>
|
||||
<h2>1234</h2>
|
||||
<h6>记录数</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -52,8 +52,8 @@
|
||||
<span class="layui-badge layui-bg-red pull-right ">实时</span>
|
||||
<div class="panel-content">
|
||||
<h5>订单统计</h5>
|
||||
<h1>1234</h1>
|
||||
<h6>当前分类总记录数</h6>
|
||||
<h2>1234</h2>
|
||||
<h6>记录数</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -199,7 +199,7 @@
|
||||
<div class="layui-card-header"><i class="fa fa-paper-plane-o icon"></i>作者心语</div>
|
||||
<div class="layui-card-body layui-text">
|
||||
<p>
|
||||
本模板基于layui2.9.x以及font-awesome-4.7.0进行实现。
|
||||
本模板基于layui2.x以及font-awesome-4.7.0进行实现。
|
||||
<a class="layui-btn layui-btn-xs layui-btn-danger" style="vertical-align: baseline;" target="_blank" href="http://layui.dev/docs">layui文档</a>
|
||||
</p>
|
||||
<hr>
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="image" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传分类图片" value="">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="image" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_image" data-upload-select="image" data-upload-number="one" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<span><a class="layui-btn" data-upload="image" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_image" data-upload-select="image" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="image" class="layui-input layui-col-xs6" lay-verify="required" lay-reqtext="请上传分类图片" placeholder="请上传分类图片" value="{$row.image|default=''}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="image" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_image" data-upload-select="image" data-upload-number="one" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<span><a class="layui-btn" data-upload="image" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_image" data-upload-select="image" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -46,8 +46,8 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="logo" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传分类图片" value="">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="logo" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_logo" data-upload-select="logo" data-upload-number="one" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<span><a class="layui-btn" data-upload="logo" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_logo" data-upload-select="logo" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -57,8 +57,8 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="images" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传商品图片" value="">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="images" data-upload-number="more" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_images" data-upload-select="images" data-upload-number="more" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<span><a class="layui-btn" data-upload="images" data-upload-number="more" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_images" data-upload-select="images" data-upload-number="more"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,6 +91,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 文档:https://xm-select.com/file/xm-select/v1.2.4/#/basic/use -->
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">模拟多选</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="demo1" class="xm-select-demo"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注信息</label>
|
||||
<div class="layui-input-block">
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xs2">
|
||||
<button class="layui-btn layui-bg-purple layui-btn-fluid" type="button" lay-on="AiOptimization">AI优化</button>
|
||||
<button class="layui-btn layui-bg-purple" type="button" lay-on="AiOptimization">AI优化</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -47,8 +47,8 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="logo" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传分类图片" value="{$row.logo|default=''}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="logo" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_logo" data-upload-select="logo" data-upload-number="one" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<span><a class="layui-btn" data-upload="logo" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_logo" data-upload-select="logo" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -58,8 +58,8 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="images" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传商品图片" value="{$row.images|default=''}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="images" data-upload-number="more" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_images" data-upload-select="images" data-upload-number="more" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<span><a class="layui-btn" data-upload="images" data-upload-number="more" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_images" data-upload-select="images" data-upload-number="more"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -92,6 +92,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 文档:https://xm-select.com/file/xm-select/v1.2.4/#/basic/use -->
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">模拟多选</label>
|
||||
<div class="layui-input-block">
|
||||
<div id="demo1" class="xm-select-demo"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-form-item layui-form-text">
|
||||
<label class="layui-form-label">备注信息</label>
|
||||
<div class="layui-input-block">
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
data-auth-edit="{:auth('mall.goods/edit')}"
|
||||
data-auth-delete="{:auth('mall.goods/delete')}"
|
||||
data-auth-stock="{:auth('mall.goods/stock')}"
|
||||
data-auth-recycle="{:auth('mall.goods/recycle')}"
|
||||
lay-filter="currentTable">
|
||||
</table>
|
||||
</div>
|
||||
|
||||
11
app/admin/view/mall/goods/recycle.html
Normal file
11
app/admin/view/mall/goods/recycle.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="currentTable" class="layui-table layui-hide"
|
||||
data-auth-recycle="{:auth('mall.goods/recycle')}"
|
||||
lay-filter="currentTable">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
let cateSelects = JSON.parse('{$cate|json_encode=256|raw}')
|
||||
</script>
|
||||
@@ -6,8 +6,8 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="head_img" class="layui-input layui-col-xs6" lay-verify="required" lay-reqtext="请上传用户头像" placeholder="请上传用户头像" value="">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="head_img" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_head_img" data-upload-select="head_img" data-upload-number="one" data-upload-mimetype="image/*"><i class="fa fa-list"></i> 选择</a></span>
|
||||
<span><a class="layui-btn" data-upload="head_img" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-icon="image" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_head_img" data-upload-select="head_img" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="head_img" class="layui-input layui-col-xs6" lay-verify="required" lay-reqtext="请上传用户头像" placeholder="请上传用户头像" value="{$row.head_img|default=''}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="head_img" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn" data-upload="head_img" data-upload-number="one" data-upload-exts="png|jpg|ico|jpeg" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_head_img" data-upload-select="head_img" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="logo_image" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传LOGO图标" value="{:sysConfig('site','logo_image')}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="logo_image" data-upload-number="one" data-upload-exts="ico|png|jpg|jpeg"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn" data-upload="logo_image" data-upload-number="one" data-upload-exts="ico|png|jpg|jpeg" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_logo_image" data-upload-select="logo_image" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="site_ico" class="layui-input layui-col-xs6" lay-verify="required" placeholder="请上传浏览器图标,ico类型" value="{:sysConfig('site','site_ico')}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="site_ico" data-upload-number="one" data-upload-exts="ico"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn" data-upload="site_ico" data-upload-number="one" data-upload-exts="ico" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_site_ico" data-upload-select="site_ico" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="layui-input-block layuimini-upload">
|
||||
<input name="admin_background" class="layui-input layui-col-xs6" placeholder="不填默认#333333" value="{:sysConfig('site','admin_background')}">
|
||||
<div class="layuimini-upload-btn">
|
||||
<span><a class="layui-btn" data-upload="admin_background" data-upload-number="one" data-upload-exts="png|jpg|jpeg"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn" data-upload="admin_background" data-upload-number="one" data-upload-exts="png|jpg|jpeg" data-upload-mimetype="image/*"><i class="fa fa-upload"></i> 上传</a></span>
|
||||
<span><a class="layui-btn layui-btn-normal" id="select_admin_background" data-upload-select="admin_background" data-upload-number="one"><i class="fa fa-list"></i> 选择</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -20,4 +20,5 @@
|
||||
<button class="layui-btn layui-btn-sm layuimini-btn-primary" data-treetable-refresh><i class="fa fa-refresh"></i></button>
|
||||
<button class="layui-btn layui-btn-normal layui-btn-sm {if !auth('system.menu/add')}layui-hide{/if}" data-open="system.menu/add" data-title="添加"><i class="fa fa-plus"></i> 添加</button>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-danger {if !auth('system.menu/delete')}layui-hide{/if}" data-url="system.menu/delete" data-treetable-delete="currentTableRenderId"><i class="fa fa-trash-o"></i> 删除</button>
|
||||
<button class="layui-btn layui-btn-sm" type="button" data-treetable-arrow data-arrow="up"><i class="fa fa-arrow-up"></i> 一键折叠</button>
|
||||
</script>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// 应用公共文件
|
||||
|
||||
use app\common\service\AuthService;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use think\db\exception\DataNotFoundException;
|
||||
use think\db\exception\DbException;
|
||||
use think\db\exception\ModelNotFoundException;
|
||||
@@ -115,6 +117,48 @@ function editor_textarea(?string $detail, string $name = 'desc', string $placeho
|
||||
'ckeditor' => "<textarea name='{$name}' rows='20' class='layui-textarea editor' placeholder='{$placeholder}'>{$detail}</textarea>",
|
||||
'ueditor' => "<script type='text/plain' id='{$name}' name='{$name}' class='editor' data-content='{$detail}'></script>",
|
||||
'EasyMDE' => "<textarea id='{$name}' class='editor' name='{$name}'>{$detail}</textarea>",
|
||||
default => "<div class='wangEditor_div'><textarea name='{$name}' rows='20' class='layui-textarea editor layui-hide'>{$detail}</textarea><div id='editor_toolbar_{$name}'></div><div id='editor_{$name}' style='height: 300px'></div></div>",
|
||||
default => "<div class='wangEditor_div'><textarea name='{$name}' rows='20' class='layui-textarea editor layui-hide'>{$detail}</textarea><div id='editor_toolbar_{$name}'></div><div id='editor_{$name}' style='height: 500px'></div></div>",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc 导出excel
|
||||
* @tip 追求性能请使用 xlsWriter https://xlswriter-docs.viest.me/zh-cn
|
||||
* @param array $header
|
||||
* @param array $list
|
||||
* @param string $fileName
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
function exportExcel(array $header = [], array $list = [], string $fileName = ''): void
|
||||
{
|
||||
if (empty($fileName)) $fileName = time();
|
||||
if (empty($header) || empty($list)) throw new \Exception('导出数据不能为空');
|
||||
$spreadsheet = new Spreadsheet();
|
||||
$sheet = $spreadsheet->getActiveSheet();
|
||||
$headers = array_column($header, 0) ?? array_keys($list[0]);
|
||||
$sheet->fromArray([$headers], null, 'A1');
|
||||
$rowIndex = 2;
|
||||
foreach ($list as $row) {
|
||||
$rowData = [];
|
||||
foreach ($header as $item) {
|
||||
$value = $row[$item[1]] ?? '';
|
||||
if ($value === null) {
|
||||
$rowData[] = '';
|
||||
continue;
|
||||
}
|
||||
$rowData[] = $value;
|
||||
}
|
||||
$sheet->fromArray([$rowData], null, "A{$rowIndex}");
|
||||
$rowIndex++;
|
||||
}
|
||||
foreach (range('A', $sheet->getHighestColumn()) as $col) {
|
||||
$sheet->getColumnDimension($col)->setAutoSize(true);
|
||||
}
|
||||
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
header('Content-Disposition: attachment;filename="' . $fileName . '.xlsx"');
|
||||
header('Cache-Control: max-age=0');
|
||||
$writer = new Xlsx($spreadsheet);
|
||||
$writer->save('php://output');
|
||||
die();
|
||||
}
|
||||
@@ -19,9 +19,9 @@ class AdminController extends BaseController
|
||||
/**
|
||||
* 当前模型
|
||||
* @Model
|
||||
* @var object
|
||||
* @var mixed
|
||||
*/
|
||||
protected object $model;
|
||||
protected static mixed $model;
|
||||
|
||||
/**
|
||||
* 字段排序
|
||||
@@ -172,7 +172,7 @@ class AdminController extends BaseController
|
||||
$where = [];
|
||||
$excludes = [];
|
||||
// 判断是否关联查询
|
||||
$tableName = Str::snake(lcfirst($this->model->getName()));
|
||||
$tableName = Str::snake(lcfirst((new self::$model)->getName()));
|
||||
foreach ($filters as $key => $val) {
|
||||
if (in_array($key, $excludeFields)) {
|
||||
$excludes[$key] = $val;
|
||||
@@ -218,7 +218,7 @@ class AdminController extends BaseController
|
||||
public function selectList(): Json
|
||||
{
|
||||
$fields = input('selectFields');
|
||||
$data = $this->model->where($this->selectWhere)->field($fields)->select()->toArray();
|
||||
$data = self::$model::where($this->selectWhere)->field($fields)->select()->toArray();
|
||||
$this->success(null, $data);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ class Install extends BaseController
|
||||
$errorInfo = '已安装系统,如需重新安装请删除文件:/config/install/lock/install.lock,或者删除 /install 路由';
|
||||
}elseif (version_compare(phpversion(), '8.1.0', '<')) {
|
||||
$errorInfo = 'PHP版本不能小于8.1.0';
|
||||
}elseif (!extension_loaded("PDO")) {
|
||||
$errorInfo = '当前未开启PDO,无法进行安装';
|
||||
}elseif (!extension_loaded("pdo_mysql")) {
|
||||
$errorInfo = '当前未开启pdo_mysql,无法进行安装';
|
||||
}
|
||||
if (!is_file(root_path() . '.env')) {
|
||||
$errorInfo = '.env 文件不存在,请先配置 .env 文件';
|
||||
@@ -105,12 +105,12 @@ class Install extends BaseController
|
||||
foreach ($sqlArray as $sql) {
|
||||
$pdo->query($sql);
|
||||
}
|
||||
$_password = password($password);
|
||||
$tableName = 'system_admin';
|
||||
$update = [
|
||||
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
||||
$tableName = 'system_admin';
|
||||
$update = [
|
||||
'username' => $username,
|
||||
'head_img' => '/static/admin/images/head.jpg',
|
||||
'password' => $_password,
|
||||
'password' => $hashedPassword,
|
||||
'create_time' => time(),
|
||||
'update_time' => time()
|
||||
];
|
||||
|
||||
@@ -29,9 +29,8 @@
|
||||
"topthink/think-filesystem": "^2.0",
|
||||
"aliyuncs/oss-sdk-php": "^2.7.2",
|
||||
"qcloud/cos-sdk-v5": "^2.6",
|
||||
"jianyan74/php-excel": "^1.0.2",
|
||||
"doctrine/annotations": "^2.0.0",
|
||||
"phpoffice/phpspreadsheet": "^1.28",
|
||||
"phpoffice/phpspreadsheet": "^4.1.0",
|
||||
"myclabs/php-enum": "^1.8",
|
||||
"qiniu/php-sdk": "^7.11.0",
|
||||
"wolf-leo/phplogviewer": "^0.11.3",
|
||||
|
||||
@@ -88,7 +88,7 @@ CREATE TABLE `ea_system_admin`
|
||||
`auth_ids` varchar(255) DEFAULT NULL COMMENT '角色权限ID',
|
||||
`head_img` varchar(255) DEFAULT NULL COMMENT '头像',
|
||||
`username` varchar(50) NOT NULL DEFAULT '' COMMENT '用户登录名',
|
||||
`password` char(40) NOT NULL DEFAULT '' COMMENT '用户登录密码',
|
||||
`password` varchar(255) NOT NULL DEFAULT '' COMMENT '用户登录密码',
|
||||
`phone` varchar(16) DEFAULT NULL COMMENT '联系手机号',
|
||||
`remark` varchar(255) DEFAULT '' COMMENT '备注说明',
|
||||
`login_num` bigint(20) unsigned DEFAULT '0' COMMENT '登录次数',
|
||||
|
||||
2
extend/.gitignore
vendored
2
extend/.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
!.gitignore
|
||||
|
||||
2
log.md
2
log.md
@@ -1,3 +1,5 @@
|
||||
> 2025年03月27日 重构了 `model` 的调用方式 原因查看 [https://github.com/top-think/think-orm/issues/704](https://github.com/top-think/think-orm/issues/704)
|
||||
>
|
||||
> 2025年01月01日 `PHP` 要求升级到 `8.1+`
|
||||
>
|
||||
> 2024年05月 更新 `EasyAdmin8` 重置版,多处语法、写法进行变更
|
||||
@@ -4,6 +4,10 @@
|
||||
@import url("../css/themes/index.css");
|
||||
@import url("../css/iconfont.css");
|
||||
|
||||
:root {
|
||||
--ea8-theme-main-color: #16b777;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
@@ -75,8 +79,8 @@ body {
|
||||
|
||||
/**重写layui表格自适应*/
|
||||
.layuimini-container .layui-table-cell {
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
height: 50px;
|
||||
line-height: 42px;
|
||||
}
|
||||
|
||||
/**数据表格-搜索表单样式*/
|
||||
@@ -304,9 +308,17 @@ table样式
|
||||
}
|
||||
|
||||
.layui-form-select dl {
|
||||
border: 1px #16b777 solid;
|
||||
border: 1px var(--ea8-theme-main-color) solid;
|
||||
border-top: none;
|
||||
z-index: 99999;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.layui-form-select dl dd.layui-this {
|
||||
background-color: var(--ea8-theme-main-color);
|
||||
border-top: none;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.form-search .layui-form-select dl {
|
||||
@@ -517,4 +529,12 @@ table样式
|
||||
.wangEditor_div {
|
||||
z-index: 99999;
|
||||
border: 1px solid var(--w-e-textarea-slight-border-color);
|
||||
}
|
||||
|
||||
.layui-input:focus, .layui-textarea:focus {
|
||||
border-color: var(--ea8-theme-main-color) !important;
|
||||
}
|
||||
|
||||
.layui-tabs-item {
|
||||
height: 100%;
|
||||
}
|
||||
@@ -146,7 +146,7 @@ define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTh
|
||||
showComposerInfo: function () {
|
||||
// <div style="padding: 25px;">12313</div>
|
||||
let html = ``
|
||||
ea.request.post({
|
||||
ea.request.get({
|
||||
url: ea.url('ajax/composerInfo'),
|
||||
}, function (success) {
|
||||
let data = success.data
|
||||
@@ -160,6 +160,7 @@ define(["jquery", "easy-admin", "echarts", "echarts-theme", "miniAdmin", "miniTh
|
||||
area: ['50%', '90%'],
|
||||
shade: 0.8,
|
||||
shadeClose: true,
|
||||
scrollbar: false,
|
||||
content: html,
|
||||
success: function () {
|
||||
layui.code({elem: '.code-demo', theme: 'dark', lang: 'php'});
|
||||
|
||||
@@ -27,6 +27,12 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (event) {
|
||||
if (event.key === 'Enter' || event.keyCode === 13) {
|
||||
$('.login-btn').trigger('click')
|
||||
}
|
||||
});
|
||||
|
||||
$('.login-tip').on('click', function () {
|
||||
$('.icon-nocheck').click();
|
||||
});
|
||||
|
||||
@@ -10,6 +10,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
export_url: 'mall.goods/export',
|
||||
modify_url: 'mall.goods/modify',
|
||||
stock_url: 'mall.goods/stock',
|
||||
recycle_url: 'mall.goods/recycle',
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -27,7 +28,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
icon: 'fa fa-plus ',
|
||||
extend: 'data-width="90%" data-height="95%"',
|
||||
}],
|
||||
'delete', 'export'],
|
||||
'delete', 'export', 'recycle'],
|
||||
cols: [[
|
||||
{type: "checkbox"},
|
||||
{field: 'id', width: 80, title: 'ID', searchOp: '='},
|
||||
@@ -92,6 +93,18 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
aiOptimization(data)
|
||||
},
|
||||
})
|
||||
|
||||
var demo1 = xmSelect.render({
|
||||
el: '#demo1',
|
||||
name: 'xxx', // form表单提交的name
|
||||
theme: {color: getComputedStyle(document.documentElement).getPropertyValue('--ea8-theme-main-color') || '#16b777'},
|
||||
data: [
|
||||
{name: 'Make', value: 1},
|
||||
{name: 'PHP', value: 2},
|
||||
{name: 'Great Again', value: 3},
|
||||
]
|
||||
})
|
||||
|
||||
ea.listen();
|
||||
},
|
||||
edit: function () {
|
||||
@@ -102,11 +115,95 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
aiOptimization(data)
|
||||
},
|
||||
})
|
||||
|
||||
var demo1 = xmSelect.render({
|
||||
el: '#demo1',
|
||||
name: 'xxx', // form表单提交的name
|
||||
theme: {color: getComputedStyle(document.documentElement).getPropertyValue('--ea8-theme-main-color') || '#16b777'},
|
||||
data: [
|
||||
{name: 'Make', value: 1},
|
||||
{name: 'PHP', value: 2, selected: true,},
|
||||
{name: 'Great Again', value: 3, selected: true,},
|
||||
]
|
||||
})
|
||||
|
||||
ea.listen();
|
||||
},
|
||||
stock: function () {
|
||||
ea.listen();
|
||||
},
|
||||
recycle: function () {
|
||||
init.index_url = init.recycle_url;
|
||||
ea.table.render({
|
||||
init: init,
|
||||
toolbar: ['refresh',
|
||||
[{
|
||||
class: 'layui-btn layui-btn-sm',
|
||||
method: 'get',
|
||||
field: 'id',
|
||||
icon: 'fa fa-refresh',
|
||||
text: '全部恢复',
|
||||
title: '确定恢复?',
|
||||
auth: 'recycle',
|
||||
url: init.recycle_url + '?type=restore',
|
||||
checkbox: true
|
||||
}, {
|
||||
class: 'layui-btn layui-btn-danger layui-btn-sm',
|
||||
method: 'get',
|
||||
field: 'id',
|
||||
icon: 'fa fa-delete',
|
||||
text: '彻底删除',
|
||||
title: '确定彻底删除?',
|
||||
auth: 'recycle',
|
||||
url: init.recycle_url + '?type=delete',
|
||||
checkbox: true
|
||||
}], 'export',
|
||||
],
|
||||
cols: [[
|
||||
{type: "checkbox"},
|
||||
{field: 'id', width: 80, title: 'ID', searchOp: '='},
|
||||
{field: 'sort', width: 80, title: '排序', edit: 'text'},
|
||||
{field: 'cate_id', minWidth: 80, title: '商品分类', search: 'select', selectList: cateSelects, laySearch: true},
|
||||
{field: 'title', minWidth: 80, title: '商品名称'},
|
||||
{field: 'logo', minWidth: 80, title: '分类图片', search: false, templet: ea.table.image},
|
||||
{field: 'status', title: '状态', width: 85, selectList: {0: '禁用', 1: '启用'}},
|
||||
// 演示多选,实际数据库并无 status2 字段,搜索后会报错
|
||||
{
|
||||
field: 'status2', title: '演示多选', width: 105, search: 'xmSelect', selectList: {1: '模拟选项1', 2: '模拟选项2', 3: '模拟选项3', 4: '模拟选项4', 5: '模拟选项5'},
|
||||
searchOp: 'in', templet: function (res) {
|
||||
// 根据自己实际项目进行输出
|
||||
return res?.status2 || '模拟数据'
|
||||
}
|
||||
},
|
||||
{field: 'create_time', minWidth: 80, title: '创建时间', search: 'range'},
|
||||
{field: 'delete_time', minWidth: 80, title: '删除时间', search: 'range'},
|
||||
{
|
||||
width: 250,
|
||||
title: '操作',
|
||||
templet: ea.table.tool,
|
||||
operat: [
|
||||
[{
|
||||
title: '确认恢复?',
|
||||
text: '恢复数据',
|
||||
filed: 'id',
|
||||
url: init.recycle_url + '?type=restore',
|
||||
method: 'get',
|
||||
auth: 'recycle',
|
||||
class: 'layui-btn layui-btn-xs layui-btn-success',
|
||||
}, {
|
||||
title: '想好了吗?',
|
||||
text: '彻底删除',
|
||||
filed: 'id',
|
||||
method: 'get',
|
||||
url: init.recycle_url + '?type=delete',
|
||||
auth: 'recycle',
|
||||
class: 'layui-btn layui-btn-xs layui-btn-normal layui-bg-red',
|
||||
}]]
|
||||
}
|
||||
]],
|
||||
});
|
||||
ea.listen();
|
||||
},
|
||||
};
|
||||
|
||||
function aiOptimization(data) {
|
||||
|
||||
@@ -18,7 +18,7 @@ define(["jquery", "easy-admin", "miniTab"], function ($, ea, miniTab) {
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend>提示</legend>
|
||||
<div class="layui-field-box">
|
||||
<p><a class="layui-font-blue" target="_blank" rel="nofollow" href="https://edocs.easyadmin8.top/curd/command.html">命令可查询文档</a></p>
|
||||
<p><a class="layui-font-blue" target="_blank" rel="nofollow" href="https://edocs.easyadmin8.top/#/md/curd/command">命令可查询文档</a></p>
|
||||
</div>
|
||||
</fieldset>
|
||||
<form class="layui-form layui-form-pane" action="">
|
||||
|
||||
@@ -121,6 +121,22 @@ define(["jquery", "easy-admin", "treetable", "iconPickerFa", "autocomplete"], fu
|
||||
return false;
|
||||
});
|
||||
|
||||
$('body').on('click', '[data-treetable-arrow]', function () {
|
||||
const $icon = $(this).find('i');
|
||||
const $textNode = $icon[0].nextSibling;
|
||||
if ($icon.hasClass('fa-arrow-up')) {
|
||||
treetable.foldAll(init.table_elem);
|
||||
$icon.removeClass('fa-arrow-up').addClass('fa-arrow-down');
|
||||
$textNode.textContent = ' 一键展开';
|
||||
$(this).attr('data-arrow', 'down');
|
||||
} else {
|
||||
treetable.expandAll(init.table_elem);
|
||||
$icon.removeClass('fa-arrow-down').addClass('fa-arrow-up');
|
||||
$textNode.textContent = ' 一键折叠';
|
||||
$(this).attr('data-arrow', 'up');
|
||||
}
|
||||
})
|
||||
|
||||
ea.table.listenSwitch({filter: 'status', url: init.modify_url});
|
||||
|
||||
ea.table.listenEdit(init, 'currentTable', init.table_render_id, true);
|
||||
|
||||
@@ -49,7 +49,11 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
}
|
||||
]],
|
||||
cols: [[
|
||||
{field: 'node', minWidth: 200, align: 'left', title: '系统节点'},
|
||||
{
|
||||
field: 'node', minWidth: 200, align: 'left', title: '系统节点', templet: function (d) {
|
||||
return `<span>${d.node}</span>`;
|
||||
}
|
||||
},
|
||||
{field: 'title', minWidth: 80, title: '节点名称 <i class="table-edit-tips color-red">*</i>', edit: 'text'},
|
||||
{field: 'update_time', minWidth: 80, title: '更新时间', search: 'range'},
|
||||
{field: 'is_auth', title: '节点控制', width: 85, search: 'select', selectList: {0: '禁用', 1: '启用'}, templet: ea.table.switch},
|
||||
|
||||
@@ -154,4 +154,46 @@ function prettyFormat(str) {
|
||||
return ''
|
||||
}
|
||||
return "<pre>" + result + "</pre>"
|
||||
}
|
||||
}
|
||||
|
||||
if (self === top) {
|
||||
console.group('温馨提示');
|
||||
console.log(`%c
|
||||
|
||||
▄▄ ▄▄
|
||||
▀███▀▀▀███ ██ ▀███ ██ ▄█▄▀▄██▄
|
||||
██ ▀█ ▄██▄ ██ ██ ██
|
||||
██ █ ▄█▀██▄ ▄██▀█████▀ ▀██▀ ▄█▀██▄ ▄█▀▀███ ▀████████▄█████▄ ▀███ ▀████████▄ ▀██▄ ▄▄█
|
||||
██████ ██ ██ ██ ▀▀ ██ ▄█ ▄█ ▀██ ▄██ ██ ██ ██ ██ ██ ██ ██ ▄█████▄
|
||||
██ █ ▄▄█████ ▀█████▄ ██ ▄█ ████████ ███ ██ ██ ██ ██ ██ ██ ██ ██ ▀███
|
||||
██ ▄██ ██ █▄ ██ ███ █▀ ██ ▀██ ██ ██ ██ ██ ██ ██ ██ ██ ▀██
|
||||
▄██████████████▀██▄██████▀ ▄█ ▄███▄ ▄████▄ ▀████▀███▄████ ████ ████▄████▄████ ████▄███████
|
||||
▄█
|
||||
██▀
|
||||
%c
|
||||
|
||||
官方网站:https://easyadmin8.top
|
||||
|
||||
官方文档:https://edocs.easyadmin8.top
|
||||
|
||||
问答社区:https://meta.easyadmin8.top
|
||||
|
||||
%c重要事情说3遍:
|
||||
%c
|
||||
常见问题:https://easyadmin8.top/guide/question.html
|
||||
|
||||
常见问题:https://easyadmin8.top/guide/question.html
|
||||
|
||||
常见问题:https://easyadmin8.top/guide/question.html
|
||||
|
||||
%c遇到问题先把 DEBUG 模式打开,然后把错误信息找出来,当不能解决的时候再去社区提问或者QQ群交流
|
||||
`,
|
||||
"color:#4290f7;font-weight:bold;font-size:10px;",
|
||||
"color:#5672cd;",
|
||||
"color:#ff5722;font-weight:bold;font-size:1rem;",
|
||||
"color:#5672cd;",
|
||||
"color:#ff5722;font-weight:bold;font-size:1rem;background:#f9de97;",
|
||||
);
|
||||
console.groupEnd();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,16 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
|
||||
//切换日夜模式
|
||||
window.onInitElemStyle = function () {
|
||||
miniTheme.renderElemStyle();
|
||||
$('iframe').each(function (index, iframe) {
|
||||
if (typeof iframe.contentWindow.onInitElemStyle == "function") {
|
||||
iframe.contentWindow.onInitElemStyle();
|
||||
}
|
||||
});
|
||||
try {
|
||||
miniTheme.renderElemStyle();
|
||||
$('iframe').each(function (index, iframe) {
|
||||
if (typeof iframe.contentWindow.onInitElemStyle == "function") {
|
||||
iframe.contentWindow.onInitElemStyle();
|
||||
}
|
||||
});
|
||||
miniTheme.changeThemeMainColor();
|
||||
} catch (e) {
|
||||
}
|
||||
};
|
||||
window.onInitElemStyle();
|
||||
|
||||
@@ -253,7 +257,7 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
}
|
||||
|
||||
// 初始化表格左上方工具栏
|
||||
options.toolbar = options.toolbar || ['refresh', 'add', 'delete', 'export'];
|
||||
options.toolbar = options.toolbar || ['refresh', 'add', 'delete', 'export', 'recycle'];
|
||||
options.toolbar = admin.table.renderToolbar(options.toolbar, options.elem, options.id, options.init);
|
||||
|
||||
// 判断是否有操作列表权限
|
||||
@@ -312,6 +316,14 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
if (admin.checkAuth('export', elem)) {
|
||||
toolbarHtml += '<button class="layui-btn layui-btn-sm layui-btn-success easyadmin-export-btn" data-url="' + init.export_url + '" data-table-export="' + tableId + '"><i class="fa fa-file-excel-o"></i> 导出</button>\n';
|
||||
}
|
||||
} else if (v === 'recycle') {
|
||||
if (init.recycle_url === undefined) {
|
||||
console.warn('未定义回收站地址 init.recycle_url')
|
||||
return false
|
||||
}
|
||||
if (admin.checkAuth('recycle', elem)) {
|
||||
toolbarHtml += '<button class="layui-btn layui-btn-sm layui-bg-orange" data-open="' + init.recycle_url + '" data-title="回收站"><i class="fa fa-recycle"></i> 回收站</button>\n';
|
||||
}
|
||||
} else if (typeof v === "object") {
|
||||
$.each(v, function (ii, vv) {
|
||||
vv.class = vv.class || '';
|
||||
@@ -364,7 +376,7 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
var selectHtml = '';
|
||||
$.each(d.selectList, function (sI, sV) {
|
||||
var selected = '';
|
||||
if (sI === d.searchValue) {
|
||||
if (sI == d.searchValue) {
|
||||
selected = 'selected=""';
|
||||
}
|
||||
selectHtml += '<option value="' + sI + '" ' + selected + '>' + sV + '</option>/n';
|
||||
@@ -387,7 +399,7 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
formHtml += '\t<div class="layui-form-item layui-inline">\n' +
|
||||
'<label class="layui-form-label">' + d.title + '</label>\n' +
|
||||
'<div class="layui-input-inline">\n' +
|
||||
'<div id="c-' + d.fieldAlias + '" class="tableSearch-xmSelect xmSelect-' + d.fieldAlias + '" name="' + d.fieldAlias + '" data-search-op="' + d.searchOp + '"></div>\n' +
|
||||
'<div id="c-' + d.fieldAlias + '" class="tableSearch-xmSelect xmSelect-' + d.fieldAlias + '" name="' + d.fieldAlias + '" data-search-op="' + d.searchOp + '" data-search-value="' + d.searchValue + '"></div>\n' +
|
||||
'</div>\n' +
|
||||
'</div>';
|
||||
init.xmSelectList[d.fieldAlias] = d.selectList
|
||||
@@ -865,12 +877,15 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
listenTableSearch: function (tableId) {
|
||||
if (Object.keys(init.xmSelectList).length > 0) {
|
||||
$.each(init.xmSelectList, function (index, value) {
|
||||
let xmSearchValue = $('#c-' + index).data('search-value') || [];
|
||||
if (!Array.isArray(xmSearchValue)) xmSearchValue = (xmSearchValue.toString()).split(',')
|
||||
const keysArray = Object.keys(value).map((key) => {
|
||||
return {name: value[key], value: key}
|
||||
return {name: value[key], value: key, selected: xmSearchValue.indexOf(key) !== -1}
|
||||
})
|
||||
init.xmSelectModel[index] = xmSelect.render({
|
||||
el: '.xmSelect-' + index, language: 'zn', data: keysArray, name: index,
|
||||
filterable: true, paging: true, pageSize: 10, theme: {color: '#16b777'}, toolbar: {show: true},
|
||||
filterable: true, paging: true, pageSize: 10, toolbar: {show: true},
|
||||
theme: {color: getComputedStyle(document.documentElement).getPropertyValue('--ea8-theme-main-color') || '#16b777'}
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -986,7 +1001,21 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
},
|
||||
listenSort: function (options) {
|
||||
table.on('sort(' + options.layFilter + ')', function (obj) {
|
||||
let defaultWhere = options.where || {}
|
||||
let defaultWhere = {}
|
||||
$.each(options.cols, function (_, colsV) {
|
||||
let formatFilter = {}
|
||||
let formatOp = {}
|
||||
$.each(colsV, function (i, v) {
|
||||
if (v.field) {
|
||||
if ($('#c-' + v.field).val()) {
|
||||
formatFilter[v.field] = $('#c-' + v.field).val()
|
||||
formatOp[v.field] = v.searchOp || '='
|
||||
defaultWhere['filter'] = JSON.stringify(formatFilter);
|
||||
defaultWhere['op'] = JSON.stringify(formatOp);
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
let sortWhere = {tableOrder: obj.field + ' ' + obj.type}
|
||||
table.reload(options.id, {
|
||||
where: {...defaultWhere, ...sortWhere}
|
||||
@@ -1023,8 +1052,9 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
maxmin: true,
|
||||
anim: 0,
|
||||
moveOut: true,
|
||||
move: false,
|
||||
shade: 0.3,
|
||||
shadeClose: shadeClose,
|
||||
scrollbar: false,
|
||||
before: function () {
|
||||
},
|
||||
success: function (layero, index) {
|
||||
@@ -1770,7 +1800,7 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
layer.open({
|
||||
'title': options?.title || 'AI建议',
|
||||
type: 1,
|
||||
area: options?.area || ['42%', '60%'],
|
||||
area: options?.area || (admin.checkMobile() ? ['95%', '60%'] : ['50%', '60%']),
|
||||
shade: options?.shade || 0,
|
||||
shadeClose: options?.shadeClose || false,
|
||||
scrollbar: options?.scrollbar || false,
|
||||
@@ -1780,11 +1810,23 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
success: function (layero, index) {
|
||||
let elem = document.getElementById(id)
|
||||
if (options?.stream) {
|
||||
clearTimeout(aiStreamTimeout)
|
||||
aiStreamCurrentIndex = 0
|
||||
setTimeout(() => {
|
||||
admin.ai.streamOutput(elem, content)
|
||||
}, 300)
|
||||
let index = 0;
|
||||
let lastTime = performance.now();
|
||||
const interval = options.interval || 100;
|
||||
|
||||
function typeCharacter(currentTime) {
|
||||
if (index < content.length) {
|
||||
if (currentTime - lastTime >= interval) {
|
||||
elem.innerHTML += content.charAt(index);
|
||||
index++;
|
||||
lastTime = currentTime;
|
||||
elem.scrollIntoView({behavior: "smooth", block: "end"});
|
||||
}
|
||||
requestAnimationFrame(typeCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(typeCharacter);
|
||||
} else {
|
||||
content = content.replace(/\r\n/g, '<br>').replace(/\n/g, '<br>')
|
||||
setTimeout(() => {
|
||||
@@ -1797,28 +1839,8 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
}
|
||||
})
|
||||
},
|
||||
streamOutput: function (dom, htmlContent) {
|
||||
const chunkSize = 1;
|
||||
let length = htmlContent.length;
|
||||
if (aiStreamCurrentIndex < length) {
|
||||
const endIndex = Math.min(aiStreamCurrentIndex + chunkSize, length);
|
||||
const chunk = htmlContent.slice(aiStreamCurrentIndex, endIndex);
|
||||
const tempDiv = document.createElement('div');
|
||||
tempDiv.innerHTML = chunk;
|
||||
while (tempDiv.firstChild) {
|
||||
dom.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
aiStreamCurrentIndex = endIndex;
|
||||
aiStreamTimeout = setTimeout(() => {
|
||||
admin.ai.streamOutput(dom, htmlContent);
|
||||
dom.scrollIntoView({behavior: "smooth", block: "end"});
|
||||
}, 60);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
var aiStreamCurrentIndex = 0;
|
||||
var aiStreamTimeout = null;
|
||||
|
||||
return admin;
|
||||
});
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
display: inline-block;
|
||||
height: 40px;
|
||||
vertical-align: middle;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layuimini-logo h1 {
|
||||
@@ -123,43 +124,47 @@
|
||||
|
||||
/**tab选项卡 */
|
||||
.layuimini-tab {
|
||||
margin: 0px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-content {
|
||||
.layuimini-tab .layui-tabs-scroll {
|
||||
position: marker;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tabs-body {
|
||||
height: calc(100% - 37px) !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-content .layui-tab-item {
|
||||
.layuimini-tab .layui-tabs-body .layui-tabs-item {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-content {
|
||||
padding: 0px;
|
||||
.layuimini-tab .layui-tabs-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title {
|
||||
.layuimini-tab .layui-tabs-header {
|
||||
border: none;
|
||||
border: 1px solid whitesmoke;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title li {
|
||||
.layuimini-tab .layui-tabs-header li {
|
||||
border-right: 1px solid whitesmoke;
|
||||
color: dimgray;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-tab-bar {
|
||||
.layuimini-tab .layui-tabs-header .layui-tab-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this:after {
|
||||
.layuimini-tab .layui-tabs-header .layui-this:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layuimini-tab-active {
|
||||
.layuimini-tab .layui-tabs-header .layuimini-tab-active {
|
||||
display: inline-block;
|
||||
background-color: lightgray;
|
||||
width: 9px;
|
||||
@@ -168,49 +173,52 @@
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this .layuimini-tab-active {
|
||||
background-color: #1aa094;
|
||||
.layuimini-tab .layui-tabs-header .layui-this .layuimini-tab-active {
|
||||
background-color: var(--ea8-theme-main-color);
|
||||
}
|
||||
|
||||
.layuimini-tab > .layui-tab-title, .layuimini-tab > .close-box {
|
||||
.layuimini-tab > .layui-tabs-header, .layuimini-tab > .close-box {
|
||||
height: 35px !important;
|
||||
}
|
||||
|
||||
.layuimini-tab > .layui-tab-title li, .layuimini-tab > .close-box li {
|
||||
.layuimini-tab > .layui-tabs-header li, .layuimini-tab > .close-box li {
|
||||
line-height: 35px !important;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title span {
|
||||
.layuimini-tab .layui-tabs-header span {
|
||||
color: #acafb1;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-this span {
|
||||
.layuimini-tab .layui-tabs-header .layui-this span {
|
||||
color: dimgray;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-tab-close {
|
||||
.layuimini-tab .layui-tabs-header .layui-tab-close {
|
||||
font-size: 12px !important;
|
||||
width: 14px !important;
|
||||
height: 14px !important;
|
||||
line-height: 16px !important;
|
||||
margin-left: 5px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .layui-tab-close:hover {
|
||||
.layuimini-tab .layui-tabs-header .layui-tab-close:hover {
|
||||
border-radius: 4em;
|
||||
background: #ff5722;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .disable-close + .layui-tab-close {
|
||||
.layuimini-tab .layui-tabs-header .disable-close + .layui-tab-close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-title .able-close + .layui-tab-close {
|
||||
.layuimini-tab .layui-tabs-header .able-close + .layui-tab-close {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-control > li {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
top: 0;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
width: 35px;
|
||||
@@ -221,7 +229,7 @@
|
||||
}
|
||||
|
||||
.layuimini-tab .layuimini-tab-roll-left {
|
||||
left: 0px;
|
||||
left: 0;
|
||||
border-right: whitesmoke 1px solid;
|
||||
border-left: whitesmoke 1px solid;
|
||||
}
|
||||
@@ -232,7 +240,7 @@
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-tool {
|
||||
right: 0px;
|
||||
right: 0;
|
||||
border-left: 1px solid whitesmoke;
|
||||
}
|
||||
|
||||
@@ -248,11 +256,11 @@
|
||||
}
|
||||
|
||||
.layuimini-tab.layui-tab-roll .layui-tab-control .layuimini-tab-roll-right {
|
||||
right: 0px;
|
||||
right: 0;
|
||||
border-right: 1px solid whitesmoke;
|
||||
}
|
||||
|
||||
.layuimini-tab.layui-tab-roll .layui-tab-title {
|
||||
.layuimini-tab.layui-tab-roll .layui-tabs-header {
|
||||
padding-left: 35px;
|
||||
padding-right: 35px;
|
||||
}
|
||||
@@ -262,13 +270,13 @@
|
||||
display: block;
|
||||
}
|
||||
|
||||
.layuimini-tab.layui-tab-tool .layui-tab-title {
|
||||
padding-left: 0px;
|
||||
.layuimini-tab.layui-tab-tool .layui-tabs-header {
|
||||
padding-left: 0;
|
||||
padding-right: 35px;
|
||||
}
|
||||
|
||||
|
||||
.layuimini-tab.layui-tab-rollTool .layui-tab-title {
|
||||
.layuimini-tab.layui-tab-rollTool .layui-tabs-header {
|
||||
padding-left: 35px;
|
||||
padding-right: 80px;
|
||||
}
|
||||
@@ -451,7 +459,7 @@
|
||||
|
||||
|
||||
/**其它 */
|
||||
.layui-tab-item {
|
||||
.layui-tabs-item {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
@@ -466,7 +474,7 @@
|
||||
}
|
||||
|
||||
.layui-tab {
|
||||
margin: 0 0 0 0;
|
||||
margin: 0;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
@@ -630,9 +638,10 @@
|
||||
.layuimini-tab-mousedown {
|
||||
display: none;
|
||||
width: 80px;
|
||||
position: absolute;
|
||||
top: 0px !important;
|
||||
left: 0px !important;
|
||||
position: fixed;
|
||||
top: 55px !important;
|
||||
left: 0 !important;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.layuimini-tab-mousedown dd a {
|
||||
@@ -640,26 +649,28 @@
|
||||
color: #484545;
|
||||
}
|
||||
|
||||
.layuimini-tab-make{
|
||||
.layuimini-tab-make {
|
||||
position: absolute;
|
||||
top: 36px;
|
||||
bottom: 0px;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background: rgb(255, 255, 255,0);
|
||||
padding: 0px;
|
||||
background: rgb(255, 255, 255, 0);
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
菜单缩放
|
||||
*/
|
||||
.popup-tips .layui-layer-TipsG{
|
||||
.popup-tips .layui-layer-TipsG {
|
||||
display: none;
|
||||
}
|
||||
.popup-tips.layui-layer-tips .layui-layer-content{
|
||||
|
||||
.popup-tips.layui-layer-tips .layui-layer-content {
|
||||
padding: 0;
|
||||
}
|
||||
.popup-tips .layui-nav-tree{
|
||||
|
||||
.popup-tips .layui-nav-tree {
|
||||
width: 150px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
@@ -670,13 +681,13 @@
|
||||
}
|
||||
|
||||
/**头部菜单字体间距*/
|
||||
.layui-layout-admin .layui-header .layuimini-header-menu.layuimini-pc-show,.layui-layout-admin .layui-header .layuimini-header-menu.layuimini-mobile-show {
|
||||
.layui-layout-admin .layui-header .layuimini-header-menu.layuimini-pc-show, .layui-layout-admin .layui-header .layuimini-header-menu.layuimini-mobile-show {
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
|
||||
/**左侧菜单更多下拉样式*/
|
||||
.layuimini-menu-left .layui-nav-more,.layuimini-menu-left-zoom .layui-nav-more {
|
||||
.layuimini-menu-left .layui-nav-more, .layuimini-menu-left-zoom .layui-nav-more {
|
||||
font-family: layui-icon !important;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
@@ -695,10 +706,11 @@
|
||||
margin-top: -6px !important;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-more:before,.layuimini-menu-left-zoom .layui-nav-more:before {
|
||||
.layuimini-menu-left .layui-nav-more:before, .layuimini-menu-left-zoom .layui-nav-more:before {
|
||||
content: "\e61a";
|
||||
}
|
||||
.layuimini-menu-left .layui-nav-itemed > a > .layui-nav-more,.layuimini-menu-left-zoom .layui-nav-itemed > a > .layui-nav-more {
|
||||
|
||||
.layuimini-menu-left .layui-nav-itemed > a > .layui-nav-more, .layuimini-menu-left-zoom .layui-nav-itemed > a > .layui-nav-more {
|
||||
transform: rotate(180deg);
|
||||
-ms-transform: rotate(180deg);
|
||||
-moz-transform: rotate(180deg);
|
||||
@@ -706,10 +718,10 @@
|
||||
-o-transform: rotate(180deg);
|
||||
width: 12px;
|
||||
text-align: center;
|
||||
border-style:none;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
.layuimini-menu-left .layui-nav-itemed > a > .layui-nav-more:before,.layuimini-menu-left-zoom .layui-nav-itemed > a > .layui-nav-more:before {
|
||||
.layuimini-menu-left .layui-nav-itemed > a > .layui-nav-more:before, .layuimini-menu-left-zoom .layui-nav-itemed > a > .layui-nav-more:before {
|
||||
content: '\e61a';
|
||||
background-color: transparent;
|
||||
display: inline-block;
|
||||
@@ -717,7 +729,7 @@
|
||||
}
|
||||
|
||||
/**修复左侧菜单字体不对齐的问题*/
|
||||
.layuimini-menu-left .layui-nav-item a .fa,.layuimini-menu-left .layui-nav-item a .layui-icon{
|
||||
.layuimini-menu-left .layui-nav-item a .fa, .layuimini-menu-left .layui-nav-item a .layui-icon {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
@@ -773,16 +785,18 @@
|
||||
left: 95px !important;
|
||||
}
|
||||
|
||||
.layuimini-pc-show{
|
||||
.layuimini-pc-show {
|
||||
display: block;
|
||||
}
|
||||
.layuimini-mobile-show{
|
||||
|
||||
.layuimini-mobile-show {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/**菜单缩放*/
|
||||
.layuimini-mini .layuimini-menu-left .layui-nav-more,.layuimini-mini .layuimini-menu-left .layui-nav-child{
|
||||
display: none;!important;
|
||||
.layuimini-mini .layuimini-menu-left .layui-nav-more, .layuimini-mini .layuimini-menu-left .layui-nav-child {
|
||||
display: none;
|
||||
!important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -794,29 +808,31 @@
|
||||
/**
|
||||
todo 修复低版本IOS不能滑动问题, 但还是有问题, 低版本IOS部分情况下子页面无法自适应
|
||||
*/
|
||||
.layuimini-tab .layui-tab-content .layui-tab-item{
|
||||
.layuimini-tab .layui-tabs-body .layui-tabs-item {
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow: scroll;
|
||||
width:100%;
|
||||
height:100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.layuimini-tab .layui-tab-content .layui-tab-item iframe {
|
||||
.layuimini-tab .layui-tabs-body .layui-tabs-item iframe {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.layuimini-pc-show{
|
||||
.layuimini-pc-show {
|
||||
display: none;
|
||||
}
|
||||
.layuimini-mobile-show{
|
||||
|
||||
.layuimini-mobile-show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.layuimini-header-content {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.layui-layout-admin .layui-body .layui-tab-item.layui-show {
|
||||
.layui-layout-admin .layui-body .layui-tabs-item.layui-show {
|
||||
border-top: 1px solid #e2e2e2;
|
||||
}
|
||||
|
||||
@@ -854,7 +870,7 @@
|
||||
}
|
||||
|
||||
.layuimini-mini .layui-layout-admin .layui-body {
|
||||
left: 0!important;
|
||||
left: 0 !important;
|
||||
transition: left .2s;
|
||||
top: 0;
|
||||
z-index: 998;
|
||||
@@ -905,7 +921,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 550px){
|
||||
@media screen and (max-width: 550px) {
|
||||
|
||||
/**头部右侧数据*/
|
||||
.layuimini-multi-module.layuimini-mini .layuimini-header-content .layui-layout-right {
|
||||
|
||||
@@ -360,7 +360,7 @@ define(["jquery", "miniMenu", "miniTheme", "miniTab", "colorMode"], function ($,
|
||||
* 刷新
|
||||
*/
|
||||
$('body').on('click', '[data-refresh]', function () {
|
||||
$(".layui-tab-item.layui-show").find("iframe")[0].contentWindow.location.reload();
|
||||
$(".layui-tabs-item.layui-show").find("iframe")[0].contentWindow.location.reload();
|
||||
miniAdmin.success('刷新成功');
|
||||
});
|
||||
|
||||
|
||||
@@ -94,7 +94,14 @@ define(["jquery"], function ($) {
|
||||
renderLeftMenu :function(leftMenus,options){
|
||||
options = options || {};
|
||||
var me = this ;
|
||||
var leftMenusHtml = me.each(leftMenus || [],function (idx,leftMenu) { // 左侧菜单遍历
|
||||
let _i = 0
|
||||
// 左侧菜单遍历
|
||||
var leftMenusHtml = me.each(leftMenus || [],function (idx,leftMenu) {
|
||||
$(leftMenu).each(function (index, child) {
|
||||
options.childOpenClass = ''
|
||||
if (child.child && child.child.length && _i === 0) options.childOpenClass = ' layui-nav-itemed'
|
||||
_i++
|
||||
})
|
||||
var children = me.renderChildrenMenu(leftMenu.child, { childOpenClass:options.childOpenClass });
|
||||
var leftMenuHtml = me.compileMenu({
|
||||
href:leftMenu.href,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
define(["jquery"], function ($) {
|
||||
var element = layui.element,
|
||||
tabs = layui.tabs,
|
||||
$ = layui.$;
|
||||
|
||||
|
||||
@@ -44,15 +45,14 @@ define(["jquery"], function ($) {
|
||||
options.title = options.title || null;
|
||||
options.isIframe = options.isIframe || false;
|
||||
options.maxTabNum = options.maxTabNum || 20;
|
||||
if ($(".layuimini-tab .layui-tab-title li").length >= options.maxTabNum) {
|
||||
if ($(".layuimini-tab .layui-tabs-header li").length >= options.maxTabNum) {
|
||||
layer.msg('Tab窗口已达到限定数量,请先关闭部分Tab');
|
||||
return false;
|
||||
}
|
||||
var ele = element;
|
||||
if (options.isIframe) ele = parent.layui.element;
|
||||
ele.tabAdd('layuiminiTab', {
|
||||
title: '<span class="layuimini-tab-active"></span><span>' + options.title + '</span><i class="layui-icon layui-unselect layui-tab-close">ဆ</i>' //用于演示
|
||||
, content: '<iframe width="100%" height="100%" frameborder="no" border="0" marginwidth="0" marginheight="0" src="' + options.href + '"></iframe>'
|
||||
if (options.isIframe) tabs = parent.layui.tabs;
|
||||
tabs.add('layuiminiTab', {
|
||||
title: `<span class="layuimini-tab-active"></span><span>${options.title}</span><i class="layui-icon layui-unselect layui-tab-close">ဆ</i>`
|
||||
, content: `<iframe width="100%" height="100%" frameborder="no" border="0" src="${options.href}" style="width: 100%; height:100%;"></iframe>`
|
||||
, id: options.tabId
|
||||
});
|
||||
$('.layuimini-menu-left').attr('layuimini-tab-tag', 'add');
|
||||
@@ -65,7 +65,7 @@ define(["jquery"], function ($) {
|
||||
* @param tabId
|
||||
*/
|
||||
change: function (tabId) {
|
||||
element.tabChange('layuiminiTab', tabId);
|
||||
tabs.change('layuiminiTab', tabId);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -74,13 +74,10 @@ define(["jquery"], function ($) {
|
||||
* @param isParent
|
||||
*/
|
||||
delete: function (tabId, isParent) {
|
||||
// todo 未知BUG,不知道是不是layui问题,必须先删除元素
|
||||
$(".layuimini-tab .layui-tab-title .layui-unselect.layui-tab-bar").remove();
|
||||
|
||||
if (isParent === true) {
|
||||
parent.layui.element.tabDelete('layuiminiTab', tabId);
|
||||
parent.layui.tabs.close('layuiminiTab', tabId);
|
||||
} else {
|
||||
element.tabDelete('layuiminiTab', tabId);
|
||||
tabs.close('layuiminiTab', tabId);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -101,7 +98,7 @@ define(["jquery"], function ($) {
|
||||
isIframe: true,
|
||||
});
|
||||
}
|
||||
parent.layui.element.tabChange('layuiminiTab', options.href);
|
||||
parent.layui.tabs.change('layuiminiTab', options.href);
|
||||
parent.layer.close(loading);
|
||||
},
|
||||
|
||||
@@ -109,7 +106,7 @@ define(["jquery"], function ($) {
|
||||
* 在iframe层关闭当前tab方法
|
||||
*/
|
||||
deleteCurrentByIframe: function () {
|
||||
var ele = $(".layuimini-tab .layui-tab-title li.layui-this", parent.document);
|
||||
var ele = $(".layuimini-tab .layui-tabs-header li.layui-this", parent.document);
|
||||
if (ele.length > 0) {
|
||||
var layId = $(ele[0]).attr('lay-id');
|
||||
miniTab.delete(layId, true);
|
||||
@@ -123,14 +120,14 @@ define(["jquery"], function ($) {
|
||||
// 判断选项卡上是否有
|
||||
var checkTab = false;
|
||||
if (isIframe === undefined || isIframe === false) {
|
||||
$(".layui-tab-title li").each(function () {
|
||||
$(".layui-tabs-header li").each(function () {
|
||||
var checkTabId = $(this).attr('lay-id');
|
||||
if (checkTabId != null && checkTabId === tabId) {
|
||||
checkTab = true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
parent.layui.$(".layui-tab-title li").each(function () {
|
||||
parent.layui.$(".layui-tabs-header li").each(function () {
|
||||
var checkTabId = $(this).attr('lay-id');
|
||||
if (checkTabId != null && checkTabId === tabId) {
|
||||
checkTab = true;
|
||||
@@ -155,7 +152,7 @@ define(["jquery"], function ($) {
|
||||
'</dl>\n' +
|
||||
'</div>';
|
||||
var makeHtml = '<div class="layuimini-tab-make"></div>';
|
||||
$('.layuimini-tab .layui-tab-title').after(menuHtml);
|
||||
$('.layuimini-tab .layui-tabs-header').after(menuHtml);
|
||||
$('.layuimini-tab .layui-tab-content').after(makeHtml);
|
||||
},
|
||||
|
||||
@@ -233,7 +230,7 @@ define(["jquery"], function ($) {
|
||||
maxTabNum: options.maxTabNum,
|
||||
});
|
||||
}
|
||||
element.tabChange('layuiminiTab', tabId);
|
||||
tabs.change('layuiminiTab', tabId);
|
||||
layer.close(loading);
|
||||
});
|
||||
|
||||
@@ -262,14 +259,14 @@ define(["jquery"], function ($) {
|
||||
maxTabNum: options.maxTabNum,
|
||||
});
|
||||
}
|
||||
parent.layui.element.tabChange('layuiminiTab', tabId);
|
||||
parent.layui.tabs.change('layuiminiTab', tabId);
|
||||
parent.layer.close(loading);
|
||||
});
|
||||
|
||||
/**
|
||||
* 关闭选项卡
|
||||
**/
|
||||
$('body').on('click', '.layuimini-tab .layui-tab-title .layui-tab-close', function () {
|
||||
$('body').on('click', '.layuimini-tab .layui-tabs-header .layui-tab-close', function () {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var $parent = $(this).parent();
|
||||
var tabId = $parent.attr('lay-id');
|
||||
@@ -285,7 +282,7 @@ define(["jquery"], function ($) {
|
||||
$('body').on('click', '[layuimini-tab-close]', function () {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var closeType = $(this).attr('layuimini-tab-close');
|
||||
$(".layuimini-tab .layui-tab-title li").each(function () {
|
||||
$(".layuimini-tab .layui-tabs-header li").each(function () {
|
||||
var tabId = $(this).attr('lay-id');
|
||||
var id = $(this).attr('id');
|
||||
var isCurrent = $(this).hasClass('layui-this');
|
||||
@@ -307,7 +304,7 @@ define(["jquery"], function ($) {
|
||||
/**
|
||||
* 禁用网页右键
|
||||
*/
|
||||
$(".layuimini-tab .layui-tab-title").unbind("mousedown").bind("contextmenu", function (e) {
|
||||
$(".layuimini-tab .layui-tabs-header").unbind("mousedown").bind("contextmenu", function (e) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
@@ -315,10 +312,11 @@ define(["jquery"], function ($) {
|
||||
/**
|
||||
* 注册鼠标右键
|
||||
*/
|
||||
$('body').on('mousedown', '.layuimini-tab .layui-tab-title li', function (e) {
|
||||
var left = $(this).offset().left - $('.layuimini-tab ').offset().left + ($(this).width() / 2),
|
||||
$('body').on('mousedown', '.layuimini-tab .layui-tabs-header li', function (e) {
|
||||
var left = e.pageX ,
|
||||
tabId = $(this).attr('lay-id');
|
||||
if (e.which === 3) {
|
||||
e.preventDefault();
|
||||
miniTab.openTabRignMenu(tabId, left);
|
||||
}
|
||||
});
|
||||
@@ -337,7 +335,7 @@ define(["jquery"], function ($) {
|
||||
var loading = layer.load(0, {shade: false, time: 2 * 1000});
|
||||
var closeType = $(this).attr('layuimini-tab-menu-close'),
|
||||
currentTabId = $('.layuimini-tab-mousedown').attr('data-tab-id');
|
||||
$(".layuimini-tab .layui-tab-title li").each(function () {
|
||||
$(".layuimini-tab .layui-tabs-header li").each(function () {
|
||||
var tabId = $(this).attr('lay-id');
|
||||
var id = $(this).attr('id');
|
||||
if (id !== 'layuiminiHomeTabId') {
|
||||
@@ -368,7 +366,7 @@ define(["jquery"], function ($) {
|
||||
options.listenSwichCallback = options.listenSwichCallback || function () {
|
||||
|
||||
};
|
||||
element.on('tab(' + options.filter + ')', function (data) {
|
||||
tabs.on('afterChange(layuiminiTab)', function (data) {
|
||||
var tabId = $(this).attr('lay-id');
|
||||
if (options.urlHashLocation) {
|
||||
location.hash = tabId;
|
||||
@@ -403,10 +401,10 @@ define(["jquery"], function ($) {
|
||||
options.menuList = options.menuList || [];
|
||||
if (!options.urlHashLocation) return false;
|
||||
var tabId = location.hash.replace(/^#/, '');
|
||||
if (tabId === null || tabId === undefined || tabId ==='') return false;
|
||||
if (tabId === null || tabId === undefined || tabId === '') return false;
|
||||
|
||||
// 判断是否为首页
|
||||
if(tabId ===options.homeInfo.href) return false;
|
||||
if (tabId === options.homeInfo.href) return false;
|
||||
|
||||
// 判断是否为右侧菜单
|
||||
var menu = miniTab.searchMenu(tabId, options.menuList);
|
||||
@@ -419,7 +417,7 @@ define(["jquery"], function ($) {
|
||||
maxTabNum: options.maxTabNum,
|
||||
});
|
||||
$('.layuimini-menu-left').attr('layuimini-tab-tag', 'no');
|
||||
element.tabChange('layuiminiTab', tabId);
|
||||
tabs.change('layuiminiTab', tabId);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -436,7 +434,7 @@ define(["jquery"], function ($) {
|
||||
maxTabNum: options.maxTabNum,
|
||||
});
|
||||
$('.layuimini-menu-left').attr('layuimini-tab-tag', 'no');
|
||||
element.tabChange('layuiminiTab', tabId);
|
||||
tabs.change('layuiminiTab', tabId);
|
||||
isSearchMenu = true;
|
||||
return false;
|
||||
}
|
||||
@@ -452,7 +450,7 @@ define(["jquery"], function ($) {
|
||||
isIframe: false,
|
||||
maxTabNum: options.maxTabNum,
|
||||
});
|
||||
element.tabChange('layuiminiTab', tabId);
|
||||
tabs.change('layuiminiTab', tabId);
|
||||
return false;
|
||||
},
|
||||
|
||||
@@ -543,7 +541,7 @@ define(["jquery"], function ($) {
|
||||
* 自动定位
|
||||
*/
|
||||
rollPosition: function () {
|
||||
var $tabTitle = $('.layuimini-tab .layui-tab-title');
|
||||
var $tabTitle = $('.layuimini-tab .layui-tabs-header');
|
||||
var autoLeft = 0;
|
||||
$tabTitle.children("li").each(function () {
|
||||
if ($(this).hasClass('layui-this')) {
|
||||
@@ -562,7 +560,7 @@ define(["jquery"], function ($) {
|
||||
* @param direction
|
||||
*/
|
||||
rollClick: function (direction) {
|
||||
var $tabTitle = $('.layuimini-tab .layui-tab-title');
|
||||
var $tabTitle = $('.layuimini-tab .layui-tabs-header');
|
||||
var left = $tabTitle.scrollLeft();
|
||||
if ('left' === direction) {
|
||||
$tabTitle.animate({
|
||||
|
||||
@@ -41,7 +41,7 @@ define(["jquery"], function ($) {
|
||||
headerRightBg: '#23262e', //头部右侧背景色
|
||||
headerRightBgThis: '#0c0c0c', //头部右侧选中背景色,
|
||||
headerRightColor: 'rgba(255,255,255,.7)', //头部右侧字体颜色,
|
||||
headerRightChildColor: 'rgba(255,255,255,.7)', //头部右侧下拉字体颜色,
|
||||
headerRightChildColor: '#676767', //头部右侧下拉字体颜色,
|
||||
headerRightColorThis: 'rgba(255,255,255,.7)', //头部右侧鼠标选中,
|
||||
headerRightNavMore: 'rgba(255,255,255,.7)', //头部右侧更多下拉颜色,
|
||||
headerRightNavMoreBg: '#1aa094', //头部右侧更多下拉列表选中背景色,
|
||||
@@ -295,6 +295,24 @@ define(["jquery"], function ($) {
|
||||
}
|
||||
miniTheme.buildBodyElemStyle(elemStyleName);
|
||||
},
|
||||
|
||||
changeThemeMainColor() {
|
||||
let bgcolorId = localStorage.getItem('layuiminiBgColorId');
|
||||
if (bgcolorId === null || bgcolorId === undefined || bgcolorId === '') return false;
|
||||
let bgcolorData = miniTheme.config(bgcolorId);
|
||||
let mainColor = bgcolorData.headerRightBg
|
||||
if (bgcolorId == 0) mainColor = '#16b777';
|
||||
const bgColor = window.getComputedStyle(document.documentElement).getPropertyValue('--ea8-theme-main-color');
|
||||
document.documentElement.style.setProperty('--ea8-theme-main-color', mainColor);
|
||||
const iframes = document.getElementsByTagName('iframe');
|
||||
if (iframes.length === 0) return false;
|
||||
$.each(iframes, (i, iframe) => {
|
||||
if (iframe === '' || iframe === undefined) return false;
|
||||
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
||||
iframeDocument.documentElement.style.setProperty('--ea8-theme-main-color', mainColor);
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 构建主题样式
|
||||
* @param bgcolorId
|
||||
@@ -555,6 +573,7 @@ define(["jquery"], function ($) {
|
||||
bgColorDefault: bgcolorId,
|
||||
listen: false,
|
||||
});
|
||||
miniTheme.changeThemeMainColor()
|
||||
});
|
||||
$('body').on('click', '[data-select-style]', function () {
|
||||
var elemStyleName = $(this).attr('data-select-style');
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -10,10 +10,4 @@
|
||||
// +----------------------------------------------------------------------
|
||||
use think\facade\Route;
|
||||
|
||||
Route::get('think', function () {
|
||||
return 'hello,ThinkPHP6!';
|
||||
});
|
||||
|
||||
Route::get('hello/:name', 'index/hello');
|
||||
|
||||
Route::any('install', '\app\index\controller\Install@index');
|
||||
|
||||
2
runtime/.gitignore
vendored
2
runtime/.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
!.gitignore
|
||||
|
||||
Reference in New Issue
Block a user