initShare.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. {
  2. var LZString=function(){var r=String.fromCharCode,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",e={};function t(r,o){if(!e[r]){e[r]={};for(var n=0;n<r.length;n++)e[r][r.charAt(n)]=n}return e[r][o]}var i={compressToBase64:function(r){if(null==r)return"";var n=i._compress(r,6,function(r){return o.charAt(r)});switch(n.length%4){default:case 0:return n;case 1:return n+"===";case 2:return n+"==";case 3:return n+"="}},decompressFromBase64:function(r){return null==r?"":""==r?null:i._decompress(r.length,32,function(n){return t(o,r.charAt(n))})},compressToUTF16:function(o){return null==o?"":i._compress(o,15,function(o){return r(o+32)})+" "},decompressFromUTF16:function(r){return null==r?"":""==r?null:i._decompress(r.length,16384,function(o){return r.charCodeAt(o)-32})},compressToUint8Array:function(r){for(var o=i.compress(r),n=new Uint8Array(2*o.length),e=0,t=o.length;e<t;e++){var s=o.charCodeAt(e);n[2*e]=s>>>8,n[2*e+1]=s%256}return n},decompressFromUint8Array:function(o){if(null==o)return i.decompress(o);for(var n=new Array(o.length/2),e=0,t=n.length;e<t;e++)n[e]=256*o[2*e]+o[2*e+1];var s=[];return n.forEach(function(o){s.push(r(o))}),i.decompress(s.join(""))},compressToEncodedURIComponent:function(r){return null==r?"":i._compress(r,6,function(r){return n.charAt(r)})},decompressFromEncodedURIComponent:function(r){return null==r?"":""==r?null:(r=r.replace(/ /g,"+"),i._decompress(r.length,32,function(o){return t(n,r.charAt(o))}))},compress:function(o){return i._compress(o,16,function(o){return r(o)})},_compress:function(r,o,n){if(null==r)return"";var e,t,i,s={},u={},a="",p="",c="",l=2,f=3,h=2,d=[],m=0,v=0;for(i=0;i<r.length;i+=1)if(a=r.charAt(i),Object.prototype.hasOwnProperty.call(s,a)||(s[a]=f++,u[a]=!0),p=c+a,Object.prototype.hasOwnProperty.call(s,p))c=p;else{if(Object.prototype.hasOwnProperty.call(u,c)){if(c.charCodeAt(0)<256){for(e=0;e<h;e++)m<<=1,v==o-1?(v=0,d.push(n(m)),m=0):v++;for(t=c.charCodeAt(0),e=0;e<8;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;e<h;e++)m=m<<1|t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=c.charCodeAt(0),e=0;e<16;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e<h;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;0==--l&&(l=Math.pow(2,h),h++),s[p]=f++,c=String(a)}if(""!==c){if(Object.prototype.hasOwnProperty.call(u,c)){if(c.charCodeAt(0)<256){for(e=0;e<h;e++)m<<=1,v==o-1?(v=0,d.push(n(m)),m=0):v++;for(t=c.charCodeAt(0),e=0;e<8;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}else{for(t=1,e=0;e<h;e++)m=m<<1|t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t=0;for(t=c.charCodeAt(0),e=0;e<16;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1}0==--l&&(l=Math.pow(2,h),h++),delete u[c]}else for(t=s[c],e=0;e<h;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;0==--l&&(l=Math.pow(2,h),h++)}for(t=2,e=0;e<h;e++)m=m<<1|1&t,v==o-1?(v=0,d.push(n(m)),m=0):v++,t>>=1;for(;;){if(m<<=1,v==o-1){d.push(n(m));break}v++}return d.join("")},decompress:function(r){return null==r?"":""==r?null:i._decompress(r.length,32768,function(o){return r.charCodeAt(o)})},_decompress:function(o,n,e){var t,i,s,u,a,p,c,l=[],f=4,h=4,d=3,m="",v=[],g={val:e(0),position:n,index:1};for(t=0;t<3;t+=1)l[t]=t;for(s=0,a=Math.pow(2,2),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;c=r(s);break;case 2:return""}for(l[3]=c,i=c,v.push(c);;){if(g.index>o)return"";for(s=0,a=Math.pow(2,d),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;switch(c=s){case 0:for(s=0,a=Math.pow(2,8),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 1:for(s=0,a=Math.pow(2,16),p=1;p!=a;)u=g.val&g.position,g.position>>=1,0==g.position&&(g.position=n,g.val=e(g.index++)),s|=(u>0?1:0)*p,p<<=1;l[h++]=r(s),c=h-1,f--;break;case 2:return v.join("")}if(0==f&&(f=Math.pow(2,d),d++),l[c])m=l[c];else{if(c!==h)return null;m=i+i.charAt(0)}v.push(m),l[h++]=i+m.charAt(0),i=m,0==--f&&(f=Math.pow(2,d),d++)}}};return i}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module?module.exports=LZString:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return LZString});
  3. const oss_domain = 'https://matchexpo.obs.cn-north-1.myhuaweicloud.com'
  4. let host = ''
  5. function getParams(){
  6. const scripts = document.getElementsByTagName('script')
  7. for(let script of scripts){
  8. const src = script.src
  9. if(src && src.includes('/shareModule/initShare.js')){
  10. let url = new URL(src)
  11. host = mpShareModule.host
  12. return url.searchParams
  13. }
  14. }
  15. return null
  16. }
  17. function initModule(){
  18. let params = getParams()
  19. if(params.get('url') === undefined){
  20. console.error('多果表单分享初始化失败,分享代码未携带apiUrl')
  21. }else{
  22. console.log('多果表单分享初始化成功')
  23. class mpShareCard extends HTMLElement {
  24. static observedAttributes = ['res']
  25. renderData = {}
  26. expoData = {}
  27. shadow = null
  28. getData(){
  29. window.fetch(`${params.get('url')}/api/expo/info?key=${this.renderData.key}`,{
  30. method: 'GET'
  31. })
  32. .then(res => {
  33. return res.json()
  34. })
  35. .then(json => {
  36. if(json.data){
  37. json = json.data
  38. }
  39. json.images = JSON.parse(json.images)
  40. json.social_links = JSON.parse(json.social_links)
  41. this.expoData = json
  42. this.render()
  43. })
  44. .catch(err => {
  45. console.error('多果表单分享卡片数据获取失败',err)
  46. })
  47. }
  48. render(){
  49. console.log('多果表单分享卡片渲染开始')
  50. if(!this.shadow){
  51. this.shadow = this.attachShadow({mode: 'open'})
  52. }
  53. let url = ''
  54. if(this.renderData.utm){
  55. url= `https://s1.matchexpo.cn/${this.renderData.utm}`
  56. }else{
  57. url = `${host}/register/${this.renderData.key}`
  58. }
  59. const body = `
  60. <div class="mp-card">
  61. <img class="bg-img" src="${oss_domain}${this.expoData.images[0]}" />
  62. <div class="info-cont">
  63. <div class="head">
  64. <img class="avatar" src="${oss_domain}${this.expoData.logo}">
  65. <div class="name">${this.expoData.expo_name}</div>
  66. </div>
  67. <div class="content">
  68. ${this.expoData.content}
  69. </div>
  70. <div class="button-list">
  71. <a class="button" href="${url}">${this.renderData.cardbuttontext}</a>
  72. </div>
  73. </div>
  74. </div>
  75. `
  76. const style = `
  77. <style>
  78. .mp-card{
  79. font-family: ${this.renderData.cardfontinherit==1?'inherit':'sans-serif'};
  80. position: relative;
  81. width: 100%;
  82. border-radius: 16px;
  83. overflow: hidden;
  84. background-color: ${this.renderData.backcolor};
  85. color: ${this.renderData.fontcolor};
  86. box-shadow: 0 0 12px 0 #00000022;
  87. &::after{
  88. content: '';
  89. display: block;
  90. position: absolute;
  91. height: 50px;
  92. width: 100%;
  93. top: 130px;
  94. left: 0;
  95. background-image: linear-gradient(${this.renderData.backcolor}00,${this.renderData.backcolor}ff);
  96. @media (max-width: 992px) {
  97. top: 81px;
  98. height: 40px;
  99. }
  100. }
  101. .bg-img{
  102. display: block;
  103. width: 100%;
  104. height: 180px;
  105. object-fit: cover;
  106. position: relative;
  107. @media (max-width: 992px) {
  108. height: 120px;
  109. }
  110. }
  111. .info-cont{
  112. z-index: 1;
  113. position: relative;
  114. padding: 0 20px 20px;
  115. .button-list{
  116. display: flex;
  117. justify-content: flex-end;
  118. .button{
  119. text-decoration: none;
  120. text-align: center;
  121. border-radius: 4px;
  122. color: ${this.renderData.cardbuttoncolor};
  123. background-color: ${this.renderData.themecolor};
  124. padding: 12px 36px;
  125. display: inline-block;
  126. font-weight: bold;
  127. font-size: 18px;
  128. }
  129. @media (max-width: 992px) {
  130. .button{
  131. width: 100%;
  132. font-size: 16px;
  133. }
  134. }
  135. }
  136. .content{
  137. margin-top: 24px;
  138. font-size: 16px;
  139. img{
  140. width: 100%;
  141. }
  142. @media (max-width: 992px) {
  143. font-size: 14px;
  144. }
  145. }
  146. .head{
  147. display: flex;
  148. align-items: flex-end;
  149. gap: 16px;
  150. margin-top: -32px;
  151. .avatar{
  152. box-shadow: 0 0 8px 0 #00000022;
  153. border-radius: 8px;
  154. border: 4px solid white;
  155. width: 72px;
  156. height: 72px;
  157. object-fit: cover;
  158. @media (max-width: 992px) {
  159. width: 52px;
  160. height: 52px;
  161. border: 2px solid white;
  162. }
  163. }
  164. .name{
  165. color: #111111;
  166. font-weight: bolder;
  167. line-height: 1;
  168. font-size: 28px;
  169. margin-bottom: 8px;
  170. @media (max-width: 992px) {
  171. font-size: 20px;
  172. margin-bottom: 4px;
  173. }
  174. }
  175. }
  176. }
  177. }
  178. </style>
  179. `
  180. this.shadow.innerHTML = ''
  181. this.shadow.innerHTML = style + body
  182. }
  183. constructor() {
  184. super()
  185. }
  186. attributeChangedCallback(name, oldValue, newValue) {
  187. if(name === 'res'){
  188. let attr = ['key','themecolor','backcolor','fontcolor','cardbuttontext','cardbuttoncolor','cardfontinherit','utm']
  189. let dataArr = LZString.decompressFromBase64(newValue).split(',')
  190. if(dataArr[0] !== this.renderData.key){
  191. for(let i = 0; i < dataArr.length; i++){
  192. this.renderData[attr[i]] = dataArr[i]
  193. }
  194. this.getData()
  195. }else{
  196. for(let i = 0; i < dataArr.length; i++){
  197. this.renderData[attr[i]] = dataArr[i]
  198. }
  199. this.render()
  200. }
  201. }
  202. }
  203. }
  204. class mpFloatButton extends HTMLElement {
  205. static observedAttributes = ['res']
  206. renderData = {}
  207. expoData = {}
  208. shadow = null
  209. getData(){
  210. window.fetch(`${params.get('url')}/api/expo/info?key=${this.renderData.key}`,{
  211. method: 'GET'
  212. })
  213. .then(res => {
  214. return res.json()
  215. })
  216. .then(json => {
  217. if(json.data){
  218. json = json.data
  219. }
  220. json.images = JSON.parse(json.images)
  221. json.social_links = JSON.parse(json.social_links)
  222. this.expoData = json
  223. this.render()
  224. })
  225. .catch(err => {
  226. console.error('多果表单浮动按钮数据获取失败',err)
  227. })
  228. }
  229. render() {
  230. if(!this.shadow){
  231. this.shadow = this.attachShadow({mode: 'open'})
  232. }
  233. let url = ''
  234. if(this.renderData.utm){
  235. url= `https://s1.matchexpo.cn/${this.renderData.utm}`
  236. }else{
  237. url = `${host}/register/${this.renderData.key}`
  238. }
  239. const body = `
  240. <a href="${url}" class="mp-button">
  241. <img class="background" src="${oss_domain}${this.expoData.images[0]}">
  242. <div class="expo-name">${this.expoData.expo_name}</div>
  243. <div class="goto-text">${this.renderData.buttontext}</div>
  244. </a>`
  245. const style = `
  246. <style>
  247. .mp-button{
  248. max-width: 240px;
  249. border-radius: 16px;
  250. overflow: hidden;
  251. font-family: sans-serif;
  252. text-decoration: none;
  253. display: block;
  254. position: fixed;
  255. z-index: 10;
  256. ${this.renderData.buttonposition.includes('l')?'left: 24px;':''}
  257. ${this.renderData.buttonposition.includes('r')?'right: 24px;':''}
  258. ${this.renderData.buttonposition.includes('c')?'bottom: 40%;':''}
  259. ${this.renderData.buttonposition.includes('b')?'bottom: 24px;':''}
  260. padding: 10px 20px;
  261. background-color: ${this.renderData.themecolor};
  262. .goto-text{
  263. text-align: right;
  264. position: relative;
  265. color: ${this.renderData.buttoncolor};
  266. }
  267. .expo-name{
  268. position: relative;
  269. margin-bottom: 0.5em;
  270. font-weight: bold;
  271. color: ${this.renderData.buttoncolor};
  272. font-size: 1.4em;
  273. }
  274. .background{
  275. transition-duration: 300ms;
  276. position: absolute;
  277. left: 0;
  278. top: 0;
  279. width: 100%;
  280. height: 100%;
  281. object-fit: cover;
  282. opacity: 0.1;
  283. filter: grayscale(1);
  284. }
  285. &:hover{
  286. .background{
  287. opacity: 0.15;
  288. scale: 1.1;
  289. }
  290. }
  291. }
  292. </style>
  293. `
  294. this.shadow.innerHTML = ''
  295. this.shadow.innerHTML = style + body
  296. }
  297. constructor() {
  298. super()
  299. }
  300. attributeChangedCallback(name, oldValue, newValue) {
  301. if(name === 'res'){
  302. let attr = ['key','themecolor','backcolor','fontcolor','buttontext','buttoncolor','buttonposition','utm']
  303. let dataArr = LZString.decompressFromBase64(newValue).split(',')
  304. if(dataArr[0] !== this.renderData.key){
  305. for(let i = 0; i < dataArr.length; i++){
  306. this.renderData[attr[i]] = dataArr[i]
  307. }
  308. this.getData()
  309. }else{
  310. for(let i = 0; i < dataArr.length; i++){
  311. this.renderData[attr[i]] = dataArr[i]
  312. }
  313. this.render()
  314. }
  315. }
  316. }
  317. }
  318. customElements.define('mp-share-card', mpShareCard)
  319. customElements.define('mp-float-button', mpFloatButton)
  320. }
  321. }
  322. initModule()
  323. }