mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-07-01 15:32:48 +08:00
feat(tools): 添加 Ulthon Admin 前端静态构建工具
- 新增 `tools:ua:build` 命令,用于合并前端模块文件 - 添加构建配置文件 `ua.build.json` 定义源文件和输出 - 引入基础服务类 `ToolsUaServiceBase` 处理路径和配置读取 - 创建命令基类 `ToolsUaBuildBase` 实现文件合并逻辑 - 注册新命令到 UlthonAdminService 服务容器 - 提供完整的模块化前端代码结构(core、common、table、listen、api、utils) - 添加详细的使用说明文档 README.md - 包含示例 Scheme 文件展示功能
This commit is contained in:
121
app/admin/scheme/TestGoods.php
Normal file
121
app/admin/scheme/TestGoods.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace app\admin\scheme;
|
||||
|
||||
use app\common\scheme\BaseScheme;
|
||||
use app\common\scheme\attribute\Table;
|
||||
use app\common\scheme\attribute\Field;
|
||||
use app\common\scheme\attribute\Component;
|
||||
use app\common\scheme\attribute\Index;
|
||||
|
||||
#[Table(name: 'ul_test_goods', comment: '')]
|
||||
#[Index(columns: ['uid'], name: 'uid', type: 'UNIQUE')]
|
||||
#[Index(columns: ['cate_id'], name: 'cate_id', type: 'NORMAL')]
|
||||
#[Index(columns: ['detail'], name: 'detail', type: 'FULLTEXT')]
|
||||
class TestGoods extends BaseScheme
|
||||
{
|
||||
#[Field(type: 'int', length: 11, nullable: false, unsigned: true, autoIncrement: true, primary: true)]
|
||||
public $id;
|
||||
|
||||
#[Field(type: 'bigint', length: 11, nullable: false, default: '0', comment: '分类ID', unsigned: true)]
|
||||
#[Component(type: 'relation', options: ['table' => 'mall_cate', 'relationBindSelect' => 'title'])]
|
||||
public $cate_id;
|
||||
|
||||
#[Field(type: 'char', length: 20, precision: 20, nullable: false, default: '', comment: '商品名称')]
|
||||
public $title;
|
||||
|
||||
#[Field(type: 'char', length: 255, precision: 255, nullable: false, comment: '商品logo')]
|
||||
#[Component(type: 'image', options: [])]
|
||||
public $logo;
|
||||
|
||||
#[Field(type: 'text', nullable: false, comment: '商品图片')]
|
||||
#[Component(type: 'images', options: [])]
|
||||
public $images;
|
||||
|
||||
#[Field(type: 'text', nullable: false, comment: '商品描述')]
|
||||
#[Component(type: 'editor', options: [])]
|
||||
public $describe;
|
||||
|
||||
#[Field(type: 'int', length: 11, nullable: false, default: '0', comment: '总库存', unsigned: true)]
|
||||
public $total_stock;
|
||||
|
||||
#[Field(type: 'int', length: 11, nullable: false, default: '0', comment: '排序', unsigned: true)]
|
||||
public $sort;
|
||||
|
||||
#[Field(type: 'int', length: 11, nullable: false, default: '0', comment: '状态', unsigned: true)]
|
||||
#[Component(type: 'radio', options: ['正常', '禁用'])]
|
||||
public $status;
|
||||
|
||||
#[Field(length: 100, precision: 100, nullable: false, comment: '合格证')]
|
||||
#[Component(type: 'file', options: [])]
|
||||
public $cert_file;
|
||||
|
||||
#[Field(type: 'text', nullable: false, comment: '检测报告')]
|
||||
#[Component(type: 'files', options: [])]
|
||||
public $verfiy_file;
|
||||
|
||||
#[Field(type: 'char', length: 255, precision: 255, nullable: false, default: '', comment: '备注说明')]
|
||||
public $remark;
|
||||
|
||||
#[Field(type: 'int', length: 11, nullable: false, default: '0', unsigned: true)]
|
||||
public $create_time;
|
||||
|
||||
#[Field(type: 'int', length: 11, nullable: false, default: '0', unsigned: true)]
|
||||
public $update_time;
|
||||
|
||||
#[Field(type: 'int', length: 11, nullable: false, default: '0', unsigned: true)]
|
||||
public $delete_time;
|
||||
|
||||
#[Field(type: 'datetime', nullable: false, comment: '发布日期')]
|
||||
#[Component(type: 'date', options: ['date'])]
|
||||
public $publish_time;
|
||||
|
||||
#[Field(type: 'date', nullable: false, comment: '售卖日期')]
|
||||
#[Component(type: 'date', options: ['datetime'])]
|
||||
public $sale_time;
|
||||
|
||||
#[Field(length: 100, precision: 100, nullable: false, comment: '简介')]
|
||||
#[Component(type: 'textarea', options: [])]
|
||||
public $intro;
|
||||
|
||||
#[Field(type: 'int', length: 11, nullable: false, comment: '秒杀状态', unsigned: true)]
|
||||
#[Component(type: 'select', options: [0 => '未参加', 1 => '已开始', 3 => '已结束'])]
|
||||
public $time_status;
|
||||
|
||||
#[Field(type: 'int', length: 11, nullable: false, default: '0', comment: '是否推荐')]
|
||||
#[Component(type: 'switch', options: ['不推荐', '推荐'])]
|
||||
public $is_recommend;
|
||||
|
||||
#[Field(length: 100, precision: 100, nullable: false, default: '0', comment: '商品类型')]
|
||||
#[Component(type: 'checkbox', options: ['taobao' => '淘宝', 'jd' => '京东'])]
|
||||
public $shop_type;
|
||||
|
||||
#[Field(length: 100, precision: 100, nullable: false, comment: '商品标签')]
|
||||
#[Component(type: 'table', options: ['table' => 'mall_tag', 'type' => 'checkbox', 'valueField' => 'id', 'fieldName' => 'title'])]
|
||||
public $tag;
|
||||
|
||||
#[Field(length: 100, precision: 100, comment: '商品标签(单选)')]
|
||||
#[Component(type: 'table', options: ['table' => 'mall_tag', 'type' => 'radio', 'valueField' => 'id', 'fieldName' => 'title'])]
|
||||
public $tag_backup;
|
||||
|
||||
#[Field(length: 100, precision: 100, nullable: false, comment: '产地')]
|
||||
#[Component(type: 'city', options: ['name-province' => '0', 'code' => '0'])]
|
||||
public $from_area;
|
||||
|
||||
#[Field(length: 100, precision: 100, nullable: false, default: '山东省/临沂市', comment: '仓库')]
|
||||
#[Component(type: 'city', options: ['level' => 'city'])]
|
||||
public $store_city;
|
||||
|
||||
#[Field(length: 100, precision: 100, nullable: false, comment: '商品标签 (输入)')]
|
||||
#[Component(type: 'tag', options: [])]
|
||||
public $tag_input;
|
||||
|
||||
#[Field(length: 100, precision: 100, nullable: false, comment: '唯一id')]
|
||||
public $uid;
|
||||
|
||||
#[Field(type: 'decimal', length: 10, precision: 10, comment: '价格')]
|
||||
public $price;
|
||||
|
||||
#[Field(type: 'text', comment: '详情')]
|
||||
public $detail;
|
||||
}
|
||||
9
app/common/command/tools/ua/ToolsUaBuild.php
Normal file
9
app/common/command/tools/ua/ToolsUaBuild.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\command\tools\ua;
|
||||
|
||||
use base\common\command\tools\ua\ToolsUaBuildBase;
|
||||
|
||||
class ToolsUaBuild extends ToolsUaBuildBase
|
||||
{
|
||||
}
|
||||
65
extend/base/common/command/tools/ua/ToolsUaBuildBase.php
Normal file
65
extend/base/common/command/tools/ua/ToolsUaBuildBase.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace base\common\command\tools\ua;
|
||||
|
||||
use base\common\service\ToolsUaServiceBase;
|
||||
use think\console\Command;
|
||||
use think\console\Input;
|
||||
use think\console\input\Option;
|
||||
use think\console\Output;
|
||||
|
||||
class ToolsUaBuildBase extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('tools:ua:build')
|
||||
->setDescription('构建 ulthon-admin 静态合并文件')
|
||||
->addOption('config', null, Option::VALUE_OPTIONAL, '配置文件路径', 'public/static/plugs/ulthon-admin/ua.build.json')
|
||||
->addOption('help', 'h', Option::VALUE_NONE, '显示帮助信息');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
$service = new ToolsUaServiceBase();
|
||||
$configOption = $input->getOption('config');
|
||||
$configPath = $service->getConfigPath($configOption);
|
||||
[$ok, $config] = $service->readConfig($configPath);
|
||||
if (!$ok) {
|
||||
$output->writeln($config);
|
||||
return 1;
|
||||
}
|
||||
if (!isset($config['sources']) || !is_array($config['sources']) || count($config['sources']) === 0) {
|
||||
$output->writeln('配置文件 sources 不能为空');
|
||||
return 1;
|
||||
}
|
||||
if (!isset($config['output']) || !$config['output']) {
|
||||
$output->writeln('配置文件 output 不能为空');
|
||||
return 1;
|
||||
}
|
||||
$baseDir = dirname($configPath);
|
||||
$outputPath = $service->resolvePath($config['output'], $baseDir);
|
||||
$contents = [];
|
||||
foreach ($config['sources'] as $source) {
|
||||
if (!is_string($source) || $source === '') {
|
||||
$output->writeln('sources 中存在无效路径');
|
||||
return 1;
|
||||
}
|
||||
$sourcePath = $service->resolvePath($source, $baseDir);
|
||||
if (!is_file($sourcePath)) {
|
||||
$output->writeln('源文件不存在: ' . $sourcePath);
|
||||
return 1;
|
||||
}
|
||||
$contents[] = file_get_contents($sourcePath);
|
||||
}
|
||||
$final = implode("\n\n", $contents);
|
||||
$outputDir = dirname($outputPath);
|
||||
if (!is_dir($outputDir)) {
|
||||
mkdir($outputDir, 0755, true);
|
||||
}
|
||||
file_put_contents($outputPath, $final);
|
||||
$output->writeln('构建完成: ' . $outputPath);
|
||||
$output->writeln('源文件数量: ' . count($contents));
|
||||
$output->writeln('输出大小: ' . strlen($final));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
49
extend/base/common/service/ToolsUaServiceBase.php
Normal file
49
extend/base/common/service/ToolsUaServiceBase.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace base\common\service;
|
||||
|
||||
use think\facade\App;
|
||||
|
||||
class ToolsUaServiceBase
|
||||
{
|
||||
public function getConfigPath($configPath)
|
||||
{
|
||||
if ($this->isAbsolutePath($configPath)) {
|
||||
return $configPath;
|
||||
}
|
||||
$root = App::getRootPath();
|
||||
return rtrim($root, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ltrim($configPath, DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
public function readConfig($configPath)
|
||||
{
|
||||
if (!is_file($configPath)) {
|
||||
return [false, '配置文件不存在: ' . $configPath];
|
||||
}
|
||||
$content = file_get_contents($configPath);
|
||||
$data = json_decode($content, true);
|
||||
if (!$data || !is_array($data)) {
|
||||
return [false, '配置文件JSON格式不正确: ' . $configPath];
|
||||
}
|
||||
return [true, $data];
|
||||
}
|
||||
|
||||
public function resolvePath($path, $baseDir)
|
||||
{
|
||||
if ($this->isAbsolutePath($path)) {
|
||||
return $path;
|
||||
}
|
||||
return rtrim($baseDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . ltrim($path, DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
public function isAbsolutePath($path)
|
||||
{
|
||||
if ($path === '' || $path === null) {
|
||||
return false;
|
||||
}
|
||||
if ($path[0] === '/' || $path[0] === '\\') {
|
||||
return true;
|
||||
}
|
||||
return preg_match('/^[a-zA-Z]:[\\\\\\/]/', $path) === 1;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ use app\common\command\tools\db\ToolsDbExecute;
|
||||
use app\common\command\tools\db\ToolsDbInfo;
|
||||
use app\common\command\tools\db\ToolsDbQuery;
|
||||
use app\common\command\tools\db\ToolsDbTable;
|
||||
use app\common\command\tools\ua\ToolsUaBuild;
|
||||
use app\common\command\Test;
|
||||
use app\common\event\AdminLoginSuccess\LogEvent;
|
||||
use app\common\event\AdminLoginType\DemoEvent;
|
||||
@@ -64,6 +65,7 @@ class UlthonAdminService extends Service
|
||||
ToolsDbInfo::class,
|
||||
ToolsDbDesc::class,
|
||||
ToolsDbCount::class,
|
||||
ToolsUaBuild::class,
|
||||
]);
|
||||
|
||||
// 绑定标识容器
|
||||
|
||||
101
public/static/plugs/ulthon-admin/README.md
Normal file
101
public/static/plugs/ulthon-admin/README.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# Ulthon Admin 前端静态构建说明
|
||||
|
||||
本目录使用纯 PHP 的 ThinkPHP 命令进行静态合并构建,不依赖前端构建工具。拆分后的模块文件都会“完善 ua 对象”,最终合并为单文件供页面直接引用。
|
||||
|
||||
## 设计结构
|
||||
|
||||
**目录结构**
|
||||
- `src/`:拆分后的源码模块
|
||||
- `ua.build.json`:构建清单(sources + output)
|
||||
- `ulthon-admin.js`:合并输出文件(运行时引用)
|
||||
|
||||
**模块划分**
|
||||
- `ulthon-admin.01-core.js`:基础上下文与核心能力(ctx、init、config、url、headers、checkAuth、parame)
|
||||
- `ulthon-admin.02-common.js`:请求/消息/公共方法(request、common、msg)
|
||||
- `ulthon-admin.03-table.js`:表格能力(admin.table)
|
||||
- `ulthon-admin.04-listen.js`:统一监听入口(admin.listen、open、checkMobile)
|
||||
- `ulthon-admin.05-api.js`:组件 API 能力(admin.api)
|
||||
- `ulthon-admin.06-utils.js`:工具能力(查询、缓存、页面设置、扩展名识别等)
|
||||
|
||||
**设计要点**
|
||||
- 每个模块都只做“补全 ua 对象”的工作,避免模块间互相覆盖。
|
||||
- 使用 `window.__uaCtx` 做跨模块上下文共享,保证拆分后仍能共享变量。
|
||||
- 构建顺序严格依赖 `ua.build.json`,以顺序决定覆盖与依赖关系。
|
||||
|
||||
## 如何使用
|
||||
|
||||
**前端引用**
|
||||
- 页面只需要引用合并后的 `ulthon-admin.js`,无需加载 `src/` 内的拆分文件。
|
||||
- 全局入口保持不变:`window.ua` / `window.ulAdmin`。
|
||||
|
||||
**常见调用**
|
||||
- `ua.listen()`:初始化页面常规行为
|
||||
- `ua.table.render(...)`:渲染表格
|
||||
- `ua.request.post(...)`:通用请求
|
||||
- `ua.msg.success(...)`:统一消息
|
||||
|
||||
## 如何开发
|
||||
|
||||
**新增功能的推荐方式**
|
||||
1. 判断属于哪类能力:核心/公共/表格/监听/API/工具
|
||||
2. 在对应模块内追加 `admin.xxx = ...` 或 `admin.xxx = { ... }`
|
||||
3. 若新增模块,请更新 `ua.build.json` 中的 `sources` 顺序
|
||||
4. 执行构建命令生成最新 `ulthon-admin.js`
|
||||
|
||||
**新增模块的边界**
|
||||
- 只负责“补全 ua 对象”,不引入不必要的全局变量
|
||||
- 只引用 `__uaCtx` 中已注册的上下文
|
||||
- 避免模块内重复初始化全局配置
|
||||
|
||||
**构建命令**
|
||||
```bash
|
||||
php think tools:ua:build
|
||||
```
|
||||
|
||||
可通过命令参数指定配置文件路径(默认读取本目录的 `ua.build.json`):
|
||||
```bash
|
||||
php think tools:ua:build --config public/static/plugs/ulthon-admin/ua.build.json
|
||||
```
|
||||
|
||||
## 构建清单说明
|
||||
|
||||
`ua.build.json` 使用相对路径时,基于配置文件所在目录解析:
|
||||
|
||||
```json
|
||||
{
|
||||
"output": "ulthon-admin.js",
|
||||
"sources": [
|
||||
"src/ulthon-admin.01-core.js",
|
||||
"src/ulthon-admin.02-common.js",
|
||||
"src/ulthon-admin.03-table.js",
|
||||
"src/ulthon-admin.04-listen.js",
|
||||
"src/ulthon-admin.05-api.js",
|
||||
"src/ulthon-admin.06-utils.js"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 兼容性与约定
|
||||
|
||||
- 兼容原有 `ua` 对外 API,保持使用方式不变
|
||||
- 不依赖前端打包工具
|
||||
- 模块拆分后只影响维护方式,不改变运行结果
|
||||
|
||||
## 常见问题
|
||||
|
||||
**1. 构建后功能异常**
|
||||
- 检查 `ua.build.json` 的顺序是否符合依赖
|
||||
- 检查新增模块是否遗漏 `window.ulAdmin = window.ua = admin;`
|
||||
|
||||
**2. 新方法不可用**
|
||||
- 确认方法定义在 `admin` 上
|
||||
- 确认构建文件已更新(重新执行构建)
|
||||
|
||||
**3. 引用未更新**
|
||||
- 页面只引用 `ulthon-admin.js`,不要引用 `src/` 文件
|
||||
|
||||
## 进一步建议
|
||||
|
||||
- 若模块继续增大,建议细分 `admin.api` 为 upload/editor/form 等更小模块
|
||||
- 对外 API 建议保持稳定,避免破坏老页面
|
||||
- 合并构建可纳入发布流程,避免线上文件与源码不一致
|
||||
147
public/static/plugs/ulthon-admin/src/ulthon-admin.01-core.js
Normal file
147
public/static/plugs/ulthon-admin/src/ulthon-admin.01-core.js
Normal file
@@ -0,0 +1,147 @@
|
||||
(function () {
|
||||
|
||||
var ctx = window.__uaCtx || {};
|
||||
|
||||
window.onInitElemStyle = function () {
|
||||
miniTheme.renderElemStyle();
|
||||
|
||||
$('iframe').each(function (index, iframe) {
|
||||
|
||||
if (typeof iframe.contentWindow.onInitElemStyle == "function") {
|
||||
iframe.contentWindow.onInitElemStyle();
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
window.onInitElemStyle();
|
||||
|
||||
const { createEditor, createToolbar } = window.wangEditor;
|
||||
|
||||
var form = layui.form,
|
||||
layer = layui.layer,
|
||||
laydate = layui.laydate,
|
||||
upload = layui.upload,
|
||||
element = layui.element,
|
||||
laytpl = layui.laytpl,
|
||||
util = layui.util;
|
||||
|
||||
layer.config({
|
||||
skin: 'layui-layer-easy'
|
||||
});
|
||||
|
||||
var init = {
|
||||
tableElem: '#currentTable',
|
||||
tableRenderId: 'currentTableRenderId',
|
||||
uploadUrl: 'ajax/upload',
|
||||
uploadExts: '',
|
||||
extGroup: {}
|
||||
};
|
||||
|
||||
var table;
|
||||
|
||||
table = layui.table;
|
||||
|
||||
var extGroup = {
|
||||
// 图片扩展名数组
|
||||
'image': ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'ico', 'webp', 'svg'],
|
||||
// word扩展名数组
|
||||
'word': ['doc', 'docx'],
|
||||
// excel扩展名数组
|
||||
'excel': ['xls', 'xlsx'],
|
||||
// ppt扩展名数组
|
||||
'ppt': ['ppt', 'pptx'],
|
||||
// pdf扩展名数组
|
||||
'pdf': ['pdf'],
|
||||
// 压缩文件扩展名数组
|
||||
'zip': ['zip', 'rar', '7z'],
|
||||
// 文本文件扩展名数组
|
||||
'txt': ['txt'],
|
||||
// 音乐文件扩展名数组
|
||||
'music': ['mp3', 'wma', 'wav', 'mid', 'm4a'],
|
||||
// 视频文件扩展名数组
|
||||
'video': ['mp4', 'avi', 'wmv', '3gp', 'flv'],
|
||||
// visio扩展名数组
|
||||
'visio': ['vsd', 'vsdx'],
|
||||
'file': []
|
||||
};
|
||||
|
||||
var allExtGroup = [];
|
||||
|
||||
for (const extGroupName in extGroup) {
|
||||
if (Object.hasOwnProperty.call(extGroup, extGroupName)) {
|
||||
const extGroupList = extGroup[extGroupName];
|
||||
|
||||
allExtGroup = allExtGroup.concat(extGroupList);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extGroup['office'] = [].concat(extGroup['word'], extGroup['excel'], extGroup['ppt'], extGroup['pdf']);
|
||||
extGroup['media'] = [].concat(extGroup['image'], extGroup['music'], extGroup['video']);
|
||||
|
||||
init.uploadExts += allExtGroup.join('|');
|
||||
init.extGroup = extGroup;
|
||||
|
||||
ctx.createEditor = createEditor;
|
||||
ctx.createToolbar = createToolbar;
|
||||
ctx.layui = {
|
||||
form: form,
|
||||
layer: layer,
|
||||
laydate: laydate,
|
||||
upload: upload,
|
||||
element: element,
|
||||
laytpl: laytpl,
|
||||
util: util,
|
||||
};
|
||||
ctx.init = init;
|
||||
ctx.table = table;
|
||||
ctx.extGroup = extGroup;
|
||||
ctx.lastTableWhere = ctx.lastTableWhere || {};
|
||||
ctx.selectMode = ctx.selectMode;
|
||||
ctx.selectConfirmCallback = ctx.selectConfirmCallback;
|
||||
|
||||
window.__uaCtx = ctx;
|
||||
|
||||
var admin = window.ua || {};
|
||||
admin.init = init;
|
||||
admin.config = {
|
||||
shade: [0.02, '#000'],
|
||||
};
|
||||
admin.url = function (url) {
|
||||
|
||||
var urlPrefixCheck = ['/', 'http://', 'https://'];
|
||||
|
||||
for (const index in urlPrefixCheck) {
|
||||
if (Object.hasOwnProperty.call(urlPrefixCheck, index)) {
|
||||
const prefix = urlPrefixCheck[index];
|
||||
if (url.indexOf(prefix) === 0) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '/' + CONFIG.ADMIN + '/' + url;
|
||||
};
|
||||
admin.headers = function () {
|
||||
return { 'X-CSRF-TOKEN': window.CONFIG.CSRF_TOKEN };
|
||||
};
|
||||
|
||||
admin.checkAuth = function (node, elem) {
|
||||
if (node === '1') {
|
||||
return true;
|
||||
}
|
||||
if (CONFIG.IS_SUPER_ADMIN) {
|
||||
return true;
|
||||
}
|
||||
if ($(elem).attr('data-auth-' + node) === '1') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
admin.parame = function (param, defaultParam) {
|
||||
return param !== undefined ? param : defaultParam;
|
||||
};
|
||||
|
||||
window.ulAdmin = window.ua = admin;
|
||||
})();
|
||||
170
public/static/plugs/ulthon-admin/src/ulthon-admin.02-common.js
Normal file
170
public/static/plugs/ulthon-admin/src/ulthon-admin.02-common.js
Normal file
@@ -0,0 +1,170 @@
|
||||
(function () {
|
||||
|
||||
var ctx = window.__uaCtx || {};
|
||||
var admin = window.ua || {};
|
||||
var layer = ctx.layui.layer;
|
||||
|
||||
admin.request = {
|
||||
post: function (option, ok, no, ex, complete) {
|
||||
return admin.request.ajax('post', option, ok, no, ex, complete);
|
||||
},
|
||||
get: function (option, ok, no, ex, complete) {
|
||||
return admin.request.ajax('get', option, ok, no, ex, complete);
|
||||
},
|
||||
ajax: function (type, option, ok, no, ex, complete) {
|
||||
type = type || 'get';
|
||||
option.url = option.url || '';
|
||||
option.data = option.data || {};
|
||||
option.prefix = option.prefix || false;
|
||||
option.statusName = option.statusName || 'code';
|
||||
option.statusCode = option.statusCode || 0;
|
||||
ok = ok || function (res) { };
|
||||
|
||||
var originalOk = ok;
|
||||
ok = function (res) {
|
||||
originalOk(res);
|
||||
complete()
|
||||
}
|
||||
complete = complete || function () {
|
||||
};
|
||||
|
||||
if (no) {
|
||||
var originalNo = no;
|
||||
no = function (res) {
|
||||
originalNo(res);
|
||||
complete();
|
||||
};
|
||||
} else {
|
||||
no = function (res) {
|
||||
var msg = res.msg == undefined ? '返回数据格式有误' : res.msg;
|
||||
admin.msg.error(msg);
|
||||
complete();
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
if (ex) {
|
||||
var originalEx = ex;
|
||||
ex = function (res) {
|
||||
originalEx(res);
|
||||
complete();
|
||||
};
|
||||
} else {
|
||||
ex = function (res) {
|
||||
complete();
|
||||
};
|
||||
}
|
||||
if (option.url == '') {
|
||||
admin.msg.error('请求地址不能为空');
|
||||
return false;
|
||||
}
|
||||
if (option.prefix == true) {
|
||||
option.url = admin.url(option.url);
|
||||
}
|
||||
loading.show();
|
||||
$.ajax({
|
||||
url: option.url,
|
||||
type: type,
|
||||
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
dataType: "json",
|
||||
headers: admin.headers(),
|
||||
data: option.data,
|
||||
timeout: 60000,
|
||||
success: function (res) {
|
||||
loading.hide();
|
||||
if (eval('res.' + option.statusName) == option.statusCode) {
|
||||
return ok(res);
|
||||
} else {
|
||||
return no(res);
|
||||
}
|
||||
},
|
||||
error: function (xhr, textstatus, thrown) {
|
||||
var errorMsg = '';
|
||||
if (xhr.responseJSON.message) {
|
||||
errorMsg = xhr.responseJSON.message;
|
||||
}
|
||||
loading.hide();
|
||||
admin.msg.error('Status:' + xhr.status + ',' + xhr.statusText + ',请稍后再试!<br/>' + errorMsg, function () {
|
||||
ex(this);
|
||||
});
|
||||
return false;
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
admin.common = {
|
||||
parseNodeStr: function (node) {
|
||||
var array = node.split('/');
|
||||
$.each(array, function (key, val) {
|
||||
if (key === 0) {
|
||||
val = val.split('.');
|
||||
$.each(val, function (i, v) {
|
||||
val[i] = admin.common.humpToLine(v.replace(v[0], v[0].toLowerCase()));
|
||||
});
|
||||
val = val.join(".");
|
||||
array[key] = val;
|
||||
}
|
||||
});
|
||||
node = array.join("/");
|
||||
return node;
|
||||
},
|
||||
lineToHump: function (name) {
|
||||
return name.replace(/\_(\w)/g, function (all, letter) {
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
},
|
||||
humpToLine: function (name) {
|
||||
return name.replace(/([A-Z])/g, "_$1").toLowerCase();
|
||||
},
|
||||
};
|
||||
admin.msg = {
|
||||
// 成功消息
|
||||
success: function (msg, callback) {
|
||||
if (callback === undefined) {
|
||||
callback = function () {
|
||||
};
|
||||
}
|
||||
var index = layer.msg(msg, { icon: 1, shade: admin.config.shade, scrollbar: false, time: 800, shadeClose: true }, callback);
|
||||
return index;
|
||||
},
|
||||
// 失败消息
|
||||
error: function (msg, callback) {
|
||||
if (callback === undefined) {
|
||||
callback = function () {
|
||||
};
|
||||
}
|
||||
var index = layer.msg(msg, { icon: 2, shade: admin.config.shade, scrollbar: false, time: -1, shadeClose: true }, callback);
|
||||
return index;
|
||||
},
|
||||
// 警告消息框
|
||||
alert: function (msg, callback) {
|
||||
var index = layer.alert(msg, { end: callback, scrollbar: false });
|
||||
return index;
|
||||
},
|
||||
// 对话框
|
||||
confirm: function (msg, ok, no) {
|
||||
var index = layer.confirm(msg, { title: '操作确认', btn: ['确认', '取消'] }, function () {
|
||||
typeof ok === 'function' && ok.call(this);
|
||||
}, function () {
|
||||
typeof no === 'function' && no.call(this);
|
||||
});
|
||||
return index;
|
||||
},
|
||||
// 消息提示
|
||||
tips: function (msg, time, callback) {
|
||||
var index = layer.msg(msg, { time: (time || 0.8) * 1000, shade: this.shade, end: callback, shadeClose: true });
|
||||
return index;
|
||||
},
|
||||
// 加载中提示
|
||||
loading: function (msg, callback) {
|
||||
var index = msg ? layer.msg(msg, { icon: 16, scrollbar: false, shade: this.shade, time: 0, end: callback }) : layer.load(2, { time: 0, scrollbar: false, shade: this.shade, end: callback });
|
||||
return index;
|
||||
},
|
||||
// 关闭消息框
|
||||
close: function (index) {
|
||||
return layer.close(index);
|
||||
}
|
||||
};
|
||||
|
||||
window.ulAdmin = window.ua = admin;
|
||||
})();
|
||||
1577
public/static/plugs/ulthon-admin/src/ulthon-admin.03-table.js
Normal file
1577
public/static/plugs/ulthon-admin/src/ulthon-admin.03-table.js
Normal file
File diff suppressed because it is too large
Load Diff
360
public/static/plugs/ulthon-admin/src/ulthon-admin.04-listen.js
Normal file
360
public/static/plugs/ulthon-admin/src/ulthon-admin.04-listen.js
Normal file
@@ -0,0 +1,360 @@
|
||||
(function () {
|
||||
|
||||
var ctx = window.__uaCtx || {};
|
||||
var admin = window.ua || {};
|
||||
var init = ctx.init;
|
||||
var table = ctx.table;
|
||||
var form = ctx.layui.form;
|
||||
var layer = ctx.layui.layer;
|
||||
|
||||
admin.checkMobile = function () {
|
||||
return tools.checkMobile();
|
||||
};
|
||||
admin.open = function (title, url, width, height, isResize, shadeClose = false) {
|
||||
isResize = isResize === undefined ? true : isResize;
|
||||
var index = layer.open({
|
||||
title: title,
|
||||
type: 2,
|
||||
area: [width, height],
|
||||
content: url,
|
||||
maxmin: true,
|
||||
moveOut: true,
|
||||
shadeClose: shadeClose,
|
||||
success: function (layero, index) {
|
||||
var body = layer.getChildFrame('body', index);
|
||||
if (body.length > 0) {
|
||||
$.each(body, function (i, v) {
|
||||
|
||||
// todo 优化弹出层背景色修改
|
||||
$(v).before('<style>\n' +
|
||||
'html, body {\n' +
|
||||
' background: #ffffff;\n' +
|
||||
'}\n' +
|
||||
'</style>');
|
||||
});
|
||||
}
|
||||
},
|
||||
end: function () {
|
||||
index = null;
|
||||
}
|
||||
});
|
||||
if (admin.checkMobile() || width === undefined || height === undefined) {
|
||||
layer.full(index);
|
||||
}
|
||||
if (isResize) {
|
||||
$(window).on("resize", function () {
|
||||
index && layer.full(index);
|
||||
});
|
||||
}
|
||||
};
|
||||
admin.listen = function (preposeCallback, ok, no, ex, complete) {
|
||||
|
||||
// 监听表单是否为必填项
|
||||
admin.api.formRequired();
|
||||
|
||||
// 监听表单提交事件
|
||||
admin.api.formSubmit(preposeCallback, ok, no, ex, complete);
|
||||
|
||||
// 监听按钮操作
|
||||
admin.api.button();
|
||||
|
||||
// 初始化图片显示以及监听上传事件
|
||||
admin.api.upload();
|
||||
|
||||
// 监听富文本初始化
|
||||
admin.api.editor();
|
||||
|
||||
// 监听下拉选择生成
|
||||
admin.api.select();
|
||||
|
||||
// 监听原生单选框选中
|
||||
admin.api.nativeRadio();
|
||||
admin.api.nativeSelect();
|
||||
|
||||
// 监听时间控件生成
|
||||
admin.api.date();
|
||||
|
||||
// 监听通用表格数据控件生成
|
||||
admin.api.tableData();
|
||||
// 监听地图组件
|
||||
admin.api.mapLocation();
|
||||
|
||||
// 监听标签输入控件生成
|
||||
admin.api.tagInput();
|
||||
// 监听属性输入控件生成
|
||||
admin.api.propertyInput();
|
||||
|
||||
// 监听点击复制
|
||||
admin.api.copyText();
|
||||
|
||||
// 监听点击粘贴
|
||||
admin.api.pasteText();
|
||||
|
||||
// 监听tab操作
|
||||
miniTab.listen();
|
||||
|
||||
// 初始化layui表单
|
||||
form.render();
|
||||
|
||||
// 表格修改
|
||||
$("body").on("mouseenter", ".table-edit-tips", function () {
|
||||
var openTips = layer.tips('点击行内容可以进行修改', $(this), { tips: [2, '#e74c3c'], time: 4000 });
|
||||
});
|
||||
|
||||
// 监听弹出层的打开
|
||||
$('body').on('click', '[data-open]', function () {
|
||||
|
||||
var clienWidth = $(this).attr('data-width'),
|
||||
clientHeight = $(this).attr('data-height'),
|
||||
dataFull = $(this).attr('data-full'),
|
||||
checkbox = $(this).attr('data-checkbox'),
|
||||
url = $(this).attr('data-open'),
|
||||
external = $(this).attr('data-external') || false,
|
||||
tableId = $(this).attr('data-table');
|
||||
|
||||
if (checkbox === 'true') {
|
||||
tableId = tableId || init.tableRenderId;
|
||||
var checkStatus = table.checkStatus(tableId),
|
||||
data = checkStatus.data;
|
||||
if (data.length <= 0) {
|
||||
admin.msg.error('请勾选需要操作的数据');
|
||||
return false;
|
||||
}
|
||||
var ids = [];
|
||||
$.each(data, function (i, v) {
|
||||
ids.push(v.id);
|
||||
});
|
||||
if (url.indexOf("?") === -1) {
|
||||
url += '?id=' + ids.join(',');
|
||||
} else {
|
||||
url += '&id=' + ids.join(',');
|
||||
}
|
||||
}
|
||||
|
||||
if (clienWidth === undefined || clientHeight === undefined) {
|
||||
var width = document.body.clientWidth,
|
||||
height = document.body.clientHeight;
|
||||
if (width >= 800 && height >= 600) {
|
||||
clienWidth = '800px';
|
||||
clientHeight = '600px';
|
||||
} else {
|
||||
clienWidth = '100%';
|
||||
clientHeight = '100%';
|
||||
}
|
||||
}
|
||||
if (dataFull === 'true') {
|
||||
clienWidth = '100%';
|
||||
clientHeight = '100%';
|
||||
}
|
||||
|
||||
// 如果是手机版,则直接跳转
|
||||
if (admin.checkMobile()) {
|
||||
location.href = external ? url : admin.url(url);
|
||||
} else {
|
||||
admin.open(
|
||||
$(this).attr('data-title'),
|
||||
external ? url : admin.url(url),
|
||||
clienWidth,
|
||||
clientHeight
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 放大图片
|
||||
$('body').on('click', '[data-image]', function () {
|
||||
var title = $(this).attr('data-image'),
|
||||
src = $(this).attr('src'),
|
||||
alt = $(this).attr('alt');
|
||||
var photos = {
|
||||
"title": title,
|
||||
"id": Math.random(),
|
||||
"data": [
|
||||
{
|
||||
"alt": alt,
|
||||
"pid": Math.random(),
|
||||
"src": src,
|
||||
"thumb": src
|
||||
}
|
||||
]
|
||||
};
|
||||
layer.photos({
|
||||
photos: photos,
|
||||
anim: 5
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// 放大一组图片
|
||||
$('body').on('click', '[data-images]', function () {
|
||||
var doms = $(this).closest(".layuimini-upload-show").children("li"), // 从当前元素向上找layuimini-upload-show找到第一个后停止, 再找其所有子元素li
|
||||
currentSrc = $(this).attr('src'), // 被点击的图片地址
|
||||
start = 0,
|
||||
data = [];
|
||||
$.each(doms, function (key, value) {
|
||||
var img = $(value).find('img'),
|
||||
src = img.attr('src'),
|
||||
alt = img.attr('alt');
|
||||
data.push({
|
||||
"alt": alt,
|
||||
"pid": Math.random(),
|
||||
"src": src,
|
||||
"thumb": src
|
||||
});
|
||||
if (src === currentSrc) {
|
||||
start = key;
|
||||
}
|
||||
});
|
||||
var photos = {
|
||||
"title": '',
|
||||
"start": start,
|
||||
"id": Math.random(),
|
||||
"data": data,
|
||||
};
|
||||
|
||||
layer.photos({
|
||||
photos: photos,
|
||||
anim: 5
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
// 监听动态表格刷新
|
||||
$('body').on('click', '[data-table-refresh]', function () {
|
||||
var tableId = $(this).attr('data-table-refresh');
|
||||
if (tableId === undefined || tableId === '' || tableId == null) {
|
||||
tableId = init.tableRenderId;
|
||||
}
|
||||
table.reloadData(tableId);
|
||||
});
|
||||
|
||||
// 监听搜索表格重置
|
||||
$('body').on('click', '[data-table-reset]', function () {
|
||||
var tableId = $(this).attr('data-table-reset');
|
||||
if (tableId === undefined || tableId === '' || tableId == null) {
|
||||
tableId = init.tableRenderId;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
var searchVals = form.val(tableId + '_filter_form');
|
||||
var dataField = searchVals;
|
||||
var formatFilter = {},
|
||||
formatOp = {};
|
||||
$.each(dataField, function (key, val) {
|
||||
if (val !== '') {
|
||||
formatFilter[key] = val;
|
||||
|
||||
var elemId = admin.table.renderSearchFormItemElementId(key);
|
||||
|
||||
var op = $('#c-' + elemId).attr('data-search-op');
|
||||
op = op || '%*%';
|
||||
formatOp[key] = op;
|
||||
}
|
||||
});
|
||||
|
||||
var where = {
|
||||
filter: JSON.stringify(formatFilter),
|
||||
op: JSON.stringify(formatOp)
|
||||
};
|
||||
table.reloadData(tableId, {
|
||||
page: {
|
||||
curr: 1
|
||||
}
|
||||
, where: where
|
||||
}, 'data');
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// 监听请求
|
||||
$('body').on('click', '[data-request]', function () {
|
||||
var title = $(this).attr('data-title'),
|
||||
url = $(this).attr('data-request'),
|
||||
tableId = $(this).attr('data-table'),
|
||||
checkbox = $(this).attr('data-checkbox'),
|
||||
direct = $(this).attr('data-direct'),
|
||||
field = $(this).attr('data-field') || 'id',
|
||||
endMethod = $(this).attr('data-end-method') || 'reload-table';
|
||||
|
||||
title = title || '确定进行该操作?';
|
||||
|
||||
if (direct === 'true') {
|
||||
admin.msg.confirm(title, function () {
|
||||
window.location.href = url;
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
var postData = {};
|
||||
if (checkbox === 'true') {
|
||||
tableId = tableId || init.tableRenderId;
|
||||
var checkStatus = table.checkStatus(tableId),
|
||||
data = checkStatus.data;
|
||||
if (data.length <= 0) {
|
||||
admin.msg.error('请勾选需要操作的数据');
|
||||
return false;
|
||||
}
|
||||
var ids = [];
|
||||
$.each(data, function (i, v) {
|
||||
ids.push(v[field]);
|
||||
});
|
||||
postData[field] = ids;
|
||||
}
|
||||
|
||||
url = admin.url(url);
|
||||
|
||||
admin.msg.confirm(title, function () {
|
||||
admin.request.post({
|
||||
url: url,
|
||||
data: postData,
|
||||
}, function (res) {
|
||||
admin.msg.success(res.msg, function () {
|
||||
if (endMethod == 'reload-table') {
|
||||
tableId = tableId || init.tableRenderId;
|
||||
table.reloadData(tableId);
|
||||
} else if (endMethod == 'refresh-page') {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 数据表格多删除
|
||||
$('body').on('click', '[data-table-delete]', function () {
|
||||
var tableId = $(this).attr('data-table-delete'),
|
||||
url = $(this).attr('data-url');
|
||||
tableId = tableId || init.tableRenderId;
|
||||
url = url !== undefined ? admin.url(url) : window.location.href;
|
||||
var checkStatus = table.checkStatus(tableId),
|
||||
data = checkStatus.data;
|
||||
if (data.length <= 0) {
|
||||
admin.msg.error('请勾选需要删除的数据');
|
||||
return false;
|
||||
}
|
||||
var ids = [];
|
||||
$.each(data, function (i, v) {
|
||||
ids.push(v.id);
|
||||
});
|
||||
admin.msg.confirm('确定删除?', function () {
|
||||
admin.request.post({
|
||||
url: url,
|
||||
data: {
|
||||
id: ids
|
||||
},
|
||||
}, function (res) {
|
||||
admin.msg.success(res.msg, function () {
|
||||
table.reloadData(tableId);
|
||||
});
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
window.ulAdmin = window.ua = admin;
|
||||
})();
|
||||
802
public/static/plugs/ulthon-admin/src/ulthon-admin.05-api.js
Normal file
802
public/static/plugs/ulthon-admin/src/ulthon-admin.05-api.js
Normal file
@@ -0,0 +1,802 @@
|
||||
(function () {
|
||||
|
||||
var ctx = window.__uaCtx || {};
|
||||
var admin = window.ua || {};
|
||||
var init = ctx.init;
|
||||
var table = ctx.table;
|
||||
var form = ctx.layui.form;
|
||||
var layer = ctx.layui.layer;
|
||||
var laydate = ctx.layui.laydate;
|
||||
var upload = ctx.layui.upload;
|
||||
var extGroup = ctx.extGroup;
|
||||
var createEditor = ctx.createEditor;
|
||||
var createToolbar = ctx.createToolbar;
|
||||
|
||||
admin.api = {
|
||||
button: function () {
|
||||
$('button[target="_blank"]').click(function () {
|
||||
window.open(admin.url($(this).attr('href')));
|
||||
});
|
||||
},
|
||||
|
||||
closeCurrentOpen: function (option) {
|
||||
option = option || {};
|
||||
option.backHref = option.backHref || '';
|
||||
option.refreshTable = option.refreshTable || false;
|
||||
option.refreshFrame = option.refreshFrame || false;
|
||||
option.onClose = option.onClose || function () { };
|
||||
if (option.refreshTable === true) {
|
||||
option.refreshTable = init.tableRenderId;
|
||||
}
|
||||
var backWindow = window.parent;
|
||||
if (option.backHref) {
|
||||
// 标签打开页面,需要返回上一个标签刷新的情况
|
||||
backWindow = admin.findPageId(option.backHref);
|
||||
if (backWindow) {
|
||||
backWindow.layui.table.reloadData(option.refreshTable);
|
||||
} else {
|
||||
admin.findIndexPage(function (w) {
|
||||
var menu = w.miniTab.searchMenu(option.backHref);
|
||||
var title = option.backHref;
|
||||
|
||||
if (menu) {
|
||||
title = menu.title;
|
||||
}
|
||||
w.miniTab.create({
|
||||
tabId: option.backHref,
|
||||
href: option.backHref,
|
||||
title: title,
|
||||
});
|
||||
});
|
||||
}
|
||||
admin.findIndexPage(function (w) {
|
||||
w.layui.element.tabDelete('layuiminiTab', admin.getCurrentPageId());
|
||||
w.layui.element.tabChange('layuiminiTab', option.backHref);
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 弹框保存后刷新的情况
|
||||
var index = parent.layer.getFrameIndex(window.name);
|
||||
backWindow.layer.close(index, option.onClose);
|
||||
if (option.refreshTable !== false) {
|
||||
backWindow.layui.table.reloadData(option.refreshTable);
|
||||
}
|
||||
if (option.refreshFrame) {
|
||||
backWindow.location.reload();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
refreshFrame: function () {
|
||||
parent.location.reload();
|
||||
return false;
|
||||
},
|
||||
refreshTable: function (tableName, mode) {
|
||||
tableName = tableName || 'currentTableRenderId';
|
||||
if (mode == 'table') {
|
||||
table.reload(tableName);
|
||||
} else {
|
||||
table.reloadData(tableName);
|
||||
}
|
||||
},
|
||||
// var options = {
|
||||
// url :'system.menu/index?id=1'
|
||||
// }
|
||||
// ua.api.reloadTable('currentTableRenderId',options)
|
||||
reloadTable: function (tableName, options, mode) {
|
||||
tableName = tableName || 'currentTableRenderId';
|
||||
if (mode == 'table') {
|
||||
table.reload(tableName, options);
|
||||
} else {
|
||||
table.reloadData(tableName, options);
|
||||
}
|
||||
},
|
||||
formRequired: function () {
|
||||
var verifyList = document.querySelectorAll("[lay-verify]");
|
||||
if (verifyList.length > 0) {
|
||||
$.each(verifyList, function (i, v) {
|
||||
var verify = $(this).attr('lay-verify');
|
||||
|
||||
// todo 必填项处理
|
||||
if (verify.includes('required')) {
|
||||
var label = $(this).parent().prev();
|
||||
if (label.is('label') && !label.hasClass('required')) {
|
||||
label.addClass('required');
|
||||
}
|
||||
if ($(this).attr('lay-reqtext') === undefined && $(this).attr('placeholder') !== undefined) {
|
||||
$(this).attr('lay-reqtext', $(this).attr('placeholder'));
|
||||
}
|
||||
if ($(this).attr('placeholder') === undefined && $(this).attr('lay-reqtext') !== undefined) {
|
||||
$(this).attr('placeholder', $(this).attr('lay-reqtext'));
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
formSubmit: function (preposeCallback, ok, no, ex, complete) {
|
||||
var formList = document.querySelectorAll("[lay-submit]");
|
||||
|
||||
// 表单提交自动处理
|
||||
if (formList.length > 0) {
|
||||
$.each(formList, function (i, v) {
|
||||
var filter = $(this).attr('lay-filter'),
|
||||
type = $(this).attr('data-type'),
|
||||
refresh = $(this).attr('data-refresh'),
|
||||
close = $(this).attr('data-close'),
|
||||
url = $(this).attr('lay-submit');
|
||||
// 表格搜索不做自动提交
|
||||
if (type === 'tableSearch') {
|
||||
return false;
|
||||
}
|
||||
// 判断是否需要刷新表格
|
||||
if (refresh === 'false') {
|
||||
refresh = false;
|
||||
} else {
|
||||
refresh = true;
|
||||
}
|
||||
if (close === 'false') {
|
||||
close = false;
|
||||
} else {
|
||||
close = true;
|
||||
}
|
||||
// 自动添加layui事件过滤器
|
||||
if (filter === undefined || filter === '') {
|
||||
filter = 'save_form_' + (i + 1);
|
||||
$(this).attr('lay-filter', filter);
|
||||
}
|
||||
if (url === undefined || url === '' || url === null) {
|
||||
url = window.location.href;
|
||||
} else {
|
||||
url = admin.url(url);
|
||||
}
|
||||
form.on('submit(' + filter + ')', function (data) {
|
||||
|
||||
var btnElem = data.elem;
|
||||
|
||||
var form = $(this).closest('form');
|
||||
if ($(form).hasClass('loading')) return false;
|
||||
$(form).addClass('loading');
|
||||
|
||||
// 判断btn是否具备name和value属性,如果有,则加到表单数据里
|
||||
var btnName = $(btnElem).attr('name');
|
||||
var btnValue = $(btnElem).attr('value');
|
||||
var backHref = $(btnElem).attr('data-back-href');
|
||||
if (btnName !== undefined && btnValue !== undefined) {
|
||||
data.field[btnName] = btnValue;
|
||||
}
|
||||
if (!backHref) {
|
||||
backHref = admin.getQueryVariable('backTagId');
|
||||
}
|
||||
|
||||
var dataField = data.field;
|
||||
dataField = admin.api.formSubmitEditor(dataField, v);
|
||||
dataField = admin.api.formSubmitCity(dataField, v);
|
||||
|
||||
if (typeof preposeCallback === 'function') {
|
||||
dataField = preposeCallback(dataField);
|
||||
}
|
||||
complete = complete || function () {
|
||||
$(form).removeClass('loading');
|
||||
};
|
||||
|
||||
if (ok) {
|
||||
var originalOk = ok;
|
||||
ok = function (res) {
|
||||
originalOk(res);
|
||||
complete();
|
||||
};
|
||||
} else {
|
||||
ok = function (res) {
|
||||
res.msg = res.msg || '';
|
||||
admin.msg.success(res.msg, function () {
|
||||
if (close) {
|
||||
|
||||
admin.api.closeCurrentOpen({
|
||||
refreshTable: refresh,
|
||||
backHref: backHref,
|
||||
onClose: function () {
|
||||
complete();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
admin.request.post({
|
||||
url: url,
|
||||
data: dataField,
|
||||
}, ok, no, ex, complete);
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
formSubmitEditor(dataField, form) {
|
||||
return dataField;
|
||||
},
|
||||
|
||||
formSubmitCity(dataField, form) {
|
||||
|
||||
var cityList = $(form).closest('.layui-form').find('[data-toggle="city-picker"]');
|
||||
|
||||
if (cityList.length > 0) {
|
||||
$.each(cityList, function (i, v) {
|
||||
|
||||
var fieldName = $(v).attr('name');
|
||||
var code = $(v).data('citypicker').getCode();
|
||||
var text = $(v).data('citypicker').getVal();
|
||||
var level = $(v).data('level');
|
||||
var formatTargetList = {};
|
||||
|
||||
formatTargetList['name'] = 1;
|
||||
formatTargetList['code'] = 1;
|
||||
formatTargetList['name-province'] = 1;
|
||||
formatTargetList['name-city'] = 1;
|
||||
formatTargetList['name-district'] = 1;
|
||||
formatTargetList['code-province'] = 1;
|
||||
formatTargetList['code-city'] = 1;
|
||||
formatTargetList['code-district'] = 1;
|
||||
|
||||
|
||||
$.each(formatTargetList, function (targetType, value) {
|
||||
|
||||
var valueSet = $(v).data('field-' + targetType);
|
||||
|
||||
if (valueSet == 0) {
|
||||
formatTargetList[targetType] = 0;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var codeArr = code.split('/');
|
||||
var textArr = text.split('/');
|
||||
|
||||
if (formatTargetList['name'] == 1) {
|
||||
dataField[fieldName] = text;
|
||||
}
|
||||
if (formatTargetList['code'] == 1) {
|
||||
dataField[fieldName + '_code'] = code;
|
||||
}
|
||||
if (formatTargetList['name-province'] == 1) {
|
||||
dataField[fieldName + '_name_province'] = textArr[0] || '';
|
||||
}
|
||||
if (formatTargetList['name-city'] == 1) {
|
||||
dataField[fieldName + '_name_city'] = textArr[1] || '';
|
||||
}
|
||||
if (formatTargetList['name-district'] == 1) {
|
||||
dataField[fieldName + '_name_district'] = textArr[2] || '';
|
||||
}
|
||||
if (formatTargetList['code-province'] == 1) {
|
||||
dataField[fieldName + '_code_province'] = codeArr[0] || '';
|
||||
}
|
||||
if (formatTargetList['code-city'] == 1) {
|
||||
dataField[fieldName + '_code_city'] = codeArr[1] || '';
|
||||
}
|
||||
if (formatTargetList['code-district'] == 1) {
|
||||
dataField[fieldName + '_code_district'] = codeArr[2] || '';
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
return dataField;
|
||||
},
|
||||
upload: function () {
|
||||
var uploadList = document.querySelectorAll("[data-upload]");
|
||||
var uploadSelectList = document.querySelectorAll("[data-upload-select]");
|
||||
|
||||
if (uploadList.length > 0) {
|
||||
$.each(uploadList, function (i, v) {
|
||||
var uploadExts = $(this).attr('data-upload-exts'),
|
||||
uploadName = $(this).attr('data-upload'),
|
||||
uploadNumber = $(this).attr('data-upload-number') || 'one',
|
||||
uploadSign = $(this).attr('data-upload-sign') || '|',
|
||||
uploadAccept = $(this).attr('data-upload-accept') || 'file',
|
||||
uploadAcceptMime = $(this).attr('data-upload-mimetype') || '',
|
||||
uploadDisablePreview = $(this).attr('data-upload-disable-preview') || '0',
|
||||
uploadFilenameField = $(this).attr('data-upload-filename-field') || '',
|
||||
elem = "input[name='" + uploadName + "']",
|
||||
|
||||
uploadElem = this;
|
||||
if (uploadFilenameField) {
|
||||
var elemFilenameField = "[name='" + uploadFilenameField + "']";
|
||||
}
|
||||
if (uploadExts == '*') {
|
||||
uploadExts = init.uploadExts;
|
||||
} else if (uploadExts.charAt(0) == '*') {
|
||||
var extGroupName = uploadExts.slice(1);
|
||||
if (extGroup[extGroupName]) {
|
||||
uploadExts = extGroup[extGroupName].join('|');
|
||||
}
|
||||
}
|
||||
|
||||
// 监听上传事件
|
||||
upload.render({
|
||||
elem: this,
|
||||
url: admin.url(init.uploadUrl),
|
||||
exts: uploadExts,
|
||||
accept: uploadAccept,//指定允许上传时校验的文件类型
|
||||
acceptMime: uploadAcceptMime,//规定打开文件选择框时,筛选出的文件类型
|
||||
multiple: uploadNumber !== 'one',//是否多文件上传
|
||||
headers: admin.headers(),
|
||||
done: function (res) {
|
||||
if (res.code === 0) {
|
||||
var url = res.data.url;
|
||||
var filename = res.data.original_name;
|
||||
if (uploadNumber !== 'one') {
|
||||
var oldUrl = $(elem).val();
|
||||
if (oldUrl !== '') {
|
||||
url = oldUrl + uploadSign + url;
|
||||
}
|
||||
if (elemFilenameField) {
|
||||
var oldFilename = $(elemFilenameField).val();
|
||||
if (oldFilename !== '') {
|
||||
filename = oldFilename + uploadSign + filename;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (elemFilenameField) {
|
||||
$(elemFilenameField).val(filename);
|
||||
}
|
||||
$(elem).val(url);
|
||||
$(elem).trigger("input");
|
||||
admin.msg.success(res.msg);
|
||||
} else {
|
||||
admin.msg.error(res.msg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (uploadDisablePreview == 0) {
|
||||
// 监听上传input值变化
|
||||
$(elem).bind("input propertychange", function (event) {
|
||||
var urlString = $(this).val(),
|
||||
urlArray = urlString.split(uploadSign),
|
||||
uploadIcon = $(uploadElem).attr('data-upload-icon') || "file";
|
||||
var uploadNameKey = uploadName.replace(/\[/g, "-").replace(/\]/g, "-");
|
||||
$('#bing-' + uploadNameKey).remove();
|
||||
if (urlString.length > 0) {
|
||||
var parant = $(this).parent('div');
|
||||
var liHtml = '';
|
||||
var filenameArray = [];
|
||||
if (uploadFilenameField) {
|
||||
var filenameVal = $(elemFilenameField).val() || '';
|
||||
if (filenameVal) {
|
||||
filenameArray = filenameVal.split(uploadSign);
|
||||
}
|
||||
}
|
||||
|
||||
$.each(urlArray, function (i, v) {
|
||||
|
||||
// 获取链接扩展名
|
||||
var ext = v.substr(v.lastIndexOf('.') + 1);
|
||||
var currentFilename = filenameArray[i] || '';
|
||||
currentFilename = currentFilename.replace(/"/g, '"');
|
||||
|
||||
if (extGroup.image.indexOf(ext) != -1) {
|
||||
// 是图片
|
||||
liHtml += '<li><a title="点击预览"><img src="' + v + '" data-images onerror="this.src=\'/static/admin/images/upload-icons/image-error.png\';this.onerror=null"></a><small class="uploads-delete-tip bg-red badge" data-upload-delete="' + uploadName + '" data-upload-filename-field="' + uploadFilenameField + '" data-upload-url="' + v + '" data-upload-sign="' + uploadSign + '" data-upload-filename="' + currentFilename + '">×</small></li>\n';
|
||||
} else {
|
||||
// 不是图片
|
||||
// 遍历extGroup数组找到扩展名所在的索引
|
||||
|
||||
uploadIcon = admin.getExtGroupName(ext);
|
||||
|
||||
liHtml += '<li><a title="点击打开文件" target="_blank" href="' + v + '" ><img src="/static/admin/images/upload-icons/' + uploadIcon + '.png"></a><small class="uploads-delete-tip bg-red badge" data-upload-delete="' + uploadName + '" data-upload-filename-field="' + uploadFilenameField + '" data-upload-url="' + v + '" data-upload-sign="' + uploadSign + '" data-upload-filename="' + currentFilename + '">×</small></li>\n';
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
parant.after('<ul id="bing-' + uploadNameKey + '" class="layui-input-block layuimini-upload-show">\n' + liHtml + '</ul>');
|
||||
|
||||
var initSortable = function () {
|
||||
var el = document.getElementById('bing-' + uploadNameKey);
|
||||
if (el) {
|
||||
new Sortable(el, {
|
||||
animation: 150,
|
||||
onEnd: function (evt) {
|
||||
var newUrls = [];
|
||||
var newFilenames = [];
|
||||
$(el).find('.uploads-delete-tip').each(function () {
|
||||
newUrls.push($(this).attr('data-upload-url'));
|
||||
newFilenames.push($(this).attr('data-upload-filename'));
|
||||
});
|
||||
$(elem).val(newUrls.join(uploadSign));
|
||||
if (uploadFilenameField) {
|
||||
$(elemFilenameField).val(newFilenames.join(uploadSign));
|
||||
}
|
||||
$(elem).trigger("input");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
initSortable();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 非空初始化图片显示
|
||||
if ($(elem).val() !== '') {
|
||||
$(elem).trigger("input");
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// 监听上传文件的删除事件
|
||||
$('body').on('click', '[data-upload-delete]', function () {
|
||||
var uploadName = $(this).attr('data-upload-delete'),
|
||||
deleteUrl = $(this).attr('data-upload-url'),
|
||||
uploadFilenameField = $(this).attr('data-upload-filename-field'),
|
||||
sign = $(this).attr('data-upload-sign');
|
||||
var confirm = admin.msg.confirm('确定删除?', function () {
|
||||
var elem = "input[name='" + uploadName + "']";
|
||||
var elemFilenameField = "[name='" + uploadFilenameField + "']";
|
||||
var currentUrl = $(elem).val();
|
||||
var currentFilename = $(elemFilenameField).val();
|
||||
|
||||
var currentUrlList = currentUrl.split(sign);
|
||||
var deleteIndex = currentUrlList.indexOf(deleteUrl);
|
||||
|
||||
currentUrlList.splice(deleteIndex, 1);
|
||||
$(elem).val(currentUrlList.join(sign));
|
||||
$(elem).trigger("input");
|
||||
|
||||
if (currentFilename) {
|
||||
|
||||
var currentFilenameList = currentFilename.split(sign);
|
||||
currentFilenameList.splice(deleteIndex, 1);
|
||||
|
||||
$(elemFilenameField).val(currentFilenameList.join(sign));
|
||||
}
|
||||
|
||||
admin.msg.close(confirm);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
if (uploadSelectList.length > 0) {
|
||||
$.each(uploadSelectList, function (i, v) {
|
||||
var uploadName = $(this).attr('data-upload-select'),
|
||||
uploadNumber = $(this).attr('data-upload-number') || 'one',
|
||||
uploadSign = $(this).attr('data-upload-sign') || '|',
|
||||
uploadFilenameField = $(this).attr('data-upload-filename-field') || '';
|
||||
|
||||
if (uploadFilenameField) {
|
||||
var elemFilenameField = "[name='" + uploadFilenameField + "']";
|
||||
var elemFilename = $(elemFilenameField);
|
||||
}
|
||||
|
||||
var selectCheck = uploadNumber === 'one' ? 'radio' : 'checkbox';
|
||||
var elem = "input[name='" + uploadName + "']";
|
||||
var width = document.body.clientWidth,
|
||||
height = document.body.clientHeight;
|
||||
|
||||
if (width >= 800 && height >= 600) {
|
||||
clienWidth = '800px';
|
||||
clientHeight = '600px';
|
||||
} else {
|
||||
clienWidth = '100%';
|
||||
clientHeight = '100%';
|
||||
}
|
||||
|
||||
$(v).click(function () {
|
||||
|
||||
layer.open({
|
||||
title: '选择文件',
|
||||
type: 2,
|
||||
area: [clienWidth, clientHeight],
|
||||
content: admin.url('system.uploadfile/index') + '?select_mode=' + selectCheck,
|
||||
success(layero, index) {
|
||||
window.onTableDataConfirm = function (data) {
|
||||
var currentUrl = $(elem).val();
|
||||
var urlArray = currentUrl.split(uploadSign);
|
||||
if (currentUrl.length == 0 || selectCheck == 'radio') {
|
||||
urlArray = [];
|
||||
}
|
||||
if (uploadFilenameField) {
|
||||
var currentFilename = $(elemFilename).val();
|
||||
var filenameArray = currentFilename.split(uploadSign);
|
||||
if (currentFilename.length == 0 || selectCheck == 'radio') {
|
||||
filenameArray = [];
|
||||
}
|
||||
}
|
||||
$.each(data, function (index, val) {
|
||||
if (urlArray.indexOf(val.url) == -1) {
|
||||
urlArray.push(val.url);
|
||||
}
|
||||
if (uploadFilenameField) {
|
||||
if (filenameArray.indexOf(val.original_name) == -1) {
|
||||
filenameArray.push(val.original_name);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
var url = urlArray.join(uploadSign);
|
||||
|
||||
if (uploadFilenameField) {
|
||||
var filename = filenameArray.join(uploadSign);
|
||||
}
|
||||
$(elem).val(url);
|
||||
if (uploadFilenameField) {
|
||||
$(elemFilenameField).val(filename);
|
||||
}
|
||||
$(elem).trigger("input");
|
||||
layer.close(index);
|
||||
admin.msg.success('选择成功');
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
editor: function () {
|
||||
var editorList = document.querySelectorAll(".editor");
|
||||
if (editorList.length > 0) {
|
||||
$.each(editorList, function (i, v) {
|
||||
var editorConfig = {
|
||||
placeholder: '请输入内容',
|
||||
onChange(editor) {
|
||||
const html = editor.getHtml();
|
||||
$(v).val(html);
|
||||
},
|
||||
MENU_CONF: {
|
||||
uploadImage: {
|
||||
server: admin.url('ajax/uploadEditor'),
|
||||
maxFileSize: 10 * 1024 * 1024,
|
||||
fieldName: 'upload',
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
var formName = $(this).attr('name');
|
||||
|
||||
var editorId = 'editor-' + formName.replace(/\[/g, '-').replace(/\]/g, '-');
|
||||
var editorContainer = $('<div id="' + editorId + '" style="height:60vh;"></div>');
|
||||
$(this).after(editorContainer);
|
||||
|
||||
var toolbarId = 'toolbar-' + formName.replace(/\[/g, '-').replace(/\]/g, '-');
|
||||
var toolbarContent = $('<div id="' + toolbarId + '"></div>');
|
||||
$(this).after(toolbarContent);
|
||||
|
||||
$(this).hide();
|
||||
|
||||
var originalValue = $(this).val();
|
||||
const editor = createEditor({
|
||||
selector: '#' + editorId,
|
||||
html: originalValue,
|
||||
config: editorConfig,
|
||||
mode: 'default',
|
||||
scroll: true
|
||||
});
|
||||
$(v).data('editor', editor);
|
||||
|
||||
|
||||
const toolbarConfig = {
|
||||
excludeKeys: [
|
||||
'uploadVideo',
|
||||
'fullScreen',
|
||||
'todo',
|
||||
]
|
||||
};
|
||||
|
||||
const toolbar = createToolbar({
|
||||
editor,
|
||||
selector: '#' + toolbarId,
|
||||
config: toolbarConfig,
|
||||
mode: 'default', // or 'simple'
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
},
|
||||
select: function () {
|
||||
|
||||
var selectList = document.querySelectorAll("[data-select]");
|
||||
$.each(selectList, function (i, v) {
|
||||
var url = $(this).attr('data-select'),
|
||||
selectFields = $(this).attr('data-fields'),
|
||||
value = $(this).attr('data-value'),
|
||||
that = this,
|
||||
html = '<option value=""></option>';
|
||||
|
||||
var template = $(that).data('template');
|
||||
|
||||
if (typeof template != 'function') {
|
||||
template = function (data, fields) {
|
||||
return data[fields[1]];
|
||||
};
|
||||
}
|
||||
|
||||
var fields = selectFields.replace(/\s/g, "").split(',');
|
||||
if (fields.length < 2) {
|
||||
return admin.msg.error('下拉选择字段有误');
|
||||
}
|
||||
admin.request.get(
|
||||
{
|
||||
url: url,
|
||||
data: {
|
||||
selectFields: selectFields
|
||||
},
|
||||
}, function (res) {
|
||||
var list = res.data;
|
||||
|
||||
|
||||
|
||||
list.forEach(val => {
|
||||
var key = val[fields[0]];
|
||||
|
||||
var valueTitle = template(val, fields);
|
||||
|
||||
if (value !== undefined && key.toString() === value) {
|
||||
html += '<option value="' + key + '" selected="">' + valueTitle + '</option>';
|
||||
} else {
|
||||
html += '<option value="' + key + '">' + valueTitle + '</option>';
|
||||
}
|
||||
});
|
||||
$(that).html(html);
|
||||
form.render();
|
||||
}
|
||||
);
|
||||
});
|
||||
},
|
||||
nativeRadio() {
|
||||
$('[value-checked]').each(function (index, elem) {
|
||||
if ($(this).hasClass('checked-rendered')) {
|
||||
return;
|
||||
}
|
||||
$(this).addClass('checked-rendered');
|
||||
if ($(this).attr('value') == $(this).attr('value-checked')) {
|
||||
$(this).prop('checked', true);
|
||||
}
|
||||
});
|
||||
},
|
||||
nativeSelect() {
|
||||
$('[value-selected]').each(function (index, elem) {
|
||||
if ($(this).hasClass('selected-rendered')) {
|
||||
return;
|
||||
}
|
||||
$(this).addClass('selected-rendered');
|
||||
if ($(this).attr('value') == $(this).attr('value-selected')) {
|
||||
$(this).prop('selected', true);
|
||||
}
|
||||
});
|
||||
},
|
||||
date: function () {
|
||||
var dateList = document.querySelectorAll("[data-date]");
|
||||
if (dateList.length > 0) {
|
||||
$.each(dateList, function (i, v) {
|
||||
var format = $(this).attr('data-date'),
|
||||
type = $(this).attr('data-date-type'),
|
||||
range = $(this).attr('data-date-range');
|
||||
if (type === undefined || type === '' || type === null) {
|
||||
type = 'datetime';
|
||||
}
|
||||
var options = {
|
||||
elem: this,
|
||||
type: type,
|
||||
};
|
||||
if (format !== undefined && format !== '' && format !== null) {
|
||||
options['format'] = format;
|
||||
}
|
||||
if (range !== undefined) {
|
||||
if (range === null || range === '') {
|
||||
range = '-';
|
||||
}
|
||||
options['range'] = range;
|
||||
}
|
||||
laydate.render(options);
|
||||
});
|
||||
}
|
||||
},
|
||||
tableData() {
|
||||
var tableList = document.querySelectorAll('[data-toggle="table-data"]');
|
||||
$.each(tableList, function (i, v) {
|
||||
var data = $(v).data();
|
||||
tableData.render(v, data, admin);
|
||||
});
|
||||
|
||||
},
|
||||
mapLocation() {
|
||||
var mapList = document.querySelectorAll('[data-toggle="map-location"]');
|
||||
|
||||
$.each(mapList, function (i, v) {
|
||||
if ($(v).hasClass('map-rendered')) {
|
||||
return;
|
||||
}
|
||||
$(v).addClass('map-rendered');
|
||||
var data = $(v).data();
|
||||
mapLocation.render(v, data, admin);
|
||||
});
|
||||
|
||||
},
|
||||
tagInput() {
|
||||
var list = document.querySelectorAll('[data-toggle="tag-input"]');
|
||||
$.each(list, function (i, v) {
|
||||
var data = $(v).data();
|
||||
tagInput.render(v, data, admin);
|
||||
});
|
||||
|
||||
},
|
||||
propertyInput() {
|
||||
var list = document.querySelectorAll('[data-toggle="property-input"]');
|
||||
$.each(list, function (i, v) {
|
||||
var data = $(v).data();
|
||||
|
||||
data.value = $(v).text();
|
||||
|
||||
propertyInput.render(v, data, admin);
|
||||
});
|
||||
|
||||
},
|
||||
copyText(elem) {
|
||||
if (elem == undefined) {
|
||||
elem = 'body';
|
||||
}
|
||||
var list = $(elem).find('[data-toggle="copy-text"]');
|
||||
|
||||
$.each(list, function (i, v) {
|
||||
|
||||
if ($(v).hasClass('copy-rendered')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$(v).addClass('copy-rendered');
|
||||
var clipboard = new ClipboardJS(v);
|
||||
|
||||
clipboard.on('success', function (e) {
|
||||
admin.msg.success('复制成功');
|
||||
});
|
||||
|
||||
clipboard.on('error', function (e) {
|
||||
admin.msg.error('复制失败');
|
||||
|
||||
});
|
||||
});
|
||||
},
|
||||
pasteText(elem) {
|
||||
if (elem == undefined) {
|
||||
elem = 'body';
|
||||
}
|
||||
var list = $(elem).find('[data-toggle="paste-text"]');
|
||||
|
||||
$.each(list, function (i, v) {
|
||||
|
||||
if ($(v).hasClass('paste-rendered')) {
|
||||
return;
|
||||
}
|
||||
$(v).addClass('paste-rendered');
|
||||
|
||||
var targetElemName = $(v).data('paste-target');
|
||||
$(v).on('click', function () {
|
||||
if (!navigator.clipboard) {
|
||||
admin.msg.error('您的当前不支持粘贴操作');
|
||||
return;
|
||||
}
|
||||
navigator.clipboard.readText()
|
||||
.then(text => {
|
||||
$(targetElemName).val(text);
|
||||
layer.msg('粘贴成功');
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Failed to read clipboard contents: ', err);
|
||||
layer.msg('粘贴失败,请手动粘贴');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
window.ulAdmin = window.ua = admin;
|
||||
})();
|
||||
203
public/static/plugs/ulthon-admin/src/ulthon-admin.06-utils.js
Normal file
203
public/static/plugs/ulthon-admin/src/ulthon-admin.06-utils.js
Normal file
@@ -0,0 +1,203 @@
|
||||
(function () {
|
||||
|
||||
var ctx = window.__uaCtx || {};
|
||||
var admin = window.ua || {};
|
||||
var extGroup = ctx.extGroup;
|
||||
|
||||
admin.getQueryVariable = function (variable, defaultValue) {
|
||||
if (typeof defaultValue == 'undefined') {
|
||||
defaultValue = undefined;
|
||||
}
|
||||
|
||||
var query = window.location.search.substring(1);
|
||||
query = query.replace(/\+/g, ' ');
|
||||
var vars = query.split("&");
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split("=");
|
||||
if (pair[0] == variable) {
|
||||
return decodeURIComponent(pair[1]);
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
};
|
||||
admin.dataBrage = null;
|
||||
admin.getDataBrage = function (keys, defaultValue) {
|
||||
if (this.dataBrage == null) {
|
||||
this.dataBrage = JSON.parse($('#data-brage').text());
|
||||
}
|
||||
|
||||
if (typeof defaultValue == 'undefined') {
|
||||
defaultValue = undefined;
|
||||
}
|
||||
|
||||
return admin.dataGet(this.dataBrage, keys, defaultValue);
|
||||
};
|
||||
admin.dataGet = function (data, keys, defaultValue) {
|
||||
return (
|
||||
(!Array.isArray(keys)
|
||||
? keys.replace(/\[/g, '.').replace(/\]/g, '').split('.')
|
||||
: keys
|
||||
).reduce((o, k) => (o || {})[k], data) || defaultValue
|
||||
);
|
||||
};
|
||||
admin.getExtGroupName = function (ext) {
|
||||
var groupName = 'file';
|
||||
for (const extGroupName in extGroup) {
|
||||
if (Object.hasOwnProperty.call(extGroup, extGroupName)) {
|
||||
const extGroupList = extGroup[extGroupName];
|
||||
if (extGroupList.indexOf(ext) != -1) {
|
||||
groupName = extGroupName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return groupName;
|
||||
};
|
||||
//js版empty,判断变量是否为空
|
||||
admin.empty = function (r) {
|
||||
var n, t, e, f = [void 0, null, !1, 0, "", "0"];
|
||||
for (t = 0, e = f.length; t < e; t++) if (r === f[t]) return !0;
|
||||
if ("object" == typeof r) {
|
||||
for (n in r) if (r.hasOwnProperty(n)) return !1;
|
||||
return !0;
|
||||
}
|
||||
return !1;
|
||||
};
|
||||
|
||||
admin.bytes = function (size) {
|
||||
if (size > 0) {
|
||||
const kb = 1024;
|
||||
const unit = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
const i = Math.floor(Math.log(size) / Math.log(kb));
|
||||
const num = (size / Math.pow(kb, i)).toPrecision(3);
|
||||
const u = unit[i];
|
||||
return num + u;
|
||||
}
|
||||
return '0B';
|
||||
};
|
||||
admin.triggerEventReplaceJs = function (name, defaultCallback, replaceCallback) {
|
||||
var code = $('#event-replace-js-' + name).html();
|
||||
|
||||
if (admin.empty(code)) {
|
||||
defaultCallback();
|
||||
} else {
|
||||
replaceCallback(code);
|
||||
}
|
||||
};
|
||||
admin.randdomString = function (len) {
|
||||
len = len || 32;
|
||||
var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
|
||||
var maxPos = $chars.length;
|
||||
var pwd = '';
|
||||
for (var i = 0; i < len; i++) {
|
||||
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
|
||||
}
|
||||
return pwd;
|
||||
};
|
||||
admin.getPageSetting = function (key, defaultValue, global = false) {
|
||||
if (!global) {
|
||||
key = window.CONFIG.PAGE_KEY_NAME + '_' + key;
|
||||
}
|
||||
return tools.getLocal(key, defaultValue);
|
||||
};
|
||||
admin.setPageSetting = function (key, value, global) {
|
||||
if (!global) {
|
||||
key = window.CONFIG.PAGE_KEY_NAME + '_' + key;
|
||||
}
|
||||
return tools.setLocal(key, value);
|
||||
};
|
||||
/**
|
||||
* 如果不存在则写入,返回有效的值
|
||||
* 如果不存在则返回新的值,否则返回之前设置的值
|
||||
*
|
||||
* @param {string} key
|
||||
* @param {mixed} value
|
||||
* @param {boolean} global
|
||||
* @returns
|
||||
*/
|
||||
admin.trySetPageSetting = function (key, value, global) {
|
||||
var oldValue = admin.getPageSetting(key, undefined, global);
|
||||
if (!oldValue) {
|
||||
admin.setPageSetting(key, value, global);
|
||||
return value;
|
||||
}
|
||||
|
||||
return oldValue;
|
||||
};
|
||||
admin.isCurrentIndex = function () {
|
||||
if (window.pageType && window.pageType == 'index') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
admin.isParentIndex = function () {
|
||||
try {
|
||||
if (window.parent && window.parent.pageType && window.parent.pageType == 'index') {
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
admin.findIndexPage = function (findCallback, missCallback) {
|
||||
if (!findCallback) {
|
||||
findCallback = function (w) { return w; };
|
||||
}
|
||||
if (!missCallback) {
|
||||
missCallback = function (w) { return w; };
|
||||
}
|
||||
if (this.isCurrentIndex()) {
|
||||
return findCallback(window);
|
||||
}
|
||||
|
||||
var parent = window.parent;
|
||||
if (parent && parent != window) {
|
||||
return parent.ua.findIndexPage(findCallback, missCallback);
|
||||
}
|
||||
|
||||
return missCallback(null);
|
||||
};
|
||||
admin.getCurrentPageId = function () {
|
||||
// pageId就是路径加参数
|
||||
var path = location.pathname;
|
||||
var params = location.search;
|
||||
return path + params;
|
||||
};
|
||||
admin.findPageId = function (tabId) {
|
||||
var iframeWindow;
|
||||
this.findIndexPage(function (window) {
|
||||
// 查找对应的tab内容区域
|
||||
var tabContent = window.layui.$('.layui-tab-content .layui-tab-item[lay-id="' + tabId + '"]');
|
||||
if (tabContent.length > 0) {
|
||||
var iframe = tabContent.find('iframe')[0];
|
||||
if (iframe) {
|
||||
iframeWindow = iframe.contentWindow;
|
||||
}
|
||||
}
|
||||
});
|
||||
return iframeWindow;
|
||||
};
|
||||
admin.getMenuInfoByTabId = function (tabId) {
|
||||
var menuValue = null;
|
||||
this.findIndexPage(function (w) {
|
||||
var menu = w.miniTab.searchMenu(tabId);
|
||||
if (menu) {
|
||||
menuValue = menu;
|
||||
}
|
||||
});
|
||||
return menuValue;
|
||||
};
|
||||
admin.getMenuTitleByTabId = function (tabId, defaultValue) {
|
||||
var menuTitle = defaultValue;
|
||||
var menu = this.getMenuInfoByTabId(tabId);
|
||||
|
||||
if (menu) {
|
||||
menuTitle = menu.title;
|
||||
}
|
||||
return menuTitle;
|
||||
};
|
||||
|
||||
window.ulAdmin = window.ua = admin;
|
||||
})();
|
||||
11
public/static/plugs/ulthon-admin/ua.build.json
Normal file
11
public/static/plugs/ulthon-admin/ua.build.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"output": "ulthon-admin.js",
|
||||
"sources": [
|
||||
"src/ulthon-admin.01-core.js",
|
||||
"src/ulthon-admin.02-common.js",
|
||||
"src/ulthon-admin.03-table.js",
|
||||
"src/ulthon-admin.04-listen.js",
|
||||
"src/ulthon-admin.05-api.js",
|
||||
"src/ulthon-admin.06-utils.js"
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user