邹景立 568fb5d274 refactor(editor): 统一富文本编辑器实现
将后台富文本模块统一切换为 wangEditor 加载入口,移除 CKEditor4/CKEditor5 的动态选择与运行时编辑器驱动配置,降低前端资源体积和配置复杂度。

重写 createEditor 封装,支持初始化复用、内容同步、销毁恢复、上传配置透传和图片/视频自定义上传,并在表单提交前通过 data-editor-source 统一回写编辑器内容。

同步更新系统配置页面、接口脚本、初始化数据、语言包、测试用例和业务表单引用,将原 ckeditor 模块调用改为 editor 模块,避免遗留编辑器入口失效。
2026-05-20 23:17:43 +08:00

128 lines
7.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// +----------------------------------------------------------------------
// | Static Plugin for ThinkAdmin
// +----------------------------------------------------------------------
// | 版权所有 2014~2024 ThinkAdmin [ thinkadmin.top ]
// +----------------------------------------------------------------------
// | 官方网站: https://thinkadmin.top
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// | 免责声明 ( https://thinkadmin.top/disclaimer )
// +----------------------------------------------------------------------
// | gitee 代码仓库https://gitee.com/zoujingli/think-plugs-static
// | github 代码仓库https://github.com/zoujingli/think-plugs-static
// +----------------------------------------------------------------------
layui.define(function (exports) {
function Validate(form) {
let that = this;
// 绑定表单元素
this.form = $(form);
// 绑定元素事件
this.evts = 'blur change';
// 检测表单元素
this.tags = 'input,textarea';
// 验证成功回调
this.dones = [];
// 预设检测规则
this.patterns = {
qq: '^[1-9][0-9]{4,11}$',
ip: '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$',
url: '^https?://([a-zA-Z0-9-]+\\.)+[-_a-zA-Z0-9-]+',
phone: '^1[3-9][0-9]{9}$',
mobile: '^1[3-9][0-9]{9}$',
email: '^([a-zA-Z0-9_\\.-])+@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,4})+$',
wechat: '^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$',
cardid: '^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$',
userame: '^[a-zA-Z0-9_-]{4,16}$',
};
// 设置完成回调
this.addDoneEvent = function (done) {
if (typeof done === 'function') this.dones.push(done);
};
this.isRegex = function (el, value, pattern) {
pattern = pattern || el.getAttribute('pattern');
if ((value = value || $.trim($(el).val())) === '') return true;
if (!(pattern = this.patterns[pattern] || pattern)) return true;
return new RegExp(pattern, 'i').test(value);
};
this.hasProp = function (el, prop) {
let attrProp = el.getAttribute(prop);
return typeof attrProp !== 'undefined' && attrProp !== null && attrProp !== false;
};
this.hasCheck = function (el, type) {
if (this.hasProp(el, 'data-auto-none')) return false;
type = (el.getAttribute('type') || '').replace(/\W+/, '').toLowerCase();
return $.inArray(type, ['file', 'reset', 'image', 'radio', 'checkbox', 'submit', 'hidden']) < 0;
};
this.checkAllInput = function () {
let status = true;
return this.form.find(this.tags).each(function () {
!that.checkInput(this) && status && (status = !$(this).focus());
}) && status;
};
this.checkInput = function (el) {
if (!this.hasCheck(el = typeof el === 'string' ? form[el] : el)) return true;
if (this.hasProp(el, 'required') && $.trim($(el).val()) === '') return this.remind(el, 'required');
return this.isRegex(el) ? !!this.hideError(el) : this.remind(el, 'pattern');
};
this.remind = function (el, type, tips) {
return $(el).is(':visible') ? this.showError(el, tips || el.getAttribute(type + '-error') || function (name, tips) {
return name ? name + (type === 'required' ? '不能为空' : "格式错误") : (tips || el.getAttribute('placeholder') || '输入格式错误');
}(el.getAttribute('vali-name') || el.getAttribute('data-vali-name'), el.getAttribute('title'))) && false : true;
};
this.showError = function (el, tip) {
return this.insertError($(el).addClass('validate-error')).addClass('layui-anim-fadein').css({width: 'auto'}).html(tip);
};
this.hideError = function (el) {
return this.insertError($(el).removeClass('validate-error')).removeClass('layui-anim-fadein').css({width: '30px'}).html('');
};
this.insertError = function ($el) {
return (function ($icon) {
return $el.data('vali-tags').css({
top: $el.position().top + 'px', right: (($icon ? $icon.width() + parseFloat($icon.css('right') || 0) : 0) + 10) + 'px',
paddingTop: $el.css('marginTop'), lineHeight: ($el.get(0).nodeName || '') === 'TEXTAREA' ? '32px' : $el.css('height'),
});
})($el.nextAll('.input-right-icon'), $el.data('vali-tags') || function () {
let css = 'display:block;position:absolute;text-align:center;color:#c44;font-size:12px;z-index:2;right:8px';
$el.data('vali-tags', $('<span class="layui-anim notselect" style="' + css + '"></span>').insertAfter($el));
}());
};
/*! 预埋异常标签*/
this.form.find(this.tags).each(function (i, el) {
that.hasCheck(this) && that.hideError(el, '');
});
/*! 表单元素验证 */
this.form.attr({onsubmit: 'return false', novalidate: 'novalidate', autocomplete: 'off'}).on('keydown', this.tags, function () {
that.hideError(this)
}).off(this.evts, this.tags).on(this.evts, this.tags, function () {
that.checkInput(this);
}).data('validate', this).bind('submit', function (evt) {
evt.preventDefault();
/* 检查所有表单元素是否通过H5的规则验证 */
if (that.checkAllInput() && that.dones.length > 0) {
that.form.find('[data-editor-source]').each(function () {
let editor = $(this).data('editorInstance');
if (editor && typeof editor.updateElement === 'function') editor.updateElement();
});
/* 触发表单提交后,锁定三秒不能再次提交表单 */
if (that.form.attr('submit-locked')) return false;
evt.submit = that.form.find('button[type=submit],button:not([type=button])');
$.base.onConfirm(evt.submit.attr('data-confirm'), function () {
that.form.attr('submit-locked', 1) && evt.submit.addClass('submit-button-loading');
setTimeout(function () {
that.form.removeAttr('submit-locked') && evt.submit.removeClass('submit-button-loading');
}, 3000) && that.dones.forEach(function (done) {
done.call(form, that.form.formToJson(), []);
});
});
}
}).find('[data-form-loaded]').map(function () {
$(this).html(this.dataset.formLoaded || this.innerHTML);
$(this).removeAttr('data-form-loaded').removeClass('layui-disabled');
});
}
exports('taValidate', Validate);
});