/******************************宏代码说明****************************** * 类型:ClientSide * 事件:onAfterRender * 效果描述:根据富文本面板,设置时间更新。 * 实现步骤: * (1)在富文本中将需要替换为时间的地方用 {} 符号包裹起来, 在该数值的前后加入, 举例: "{DATETIME}" * (2) 在宏中可修改一些配置项 * 注意事项: * (1){} 符号包裹的内容,需要移除它们内容改为需要刷新的时间。 *********************************************************************/ function main(page: IPage, portlet: IStaticTextPortlet) { /**********************配置开始******************** */ let timeConfig: TimeConfig = [{ flag: 'DATE', format: 'yyyy-MM-dd' }, { flag: 'DATETIME', format: 'yyyy-MM-dd hh:mm:ss' }, { flag: 'DATETIME.S', format: 'yyyy-MM-dd hh:mm:ss.S' }, { flag: 'H_DATETIME', format: 'yyyy-M-d h:m:s.S' }] /**********************配置结束******************** */ renderTime(portlet, timeConfig) } /** 占位符配置(不建议修改) */ const flagConfig: FlagConfig = { prefix: '{', suffix: '}', attrName: 'flag-span', itemAttrName: 'flag-item-config', prefixName: 'prefix', suffixName: 'suffix', contentName: 'content', } /** * 渲染时间 */ function renderTime(portlet: IStaticTextPortlet, timeConfig: TimeConfig) { let content = portlet.getHtmlContent() let editorDom = content.querySelector('.ql-editor') let slots: any = [] findSlots(slots, editorDom, timeConfig) let { prefix, suffix, attrName, itemAttrName, prefixName, suffixName, contentName } = flagConfig slots.forEach((slot: any, index: number) => { let attr = slot.getAttribute(attrName); let cont = slot; if (attr !== contentName) { /** 前缀 */ let pre: any = buildFlag(prefixName, prefix, false); /** 后缀 */ let suf: any = buildFlag(suffixName, suffix, false); /** 内容 */ let newCont = buildFlag(contentName, '', true) newCont.setAttribute(itemAttrName, cont.getAttribute(itemAttrName)) cont = newCont // 替换富文本上的内容 slot.innerHTML = '' slot.appendChild(pre) slot.appendChild(cont) slot.appendChild(suf) } // 运行时间 runTime(portlet, cont, index, timeConfig); }) } /** * 运行时间 */ function runTime(portlet: IStaticTextPortlet, dom: any, index: number, timeConfig:TimeConfig) { let str = '_refresh_time_' let { itemAttrName } = flagConfig let name = `${portlet.getId()}${str}${index}`; (SmartbiXMacro as any).data || ((SmartbiXMacro as any).data = {}); clearInterval((SmartbiXMacro as any).data[name]); let flag = dom.getAttribute(itemAttrName) if (flag) { let conf = (timeConfig as any).find((el: any) => el.flag === flag) || {} let format = conf.format || 'yyyy-MM-dd hh:mm:ss'; (SmartbiXMacro as any).data[name] = setInterval(() => { dom.innerHTML = SmartbiXMacro.utils.formatDate(new Date(), format) }, 1000) } } /** * 根据规则构建dom */ function buildFlag(attr: string, text: string, show: boolean) { let { attrName } = flagConfig let dom: any = document.createElement('span'); show || (dom.style.display = 'none') dom.setAttribute(attrName, attr); dom.innerHTML = text; return dom } /** * 查找所有需要替换的地方 */ function findSlots(slots: any, dom: any, timeConfig: TimeConfig) { let { prefix, suffix, attrName, itemAttrName, contentName } = flagConfig let find = (targetText: any) => { return (timeConfig as any).find((item: any) => { let text = `${prefix}${item.flag}${suffix}` return text === targetText }) } dom && dom.childNodes.forEach((el: any) => { if (el && el.getAttribute) { let attr = el.getAttribute(attrName); /** 是否占位符dom */ let isCont = attr === contentName; let conf = find(el.innerText) if (conf || isCont) { if (conf) { el.setAttribute(itemAttrName, conf.flag) } slots.push(el) } else if (el.childNodes && el.childNodes.length) { findSlots(slots, el, timeConfig) } } }) } /** * 时间配置类型 * [{ * flag: 占位符 * format: 时间格式(常用的) * }] */ type TimeConfig = Array /** * 时间配置项类型 * flag: 占位符 * format: 时间格式(常用的) */ type TimeItemConfig = { flag: string, format: string } /** * 占位符配置类型 * prefix: 占位符包裹前缀,例如:'{' * suffix: 占位符包裹后缀,例如:'}' * attrName: 占位符dom的标识属性 * prefixName: 占位符包裹前缀dom的标识属性值 * suffixName: 占位符包裹后缀dom的标识属性值 * contentName: 占位符dom的标识属性值 */ type FlagConfig = { prefix: string suffix: string attrName: string itemAttrName: string, prefixName: string suffixName: string contentName: string }