diff --git a/api/router/tl_ops_api_get_store.lua b/api/router/tl_ops_api_get_store.lua index 090a56d..d0d8612 100644 --- a/api/router/tl_ops_api_get_store.lua +++ b/api/router/tl_ops_api_get_store.lua @@ -14,7 +14,7 @@ cjson.encode_empty_table_as_object(false) -- 读取文件 local read = function( filename ) - local store_file_name = tl_ops_manage_env.log.store_dir .. filename + local store_file_name = tl_ops_manage_env.path.store .. filename local store_file_io, _ = io.open(store_file_name, "r") if not store_file_io then tlog:err("failed to open file in read: " .. store_file_name) diff --git a/conf/tl_ops_manage.conf b/conf/tl_ops_manage.conf index 7d5d7ff..15e267d 100644 --- a/conf/tl_ops_manage.conf +++ b/conf/tl_ops_manage.conf @@ -60,7 +60,19 @@ server { } location /tlopsmanage/ { - alias /path/to/tl-ops-manage/web/; + set $tlopsmanage ""; + alias $tlopsmanage; + rewrite_by_lua_block { + tlops:tl_ops_process_init_rewrite('onlyplugin'); + } + } + + location /website/ { + set $website ""; + alias $website; + rewrite_by_lua_block { + tlops:tl_ops_process_init_rewrite('onlyplugin'); + } } location /balanceerr/ { diff --git a/doc/change.md b/doc/change.md index 74ff6ee..787f8e7 100644 --- a/doc/change.md +++ b/doc/change.md @@ -1,6 +1,23 @@ ## 事务更新日程 +2022-08-18 + + 1. 拆分页面转发插件 + + 2. 调整路径配置 + + 3. 补充示例模板方法参数 + + 4. 调整sync插件日志输出位置 + + 5. 补充官网文件 + + 6. 即将支持一系列插件 + + 7. 事务日程调整 + + 2022-08-10 1. 支持集群数据同步 diff --git a/doc/feature.md b/doc/feature.md index f45ce81..de89716 100644 --- a/doc/feature.md +++ b/doc/feature.md @@ -87,6 +87,10 @@ - [ ] 支持自定义回源缓存 +- [ ] 支持动态插拔插件 + +- [ ] 支持动态自定义数据源 + - [ ] 支持多协议转换转发 @@ -100,9 +104,7 @@ - [ ] 【插件】支持请求ID追踪 -- [ ] 【插件】支持请求耗时统计 - -- [ ] 【插件】支持请求告警通知 +- [ ] 【插件】支持请求耗时统计告警 - [ ] 【插件】支持权限身份控制 diff --git a/plugins/tl_ops_cors/tl_ops_plugin_constant.lua b/plugins/tl_ops_cors/tl_ops_plugin_constant.lua new file mode 100644 index 0000000..a210b28 --- /dev/null +++ b/plugins/tl_ops_cors/tl_ops_plugin_constant.lua @@ -0,0 +1,3 @@ +return { + +} \ No newline at end of file diff --git a/plugins/tl_ops_cors/tl_ops_plugin_core.lua b/plugins/tl_ops_cors/tl_ops_plugin_core.lua new file mode 100644 index 0000000..09f820a --- /dev/null +++ b/plugins/tl_ops_cors/tl_ops_plugin_core.lua @@ -0,0 +1,51 @@ +-- tl_ops_plugin_cors +-- en : cors +-- zn : 跨域插件 +-- @author iamtsm +-- @email 1905333456@qq.com + +local tlog = require("utils.tl_ops_utils_log"):new("tl_ops_plugin_cors"); +local tl_ops_utils_func = require("utils.tl_ops_utils_func"); + +local _M = { + _VERSION = '0.01' +} + +local mt = { __index = _M } + + +function _M:new(options) + if not options then + options = {} + end + return setmetatable(options, mt) +end + + +function _M:tl_ops_process_before_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_header(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_header(ctx) + + + return true, "ok" +end + + + +return _M diff --git a/plugins/tl_ops_jwt/tl_ops_plugin_constant.lua b/plugins/tl_ops_jwt/tl_ops_plugin_constant.lua new file mode 100644 index 0000000..a210b28 --- /dev/null +++ b/plugins/tl_ops_jwt/tl_ops_plugin_constant.lua @@ -0,0 +1,3 @@ +return { + +} \ No newline at end of file diff --git a/plugins/tl_ops_jwt/tl_ops_plugin_core.lua b/plugins/tl_ops_jwt/tl_ops_plugin_core.lua new file mode 100644 index 0000000..b16d0e9 --- /dev/null +++ b/plugins/tl_ops_jwt/tl_ops_plugin_core.lua @@ -0,0 +1,62 @@ +-- tl_ops_plugin_jwt +-- en : jwt +-- zn : jwt权限认证插件 +-- @author iamtsm +-- @email 1905333456@qq.com + +local tlog = require("utils.tl_ops_utils_log"):new("tl_ops_plugin_jwt"); +local tl_ops_utils_func = require("utils.tl_ops_utils_func"); + +local _M = { + _VERSION = '0.01' +} + +local mt = { __index = _M } + + +function _M:new(options) + if not options then + options = {} + end + return setmetatable(options, mt) +end + + +function _M:tl_ops_process_before_init_rewrite(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_rewrite(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_header(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_header(ctx) + + + return true, "ok" +end + + +return _M diff --git a/plugins/tl_ops_log_analyze/tl_ops_plugin_constant.lua b/plugins/tl_ops_log_analyze/tl_ops_plugin_constant.lua new file mode 100644 index 0000000..a210b28 --- /dev/null +++ b/plugins/tl_ops_log_analyze/tl_ops_plugin_constant.lua @@ -0,0 +1,3 @@ +return { + +} \ No newline at end of file diff --git a/plugins/tl_ops_log_analyze/tl_ops_plugin_core.lua b/plugins/tl_ops_log_analyze/tl_ops_plugin_core.lua new file mode 100644 index 0000000..0c791f7 --- /dev/null +++ b/plugins/tl_ops_log_analyze/tl_ops_plugin_core.lua @@ -0,0 +1,122 @@ +-- tl_ops_plugin_log_analyze +-- en : log_analyze +-- zn : 日志分析插件 +-- @author iamtsm +-- @email 1905333456@qq.com + +local tlog = require("utils.tl_ops_utils_log"):new("tl_ops_plugin_log_analyze"); +local tl_ops_utils_func = require("utils.tl_ops_utils_func"); + +local _M = { + _VERSION = '0.01' +} + +local mt = { __index = _M } + + +function _M:new(options) + if not options then + options = {} + end + return setmetatable(options, mt) +end + + +function _M:tl_ops_process_before_init_worker() + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_worker() + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_ssl() + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_ssl() + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_rewrite(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_rewrite(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_balancer(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_balancer(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_header(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_header(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_body(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_body(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_log(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_log(ctx) + + + return true, "ok" +end + + +return _M diff --git a/plugins/tl_ops_page_proxy/tl_ops_plugin_constant.lua b/plugins/tl_ops_page_proxy/tl_ops_plugin_constant.lua new file mode 100644 index 0000000..a210b28 --- /dev/null +++ b/plugins/tl_ops_page_proxy/tl_ops_plugin_constant.lua @@ -0,0 +1,3 @@ +return { + +} \ No newline at end of file diff --git a/plugins/tl_ops_page_proxy/tl_ops_plugin_core.lua b/plugins/tl_ops_page_proxy/tl_ops_plugin_core.lua new file mode 100644 index 0000000..2fe3d4b --- /dev/null +++ b/plugins/tl_ops_page_proxy/tl_ops_plugin_core.lua @@ -0,0 +1,42 @@ +-- tl_ops_plugin_page_proxy +-- en : page_proxy +-- zn : 页面转发插件 +-- @author iamtsm +-- @email 1905333456@qq.com + +local utils = tlops.utils +local env = tlops.env + +local _M = { + _VERSION = '0.01' +} + +local mt = { __index = _M } + + +function _M:new(options) + if not options then + options = {} + end + return setmetatable(options, mt) +end + + +-- 页面转发插件实现 +function _M:tl_ops_process_before_init_rewrite(ctx) + + local request_uri = utils:get_req_uri() + + if ngx.re.find(request_uri, "/tlopsmanage/", 'jo') then + ngx.var.tlopsmanage = env.path.tlopsmanage + end + + if ngx.re.find(request_uri, "/website/", 'jo') then + ngx.var.website = env.path.website + end + + return true, "ok" +end + + +return _M diff --git a/plugins/tl_ops_sync/sync_data.lua b/plugins/tl_ops_sync/sync_data.lua index e634eee..dc0742e 100644 --- a/plugins/tl_ops_sync/sync_data.lua +++ b/plugins/tl_ops_sync/sync_data.lua @@ -41,7 +41,7 @@ local cache_waf = tlops.cache.waf local utils = tlops.utils local cjson = require("cjson.safe"); cjson.encode_empty_table_as_object(false) -local tlog = require("utils.tl_ops_utils_log"):new("tl_ops_plugin_sync_data"); +local tlog = require("utils.tl_ops_utils_log"):new("tl_ops_plugin_sync"); local _M = { diff --git a/plugins/tl_ops_sync/sync_fields.lua b/plugins/tl_ops_sync/sync_fields.lua index a0c9169..205e95b 100644 --- a/plugins/tl_ops_sync/sync_fields.lua +++ b/plugins/tl_ops_sync/sync_fields.lua @@ -43,7 +43,7 @@ local tl_ops_limit_fuse_check_version = require("limit.fuse.tl_ops_limit_fus local tl_ops_health_check_version = require("health.tl_ops_health_check_version") local cjson = require("cjson.safe"); cjson.encode_empty_table_as_object(false) -local tlog = require("utils.tl_ops_utils_log"):new("tl_ops_plugin_sync_fields"); +local tlog = require("utils.tl_ops_utils_log"):new("tl_ops_plugin_sync"); local _M = { diff --git a/plugins/tl_ops_template/tl_ops_plugin_core.lua b/plugins/tl_ops_template/tl_ops_plugin_core.lua index f8975d3..755748d 100644 --- a/plugins/tl_ops_template/tl_ops_plugin_core.lua +++ b/plugins/tl_ops_template/tl_ops_plugin_core.lua @@ -46,13 +46,13 @@ function _M:tl_ops_process_after_init_ssl() return true, "ok" end -function _M:tl_ops_process_before_init_rewrite() +function _M:tl_ops_process_before_init_rewrite(ctx) return true, "ok" end -function _M:tl_ops_process_after_init_rewrite() +function _M:tl_ops_process_after_init_rewrite(ctx) return true, "ok" diff --git a/plugins/tl_ops_time_alert/tl_ops_plugin_constant.lua b/plugins/tl_ops_time_alert/tl_ops_plugin_constant.lua new file mode 100644 index 0000000..a210b28 --- /dev/null +++ b/plugins/tl_ops_time_alert/tl_ops_plugin_constant.lua @@ -0,0 +1,3 @@ +return { + +} \ No newline at end of file diff --git a/plugins/tl_ops_time_alert/tl_ops_plugin_core.lua b/plugins/tl_ops_time_alert/tl_ops_plugin_core.lua new file mode 100644 index 0000000..3ec73ed --- /dev/null +++ b/plugins/tl_ops_time_alert/tl_ops_plugin_core.lua @@ -0,0 +1,122 @@ +-- tl_ops_plugin_time_alert +-- en : time_alert +-- zn : 请求耗时告警统计插件 +-- @author iamtsm +-- @email 1905333456@qq.com + +local tlog = require("utils.tl_ops_utils_log"):new("tl_ops_plugin_time_alert"); +local tl_ops_utils_func = require("utils.tl_ops_utils_func"); + +local _M = { + _VERSION = '0.01' +} + +local mt = { __index = _M } + + +function _M:new(options) + if not options then + options = {} + end + return setmetatable(options, mt) +end + + +function _M:tl_ops_process_before_init_worker() + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_worker() + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_ssl() + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_ssl() + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_rewrite(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_rewrite(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_balancer(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_balancer(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_header(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_header(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_body(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_body(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_log(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_log(ctx) + + + return true, "ok" +end + + +return _M diff --git a/plugins/tl_ops_tracing/tl_ops_plugin_constant.lua b/plugins/tl_ops_tracing/tl_ops_plugin_constant.lua new file mode 100644 index 0000000..a210b28 --- /dev/null +++ b/plugins/tl_ops_tracing/tl_ops_plugin_constant.lua @@ -0,0 +1,3 @@ +return { + +} \ No newline at end of file diff --git a/plugins/tl_ops_tracing/tl_ops_plugin_core.lua b/plugins/tl_ops_tracing/tl_ops_plugin_core.lua new file mode 100644 index 0000000..802b4f9 --- /dev/null +++ b/plugins/tl_ops_tracing/tl_ops_plugin_core.lua @@ -0,0 +1,62 @@ +-- tl_ops_plugin_tracing +-- en : tracing +-- zn : 请求追踪插件 +-- @author iamtsm +-- @email 1905333456@qq.com + +local tlog = require("utils.tl_ops_utils_log"):new("tl_ops_plugin_tracing"); +local tl_ops_utils_func = require("utils.tl_ops_utils_func"); + +local _M = { + _VERSION = '0.01' +} + +local mt = { __index = _M } + + +function _M:new(options) + if not options then + options = {} + end + return setmetatable(options, mt) +end + + +function _M:tl_ops_process_before_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_access(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_header(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_header(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_before_init_log(ctx) + + + return true, "ok" +end + +function _M:tl_ops_process_after_init_log(ctx) + + + return true, "ok" +end + + +return _M diff --git a/tl_ops_manage.lua b/tl_ops_manage.lua index fe83c1c..d5672b9 100644 --- a/tl_ops_manage.lua +++ b/tl_ops_manage.lua @@ -80,21 +80,23 @@ end -- rewrite阶段执行 -function _M:tl_ops_process_init_rewrite() +function _M:tl_ops_process_init_rewrite(onlyplugin) -- 初始化ctx m_ctx:init(); -- 执行插件 m_plugin:tl_ops_process_before_init_rewrite(ngx.ctx); - -- 加载管理台API - m_api:init(ngx.ctx); + if not onlyplugin then + -- 加载管理台API + m_api:init(ngx.ctx); - -- 启动全局WAF - m_waf:init_global(ngx.ctx); + -- 启动全局WAF + m_waf:init_global(ngx.ctx); - -- 负载均衡筛选 - m_balance:filter(ngx.ctx); + -- 负载均衡筛选 + m_balance:filter(ngx.ctx); + end -- 执行插件 m_plugin:tl_ops_process_after_init_rewrite(ngx.ctx); @@ -156,7 +158,8 @@ end -- log阶段执行 function _M:tl_ops_process_init_log() -- 执行插件 - m_plugin:tl_ops_process_before_init_log(ngx.ctx); + m_plugin:tl_ops_process_before_init_log(ngx.ctx); + -- 执行插件 m_plugin:tl_ops_process_after_init_log(ngx.ctx); end diff --git a/tl_ops_manage_env.lua b/tl_ops_manage_env.lua index 2e447b0..f6955db 100644 --- a/tl_ops_manage_env.lua +++ b/tl_ops_manage_env.lua @@ -1,4 +1,33 @@ +local ROOT_PATH = "/path/to/tl-ops-manage/" + return { + path = { + --[[ + en :Console path setting, the page forwarding plugin will use this path for path matching + + zn :控制台路径设置,页面转发插件会将此路径用于路径匹配 + ]] + tlopsmanage = ROOT_PATH .. "web/", + --[[ + en :The official website path setting, the page forwarding plugin + will use this path for path matching + + zn :官网路径设置,页面转发插件会将此路径用于路径匹配 + ]] + website = ROOT_PATH .. "website/", + --[[ + en :log output directory, all module logs will be output to this directory + + zn :日志输出目录,所有模块的日志都将输出到此目录下 + ]] + log = ROOT_PATH, + --[[ + en :data storage directory, the directory where the module data is stored + + zn :数据存放目录,模块的数据存放的目录 + ]] + store = ROOT_PATH .. "store/", + }, log = { --[[ en :log level, please be careful not to enable debug level logs @@ -14,20 +43,6 @@ return { zn :日志格式化,开启此选项会占用更多磁盘空间,生产环境推荐关闭此选项 ]] format_json = true, - --[[ - en :log output directory, all module logs will be output to this directory, - Notice : need to fill in the 'absolute path' - - zn :日志输出目录,所有模块的日志都将输出到此目录下,注意:需要填写 ‘绝对路径’ - ]] - log_dir = "/path/to/tl-ops-manage/", - --[[ - en :data storage directory, the directory where the module data is stored, - Notice: need to fill in the 'absolute path' - - zn :数据存放目录,模块的数据存放的目录,注意:需要填写 ‘绝对路径’ - ]] - store_dir = "/path/to/tl-ops-manage/store/", }, cache = { --[[ @@ -163,7 +178,8 @@ return { zn :插件模块定义,引入的插件需要在此定义好才能被加载。否则将不生效。注意,插件填写的顺序将影响相同插件阶段执行的顺序 ]] module = { - "ssl", "sync", "sync_cluster" + "ssl", "sync", "sync_cluster", "page_proxy", + -- "jwt", "cors", "log_analyze", "tracing" } } } diff --git a/utils/tl_ops_utils_log.lua b/utils/tl_ops_utils_log.lua index 799a449..d9f08fd 100644 --- a/utils/tl_ops_utils_log.lua +++ b/utils/tl_ops_utils_log.lua @@ -97,7 +97,7 @@ function _M:new(module) return setmetatable({ level = tl_ops_manage_env.log.level, module = module, - dir = tl_ops_manage_env.log.log_dir, + dir = tl_ops_manage_env.path.log, format_json = tl_ops_manage_env.log.format_json }, self) end diff --git a/utils/tl_ops_utils_store.lua b/utils/tl_ops_utils_store.lua index 2db4dda..42a97f9 100644 --- a/utils/tl_ops_utils_store.lua +++ b/utils/tl_ops_utils_store.lua @@ -124,7 +124,7 @@ end function _M:new(business) local store_conf = { - path = tl_ops_manage_env.log.store_dir, + path = tl_ops_manage_env.path.store, business = business } setmetatable(store_conf, self) diff --git a/website/en.html b/website/en.html new file mode 100644 index 0000000..39747b4 --- /dev/null +++ b/website/en.html @@ -0,0 +1,316 @@ + + + +
+ +i.pages||(i.curr=e,t.render())});e&&o.on(e,"change",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),n&&o.on(n,"click",function(){s()})}},t.prototype.skip=function(t){var i,e;t&&(i=this,(e=t[c]("input")[0])&&o.on(e,"keyup",function(e){var a=this.value,e=e.keyCode;/^(37|38|39|40)$/.test(e)||(/\D/.test(a)&&(this.value=a.replace(/\D/,"")),13===e&&i.jump(t,!0))}))},t.prototype.render=function(e){var a=this,t=a.config,i=a.type(),r=a.view(),i=(2===i?t.elem&&(t.elem.innerHTML=r):3===i?t.elem.html(r):n[u](t.elem)&&(n[u](t.elem).innerHTML=r),t.jump&&t.jump(t,e),n[u]("layui-laypage-"+t.index));a.jump(i),t.hash&&!e&&(location.hash="!"+t.hash+"="+t.curr),a.skip(i)},{render:function(e){return new t(e).index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(a,e,t){return a.attachEvent?a.attachEvent("on"+e,function(e){e.target=e.srcElement,t.call(a,e)}):a.addEventListener(e,t,!1),this}});e("laypage",o)});!function(i,r){"use strict";var n=i.layui&&layui.define,l={getPath:i.lay&&lay.getPath?lay.getPath:"",link:function(e,t,a){u.path&&i.lay&&lay.layui&&lay.layui.link(u.path+e,t,a)}},e=i.LAYUI_GLOBAL||{},u={v:"5.3.1",config:{weekStart:0},index:i.laydate&&i.laydate.v?1e5:0,path:e.laydate_dir||l.getPath,set:function(e){var t=this;return t.config=lay.extend({},t.config,e),t},ready:function(e){var t="laydate",a=(n?"modules/laydate/":"theme/")+"default/laydate.css?v="+u.v;return n?layui.addcss(a,e,t):l.link(a,e,t),this}},s=function(){var t=this,e=t.config.id;return{hint:function(e){t.hint.call(t,e)},config:(s.that[e]=t).config}},a="laydate",w="layui-this",x="laydate-disabled",h=[100,2e5],p="layui-laydate-static",M="layui-laydate-list",o="layui-laydate-hint",E=".laydate-btns-confirm",C="laydate-time-text",k="laydate-btns-time",f="layui-laydate-preview",g=function(e){var t=this;t.index=++u.index,t.config=lay.extend({},t.config,u.config,e),(e=t.config).id="id"in e?e.id:t.index,u.ready(function(){t.init()})},y="yyyy|y|MM|M|dd|d|HH|H|mm|m|ss|s";s.formatArr=function(e){return(e||"").match(new RegExp(y+"|.","g"))||[]},g.isLeapYear=function(e){return e%4==0&&e%100!=0||e%400==0},g.prototype.config={type:"date",range:!1,format:"yyyy-MM-dd",value:null,isInitValue:!0,min:"1900-1-1",max:"2099-12-31",trigger:"click",show:!1,showBottom:!0,isPreview:!0,btns:["clear","now","confirm"],lang:"cn",theme:"default",position:null,calendar:!1,mark:{},holidays:null,zIndex:null,done:null,change:null},g.prototype.lang=function(){var e={cn:{weeks:["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d"],time:["\u65f6","\u5206","\u79d2"],timeTips:"\u9009\u62e9\u65f6\u95f4",startTime:"\u5f00\u59cb\u65f6\u95f4",endTime:"\u7ed3\u675f\u65f6\u95f4",dateTips:"\u8fd4\u56de\u65e5\u671f",month:["\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u5341\u4e00","\u5341\u4e8c"],tools:{confirm:"\u786e\u5b9a",clear:"\u6e05\u7a7a",now:"\u73b0\u5728"},timeout:"\u7ed3\u675f\u65f6\u95f4\u4e0d\u80fd\u65e9\u4e8e\u5f00\u59cb\u65f6\u95f4
\u8bf7\u91cd\u65b0\u9009\u62e9",invalidDate:"\u4e0d\u5728\u6709\u6548\u65e5\u671f\u6216\u65f6\u95f4\u8303\u56f4\u5185",formatError:["\u65e5\u671f\u683c\u5f0f\u4e0d\u5408\u6cd5
\u5fc5\u987b\u9075\u5faa\u4e0b\u8ff0\u683c\u5f0f\uff1a
","
\u5df2\u4e3a\u4f60\u91cd\u7f6e"],preview:"\u5f53\u524d\u9009\u4e2d\u7684\u7ed3\u679c"},en:{weeks:["Su","Mo","Tu","We","Th","Fr","Sa"],time:["Hours","Minutes","Seconds"],timeTips:"Select Time",startTime:"Start Time",endTime:"End Time",dateTips:"Select Date",month:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],tools:{confirm:"Confirm",clear:"Clear",now:"Now"},timeout:"End time cannot be less than start Time
Please re-select",invalidDate:"Invalid date",formatError:["The date format error
Must be followed\uff1a
","
It has been reset"],preview:"The selected result"}};return e[this.config.lang]||e.cn},g.prototype.init=function(){var r=this,o=r.config,e="static"===o.position,t={year:"yyyy",month:"yyyy-MM",date:"yyyy-MM-dd",time:"HH:mm:ss",datetime:"yyyy-MM-dd HH:mm:ss"};o.elem=lay(o.elem),o.eventElem=lay(o.eventElem),o.elem[0]&&(r.rangeStr=o.range?"string"==typeof o.range?o.range:"-":"","array"===layui.type(o.range)&&(r.rangeElem=[lay(o.range[0]),lay(o.range[1])]),t[o.type]||(i.console&&console.error&&console.error("laydate type error:'"+o.type+"' is not supported"),o.type="date"),o.format===t.date&&(o.format=t[o.type]||t.date),r.format=s.formatArr(o.format),o.weekStart&&!/^[0-6]$/.test(o.weekStart)&&(t=r.lang(),o.weekStart=t.weeks.indexOf(o.weekStart),-1===o.weekStart&&(o.weekStart=0)),r.EXP_IF="",r.EXP_SPLIT="",lay.each(r.format,function(e,t){e=new RegExp(y).test(t)?"\\d{"+(new RegExp(y).test(r.format[0===e?e+1:e-1]||"")?/^yyyy|y$/.test(t)?4:t.length:/^yyyy$/.test(t)?"1,4":/^y$/.test(t)?"1,308":"1,2")+"}":"\\"+t;r.EXP_IF=r.EXP_IF+e,r.EXP_SPLIT=r.EXP_SPLIT+"("+e+")"}),r.EXP_IF_ONE=new RegExp("^"+r.EXP_IF+"$"),r.EXP_IF=new RegExp("^"+(o.range?r.EXP_IF+"\\s\\"+r.rangeStr+"\\s"+r.EXP_IF:r.EXP_IF)+"$"),r.EXP_SPLIT=new RegExp("^"+r.EXP_SPLIT+"$",""),r.isInput(o.elem[0])||"focus"===o.trigger&&(o.trigger="click"),o.elem.attr("lay-key")||(o.elem.attr("lay-key",r.index),o.eventElem.attr("lay-key",r.index)),o.mark=lay.extend({},o.calendar&&"cn"===o.lang?{"0-1-1":"\u5143\u65e6","0-2-14":"\u60c5\u4eba","0-3-8":"\u5987\u5973","0-3-12":"\u690d\u6811","0-4-1":"\u611a\u4eba","0-5-1":"\u52b3\u52a8","0-5-4":"\u9752\u5e74","0-6-1":"\u513f\u7ae5","0-9-10":"\u6559\u5e08","0-10-1":"\u56fd\u5e86","0-12-25":"\u5723\u8bde"}:{},o.mark),lay.each(["min","max"],function(e,t){var a,n,i=[],l=[];l="number"==typeof o[t]?(n=o[t],a=new Date,a=r.newDate({year:a.getFullYear(),month:a.getMonth(),date:a.getDate(),hours:"23",minutes:"59",seconds:"59"}).getTime(),i=[(n=new Date(n?n<864e5?a+864e5*n:n:a)).getFullYear(),n.getMonth()+1,n.getDate()],[n.getHours(),n.getMinutes(),n.getSeconds()]):(i=(o[t].match(/\d+-\d+-\d+/)||[""])[0].split("-"),(o[t].match(/\d+:\d+:\d+/)||[""])[0].split(":")),o[t]={year:0|i[0]||(new Date).getFullYear(),month:i[1]?(0|i[1])-1:(new Date).getMonth(),date:0|i[2]||(new Date).getDate(),hours:0|l[0],minutes:0|l[1],seconds:0|l[2]}}),r.elemID="layui-laydate"+o.elem.attr("lay-key"),(o.show||e)&&r.render(),e||r.events(),o.value&&o.isInitValue&&("date"===layui.type(o.value)?r.setValue(r.parse(0,r.systemDate(o.value))):r.setValue(o.value)))},g.prototype.render=function(){var n,e,t=this,o=t.config,s=t.lang(),i="static"===o.position,a=t.elem=lay.elem("div",{id:t.elemID,"class":["layui-laydate",o.range?" layui-laydate-range":"",i?" "+p:"",o.theme&&"default"!==o.theme&&!/^#/.test(o.theme)?" laydate-theme-"+o.theme:""].join("")}),y=t.elemMain=[],d=t.elemHeader=[],m=t.elemCont=[],c=t.table=[],l=t.footer=lay.elem("div",{"class":"layui-laydate-footer"});o.zIndex&&(a.style.zIndex=o.zIndex),lay.each(new Array(2),function(e){if(!o.range&&0