PageSourceSearch

https://www.szumao.com/assets/js/messages.js

js szumao.com collected 2026-10-09 00:48:37 UTC 36,690 bytes, 1,030 lines download raw bytes

1// 引入帮助按钮的提示
2import help from '../../config/help.js'
3import hooks from '../../src/hooks/index.js'
4import Template from '../../src/template.js'
5
6/** 当前操作的package */
7window.messageSelfPackage = null
8/** 是否是替换 */
9window.messagesIsReplace = false
10/** 是否是父类添加,还是同级添加 */
11window.messagesCheckTargetIsParent = false
12
13/** 数据监听Mssages */
14class MessagesManage {
15  constructor() {
16    this.receive = ReceiveMessages.ins()
17    // 不装修的时候不用初始message
18    if (Utilts.ins().checkDesign()) {
19      this.message()
20    }
21  }
22  /** 单例模式 */
23  static ins() {
24    if (!this.instance) return this.instance = new MessagesManage()
25    return this.instance
26  }
27  message() {
28    if (!this.isListenerMessage) {
29      this.isListenerMessage = true
30      window.addEventListener('message', (res) => {
31        res.data.funParam = res.data.funParam || '{}'
32        if (res.data.funName && this.receive[res.data.funName]) {
33          try {
34            this.receive[res.data.funName](JSON.parse(res.data.funParam), JSON.parse(res.data.option || '{}'))
35          } catch (err) {
36            console.error(err)
37          }
38        }
39      })
40    }
41  }
42}
43
44/** 基础公共Messages父类 */
45export class BaseMessages {
46
47  /** 当前操作的package */
48  // static selfPackage
49  /** 是否是替换 */
50  // static isReplace
51  /** 是否是父类添加,还是同级添加 */
52  // static checkTargetIsParent
53
54  constructor() { }
55
56  /** 所有packages */
57  get packages() {
58    return this.design.packages
59  }
60
61  /** designç±» */
62  get design() {
63    return window.design
64  }
65
66  /** 页面类型 */
67  get pageType() {
68    return this.design.ctx.state.page.page_type || 'index'
69  }
70
71  /** 渲染数据 */
72  async render(attr_id, isRefres = false) {
73    await this.design.render(attr_id, isRefres)
74  }
75
76  /**
77  * 跨域执行function
78  * @param {String} funName 方法名
79  * @param {Json} funParam 传参
80  */
81  postFun(funName, funParam, option) {
82    funParam = typeof funParam === 'object' && typeof funParam.stringify === 'function' ? funParam.stringify() : JSON.stringify(funParam)
83    window.parent.postMessage({ funName, funParam, option: JSON.stringify(option) }, '*')
84  }
85
86  /** 
87   * 即发送数据,也响应数据,所以写在父类好一点,
88   * 添加package,以后重新渲染 
89  */
90  async pushPackage(newPackage, option = {}) {
91    const addPackageState = window.ctx.state.addPackageState
92    if (typeof option.messageSelfPackage_attr_id !== 'undefined') window.messageSelfPackage = this.packages[option.messageSelfPackage_attr_id]
93    else if (addPackageState && addPackageState.action) {
94      const { packageItem } = window.ctx.state.addPackageState.thisDesignBox.getInsideData()
95      window.messageSelfPackage = packageItem
96      switch (addPackageState.action) {
97        case 'moduleToGrid': {
98          // module转grid
99          let gridPackage = newPackage.children[0]
100          gridPackage.parent_attr_id = packageItem.parent_attr_id
101          gridPackage.style = Utilts.ins().deepMerge(newPackage.style, gridPackage.style)
102          for (let i = 1; i < newPackage.children.length; i++) {
103            const item = newPackage.children[i];
104            item.children.forEach(cellItem => {
105              cellItem.parent_attr_id = gridPackage.attr_id
106              gridPackage.children.push(cellItem)
107            })
108          }
109          newPackage = gridPackage
110          break;
111        }
112        case 'unitToGrid': {
113          // 在unit中添加grid
114        }
115      }
116    }
117    if (typeof option.messagesIsReplace !== 'undefined') window.messagesIsReplace = option.messagesIsReplace
118    if (typeof option.messagesCheckTargetIsParent !== 'undefined') window.messagesCheckTargetIsParent = option.messagesCheckTargetIsParent
119
120    const hookKey = newPackage.dir === 'unit' ? newPackage.type : newPackage.dir
121    if (hooks[hookKey]) {
122      const hookRes = hooks[hookKey]?.beforePushPackage(newPackage, {
123        messageSelfPackage: window.messageSelfPackage,
124        messagesIsReplace: window.messagesIsReplace,
125        messagesCheckTargetIsParent: window.messagesCheckTargetIsParent
126      }, { ReceiveMessages, PostMessages })
127      if (hookRes) {
128        newPackage = hookRes
129      } else if (hookRes === false) {
130        return
131      }
132    }
133
134    const newPackageAttrId = await this._getNewPackage(newPackage, window.messageSelfPackage)
135    const packages = this.packages
136    // 更新newPackage
137    newPackage = packages[newPackageAttrId]
138    // 如果是grid或cell就弹出添加组件弹窗
139    if (newPackage.dir === 'grid' || newPackage.dir === 'cell') {
140      // 更新激活的package
141      window.messageSelfPackage = newPackage.dir === 'grid' ? newPackage.children[0] : newPackage
142      // 更新添加方式
143      window.messagesCheckTargetIsParent = true
144      // 更新父级数据
145      PostMessages.ins().updataPackage(packages[newPackage.parent_attr_id])
146      // 请求添加组件
147      // PostMessages.ins().choosePackage('unit')
148    } else {
149      PostMessages.ins().updataPackage(packages[newPackage.parent_attr_id])
150      // 其他的就弹出编辑弹窗
151      if (newPackage.dir === 'unit') {
152        PostMessages.ins().editPackage(newPackage.designBox)
153      }
154    }
155    PostMessages.ins().addRecord(newPackage.dir)
156    window.messagesIsReplace = false
157    if (option.callback) {
158      this.postFun(option.callback, newPackage)
159    }
160  }
161
162  // 处理新添加的package
163  async _getNewPackage(newPackage, selfPackage) {
164    const addPackageState = window.ctx.state.addPackageState
165
166    let newPackageAttrId = newPackage.attr_id
167    // 如果目标是父级,就往当前的子级添加
168    if (window.messagesCheckTargetIsParent) {
169      selfPackage.children.push(newPackage)
170      await selfPackage.init()
171      await this.render(selfPackage.attr_id)
172      newPackageAttrId = selfPackage.children[0].attr_id
173      return newPackageAttrId
174    }
175
176    // 如果目标是同级,就往后一个插入,或者根据 addPackageState.insertIndex
177    const pdata = this.packages[selfPackage.parent_attr_id]
178    let index = 0
179    if (!window.messagesIsReplace && addPackageState && typeof addPackageState.insertIndex === 'number') {
180      index = addPackageState.insertIndex
181    } else {
182      index = pdata.children.findIndex(item => item.attr_id === selfPackage.attr_id)
183    }
184    // 如果是替换就使用替换的下标,反之向后面添加是添加
185    if (window.messagesIsReplace) pdata.children[index] = newPackage //替换
186    else pdata.children.splice(index + 1, 0, newPackage) //添加
187    await pdata.init()
188    await this.render(pdata.attr_id)
189    // 如果是替换是index,添加是index+1
190    const newIndex = window.messagesIsReplace ? index : index + 1
191    newPackageAttrId = pdata.children[newIndex].attr_id
192    return newPackageAttrId
193  }
194}
195/** 提交方法到装修Messages */
196export class PostMessages extends BaseMessages {
197  constructor() {
198    super()
199  }
200  /** 单例模式 */
201  static ins() {
202    if (!this.instance) return this.instance = new PostMessages()
203    return this.instance
204  }
205
206  /** 初始化装修data */
207  initDesignData(data) {
208    this.postFun('initDesignData', data)
209  }
210  /** 添加Package */
211  addPackage(designBox, targetDir) {
212    let { packageItem, $selfDoc } = designBox.getInsideData()
213    if (!packageLimit(packageItem)) return
214
215    let hookKey = packageItem.dir === 'unit' ? packageItem.type : packageItem.dir
216    let hookRes = hooks[hookKey]?.beforeAddPackage(designBox, targetDir)
217    if (hookRes === false) return
218
219    if (hookRes?.dir) {
220      packageItem = hookRes
221      // console.log(`packageItem = hookRes`, packageItem);
222      
223    }
224    window.messageSelfPackage = packageItem
225    window.messagesIsReplace = false //不是替换,是添加
226    const isGridToCell = packageItem.dir === 'grid' && targetDir === 'cell'
227    const isCellToCell = packageItem.dir === 'cell' && targetDir === 'cell'
228    if (isGridToCell || isCellToCell) {
229      if (isGridToCell) window.messagesCheckTargetIsParent = true
230      if (isCellToCell) window.messagesCheckTargetIsParent = false
231      this.pushPackage(this.design.getCell(packageItem))
232      return
233    }
234    window.messagesCheckTargetIsParent = packageItem.dir !== targetDir
235    this.choosePackage(targetDir, { addPackageState: window.ctx.state.addPackageState })
236  }
237  /** 删除Package */
238  deletePackage(designBox) {
239    new Modal().confirm('是否真的删除?', '请确认', { cancelText: '取消', submitText: '确定' })
240      .then(() => {
241        let { packageItem, $selfDoc } = designBox.getInsideData()
242
243        packageItem.hook?.beforeDeletePackage(designBox, { ReceiveMessages, PostMessages })
244        if (window.app.info.page.page_type === 'all_pop_up' && packageItem.dir === 'module') {
245          $selfDoc.previousElementSibling.remove()
246        }
247        $selfDoc.remove()
248        const pdata = this.packages[packageItem.parent_attr_id]
249        pdata.children = pdata.children.filter(item => item.attr_id !== packageItem.attr_id)
250        pdata.designBox.checkBlank()
251        this.postFun('deletePackage', packageItem)
252        UtiltsMesssages.ins().updateMessage(packageItem) //更新广告导航
253      })
254  }
255  /** 修改Package */
256  editPackage(designBox) {
257    let { packageItem } = designBox.getInsideData()
258    this.postFun('editPackage', packageItem)
259  }
260  hidePc(designBox) {
261    let { packageItem } = designBox.getInsideData()
262    this.postFun('editShow', packageItem)
263  }
264  hidePad(designBox) {
265    let { packageItem } = designBox.getInsideData()
266    this.postFun('editShow', packageItem)
267  }
268  hidePhone(designBox) {
269    let { packageItem } = designBox.getInsideData()
270    this.postFun('editShow', packageItem)
271  }
272  /** 收藏package */
273  collectPackage(designBox) {
274    let { packageItem, $selfDoc } = designBox.getInsideData()
275    const isCollected = this.packages[$selfDoc.getAttribute('id')]['is_collected']
276    if (isCollected) {
277      this.postFun('cancelCollectPackage', packageItem)
278    } else {
279      this.packages[$selfDoc.getAttribute('id')]['is_collected'] = 1
280      $selfDoc.setAttribute('is-collect', 1)
281
282      const $icon = $selfDoc.querySelector('.icon-shoucang-empty')
283      if ($icon) {
284        $icon.classList.add('icon-shoucang')
285        $icon.classList.remove('icon-shoucang-empty')
286      }
287
288      const data = {}
289      packageItem.children.forEach(thisGrid => {
290        data[thisGrid.attr_id] = thisGrid
291        thisGrid.children.forEach(thisCell => {
292          data[thisCell.attr_id] = thisCell
293          thisCell.children.forEach(thisUnit => {
294            data[thisUnit.attr_id] = thisUnit
295          })
296        })
297      })
298
299      this.postFun('collectPackage', { ...packageItem, block_type: this.packages[packageItem.parent_attr_id].type })
300    }
301  }
302  /** 选择package */
303  choosePackage(targetDir, option) {
304    this.postFun('choosePackage', { targetDir, selfPackage: window.messageSelfPackage }, option)
305  }
306  /** 添加模块或组件时,点击选中事件 */
307  checkedPackage() {
308    this.postFun('checkedPackage', this.design.ctx.state.postCtxState.renderPackage)
309  }
310  /** 更新packages */
311  updataPackage(data) {
312    this.postFun('updataPackage', data)
313  }
314  /** 添加记录 */
315  addRecord(dir, pageDir = '') {
316    const typeStr = { page: '编辑页面记录', block: '编辑板块记录', module: '添加模块记录', grid: '添加布局记录', cell: '添加删格记录', unit: '添加组件记录' }
317    this.postFun('postAddRecord', pageDir ? typeStr[pageDir] : typeStr[dir])
318  }
319  /** 提交iframe 高度  */
320  postIframeHeight(data) {
321    this.postFun('postIframeHeight', data)
322  }
323  /** 提交Ifram 加载进度 */
324  postIframeIsLoading(isLoading) {
325    this.postFun('postIframeIsLoading', { src: this.design.ctx.query.render, isLoading })
326  }
327  /**复制Package */
328  copyPackage(designBox) {
329    let { packageItem } = designBox.getInsideData()
330    if (!packageLimit(packageItem)) return
331    packageItem = packageItem.hook?.beforeCopyPackage(designBox, { ReceiveMessages, PostMessages })
332    if (!packageItem) return
333    // 同级
334    window.messagesCheckTargetIsParent = false
335    window.messageSelfPackage = packageItem
336    window.messagesIsReplace = false
337
338    let newPackage = JSON.parse(JSON.stringify(packageItem))
339    // 更新attr_id、sign
340    function loopFunc(node, parentNode) {
341      node.sign = globalThis.Server.getSign()
342      node.attr_id = `${node.dir}-${node.sign}`
343      if (node.config) {
344        for (const key in node.config) {
345          const item = node.config[key]
346          for (const key in item) {
347            if (/sign$/.test(key)) {
348              item[key] = globalThis.Server.getSign()
349            }
350          }
351        }
352      }
353      for (const key in node.style) {
354        node.style[key].sign = globalThis.Server.getSign()
355      }
356      if (parentNode) node.parent_attr_id = parentNode.attr_id
357      if (node.name_sign) node.name_sign = globalThis.Server.getSign()
358      if (node.dir === 'unit' && node.content) {
359        node.content.data.forEach(item => {
360          for (const key in item) {
361            if (/sign$/.test(key)) {
362              item[key] = globalThis.Server.getSign()
363            }
364          }
365        })
366
367        if (node.content.type === 'detail') node.content.relate_list = node.content.data?.map(p => p.sign) || []
368      }
369
370      node.children?.forEach(item => {
371        loopFunc(item, node)
372      })
373    }
374    loopFunc(newPackage);
375
376    this.pushPackage(newPackage)
377  }
378  /** 替换模块 */
379  replacePackage(designBox) {
380    let { packageItem } = designBox.getInsideData()
381    // 同级添加,不是父级添加
382    window.messagesCheckTargetIsParent = false
383    window.messageSelfPackage = packageItem
384    // 替换package
385    window.messagesIsReplace = true
386    this.postFun('replacePackage', packageItem)
387  }
388  /**上移Package */
389  moveUpPackage(designBox) {
390    const { pitems, parent, currentIndex } = this._getCurrentNode(designBox)
391    let { packageItem, $selfDoc } = designBox.getInsideData()
392    //如果不是第一个节点
393    if (currentIndex !== 0) {
394      //把当前第一个节点上移
395      parent.insertBefore($selfDoc, pitems[currentIndex - 1])
396      this._getMovePackage(packageItem, 1)
397      UtiltsMesssages.ins().updateMessage(packageItem) //更新广告导航
398      this.packages[packageItem.attr_id].hook?.afterMovePackage(this.packages[packageItem.attr_id], 1, { ReceiveMessages, PostMessages })
399    }
400  }
401  /**下移Package */
402  moveDownPackage(designBox) {
403    const { pitems, parent, currentIndex } = this._getCurrentNode(designBox)
404    let { packageItem } = designBox.getInsideData()
405    //如果不是最后一个节点
406    if (currentIndex !== pitems.length - 1) {
407      //把当前下移的节点移上来,也就是下移
408      parent.insertBefore(pitems[currentIndex + 1], pitems[currentIndex])
409      this._getMovePackage(packageItem, -1)
410      UtiltsMesssages.ins().updateMessage(packageItem) //更新广告导航
411      this.packages[packageItem.attr_id].hook?.afterMovePackage(this.packages[packageItem.attr_id], -1, { ReceiveMessages, PostMessages })
412    }
413  }
414  /**生成Package */
415  generatePackage(designBox) {
416    // const { pitems, parent, currentIndex } = this._getCurrentNode(designBox)
417    let { packageItem, $selfDoc } = designBox.getInsideData()
418    if ($selfDoc.getAttribute('package-item') !== 'module') {
419      const parentModule = Utilts.ins().getParents($selfDoc, { attrName: 'package-item', attrValue: 'module' })
420      packageItem.module_code = parentModule[0].getAttribute('co
420de') || ''
421    }
422    this.postFun('generatePackage', packageItem)
423  }
424  /**生成Package */
425  clearStyle(designBox) {
426    const { packageItem } = designBox.getInsideData()
427    let newPackage = JSON.parse(JSON.stringify(packageItem))
428    for (const key in newPackage.style) {
429      for (const key2 in newPackage.style[key]) {
430        if (Object.prototype.toString.call(newPackage.style[key][key2]) === '[object Object]' && ['default', 'md', 'xl'].includes(key2)) newPackage.style[key][key2] = {}
431      }
432    }
433    newPackage.transfer = ''
434    // console.log('newPackage1', newPackage);
435    this.postFun('clearStyle', newPackage)
436  }
437  /**标记Package */
438  markPackage(designBox) {
439    // const { pitems, parent, currentIndex } = this._getCurrentNode(designBox)
440    let { packageItem, $selfDoc } = designBox.getInsideData()
441    if ($selfDoc.getAttribute('package-item') !== 'module') {
442      const parentModule = Utilts.ins().getParents($selfDoc, { attrName: 'package-item', attrValue: 'module' })
443      packageItem.module_code = parentModule[0].getAttribute('code')
444    }
445    this.postFun('markPackage', packageItem)
446  }
447  /**帮助提示设置 */
448  showHelp(designBox) {
449    let { packageItem } = designBox.getInsideData()
450    const { title, desc, img, mark } = help[packageItem.type]
451    let markHtml = ''
452    if (mark) {
453      markHtml = `<br/>${mark}`
454    }
455    new Modal().info(`<div class='help-box'>${desc}</div>
456    <a href="${img}" target="_blank" style="cursor: pointer;"><img src="${img}" alt=""></a>
457    <div>${markHtml}<br/>如果您需要帮助,请访问我们的<a href="https://www.lifisher.com/help.html" target="_blank" style="color: #00f;cursor: pointer;">帮助中心</a>页面以获取更多完整的教程列表</div>`, `组件(${title})说明`).open()
458  }
459  /**
460   * 保存页面
461   * @param {*} pageParams 保存的类型
462   */
463  savePage(pageParams) {
464    // console.log('pageParams', pageParams);
465    this.postFun('savePage', { data: this.design.ctx.state, pageParams })
466  }
467  generatePageStyle(option) {
468    this.postFun('generatePageStyle', { data: this.design.ctx.state, option })
469  }
470  /** 页面截图 */
471  initPageThumb(data, flag, picture_type) {
472    this.postFun('initPageThumb', { base64: data, flag, picture_type })
473  }
474  /** 响应装修发送过来的初始化全局样式设置 */
475  initGlobalSiteStyle() {
476    this.postFun('initGlobalSiteStyle', this.design.ctx.state.site.style)
477  }
478  /** 修改html */
479  modifyUnitHtml(packageItem) {
480    this.postFun('modifyUnitHtml', packageItem)
481    this.postFun('postAddRecord', '文本修改')
482  }
483
484  /** 发送页面渲染完成 */
485  loadPageComplete() {
486    this.postFun('loadPageComplete', true)
487  }
488  /**
489   * 移动位置
490   * @param {*} data 移动的节点
491   * @param {*} type 1上移-1下移
492  */
493  _getMovePackage(targetPackage, type) {
494    // 找到当前移动的父级
495    const parentData = this.packages[targetPackage.parent_attr_id]
496    // 找到当前移动的位置
497    const currentIndex = parentData.children.findIndex(item => item.attr_id === targetPackage.attr_id)
498    // 当前位置大于0才处理
499    if (currentIndex >= 0) {
500      if (type === 1) { //上移
501        const item = parentData.children[currentIndex - 1]
502        parentData.children[currentIndex - 1] = parentData.children[currentIndex]
503        parentData.children[currentIndex] = item
504      } else if (type === -1) { //下移
505        const item = parentData.children[currentIndex + 1]
506        parentData.children[currentIndex + 1] = parentData.children[currentIndex]
507        parentData.children[currentIndex] = item
508      }
509      //提交移动位置到design
510      this.postFun('movePackage', [targetPackage, type])
511    }
512  }
513  /**
514   * 获取当前要移动节点的基本信息
515   * @return {$selfDoc, pitems, parent, currentIndex }
516   * pitems 当前node父类下的子节点数组,
517   * parent 当前node父节点
518   * currentIndex 当前node的下标
519  */
520  _getCurrentNode(designBox) {
521    let { packageItem, $selfDoc } = designBox.getInsideData()
522    const parent = $selfDoc.parentNode
523    this._del_ff(parent)
524    const pitems = Array.from(parent.childNodes)
525    let currentIndex = pitems.findIndex(item => item.id === packageItem.attr_id)
526    return { pitems, parent, currentIndex }
527  }
528
529  /** 删除parent.childNodes 里面没用的text节点 */
530  _del_ff(elem) {
531    var elem_child = elem.childNodes;
532    for (var i = 0; i < elem_child.length; i++) {
533      if (elem_child[i].nodeName == "#text" && !/\s/.test(elem_child.nodeValue)) {
534        elem.removeChild(elem_child[i]); //表示循环的哪一个如果是空或文本就删除掉,[i]一定不能少。
535      }
536    }
537  }
538
539  getExternalContent(data, target, method) {
540    this.postFun('getExternalContent', { data, target, method })
541  }
542}
543
544/** 接收装修传过来的方法Messages */
545export class ReceiveMessages extends BaseMessages {
546  constructor() {
547    super()
548  }
549  /** 单例模式 */
550  static ins() {
551    if (!this.instance) return this.instance = new ReceiveMessages()
552    return this.instance
553  }
554  /** 修改装修数据 */
555  async editDesignData({ page }) {
556    this.design.ctx.state.page = page
557  }
558  /** 生成页面样式 */
559  generatePageStyle(option) {
560    PostMessages.ins().generatePageStyle(option)
561  }
562  /** 修改页面以后重新渲染 */
563  async editPageStyle(data) {
564    const mergeObj = (p, obj) => {
565      for (let attr in obj) {
566        if (['var(--main-color)', 'var(--sub-color1)', 'var(--sub-color2)', 'var(--sub-color3)'].includes(p[attr])) continue;
567        p[attr] = typeof obj[attr] === 'object' ? mergeObj(p[attr] ? p[attr] : {}, obj[attr]) : obj[attr]
568      }
569      return p
570    }
571
572    for (let id in data['packages']) {
573      await this.packages[id].init(mergeObj(this.packages[id], data['packages'][id]))
574    }
575
576    const siteStyle = JSON.parse(JSON.stringify(this.design.ctx.state.site.style))
577    const selectors = [':root', '[button-style="2"] .btn', '[button-style="1"] .btn', '[form-style="2"] .unit-form__control', '[form-style="2"] .unit-form__item-inner', '[form-style="1"] .unit-form__control', '[form-style="1"] .unit-form__item-inner']
578    const terminals = ['default', 'md', 'xl']
579    selectors.forEach(selector => {
580      terminals.forEach(terminal => {
581        Object.keys(data['color_mode']['main'][selector]).forEach(attr => {
582          siteStyle[selector][terminal][attr] = data['color_mode']['main'][selector][attr]
583        })
584      })
585    })
586
587    this.design.ctx.state.site.style.init(siteStyle)
588    await this.design.renderCss()
589
590    this.design.ctx.state.template.color_mode_list = data['color_mode']
591    this.postFun('updatePageColor', this.design.ctx.state)
592  }
593  /** 修改包以后重新渲染 */
594  async editPackage(data, option = {}) {
595    const packages = this.packages
596    await packages[data.attr_id].init(data)
597    packages[data.attr_id].hook?.afterEditPackage(packages[data.attr_id], { ReceiveMessages, PostMessages })
598    await this.render(data.attr_id)
599    // 修改重新渲染以后把新的数据推送给装修,重新更新。
600    PostMessages.ins().updataPackage(packages[data.attr_id])
601    UtiltsMesssages.ins().updateMessage(data) //更新广告导航
602    if (option.callback) {
603      this.postFun(option.callback, data)
604    }
605  }
606  /** 批量删除package */
607  deleteRelatePackage(packageData) {
608    if (!Array.isArray(packageData.package_list)) return
609    const parent_attr_id_map = {}
610
611    packageData.package_list.forEach(item => {
612      const designBox = this.packages[item.attr_id]?.designBox
613      if (designBox) {
614        let { packageItem, $selfDoc } = designBox.getInsideData()
615        $selfDoc?.remove()
616
617        if (!parent_attr_id_map[packageItem.parent_attr_id]) {
618          parent_attr_id_map[packageItem.parent_attr_id] = new Set([packageItem.attr_id])
619        } else {
620          parent_attr_id_map[packageItem.parent_attr_id].add(packageItem.attr_id)
621        }
622      }
623    })
624
625    for (const parent_attr_id in parent_attr_id_map) {
626      const set = parent_attr_id_map[parent_attr_id]
627      const pdata = this.packages[parent_attr_id]
628      const deletedPackages = pdata.children.filter(item => set.has(item.attr_id))
629      pdata.children = pdata.children.filter(item => !set.has(item.attr_id))
630      pdata.designBox.checkBlank()
631
632      deletedPackages.forEach(packageItem => {
633        UtiltsMesssages.ins().updateMessage(packageItem) //更新广告导航
634      })
635    }
636
637    this.postFun('deleteRelatePackage', packageData)
638  }
639  /** 根据添加组件或添加模块post过来的数据渲染 */
640  async postRenderData(ctxState) {
641    // 不能出现design-box
642    // 使用postMassage传进来的数据进行渲染
643    this.design.ctx.state.postCtxState = ctxState
644    // 提交模块或组件加载状态,在render里面设置为true表示加载完成
645    PostMessages.ins().postIframeIsLoading(false)
646    // design会监听receiveCtxState事件,继续完成数据处理然后才渲染
647    window.dispatchEvent(new CustomEvent('receiveCtxState'))
648    window.updataWindowHeightInterval = setInterval(() => {
649      this.postWindowHeight()
650    }, 500)
651  }
652
653  /** 撤回,还原,重新渲染 */
654  async refresRender(data) {
655    if (data.template.color_mode_list) {
656      this.design.ctx.state.template.color_mode_list = data.template.color_mode_list
657    }
658    if (data.site && data.site.style) {
659      this.design.ctx.state.site.style.init(data.site.style)
660    }
661
662    if (data.template && data.template.block) {
663      const packages = this.packages
664      const all = []
665      Object.keys(data.template.block).forEach(async (key) => {
666        all.push(new Promise(async (resolve, reject) => {
667          const block = data.template.block[key]
668          await packages[block.attr_id].init(block)
669          resolve()
670        }))
671      })
672      await Promise.all(all)
673      await this.render('app', true)
674    }
675  }
676
677  /**
678   * 调用main模块
679   * position:-1 插入在前面;0 替换;1 追加在后面
680  */
681  async invokeModule({ packageData, position, blockList, isSameSiteId }) {
682    const res = packageData
683    let parentPackage = {}
684    let commonPackage = {
685      header: null,
686      breadcrumb: null,
687      footer: null,
688      copyright: null
689    }
690    for (let k in this.packages) {
691      if (this.packages[k]['dir'] === 'block') {
692        if (this.packages[k]['type'] === 'main') {
693          parentPackage = this.packages[k]
694        } else if (Object.keys(commonPackage).includes(this.packages[k]['type']) && blockList.includes(this.packages[k]['type'])) {
695          commonPackage[this.packages[k]['type']] = this.packages[k]
696        }
697      }
698    }
699
700    let appendPackage = []
701    if (position < 1) {
702      if (position === -1) {
703        appendPackage = parentPackage.children
704      }
705      parentPackage.children = []
706    }
707
708    // 更新attr_id、sign
709    function loopFunc(node, parentNode) {
710      node.sign = globalThis.Server.getSign()
711      node.attr_id = `${node.dir}-${node.sign}`
712      if (node.config) {
713        for (const key in node.config) {
714          const item = node.config[key]
715          for (const key in item) {
716            if (/sign$/.test(key)) {
717              item[key] = globalThis.Server.getSign()
718            }
719          }
720        }
721      }
722      for (const key in node.style) {
723        node.style[key].sign = globalThis.Server.getSign()
724      }
725      if (parentNode) node.parent_attr_id = parentNode.attr_id
726      if (node.name_sign) node.name_sign = globalThis.Server.getSign()
727      if (node.dir === 'unit' && node.content && node.content.type === 'detail') {
728        node.content.data.forEach(item => {
729          for (const key in item) {
730            if (/sign$/.test(key)) {
731              item[key] = globalThis.Server.getSign()
732            }
733          }
734        })
735
736        node.content.relate_list = node.content.data?.map(p => p.sign) || []
737      }
738
739      node.children?.forEach(item => {
740        loopFunc(item, node)
741      })
742    }
743    function updateRelate(node) {
744      if (node.dir === 'unit' && node.content && node.content.type === 'detail' && !isSameSiteId) {
745        if (node.config?.list_nav) node.config.list_nav.column = ''
746      }
747      node.children?.forEach(item => {
748        updateRelate(item, node)
749      })
750    }
751
752    const invokeCtx = JSON.parse(JSON.stringify(this.design.ctx))
753    invokeCtx.state.postCtxState = { templateData: res }
754    invokeCtx.state.$t = this.design.ctx.state.$t
755    invokeCtx.state.request = this.design.ctx.state.request
756
757    invokeCtx.state.template = new Template(invokeCtx)
758    await invokeCtx.state.template.init()
759    invokeCtx.state.template.block.main.children.forEach(module => {
760      if (position) loopFunc(module, parentPackage)
761      parentPackage.children.push(module)
762    })
763    let packageArr = []
764    const designBlock = this.design.ctx.state.template.block
765    for (let blockType in commonPackage) {
766      if (commonPackage[blockType]) {
767        invokeCtx.state.template.block[blockType].children.forEach(module => {
768          updateRelate(module)
769        })
770        designBlock[blockType] = invokeCtx.state.template.block[blockType]
771        document.querySelector('[package-block-type="' + blockType + '"]').id = designBlock[blockType].attr_id
772        await designBlock[blockType].init()
773        await this.render(designBlock[blockType].attr_id)
774        PostMessages.ins().updataPackage(designBlock[blockType])
775      }
776    }
777
778    if (appendPackage.length) {
779      appendPackage.forEach(async module => {
780        parentPackage.children.push(module)
781      })
782    }
783    packageArr.push(parentPackage)
784    packageArr.forEach(async (val) => {
785      await val.init()
786      await this.render(val.attr_id)
787      PostMessages.ins().updataPackage(val)
788    })
789    PostMessages.ins().addRecord('', 'page')
790  }
791
792  /**
793   * 保存页面
794   * @param {*} saveType 保存的类型,分为保存页面,发布到模板,发布到页面库
795   */
796  postSavePage(data) {
797    PostMessages.ins().savePage(data)
798  }
799  // 平滑滚动到锚点
800  toScroll(flag) {
801    const scroll_content = document.querySelector('body')
802    const total = document.body.scrollHeight
803    let distance = scroll_content.scrollTop
804    let step = total / 50
805    console.log('--------------', total, distance);
806    if (total > distance) {
807      smoothDown()
808    }
809    function smoothDown() {
810      console.log('-***', distance);
811      if (distance < total) {
812        distance += step
813        window.scrollTo({
814          top: distance,
815          behavior: 'smooth'
816        })
817        setTimeout(smoothDown, 100)
818      } else {
819        window.scrollTo({
820          top: total,
821          behavior: 'smooth'
822        })
823        setTimeout(() => {
824          html2canvas(document.querySelector('body'), {
825            useCORS: true,
826            ignoreElements: element => {
827              if (element.classList.value.indexOf('design-box') > -1) return true
828              return false
829            }
830          })
831            .then(canvas => {
832              window.scrollTo({
833                top: 0,
834                behavior: 'smooth'
835              })
836              document.querySelector('[package-group="widget"]').style.display = 'block'
837              PostMessages.ins().initPageThumb(canvas.toDataURL('image/png'), flag)
838            })
839        }, 5000);
840      }
841    }
842  }
843
844  /** 保存首页时,截图 */
845  async getPicture({ flag, picture_type }) {
846    await new Load('/assets/plugins/html2canvas.min.js')
847    document.querySelector('[package-group="widget"]').style.display = 'none'
848    // this.toScroll(flag)
849    html2canvas(document.querySelector('body'), {
850      useCORS: true,
851      ignoreElements: element => {
852        if (element.classList.value.indexOf('design-box') > -1) return true
853        return false
854      }
855    })
856      .then(canvas => {
857        document.querySelector('[package-group="widget"]').style.display = 'block'
858        PostMessages.ins().initPageThumb(canvas.toDataURL('image/png'), flag, picture_type)
859      }).catch(err => {
860        console.log('html2canvas error', err)
861        PostMessages.ins().initPageThumb('', flag, picture_type)
862      })
863  }
864
865  /** 响应添加模块或组件 */
866  getWindowHeight() {
867    this.postWindowHeight()
868  }
869
870  /** 取消收藏 */
871  cancelCollectPackage(params) {
872    const $dom = document.querySelector('#module-' + params.sign)
873    if ($dom) {
874      this.packages['module-' + params.sign]['is_collected'] = 0
875      $dom.setAttribute('is-collect', 0)
876    }
877    const $icon = $dom.querySelector('.icon-shoucang')
878    if ($icon) {
879      $icon.classList.remove('icon-shoucang')
880      $icon.classList.add('icon-shoucang-empty')
881    }
882  }
883
884  /** 提交iframe 高度  */
885  postWindowHeight() {
886    if (window.windowHeight && window.windowHeight === document.querySelector('html').offsetHeight) return
887    window.windowHeight = document.querySelector('html').offsetHeight
888    PostMessages.ins().postIframeHeight({ src: this.design.ctx.query.render, height: window.windowHeight })
889  }
890
891  /** 响应装修发送过来的初始化全局样式设置 */
892  initGlobalSiteStyle(siteStyle) {
893    this.design.ctx.state.site.style.init(siteStyle)
894    // 渲染样式
895    this.design.renderCss()
896    //将重新渲染的结结果返回给装修
897    PostMessages.ins().initGlobalSiteStyle()
898  }
899
900  /** 重新设置全局样式 */
901  siteStyle(data) {
902    this.design.ctx.state.site.style.init(data)
903    // 获取样式
904    this.design.renderCss()
905    //将重新渲染的结结果返回给装修
906    PostMessages.ins().initGlobalSiteStyle()
907  }
908
909  /** 重新设置全局组件配置 */
910  siteUnitConfig(data) {
911    this.design.ctx.state.site.unit_config = data
912    const formList = document.querySelectorAll('[form-common="1"]')
913    formList.forEach(async item => {
914      await window.design.render(item.querySelector('form').getAttribute('id').replace('inquiry-', ''))
915    })
916  }
917
918  /** 修改站点属性 */
919  updateSiteAttr(info) {
920    this.design.ctx.state.site[info.attr] = info.value
921    this.design.updateRenderAttr(info)
922  }
923
924  /** 全局site站点属性还原 */
925  resetRenderAttr() {
926    this.design.resetRenderAttr()
927  }
928
929  /** 重置站点属性,样式排除 */
930  resetSiteAttr(siteAttr) {
931    Object.keys(siteAttr).forEach(key => {
932      if (key !== 'style' && key !== 'recordSiteAttr') {
933        this.design.ctx.state.site[key] = siteAttr[key]
934
935        if (key === 'unit_config') {
936          const formList = document.querySelectorAll('[form-common="1"]')
937          formList.forEach(async item => {
938            await window.design.render(item.querySelector('form').getAttribute('id').replace('inquiry-', ''))
939          })
940        }
941      }
942    })
943  }
944
945  /** 重置页面导航 */
946  async resetSiteNav() {
947    await this.design.resetSiteNav()
948  }
949
950  /** 设置装修模式 */
951  setDesignMode(type) {
952    const attribute = document.querySelector('body').attributes['design-mode']
953    if (attribute) attribute.nodeValue = type
954  }
955
956  /** 设置当前可以重新加载动态数据 */
957  updateDataReady(isLoad) {
958    this.design.ctx.state.isLoadContentData = isLoad
959  }
960
961  updateExternalContent({ data, target, method, content }) {
962    if (!data) {
963      document.querySelector('.tox-toolbar').style.pointerEvents = "visible"
964      var tinymceMaskEle = document.querySelector('.tinymce-mask-box');
965      tinymceMaskEle.style.display = 'none';
966      return;
967    }
968    const editor = tinymce.get(target)
969    let res_content = ''
970    if (method === 'insert') res_content = data.content.replace(/^\<p\>/, `<p>${content}`)
971    else res_content = data.content
972    // editor.insertContent((method === 'replace' ? '' : content) + data.content)
973    editor.insertContent(res_content)
974  }
975}
976
977/** 其它一些公共的操作 */
978class UtiltsMesssages {
979  constructor() {
980
981  }
982
983  /** 所有packages */
984  get packages() {
985    return this.design.packages
986  }
987
988  /** designç±» */
989  get design() {
990    return window.design
991  }
992
993  /** 单例模式 */
994  static ins() {
995    if (!this.instance) return this.instance = new UtiltsMesssages()
996    return this.instance
997  }
998
999  /** 更新*/
1000  updateMessage(data) {
1001    // 如果是模块更新并且有名称,并且当前为广告页,
1002    if (data.dir === 'module' && this.design.ctx.state.page.page_type === 'landing_page') {
1003      const packages = this.packages
1004      for (const key in packages) {
1005        const item = packages[key]
1006        if (item.type === 'landing-nav') {
1007          window.design.render(item.attr_id)
1008        }
1009      }
1010    }
1011  }
1012}
1013
1014MessagesManage.ins()
1015
1016/** 限制package数量,添加or复制前判断 */
1017function packageLimit(packageItem) {
1018  const packages = window.design.packages
1019  const parentPackageItem = packages[packageItem.parent_attr_id]
1020  if (
1021    parentPackageItem &&
1022    ((packageItem.dir === 'module' && window.ctx.state.addPackageState?.action === 'moduleToGrid' && packageItem.children.length > 21) ||
1023     (packageItem.dir === 'module' && parentPackageItem.children.length > 45) ||
1024     (packageItem.dir !== 'module' && parentPackageItem.children.length > 21))
1025  ) {
1026    new Modal().warning('添加内容已达到上限!', '提示').open()
1027    return false
1028  }
1029  return true
1030}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.