third-party-verify.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import { replaceKeyword } from '@jy/util'
  2. class ThirdPartyVerifyModel {
  3. constructor() {
  4. this.getKeywordsList()
  5. }
  6. // 将要匹配的列表
  7. keywordsList = []
  8. certificate = {
  9. // 证书名称
  10. name: [
  11. '质量管理体系认证',
  12. '工程建设施工质量管理体系认证',
  13. '环境管理体系认证',
  14. '职业健康安全管理体系认证',
  15. '危害分析和关键控制点',
  16. '食品安全管理体系认证',
  17. '信息技术服务管理体系认证',
  18. '信息安全管理体系认证',
  19. '五星售后服务认证 ',
  20. '五星品牌认证',
  21. '批发零售服务',
  22. '物业服务认证',
  23. ],
  24. // 证书编号
  25. number: [
  26. /(ISO\s{0,1}9001)/g,
  27. /(GB\/T\s{0,1}50430)/g,
  28. /(ISO\s{0,1}14001)/g,
  29. /(ISO\s{0,1}45001)/g,
  30. 'HACCP',
  31. /(ISO\s{0,1}2[027]000)/g, // ISO20000、ISO22000、ISO27000、
  32. ],
  33. // AAA关键词
  34. key: [
  35. '信用等级',
  36. '重合同守信用企业',
  37. '质量服务诚信单位',
  38. '重质量守信用单位',
  39. '重服务守信用',
  40. '资信等级',
  41. '诚信经营示范单位',
  42. '诚信企业家',
  43. '诚信经理人',
  44. '诚信供应商',
  45. ]
  46. }
  47. // 将certificate中的内容整合成一个数组
  48. getKeywordsList() {
  49. let arr = []
  50. const map = this.certificate
  51. for (const key in map) {
  52. const item = map[key]
  53. if (Array.isArray(item)) {
  54. arr = arr.concat(item)
  55. }
  56. }
  57. this.keywordsList = arr
  58. return arr
  59. }
  60. replaceKeysAndInsertMark(content) {
  61. // 字符串替换
  62. content = this.replaceKeys(content)
  63. try {
  64. // 将字符串转成dom
  65. this.contentDOM = this.createDomInMemory(content)
  66. // 插入button
  67. this.checkHighlightInsert(this.contentDOM)
  68. } catch (error) {
  69. console.error(error)
  70. }
  71. // 插入完成后在将dom转成字符串
  72. return this.contentDOM.innerHTML
  73. }
  74. // dom数组去重
  75. unique(array) {
  76. return array.filter(function (value, index, self) {
  77. return self.indexOf(value) === index
  78. })
  79. }
  80. // certificate相关 关键词替换
  81. replaceKeys(content) {
  82. // 1.先将关键词替换
  83. var replaced = replaceKeyword(content, this.keywordsList, "<span class='highlight-text third-party-verify-highlight'>$1</span>");
  84. // 2.替换关键词后面最近的一个中文句号(用来插入button)
  85. replaced = replaced.replace(/third-party-verify-highlight(.*?)(。|;|;)/g, function (match, p1, p2) {
  86. return match.replace(p2, `<span class='paragraph-last'>${p2}</span>`)
  87. })
  88. return replaced
  89. }
  90. getInsertButton() {
  91. // third-party-popover标记点击弹窗
  92. const htmlString = '<span class="third-party-popover third-party-verify-button"><span class="icon icon-third-party-verify-logo third-party-popover"></span><span class="third-party-popover third-party-button-text">剑鱼认证服务</span></span>'
  93. const div = document.createElement('div')
  94. div.innerHTML = htmlString
  95. const dom = div.firstChild
  96. return dom
  97. }
  98. createDomInMemory(html) {
  99. var div = document.createElement('div')
  100. div.classList.add('com-detail')
  101. div.innerHTML = html
  102. return div
  103. }
  104. // 获取当前元素下一个指定元素,同jquery的.next()
  105. getNextElement(element, tagName) {
  106. let nextSibling = element.nextElementSibling;
  107. if (!tagName) {
  108. return nextSibling
  109. }
  110. while (nextSibling) {
  111. if (nextSibling.tagName === tagName.toUpperCase()) {
  112. return nextSibling;
  113. }
  114. nextSibling = nextSibling.nextElementSibling;
  115. }
  116. return null;
  117. }
  118. // 检查并插入button
  119. checkHighlightInsert(dom) {
  120. var container = dom;
  121. var verifyIconButton = container.querySelectorAll('.third-party-verify-button');
  122. if (verifyIconButton.length) return;
  123. var waitingInsertList = [];
  124. // 1. 先找highlights同级next的.paragraph-last
  125. waitingInsertList = Array.from(container.querySelectorAll('.paragraph-last'));
  126. waitingInsertList = this.unique(waitingInsertList);
  127. if (waitingInsertList.length) {
  128. // 找到了.paragraph-last在其后插入button
  129. waitingInsertList.forEach(function (dom) {
  130. dom.insertAdjacentElement('afterend', this.getInsertButton());
  131. }.bind(this));
  132. } else {
  133. // 2. 找不到.paragraph-last。找同级next的br
  134. waitingInsertList = this.findNextMark(dom, function (element) {
  135. const nextBr = this.getNextElement(element, 'br')
  136. return nextBr
  137. }.bind(this));
  138. if (waitingInsertList.length) {
  139. // 找到了br,则在其前面插入
  140. waitingInsertList.forEach(function (dom) {
  141. dom.insertAdjacentElement('beforebegin', this.getInsertButton());
  142. }.bind(this));
  143. } else {
  144. // 3. 找不到br,找到其父级标签,并在其末尾插入
  145. waitingInsertList = this.findNextMark(dom, function (element) {
  146. return element.parentNode;
  147. });
  148. if (waitingInsertList.length) {
  149. // 找到了br,则在其前面插入
  150. waitingInsertList.forEach(function (dom) {
  151. dom.appendChild(this.getInsertButton());
  152. }.bind(this));
  153. }
  154. }
  155. }
  156. return dom
  157. }
  158. findNextMark (dom, callback) {
  159. var waitingInsertList = [] // 待插入节点dom对象
  160. var container = dom
  161. var highlights = container.querySelectorAll('.third-party-verify-highlight')
  162. highlights.forEach(function (item) {
  163. var mark = callback(item)
  164. if (mark) {
  165. waitingInsertList.push(mark)
  166. }
  167. })
  168. // 去重
  169. return this.unique(waitingInsertList)
  170. }
  171. }
  172. function useThirdPartyVerifyModel() {
  173. return new ThirdPartyVerifyModel()
  174. }
  175. export default useThirdPartyVerifyModel