give-dialog.vue 98 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864
  1. <template>
  2. <div class="overlay" v-if="visible">
  3. <div class="content"
  4. :style="{
  5. height: showComType === 'preview' ? 'calc(100vh - 40px)' : dialogStyle.dialogHeight + 'px',
  6. width: dialogStyle.dialogContentWidth + 'px',
  7. }">
  8. <div class="pop-mask"
  9. v-show="showCurrencyPop || showCurrencySelect"
  10. @click.stop="showCurrencyPop = false; showCurrencySelect=false">
  11. </div>
  12. <!-- 头部 -->
  13. <div class="head">
  14. <div class="left">
  15. <!-- 关闭按钮 -->
  16. <div class="close-btn" @click="close">
  17. <template v-if="publishType == 'TOOL_BOX'">
  18. <img class="icon-close"
  19. :src="require('@/assets/svg/icon-close.svg')"
  20. v-if="toolBoxPageData.activePage == 'EDITOR'"/>
  21. <img class="icon-close"
  22. :src="require('@/assets/svg/icon-back.svg')"
  23. v-else/>
  24. </template>
  25. <template v-else>
  26. <img class="icon-close"
  27. :src="require('@/assets/svg/icon-close.svg')"
  28. v-if="showComType == 'default'"/>
  29. <img class="icon-close"
  30. :src="require('@/assets/svg/icon-back.svg')"
  31. v-else/>
  32. </template>
  33. </div>
  34. <!-- 标题 -->
  35. <div class="title">
  36. {{publishType == 'REDPACKET' ? currentComData[showComType]["title"] : 'Tool Box' }}
  37. </div>
  38. </div>
  39. <div class="right">
  40. <!-- 更多按钮 -->
  41. <img :src="require('@/assets/svg/icon-more-l.svg')"
  42. class="more"
  43. @click="showMoreOption = true">
  44. <div class="area-option"
  45. v-if="showMoreOption"
  46. @click="showMoreOption = false">
  47. <div class="option">
  48. <div class="item" @click="goTransactionsList()">
  49. <img :src="require('@/assets/svg/icon-menu.svg')">
  50. <span>Transaction History</span>
  51. </div>
  52. </div>
  53. </div>
  54. </div>
  55. </div>
  56. <!-- 内容 -->
  57. <div class="body">
  58. <!-- 充值组件 -->
  59. <top-up
  60. v-if="showComType == 'topUp'"
  61. :asyncIng="asyncIng"
  62. :currentCurrencyInfo="tempCurrentCurrencyInfo"
  63. @topUpDone="topUpDone">
  64. </top-up>
  65. <!-- 自定义红包封面 -->
  66. <giveaway-poster
  67. v-else-if="showComType == 'poster'"
  68. :baseFormData="baseFormData"
  69. :currentCurrencyInfo="currentCurrencyInfo"
  70. :customPosterInfo="customPosterInfo"
  71. @selectImage="selectImage"
  72. @confirmData="confirmData">
  73. </giveaway-poster>
  74. <!-- 表单填写容器 -->
  75. <div class="body-content" v-else>
  76. <!-- 货币列表 -->
  77. <div class="currency-pop" v-show="showCurrencyPop">
  78. <currency-list
  79. ref="currencyListDom"
  80. :showGeneralLottery="true"
  81. @selectCurrency="selectCurrency"
  82. @setCurrencyList="setCurrentCurrencyInfo"
  83. @addGeneralLottery="addCustomizedRewardHandle"></currency-list>
  84. </div>
  85. <!-- 通用奖品编辑弹窗 -->
  86. <div class="customized-reward-edit-popup" v-if="showCustomizedRewardEditPopup">
  87. <customized-reward-edit-popup
  88. ref="rewardEditDom"
  89. :customizedReward="baseFormData.customizedReward"
  90. :rewardType="baseFormData.rewardType"
  91. @closeRewardPopup="closeRewardPopup"
  92. @removeReward="removeReward"
  93. @submitReward="submitReward"></customized-reward-edit-popup>
  94. </div>
  95. <div class="currency-pop-select" v-show="showCurrencySelect">
  96. <currency-select
  97. ref="currencySelectDom"
  98. :list="tempCurrentCurrencyList"
  99. @selectCurrency="selectCurrencyAfter"></currency-select>
  100. </div>
  101. <div class="left" v-if="showComType != 'preview' && toolBoxPageData.activePage != 'PREVIEW'">
  102. <div class="tab-item"
  103. :class="{'active-tab': item.type == publishType}"
  104. v-for="(item, index) in leftTabList"
  105. :key="index"
  106. @click="clickLeftTab(item, index)"
  107. >
  108. <img class="icon" :src="item.icon"/>
  109. </div>
  110. </div>
  111. <div class="right"
  112. :class="{'fill-right': showComType == 'preview' || toolBoxPageData.activePage == 'PREVIEW'}">
  113. <global-tip :type="'2'"></global-tip>
  114. <template v-if="publishType == 'TOOL_BOX'">
  115. <tool-box
  116. :pageData="{
  117. 'linkInputDescImage': toolBoxPageData.postEditorLinkInputDescImage
  118. }"
  119. :activePage="toolBoxPageData.activePage" @onPageChange="onToolBoxPageChange"
  120. @toolBoxPublishFinish="toolBoxPublishFinish"></tool-box>
  121. </template>
  122. <template v-else>
  123. <div class="form-wrapper" v-if="showComType == 'default'">
  124. <div class="form-cell-item base-form-wrapper">
  125. <div class="title">
  126. <img class="icon" :src="require('@/assets/svg/icon-reward-v2.svg')"/>
  127. Reward
  128. </div>
  129. <div class="form-cell-content">
  130. <div class="select-mode-ele">
  131. <img v-for="(item, index) in publishModeList"
  132. :key="index"
  133. :src="selectModeInfo.index == index ? item.imgActive : item.imgInActive"
  134. @click="selectPublishMode(item, index)">
  135. </div>
  136. <!-- 金额、数量 -->
  137. <div class="form-base">
  138. <div class="item currency-select-wrapper">
  139. <div>
  140. <div class="label currency-select"
  141. :class="{'selected': currencySelectCpd}"
  142. @click="selectCurrencyPopHandle">
  143. <img class="icon"
  144. v-if="currentIconCpd"
  145. :src="currentIconCpd"/>
  146. <div class="text">
  147. {{currentPrizeCpd}}
  148. </div>
  149. <img class="arrow"
  150. :src="currentArrowCpd"/>
  151. </div>
  152. <!-- 刷新按钮、充值 -->
  153. <div class="currency-operation"
  154. v-if="currentCurrencyInfo.currencyCode">
  155. <div class="amount">
  156. Balance:
  157. <a-tooltip :title="currentCurrencyInfo.balance">
  158. {{ getBit(currentCurrencyInfo.balance) }}
  159. </a-tooltip>
  160. <img :class="{ 'icon-refresh-rotate': refreshRotate }"
  161. :src="require('@/assets/svg/icon-form-refresh.svg')"
  162. @click="updateCurrencyBanlce"/>
  163. </div>
  164. <div v-if="currentCurrencyInfo.currencyCode != 'USD'"
  165. class="top-up"
  166. @click="goTopUp">Deposit</div>
  167. </div>
  168. </div>
  169. <input v-model="baseFormData.amountValue"
  170. placeholder="0"
  171. autofocus
  172. @input="onAmountInput"
  173. @blur="onAmountBlur"/>
  174. </div>
  175. <div class="item winners-count-input">
  176. <div>
  177. <div class="label">
  178. <img class="icon"
  179. :src="require('@/assets/svg/icon-winner-v2.svg')"/>
  180. Winner Count
  181. </div>
  182. <div class="msg" v-show="selectModeInfo.type == 1">Recommend Winners 100~10000</div>
  183. </div>
  184. <input v-model="baseFormData.totalCount"
  185. placeholder="0"
  186. :disabled="baseFormData.rewardType === RewardType.custom"
  187. @input="onCountInput"
  188. @blur="onCountBlur"/>
  189. </div>
  190. <div class="item automatically-input" v-if="selectModeInfo.type == 2">
  191. <div class="label">
  192. <img class="icon"
  193. :src="require('@/assets/svg/icon-automatically.svg')"/>
  194. Automatically Draw in
  195. </div>
  196. <div class="input-wrapper">
  197. <input v-model="baseFormData.validityDuration"
  198. placeholder="0"
  199. @input="onValidityDurationInput"
  200. @blur="onValidityDurationBlur"/>
  201. <span class="unit">h</span>
  202. </div>
  203. </div>
  204. </div>
  205. <div class="giveaway-poster" @click="customCoverImg">
  206. <div class="show-img">
  207. <div
  208. :style="{
  209. 'zoom': 55 / 500,
  210. 'position': 'absolute',
  211. 'width': '345px',
  212. }">
  213. <custom-card-cover
  214. :data="{
  215. totalCount: baseFormData.totalCount,
  216. amountValue: baseFormData.amountValue,
  217. tokenSymbol: currentCurrencyInfo.tokenSymbol,
  218. currencyIconUrl: currentCurrencyInfo.iconPath,
  219. type: baseFormData.type,
  220. validityDuration: baseFormData.validityDuration,
  221. customPosterUrl: customPosterData && customPosterData.after && customPosterData.after.imagePath || '',
  222. rewardType: baseFormData.rewardType,
  223. customizedReward: baseFormData.customizedReward
  224. }">
  225. </custom-card-cover>
  226. </div>
  227. </div>
  228. <div class="show-font">
  229. <span>Giveaway Poster</span>
  230. <img class="new" v-if="customShowNewImage" :src=" require('@/assets/svg/img-new.svg') " />
  231. </div>
  232. <div class="show-placeholder">Replace</div>
  233. <div class="arrow">
  234. <img :src=" require('@/assets/svg/icon-cell-arrow-right.svg') " />
  235. </div>
  236. </div>
  237. <!-- 提示 -->
  238. <ul class="tips-wrapper">
  239. <li class="row" style="white-space:nowrap;">
  240. Rewards can only be claimed after the target user completes all tasks you set.
  241. </li>
  242. <li class="row">
  243. Each user can only receive a reward once per task.
  244. </li>
  245. <li class="row" v-show="selectModeInfo.type == 1">
  246. The reward will expire in 7 days once issued. Please promote it as much as possible within this period. After the experiment, the remaining rewards will be returned to your DeNet Wallet.
  247. </li>
  248. </ul>
  249. </div>
  250. </div>
  251. <div class="form-cell-item task-wrapper">
  252. <div class="title">
  253. <img class="icon" :src="require('@/assets/svg/icon-tasks-v2.svg')"/>
  254. Tasks
  255. </div>
  256. <div class="form-cell-content form-require">
  257. <!-- 转推、like、关注 -->
  258. <div v-for="(item, index) in formList"
  259. :key="index">
  260. <div v-if="item.show" class="form-item"
  261. :class="{ 'border-hide': formList.length - 1 == index }">
  262. <div class="item-left">
  263. <div class="label">
  264. <img class="icon" :src="item.icon"/>
  265. {{ item.label }}
  266. </div>
  267. <div class="control"
  268. v-if="item.nodeType == 'textarea'">
  269. <follow-input
  270. :isAddSelf="!isBack"
  271. :atUserList="atUserList"
  272. @addUser="addFollowUser"
  273. @setUser="setFollowUser"
  274. @delUser="delFollowUser"></follow-input>
  275. </div>
  276. <div class="control"
  277. v-if="item.nodeType == 'input'">
  278. <div v-if="showDiscordInvitePop"
  279. class="discord-invite-info"
  280. @click="showDiscordInvitePop = false">
  281. <img class="icon" :src="discordInviteInfo.icon || require('@/assets/svg/icon-discord-mini.svg')" />
  282. <span class="name">{{discordInviteInfo.name}}</span>
  283. </div>
  284. <input v-model="item.text"
  285. placeholder="Enter discord invite link"
  286. class="discord-address"
  287. @input="onIptDiscordAddress($event, index)"
  288. @blur="onBlurDiscordAddress($event, index)" />
  289. </div>
  290. </div>
  291. <div>
  292. <a-switch
  293. v-if="item.type > 3"
  294. v-model:checked="item.checked"
  295. @change="formSwitchChange($event, item, index)"/>
  296. </div>
  297. </div>
  298. </div>
  299. </div>
  300. </div>
  301. <div class="submit-btn-wrapper">
  302. <div class="submit-btn"
  303. :class="{ 'disabled-submit': iptErrMsgTxt != ''}"
  304. @click="confirm">
  305. <img class="icon-loading"
  306. v-if="submitIng"
  307. :src="require('@/assets/svg/icon-btn-loading.svg')"
  308. />
  309. {{iptErrMsgTxt ? iptErrMsgTxt : 'NEXT'}}
  310. </div>
  311. </div>
  312. </div>
  313. <!-- 预览 -->
  314. <template v-else-if="showComType == 'preview'">
  315. <div class="preview">
  316. <div class="card"
  317. :class="{ center: !isMoneyRewardCpd || Number(baseFormData.amountValue) <= Number(currentCurrencyInfo.balance) }">
  318. <div class="card-title">
  319. <img class="img"
  320. v-if="isMoneyRewardCpd && Number(baseFormData.amountValue) > Number(currentCurrencyInfo.balance)"
  321. :src=" require('@/assets/subject/top-01.svg') " />
  322. <div class="font">
  323. Preview: <span>{{installStatus ? 'After' : 'Before' }}</span> DeNet Installed
  324. </div>
  325. </div>
  326. <div class="flash">
  327. <preview-card
  328. :currentCurrencyInfo="currentCurrencyInfo"
  329. :postData="publishRes"
  330. :baseFormData="baseFormData"
  331. :amountFontSize="previewFontSize"
  332. :customPosterInfo="customPosterData"
  333. ></preview-card>
  334. </div>
  335. </div>
  336. <!-- 需充值 -->
  337. <div class="card-content" v-if="isMoneyRewardCpd && Number(baseFormData.amountValue) > Number(currentCurrencyInfo.balance)">
  338. <template v-if="currentCurrencyInfo.currencyCode === 'USD'">
  339. <div class="card-title">
  340. <img class="img" :src=" require('@/assets/subject/top-02.svg') " />
  341. <div class="font">Deposit to Send Giveaway</div>
  342. </div>
  343. <div class="card-list">
  344. <div class="item">
  345. <div class="l">Giveaway Amount</div>
  346. <div class="r"></div>
  347. </div>
  348. <div class="item">
  349. <div class="l">Balance</div>
  350. <div class="r"></div>
  351. </div>
  352. <div class="item">
  353. <div class="l">Paypal charges fee ()</div>
  354. <div class="r"></div>
  355. </div>
  356. <div class="item">
  357. <div class="l">Deposit Amount</div>
  358. <div class="r"></div>
  359. </div>
  360. </div>
  361. </template>
  362. <template v-else>
  363. <div class="card-title">
  364. <img class="img" :src=" require('@/assets/subject/top-02.svg') " />
  365. <div class="font">Deposit to Send Giveaway</div>
  366. </div>
  367. <top-up2
  368. :asyncIng="asyncIng"
  369. :currentCurrencyInfo="tempCurrentCurrencyInfo"
  370. @topUpDone="topUpDone">
  371. </top-up2>
  372. <div class="card-title">
  373. <img class="img" :src=" require('@/assets/subject/top-03.svg') " />
  374. <div class="font">Wait for the amount to arrive</div>
  375. </div>
  376. <div class="card-amount">
  377. <img class="icon" src="@/assets/subject/icon-balance.png" />
  378. <div class="con">
  379. <div class="desc">Balance</div>
  380. <div class="price">{{currentCurrencyInfo.balance}} {{currentCurrencyInfo.tokenSymbol}}</div>
  381. </div>
  382. <img
  383. class="refresh"
  384. :class="{ 'icon-refresh-rotate': refreshRotate }"
  385. @click="updateCurrencyBanlce"
  386. :src=" require('@/assets/svg/icon-form-refresh-blue.svg') "
  387. />
  388. </div>
  389. </template>
  390. </div>
  391. </div>
  392. </template>
  393. <!-- paypal支付按钮 -->
  394. <div class="payment" v-show="showComType == 'preview'">
  395. <paypal-button
  396. v-if="isMoneyRewardCpd"
  397. :finalAmountData="finalAmountData"
  398. :payConfig="{
  399. paypalClientId,
  400. feeDesc: payConfig.feeDesc,
  401. paypalHtml,
  402. amount: baseFormData.amountValue,
  403. postId
  404. }"
  405. :currentCurrencyInfo="currentCurrencyInfo"
  406. @payPalFinsh="payPalFinsh">
  407. <template v-slot:balance>
  408. <div class="balance" v-if="Number(baseFormData.amountValue) <= Number(currentCurrencyInfo.balance)">
  409. <img class="icon" src="@/assets/subject/icon-balance.png" />
  410. <div class="con">
  411. <div class="desc">Balance</div>
  412. <div class="price">{{currentCurrencyInfo.balance}} {{currentCurrencyInfo.tokenSymbol}}</div>
  413. </div>
  414. <img class="refresh"
  415. :class="{ 'icon-refresh-rotate': refreshRotate }"
  416. :src=" require('@/assets/svg/icon-form-refresh.svg')"
  417. @click="updateCurrencyBanlce"/>
  418. </div>
  419. </template>
  420. </paypal-button>
  421. <div v-else class="btn-wrap" @click="payStatusHandle(1)"><div class="custom-submit">Confirm</div></div>
  422. </div>
  423. </template>
  424. </div>
  425. </div>
  426. </div>
  427. </div>
  428. <!-- 提示 -->
  429. <message-box
  430. :dialogVisible="showMessageBox"
  431. :title="messageBoxData.title"
  432. :content="messageBoxData.content"
  433. @cancel="messageBoxCancel"
  434. @confirm="messageBoxConfirm"
  435. ></message-box>
  436. <!-- 裁剪 -->
  437. <div class="dialog" v-if="cropperDialog">
  438. <div class="corp-title">
  439. <img class="back" :src="require('@/assets/svg/icon-back.svg')" @click="hiddenDialog" />
  440. <span>Crop</span>
  441. </div>
  442. <div class="corp-content">
  443. <vue-cropper
  444. ref="refCropper"
  445. :img="cropperOption.img"
  446. :output-type="cropperOption.outputType"
  447. :infoTrue="cropperOption.infoTrue"
  448. :full="cropperOption.full"
  449. :fixed="cropperOption.fixed"
  450. :fixed-number="cropperOption.fixedNumber"
  451. :auto-crop="cropperOption.autoCrop"
  452. :auto-crop-width="cropperOption.autoCropWidth"
  453. :auto-crop-height="cropperOption.autoCropHeight"
  454. :center-box="cropperOption.centerBox"
  455. :high="cropperOption.high"
  456. :max-img-size="cropperOption.max">
  457. </vue-cropper>
  458. </div>
  459. <div class="corp-footer">
  460. <button v-if="cropperLoading" class="confirm disable">
  461. <img :src=" require('@/assets/svg/icon-btn-loading.svg') " />
  462. <span>Confirm</span>
  463. </button>
  464. <button v-else class="confirm" @click="confirmImage">Confirm</button>
  465. </div>
  466. </div>
  467. <div class="dialog-mask" v-if="cropperDialog"></div>
  468. </div>
  469. </template>
  470. <script setup>
  471. import { ref, watch, reactive, defineProps, defineEmits, onMounted, nextTick, provide, getCurrentInstance, computed } from "vue";
  472. import { postPublish, verifyPaypalResult, syncChainTokenRechargeRecord, getCurrencyInfoByCode } from "@/http/publishApi";
  473. import { getInviteGuildInfo, getInviteGuildInfoByOpenApi, saveInviteGuildInfo } from "@/http/discordApi";
  474. import { payCalcFee, getPayConfig } from "@/http/pay";
  475. import { getFrontConfig } from "@/http/account";
  476. import { uploadSignature, uploadFile } from '@/http/media';
  477. import {setChromeStorage, getChromeStorage} from "@/uilts/chromeExtension"
  478. import { debounce, getBit } from "@/uilts/help"
  479. import { PlayType, RewardType } from '@/types';
  480. import Report from "@/log-center/log"
  481. import { ElMessage, ElLoading } from "element-plus";
  482. import "element-plus/es/components/message/style/css";
  483. import "element-plus/es/components/loading/style/css";
  484. import 'vue-cropper/dist/index.css'
  485. import { VueCropper } from "vue-cropper";
  486. import {create, all} from "mathjs";
  487. import messageBox from "@/view/components/message-box.vue";
  488. import currencyList from "@/view/components/currency-list.vue";
  489. import currencySelect from "@/view/components/currency-select.vue";
  490. import previewCard from "@/view/iframe/publish/components/preview-card";
  491. import followInput from "@/view/iframe/publish/components/follow-input";
  492. import paypalButton from "@/view/iframe/publish/components/paypal-button";
  493. import topUp from "@/view/iframe/publish/components/top-up.vue";
  494. import topUp2 from "@/view/iframe/publish/components/top-up2.vue";
  495. import toolBox from '@/view/iframe/publish/tool-box/index.vue'
  496. import giveawayPoster from '@/view/iframe/publish/components/giveaway-poster.vue';
  497. import GlobalTip from '@/view/components/global-tip.vue'
  498. import customCardCover from '@/view/components/custom-card-cover.vue'
  499. const currentInstance = getCurrentInstance();
  500. import CustomizedRewardEditPopup from '@/view/iframe/publish/components/customized-reward-edit';
  501. const config = {
  502. number: 'BigNumber',
  503. }
  504. const math = create(all, config);
  505. //临时货币信息
  506. let tempCurrentCurrencyInfo = ref({});
  507. let tempCurrentCurrencyList = ref([]);
  508. let paypalClientId = ref("");
  509. let payConfig = ref({});
  510. let paypalHtml = ref("");
  511. let installStatus = ref(false);
  512. let timer = ref(null);
  513. provide('installStatus', installStatus)
  514. // 发布后返回的结果
  515. let publishRes = reactive({});
  516. //弹窗是否展示
  517. let visible = ref(false);
  518. let publishType = ref('REDPACKET');
  519. //弹窗高度
  520. let dialogStyle = reactive({
  521. dialogHeight: 670,
  522. dialogContentWidth: 1100
  523. })
  524. let cropperOption = ref({
  525. img: '',
  526. full: true,
  527. infoTrue: true,
  528. fixed: true,
  529. fixedNumber: [16, 8.396],
  530. outputType: 'png',
  531. autoCrop: true,
  532. autoCropWidth: 99999,
  533. autoCropHeight: 99999,
  534. centerBox: true,
  535. high: true,
  536. max: 99999,
  537. })
  538. let cropperDialog = ref(false)
  539. let cropperLoading = ref(false)
  540. let cropperType = ref('before')
  541. let customPosterInfo = ref({})
  542. let customPosterData = ref({})
  543. let customShowNewImage = ref(false)
  544. let refCropper = ref('')
  545. // 当前展示组件内容 default(表单) preview(预览) topUp(充值)
  546. let showComType = ref("default");
  547. let currentComData = {
  548. default: {
  549. title: "Giveaway",
  550. },
  551. preview: {
  552. title: "Giveaway",
  553. },
  554. topUp: {
  555. title: "Deposit",
  556. },
  557. poster: {
  558. title: "Giveaway Poster",
  559. }
  560. };
  561. // 机器人开关
  562. let openAntiBot = ref(false);
  563. // 是否正在提交
  564. let submitIng = ref(false);
  565. // 艾特关注人列表
  566. let atUserList = ref([]);
  567. // 表单错误提示
  568. let iptErrMsgTxt = ref("Select a reward");
  569. // 是否返回
  570. let isBack = ref(false);
  571. // 展示消息提示
  572. let showMessageBox = ref(false);
  573. // 展示货币列表pop
  574. let showCurrencyPop = ref(false);
  575. let showCurrencySelect = ref(false);
  576. // 展示更多按钮下的选项
  577. let showMoreOption = ref(false);
  578. // 货币列表的dom
  579. let currencyListDom = ref('');
  580. // 刷新按钮旋转
  581. let refreshRotate = ref(false);
  582. // 预览字体大小
  583. let previewFontSize = ref(56);
  584. let postId = ref('');
  585. let selectModeInfo = reactive({
  586. index: 0,
  587. type: 2 // 1: 红包 2: 抽奖
  588. })
  589. // 余额是否同步中
  590. let asyncIng = ref(false);
  591. let messageBoxData = ref({
  592. title: "",
  593. content: "",
  594. });
  595. // 真实支付金额数据
  596. let finalAmountData = ref({
  597. currencyCode: '',
  598. feeAmountValue: 0,
  599. finalAmountValue: 0,
  600. requestAmountValue: 0,
  601. });
  602. // 表单数据
  603. let baseFormData = reactive({
  604. amountCurrencyCode: "",
  605. amountValue: "",
  606. totalCount: "",
  607. validityDuration: "",
  608. type: selectModeInfo.type,
  609. rewardType: RewardType.money,
  610. customizedReward: ""
  611. });
  612. const defaultCurrentCurrencyInfo = {
  613. currencyCode: "",
  614. currencyName: "",
  615. balance: "",
  616. currencyType: "",
  617. iconPath: "",
  618. minAmount: "",
  619. tokenChain: "",
  620. tokenSymbol: "",
  621. usdEstimateBalance: ""
  622. }
  623. // 当前选择的货币信息
  624. let currentCurrencyInfo = ref(defaultCurrentCurrencyInfo);
  625. const discordIptErrTxt = 'Discord invite link is wrong';
  626. const discordIptEmptyErrTxt = 'Enter discord invite link';
  627. const discordIptNerverExpiresErrTxt = 'Make sure the Discord link never expires'
  628. let iptErrType = ''; //discord
  629. let formList = reactive([
  630. {
  631. label: "Follow",
  632. icon: require("@/assets/svg/icon-task-twitter.svg"),
  633. nodeType: "textarea",
  634. type: 1,
  635. text: [],
  636. checked: true,
  637. show: true
  638. },
  639. {
  640. label: "Retweet & Like",
  641. icon: require("@/assets/svg/icon-task-twitter.svg"),
  642. nodeType: "div",
  643. type: 3,
  644. checked: true,
  645. show: true
  646. },
  647. {
  648. label: "Like Tweet",
  649. icon: require("@/assets/svg/icon-task-twitter.svg"),
  650. nodeType: "div",
  651. type: 2,
  652. checked: true,
  653. show: false
  654. },
  655. {
  656. label: "Comment and Tag 3 friends",
  657. icon: require("@/assets/svg/icon-task-twitter.svg"),
  658. nodeType: "div",
  659. type: 9,
  660. checked: true,
  661. show: true
  662. },
  663. {
  664. label: "Repost to Facebook",
  665. icon: require("@/assets/svg/icon-task-facebook.svg"),
  666. nodeType: "div",
  667. text: '',
  668. type: 8,
  669. checked: false,
  670. show: true
  671. },
  672. {
  673. label: "Join Discord",
  674. icon: require("@/assets/svg/icon-discord-mini.svg"),
  675. nodeType: "input",
  676. text: '',
  677. type: 7,
  678. checked: false,
  679. show: true
  680. },
  681. ]);
  682. let publishModeList = reactive([
  683. {
  684. imgActive: require("@/assets/svg/img-A1.svg"),
  685. imgInActive: require("@/assets/svg/img-A0.svg"),
  686. type: 2
  687. },
  688. {
  689. imgActive: require("@/assets/svg/img-B1.svg"),
  690. imgInActive: require("@/assets/svg/img-B0.svg"),
  691. type: 1
  692. }
  693. ])
  694. let discordInviteInfo = ref({});
  695. let showDiscordInvitePop = ref(false);
  696. let showCustomizedRewardEditPopup = ref(false);
  697. let lotteryMaxHourDuration = 168;
  698. let leftTabList = reactive([
  699. {
  700. icon: require('@/assets/svg/icon-gift-pack.svg'),
  701. type: 'REDPACKET'
  702. },
  703. {
  704. icon: require('@/assets/svg/icon-tool-box-02.svg'),
  705. type: 'TOOL_BOX'
  706. }
  707. ])
  708. let toolBoxPageData = reactive({
  709. activePage: 'EDITOR', //EDITOR PREVIEW
  710. postEditorLinkInputDescImage: ''
  711. })
  712. const props = defineProps({
  713. dialogData: {
  714. type: Object,
  715. default: () => {
  716. return {
  717. visible: false,
  718. type: 'REDPACKET'
  719. }
  720. },
  721. },
  722. });
  723. //selected prize icon cpd
  724. let currentIconCpd = computed(() => {
  725. if(baseFormData.rewardType === RewardType.custom) {
  726. return require("@/assets/svg/icon-gift.svg");
  727. } else {
  728. return currentCurrencyInfo.value.iconPath;
  729. }
  730. })
  731. // selected prize cpd
  732. let currentPrizeCpd = computed(() => {
  733. const {currencyCode, tokenSymbol} = currentCurrencyInfo.value
  734. if(baseFormData.rewardType === RewardType.custom) {
  735. return baseFormData.customizedReward;
  736. } else if(currencyCode == "USD") {
  737. return "USD";
  738. } else {
  739. return tokenSymbol || "Select a reward";
  740. }
  741. })
  742. let currencySelectCpd = computed(() => {
  743. return baseFormData.customizedReward || currentCurrencyInfo.value.currencyCode;
  744. })
  745. let currentArrowCpd = computed(() => {
  746. if(baseFormData.rewardType === RewardType.custom) {
  747. return require("@/assets/svg/icon-cell-arrow-right.svg");
  748. } else {
  749. return currentCurrencyInfo.value.currencyCode ? require("@/assets/svg/icon-form-arrow-down.svg") : require("@/assets/svg/icon-form-white-arrow-down.svg");
  750. }
  751. })
  752. let isMoneyRewardCpd =computed(() => baseFormData.rewardType === RewardType.money);
  753. watch(
  754. () => props.dialogData,
  755. (newVal) => {
  756. visible.value = newVal.visible;
  757. if (newVal.visible) {
  758. publishType.value = newVal.type;
  759. Report.reportLog({
  760. pageSource: Report.pageSource.publisherDialog,
  761. businessType: Report.businessType.pageView,
  762. });
  763. getLocalCurrencyInfoByCode();
  764. setTimeout(() => {
  765. setDialogStyle();
  766. }, 300);
  767. // 更新余额
  768. clearInterval(timer.value);
  769. timer.value = setInterval(() => {
  770. getCurrencyInfo({loop: true});
  771. }, 10000)
  772. } else {
  773. clearInterval(timer.value);
  774. }
  775. },
  776. {
  777. deep: true
  778. }
  779. );
  780. const emits = defineEmits(["close", "confirm", "postPublishFinish"]);
  781. const close = () => {
  782. if(publishType.value == 'TOOL_BOX') {
  783. closeToolBoxPage()
  784. } else {
  785. if (showComType.value != "default") {
  786. showComType.value = "default";
  787. isBack.value = true;
  788. } else {
  789. initParams();
  790. emits("close", false);
  791. }
  792. }
  793. };
  794. const closeToolBoxPage = () => {
  795. if(toolBoxPageData.activePage == "EDITOR") {
  796. emits("close", false);
  797. } else if(toolBoxPageData.activePage == "PREVIEW") {
  798. toolBoxPageData.activePage = "EDITOR";
  799. }
  800. };
  801. /**
  802. * 设置弹窗高度
  803. */
  804. const setDialogStyle = (resize = false) => {
  805. nextTick(() => {
  806. let clientHeight = window.innerHeight;
  807. let clientWidth = window.innerWidth;
  808. let gapSafe = 40;
  809. if (dialogStyle.dialogHeight > clientHeight - gapSafe) {
  810. dialogStyle.dialogHeight = clientHeight - gapSafe;
  811. } else {
  812. if(resize) {
  813. dialogStyle.dialogHeight = 680;
  814. }
  815. }
  816. if(dialogStyle.dialogContentWidth > clientWidth - gapSafe) {
  817. dialogStyle.dialogContentWidth = clientWidth - gapSafe;
  818. } else {
  819. if(resize) {
  820. dialogStyle.dialogContentWidth = 1080;
  821. }
  822. }
  823. })
  824. };
  825. const selectCurrencyPopHandle = () => {
  826. Report.reportLog({
  827. pageSource: Report.pageSource.currencySelectorPage,
  828. businessType: Report.businessType.pageView,
  829. });
  830. if(baseFormData.rewardType === RewardType.custom) {
  831. showCustomizedRewardEditPopup.value = true
  832. } else {
  833. showCurrencyPop.value = true;
  834. nextTick(() => {
  835. if(currencyListDom.value) {
  836. currencyListDom.value.getCurrencyInfoList && currencyListDom.value.getCurrencyInfoList({pageNum: 1});
  837. }
  838. })
  839. }
  840. }
  841. /**
  842. * 获取实际支付金额
  843. */
  844. const getPayAmount = async (amountValue) => {
  845. let res = await payCalcFee({
  846. params: {
  847. amountValue,
  848. currencyCode: currentCurrencyInfo.value.currencyCode,
  849. payChannel: 'paypal',
  850. },
  851. });
  852. if (res.code == 0) {
  853. let { finalAmountValue, feeDesc } = res.data;
  854. payConfig.value.feeDesc = feeDesc;
  855. if (finalAmountValue > 0) {
  856. finalAmountData.value = res.data;
  857. }
  858. }
  859. return res.data;
  860. };
  861. const saveDiscordGuildInfo = () => {
  862. let {guildId, inviteCode, inviteUrl} = discordInviteInfo.value;
  863. //保存服务器信息
  864. Report.reportLog({
  865. pageSource: Report.pageSource.publisherDialog,
  866. businessType: Report.businessType.buttonClick,
  867. objectType: Report.objectType.saveDiscordGuildData
  868. }, {
  869. reportData: discordInviteInfo.value
  870. });
  871. if(guildId && inviteCode && inviteUrl) {
  872. saveInviteGuildInfo({
  873. params: {
  874. guildId,
  875. inviteCode,
  876. inviteUrl
  877. }
  878. })
  879. }
  880. }
  881. const confirm = () => {
  882. if (submitIng.value || iptErrMsgTxt.value) {
  883. return;
  884. }
  885. let { totalCount = 0 } = baseFormData;
  886. if (!totalCount) {
  887. return;
  888. }
  889. saveDiscordGuildInfo();
  890. submitRequest();
  891. };
  892. /**
  893. * 货币列表-选中货币
  894. */
  895. const selectCurrency = (params) => {
  896. let { currencies } = params;
  897. tempCurrentCurrencyList.value = currencies;
  898. if (currencies.length > 1) {
  899. showCurrencyPop.value = false;
  900. showCurrencySelect.value = true;
  901. } else {
  902. selectCurrencyAfter(currencies[0])
  903. }
  904. };
  905. const selectCurrencyAfter = (params, openWindow = true) => {
  906. tempCurrentCurrencyInfo.value = params;
  907. showCurrencySelect.value = false;
  908. currentCurrencyInfo.value = params;
  909. setLocalSelectCurrencyInfo(currentCurrencyInfo.value);
  910. if (openWindow === false) {
  911. return
  912. };
  913. if (params.currencyCode != "USD" && params.balance < params.minAmount) {
  914. let tokenSymbol = params.currencyCode == 'USD' ? 'USD' : params.tokenSymbol;
  915. messageBoxBlock({
  916. title: `Whether to deposit ${tokenSymbol}`,
  917. content: `Insufficient ${tokenSymbol} balance`,
  918. });
  919. } else {
  920. setCurrentCurrencyListInfo(tempCurrentCurrencyList.value);
  921. showCurrencyPop.value = false;
  922. finalAmountData.value.currencyCode = currentCurrencyInfo.value.currencyCode;
  923. resetFormIpt(false);
  924. onIptSetErrorTxt();
  925. }
  926. baseFormData.customizedReward = "";
  927. baseFormData.rewardType = RewardType.money;
  928. }
  929. const resetFormIpt = (clearMode = true) => {
  930. baseFormData.amountValue = "";
  931. baseFormData.totalCount = "";
  932. baseFormData.validityDuration = "";
  933. baseFormData.rewardType = RewardType.money;
  934. baseFormData.customizedReward = "";
  935. if(clearMode) {
  936. selectModeInfo.index = 0;
  937. selectModeInfo.type = publishModeList[selectModeInfo.index]['type'];
  938. baseFormData.type = selectModeInfo.type;
  939. }
  940. }
  941. const setLocalSelectCurrencyInfo = (params = {}) => {
  942. setChromeStorage({ selectCurrencyInfo : JSON.stringify(params)})
  943. }
  944. const setCurrentCurrencyListInfo = (params = {}) => {
  945. setChromeStorage({ selectCurrencyList : JSON.stringify(params)})
  946. }
  947. /**
  948. * 获取完货币列表
  949. */
  950. const setCurrentCurrencyInfo = (params) => {
  951. }
  952. const messageBoxBlock = ({ title = "", content = "" }) => {
  953. showMessageBox.value = true;
  954. messageBoxData.value.title = title;
  955. messageBoxData.value.content = content;
  956. };
  957. /**
  958. * 确定
  959. */
  960. const messageBoxConfirm = () => {
  961. showMessageBox.value = false;
  962. goTopUp();
  963. };
  964. /**
  965. * 取消
  966. */
  967. const messageBoxCancel = () => {
  968. currentCurrencyInfo.value = tempCurrentCurrencyInfo.value;
  969. setLocalSelectCurrencyInfo(currentCurrencyInfo.value);
  970. setCurrentCurrencyListInfo(tempCurrentCurrencyList.value);
  971. showMessageBox.value = false;
  972. showCurrencyPop.value = false;
  973. showCurrencySelect.value = false;
  974. resetFormIpt(false);
  975. onIptSetErrorTxt();
  976. };
  977. /**
  978. * 去充值
  979. */
  980. const goTopUp = () => {
  981. Report.reportLog({
  982. pageSource: Report.pageSource.rechargePage,
  983. businessType: Report.businessType.pageView,
  984. });
  985. showComType.value = 'topUp';
  986. }
  987. /*
  988. * 自定义封面
  989. */
  990. const customCoverImg = () => {
  991. customPosterInfo.value = {}
  992. if (Object.keys(customPosterData.value).length > 0) {
  993. customPosterInfo.value = customPosterData.value;
  994. }
  995. showComType.value = 'poster';
  996. customShowNewImage.value = false;
  997. setChromeStorage({ custom_poster_guide: Date.now() });
  998. }
  999. /**
  1000. * 充值done事件
  1001. */
  1002. const topUpDone = () => {
  1003. currentCurrencyInfo.value = tempCurrentCurrencyInfo.value;
  1004. asyncIng.value = true;
  1005. asyncIng.value = false;
  1006. showCurrencyPop.value = false;
  1007. showCurrencySelect.value = false;
  1008. showComType.value = 'default';
  1009. onIptSetErrorTxt()
  1010. asyncTokenRechRecord((res) => {
  1011. if(res.code == 0 && res.data && res.data.length) {
  1012. let currencyInfo = res.data[0];
  1013. if(currencyInfo.currencyCode == currentCurrencyInfo.value.currencyCode) {
  1014. currentCurrencyInfo.value.balance = currencyInfo.balance;
  1015. onIptSetErrorTxt()
  1016. }
  1017. }
  1018. })
  1019. }
  1020. /**
  1021. * 更新货币余额
  1022. */
  1023. const updateCurrencyBanlce = () => {
  1024. if(!refreshRotate.value) {
  1025. refreshRotate.value = true;
  1026. setTimeout(() => {
  1027. refreshRotate.value = false;
  1028. }, 1000)
  1029. }
  1030. asyncTokenRechRecord((res) => {
  1031. if(res.code == 0 && res.data && res.data.length) {
  1032. let currencyInfo = res.data[0];
  1033. if(currencyInfo.currencyCode == currentCurrencyInfo.value.currencyCode) {
  1034. currentCurrencyInfo.value.balance = currencyInfo.balance;
  1035. }
  1036. }
  1037. })
  1038. }
  1039. /**
  1040. * 同步链上交易
  1041. */
  1042. const asyncTokenRechRecord = (cb) => {
  1043. syncChainTokenRechargeRecord({
  1044. params: {
  1045. currencyCode: currentCurrencyInfo.value.currencyCode
  1046. }
  1047. }).then(res => {
  1048. cb && cb(res)
  1049. })
  1050. }
  1051. /**
  1052. * 提交表单请求
  1053. */
  1054. const submitRequest = async () => {
  1055. let {
  1056. amountValue = 0,
  1057. totalCount = 0,
  1058. rewardType = RewardType.money,
  1059. customizedReward = ""
  1060. } = baseFormData;
  1061. baseFormData.amountCurrencyCode = currentCurrencyInfo.value.currencyCode;
  1062. // 组装提交参数
  1063. let finishConditions = [];
  1064. for (let i = 0; i < formList.length; i++) {
  1065. let item = {};
  1066. item.type = formList[i]["type"];
  1067. if (item.type == 1 && atUserList.value.length) {
  1068. // follow 参数
  1069. let relatedUsers = atUserList.value.filter(item => item.name);
  1070. item.relatedUsers = relatedUsers;
  1071. finishConditions.push(item);
  1072. } else if (formList[i]["type"] == 7) {
  1073. // join discord
  1074. if(formList[i]["checked"] && formList[i]["text"]) {
  1075. item.bizData = JSON.stringify({inviteUrl: formList[i]["text"]});
  1076. finishConditions.push(item);
  1077. }
  1078. } else if (formList[i]["checked"]) {
  1079. // 其余任务
  1080. finishConditions.push(item);
  1081. }
  1082. }
  1083. let receiveConditions = openAntiBot.value ? "" : [];
  1084. let validityDuration = '';
  1085. if(baseFormData.type == PlayType.lottery) {
  1086. //小时转毫秒
  1087. let unit = process.env.NODE_ENV != 'production' ? 60 * 1000 : 60 * 60 * 1000;
  1088. // let unit = 60 * 60 * 1000
  1089. validityDuration = baseFormData.validityDuration * unit;
  1090. } else {
  1091. validityDuration = '';
  1092. }
  1093. // 提交参数
  1094. let formData = {
  1095. amountValue,
  1096. totalCount,
  1097. finishConditions,
  1098. receiveConditions,
  1099. type: baseFormData.type,
  1100. posterType: 1,
  1101. validityDuration,
  1102. rewardType
  1103. };
  1104. if(rewardType === RewardType.custom) {
  1105. // 通用奖品 类型的活动,添加奖品名称
  1106. formData.customizedReward = customizedReward;
  1107. delete formData.amountValue;
  1108. } else {
  1109. // 货币类型 添加货币code
  1110. formData.amountCurrencyCode = baseFormData.amountCurrencyCode;
  1111. formData.payAmountValue = baseFormData.payAmountValue;
  1112. }
  1113. submitIng.value = true;
  1114. // 自定义封面
  1115. if (Object.keys(customPosterData.value).length > 0) {
  1116. formData['posterType'] = 2;
  1117. if (customPosterData.value && customPosterData.value.after) {
  1118. formData['customPosterInstalled'] = customPosterData.value.after.objectKey || ''
  1119. }
  1120. if (customPosterData.value && customPosterData.value.before) {
  1121. formData['customPosterUninstalled'] = customPosterData.value.before.objectKey || ''
  1122. }
  1123. }
  1124. // 法币支付需要计算费率
  1125. if(formData.amountCurrencyCode == "USD") {
  1126. let payAmountRes = await getPayAmount(amountValue);
  1127. formData["payAmountValue"] = payAmountRes.finalAmountValue;
  1128. }
  1129. let data = {
  1130. params: {
  1131. postBizData: JSON.stringify(formData),
  1132. postSrc: 1, //1 twitter
  1133. postType: 1, //1 红包
  1134. },
  1135. };
  1136. postPublish(data).then((res) => {
  1137. submitIng.value = false;
  1138. if (res.code == 0) {
  1139. publishRes = res.data;
  1140. postId.value = res.data.postId;
  1141. Report.reportLog({
  1142. pageSource: Report.pageSource.previewPage,
  1143. businessType: Report.businessType.pageView,
  1144. });
  1145. showComType.value = "preview";
  1146. previewFontSize.value = calcFontSize(baseFormData.amountValue, 238, 56);
  1147. isBack.value = false;
  1148. } else {
  1149. console.log(res);
  1150. }
  1151. })
  1152. .catch((err) => {
  1153. console.log(err);
  1154. });
  1155. };
  1156. const calcFontSize = (str, domWidth, maxSize) => {
  1157. let lenstr = str.length;
  1158. let num = parseInt(domWidth / lenstr);
  1159. let fontSize = num < maxSize ? num : maxSize
  1160. return fontSize;
  1161. }
  1162. /**
  1163. * 初始化提交参数
  1164. */
  1165. const initParams = () => {
  1166. resetFormIpt();
  1167. // clear follow value
  1168. atUserList.value = [];
  1169. submitIng.value = false;
  1170. isBack.value = false;
  1171. showCurrencyPop.value = false;
  1172. showCurrencySelect.value = false;
  1173. openAntiBot.value = false;
  1174. tempCurrentCurrencyInfo.value = {};
  1175. currentCurrencyInfo.value = {};
  1176. publishType.value = 'REDPACKET';
  1177. // clear discord value
  1178. setDiscordIptTxt({text: ''});
  1179. discordInviteInfo.value = {};
  1180. customPosterInfo.value = {};
  1181. customPosterData.value = {};
  1182. };
  1183. const setDiscordIptTxt = ({text}) => {
  1184. const index = formList.findIndex(item => item.type == 7);
  1185. formList[index]['text'] = text;
  1186. }
  1187. /**
  1188. * 支付完成回调
  1189. */
  1190. const payPalFinsh = (params) => {
  1191. let {payNetwork, payStatus} = params;
  1192. // token 支付
  1193. if(payNetwork == 'bsc') {
  1194. payStatusHandle(payStatus);
  1195. } else {
  1196. // 法币支付
  1197. let transaction = params.transaction;
  1198. let loadingInstance = ElLoading.service({
  1199. background: "rgba(0,0,0,.3)",
  1200. });
  1201. verifyPaypalResult({
  1202. params: {
  1203. paypalTransactionId: transaction.id,
  1204. postId: publishRes.postId,
  1205. paypalClientId: paypalClientId.value,
  1206. },
  1207. }).then((res) => {
  1208. loadingInstance.close();
  1209. if (res.code == 0) {
  1210. if (res.data) {
  1211. payStatusHandle(res.data.payStatus)
  1212. }
  1213. }
  1214. })
  1215. .catch(() => {
  1216. loadingInstance.close();
  1217. });
  1218. }
  1219. };
  1220. const payStatusHandle = (payStatus) => {
  1221. //支付状态 0:未支付,1:支付成功,2:支付失败,3:已关闭,4:已退款
  1222. switch (payStatus) {
  1223. case 1:
  1224. emits("postPublishFinish", { publishRes });
  1225. showComType.value = "default";
  1226. initParams();
  1227. break;
  1228. case 2:
  1229. // ElMessage({
  1230. // message: "Pay Fail",
  1231. // type: "warning",
  1232. // });
  1233. break;
  1234. case 3:
  1235. // ElMessage({
  1236. // message: "Pay Exceptions",
  1237. // type: "warning",
  1238. // });
  1239. break;
  1240. case 4:
  1241. // ElMessage({
  1242. // message: "Pay Exceptions",
  1243. // type: "warning",
  1244. // });
  1245. break;
  1246. }
  1247. }
  1248. /**
  1249. * follow组件触发新增关注人
  1250. */
  1251. const addFollowUser = (params) => {
  1252. atUserList.value.push(params);
  1253. };
  1254. const setFollowUser = (params) => {
  1255. atUserList.value[params.index]["name"] = params.name;
  1256. };
  1257. const delFollowUser = (params) => {
  1258. atUserList.value.splice(params.index, 1);
  1259. };
  1260. const onAmountInput = () => {
  1261. let val = baseFormData.amountValue;
  1262. // val = val.replace(/[^\d^\.]+/g, "");
  1263. val = val.replace(/^\D*(\d*(?:\.\d{0,18})?).*$/g, '$1');
  1264. const maxCount = baseFormData.rewardType === RewardType.money ? Number.MAX_SAFE_INTEGER : 100000000;
  1265. if(val == '00') {
  1266. val = '0'
  1267. }
  1268. if(val.indexOf('.') > -1){ //校验 例:00.12 => 0.12
  1269. let arr = val.split('.');
  1270. if(arr[0].startsWith('0')) {
  1271. let num = +arr[0];
  1272. val = num + '.' + arr[1];
  1273. }
  1274. }
  1275. if (baseFormData.rewardType === RewardType.custom) {
  1276. const maxCount = 100000000;
  1277. val = val.replace(/^(0)*/, '').replace(/\./, ''); // 通用奖品类型 过滤掉起始位的0和小数点符号
  1278. if (val > maxCount) {
  1279. val = maxCount
  1280. }
  1281. baseFormData.totalCount = val;
  1282. }
  1283. baseFormData.amountValue = val;
  1284. setInputErrorMsg({from: 'amount', type:'input'});
  1285. return val;
  1286. };
  1287. const onCountInput = () => {
  1288. let val = baseFormData.totalCount;
  1289. const maxCount = 100000000;
  1290. if (val == 0) {
  1291. val = "";
  1292. }
  1293. val = val.replace(/^\D*(\d*(?:\.\d{0,18})?).*$/g, '$1');
  1294. if(val > maxCount) {
  1295. val = maxCount
  1296. }
  1297. baseFormData.totalCount = val;
  1298. setInputErrorMsg({from: 'count', type:'input'});
  1299. return val;
  1300. };
  1301. const onValidityDurationInput = () => {
  1302. let val = baseFormData.validityDuration;
  1303. if (val == 0) {
  1304. val = "";
  1305. } else if(val > lotteryMaxHourDuration) {
  1306. val = lotteryMaxHourDuration+'';
  1307. }
  1308. val = val.replace(/[^\d]/g, "");
  1309. baseFormData.validityDuration = val;
  1310. setInputErrorMsg();
  1311. return val;
  1312. }
  1313. const onValidityDurationBlur = () => {
  1314. let val = baseFormData.validityDuration;
  1315. if (val == 0) {
  1316. val = "";
  1317. } else if(val > lotteryMaxHourDuration) {
  1318. val = lotteryMaxHourDuration+'';
  1319. }
  1320. val = val.replace(/[^\d]/g, "");
  1321. baseFormData.validityDuration = val;
  1322. setInputErrorMsg();
  1323. return val;
  1324. }
  1325. /**
  1326. * 金额输入失焦
  1327. */
  1328. const onAmountBlur = () => {
  1329. setInputErrorMsg({from: 'amount', type:'blur'});
  1330. };
  1331. /**
  1332. * count失焦,校验输入结果
  1333. */
  1334. const onCountBlur = () => {
  1335. setInputErrorMsg({from: 'count', type:'blur'});
  1336. };
  1337. /**
  1338. * 输入结果金额和数量 (金额/数量)是否小于最小货币单位
  1339. */
  1340. const calcIptValue = (cb) => {
  1341. let amountValue = baseFormData.amountValue;
  1342. let totalCount = baseFormData.totalCount;
  1343. let flag = true;
  1344. if (!amountValue || !totalCount) {
  1345. return {
  1346. flag
  1347. };
  1348. }
  1349. if (math.format(math.evaluate(`${baseFormData.amountValue} / ${baseFormData.totalCount}`)) < +currentCurrencyInfo.value.minAmount) {
  1350. flag = false;
  1351. }
  1352. return {
  1353. flag,
  1354. count: Math.floor(math.format(math.evaluate(`${baseFormData.amountValue} / ${currentCurrencyInfo.value.minAmount}`)))
  1355. }
  1356. };
  1357. /**
  1358. * 设置输入提示语
  1359. */
  1360. const setInputErrorMsg = () => {
  1361. onIptSetErrorTxt();
  1362. };
  1363. /**
  1364. * 输入时 检测设置错误信息
  1365. */
  1366. const onIptSetErrorTxt = (params = {}) => {
  1367. if((baseFormData.rewardType === RewardType.money && !currentCurrencyInfo.value.currencyCode)
  1368. || (baseFormData.rewardType === RewardType.custom && !baseFormData.customizedReward)) {
  1369. iptErrMsgTxt.value = "Select a reward"
  1370. } else if (!baseFormData.amountValue || baseFormData.amountValue == '0') {
  1371. iptErrMsgTxt.value = "Enter an amount";
  1372. } else if (!baseFormData.totalCount || baseFormData.totalCount == '0') {
  1373. iptErrMsgTxt.value = "Enter the number of winners";
  1374. } else if(baseFormData.rewardType === RewardType.money && +baseFormData.amountValue <= +currentCurrencyInfo.value.balance) {
  1375. // 输入金额 小于 余额
  1376. let res = calcIptValue();
  1377. if (!res.flag) {
  1378. iptErrMsgTxt.value = `${baseFormData.amountValue} ${currentCurrencyInfo.value.tokenSymbol} Can send up to ${res.count} winners`;
  1379. } else {
  1380. if(baseFormData.type == 2 && !baseFormData.validityDuration) {
  1381. iptErrMsgTxt.value = "Enter Automatically Draw";
  1382. } else {
  1383. //清空错误提示
  1384. iptErrMsgTxt.value = "";
  1385. if(params.actionType != 'discord_blur') {
  1386. setDiscordErrTxt({getDuildId: true});
  1387. }
  1388. }
  1389. }
  1390. } else if(baseFormData.type == 2 && !baseFormData.validityDuration) {
  1391. // 抽奖模式 没有输入时长
  1392. iptErrMsgTxt.value = "Enter Automatically Draw";
  1393. } else {
  1394. setDiscordErrTxt({getDuildId: true}, () => {
  1395. iptErrMsgTxt.value = '';
  1396. });
  1397. }
  1398. }
  1399. /**
  1400. * 监听开关触发事件
  1401. */
  1402. const formSwitchChange = (val, params, index) => {
  1403. closeDiscordTask(val, params, index);
  1404. }
  1405. const hideTask = (params, index) => {
  1406. formList[index]['checked'] = false;
  1407. formList[index]['show'] = false;
  1408. closeDiscordTask(false, {type: 7}, index)
  1409. }
  1410. const clickDropdown = (params, index) => {
  1411. formList[index]['show'] = true;
  1412. formList[index]['checked'] = true;
  1413. }
  1414. const closeDiscordTask = (val, params, index) => {
  1415. if(params.type == 7) {
  1416. if(!val) {
  1417. //错误类型 discord 清空discord错误校验
  1418. if(iptErrType == 'discord') {
  1419. iptErrMsgTxt.value = '';
  1420. formList[index]['text'] = '';
  1421. onIptSetErrorTxt();
  1422. }
  1423. } else {
  1424. onIptSetErrorTxt();
  1425. }
  1426. }
  1427. }
  1428. /** 监听 discord 输入 */
  1429. const onIptDiscordAddress = (e, index) => {
  1430. let val = formList[index].text;
  1431. let checked = formList[index].checked;
  1432. if(val && !checked) {
  1433. checked = true;
  1434. formList[index].checked = checked;
  1435. formList[index].text = formList[index].text.replace(/\s/g,'');
  1436. } else if(!val){
  1437. discordInviteInfo.value = {};
  1438. }
  1439. onIptDiscordDebounce()
  1440. }
  1441. const onBlurDiscordAddress = (e, index) => {
  1442. setDiscordErrTxt({fromType: 'discord', showPop: false, actionType: 'discord_blur'});
  1443. }
  1444. const getDiscordIptData = () => {
  1445. let discordItem = formList.find(item => item.type == 7);
  1446. return discordItem;
  1447. }
  1448. /**
  1449. * 设置输入discord错误提示信息
  1450. */
  1451. const setDiscordErrTxt = (params = {showPop: false}, cb) => {
  1452. let discordData = getDiscordIptData() || {};
  1453. if(discordData.checked) {
  1454. if(discordData.text) {
  1455. let validata = checkInviteUrl(discordData.text);
  1456. if(validata) {
  1457. getDiscordInviteInfo({inviteUrl: discordData.text, getDuildId: params.getDuildId}, (res) => {
  1458. console.log('discordData',res)
  1459. // 未知的邀请链接
  1460. if(res.inviteCode != res.data.code || !res.data.guildId) {
  1461. iptErrMsgTxt.value = discordIptErrTxt;
  1462. iptErrType = 'discord';
  1463. } else {
  1464. if(res.data.expires !== null) {
  1465. // 不是永久邀请链接
  1466. iptErrMsgTxt.value = discordIptNerverExpiresErrTxt;
  1467. iptErrType = '';
  1468. } else {
  1469. if(iptErrMsgTxt.value) {
  1470. iptErrMsgTxt.value = '';
  1471. iptErrType = '';
  1472. }
  1473. if(params.showPop && res.data) {
  1474. showDiscordInvitePop.value = true;
  1475. setTimeout(() => {
  1476. showDiscordInvitePop.value = false;
  1477. }, 2000)
  1478. }
  1479. if(params.fromType == 'discord') {
  1480. onIptSetErrorTxt();
  1481. }
  1482. }
  1483. }
  1484. cb && cb(res)
  1485. })
  1486. } else {
  1487. iptErrMsgTxt.value = discordIptErrTxt;
  1488. iptErrType = 'discord';
  1489. }
  1490. } else {
  1491. if(params.actionType == 'discord_blur') {
  1492. onIptSetErrorTxt({acitonType: 'discord_blur'});
  1493. } else {
  1494. // 设置空提示
  1495. iptErrMsgTxt.value = discordIptEmptyErrTxt;
  1496. iptErrType = 'discord';
  1497. }
  1498. }
  1499. } else {
  1500. cb && cb();
  1501. }
  1502. }
  1503. const onIptDiscordDebounce = debounce(function() {
  1504. setDiscordErrTxt({fromType: 'discord', showPop: true});
  1505. }, 800)
  1506. /**
  1507. * 校验 discord邀请url
  1508. */
  1509. const checkInviteUrl = (inviteUrl) => {
  1510. let flag = false;
  1511. const INVITE_URL_PREFIX_1 = 'https://discord.gg/';
  1512. const INVITE_URL_PREFIX_2 = 'https://discord.com/invite/';
  1513. const INVITE_URL_PREFIX_3 = 'http://discord.gg/';
  1514. const INVITE_URL_PREFIX_4 = 'http://discord.com/invite/';
  1515. const INVITE_URL_PREFIX_5 = 'discord.gg/';
  1516. const INVITE_URL_PREFIX_6 = 'discord.com/invite/';
  1517. const arr = [INVITE_URL_PREFIX_1, INVITE_URL_PREFIX_2, INVITE_URL_PREFIX_3, INVITE_URL_PREFIX_4, INVITE_URL_PREFIX_5, INVITE_URL_PREFIX_6]
  1518. if(inviteUrl) {
  1519. if(arr.indexOf(inviteUrl) > -1) {
  1520. flag = false;
  1521. } else {
  1522. let isPass = false;
  1523. for(let i = 0; i < arr.length; i++) {
  1524. let item = arr[i];
  1525. if(inviteUrl.startsWith(item)) {
  1526. isPass = true;
  1527. break;
  1528. }
  1529. }
  1530. flag = isPass;
  1531. }
  1532. }
  1533. return flag;
  1534. }
  1535. /**获取discord 邀请信息 */
  1536. const getDiscordInviteInfo = ({inviteUrl, getDuildId}, cb) => {
  1537. if(!inviteUrl) return;
  1538. let inviteCode = '';
  1539. let arr = inviteUrl.split('/');
  1540. if(arr.length > 0) {
  1541. inviteCode = arr[arr.length - 1];
  1542. }
  1543. if(!getDuildId && discordInviteInfo.value.guildId && discordInviteInfo.value.inviteCode == inviteCode) {
  1544. return;
  1545. }
  1546. getInviteGuildInfo({
  1547. inviteCode
  1548. }).then(res => {
  1549. let resData = inviteGuildResHandler(res, {inviteCode, inviteUrl});
  1550. if(resData.data.guildId) {
  1551. cb && cb(resData);
  1552. } else {
  1553. //DISCORD 接口未获取到服务器信息 resdata
  1554. Report.reportLog({
  1555. pageSource: Report.pageSource.publisherDialog,
  1556. businessType: Report.businessType.buttonClick,
  1557. objectType: Report.objectType.getDiscordGuildNoData
  1558. }, {
  1559. resData: resData
  1560. });
  1561. getGuildInfoByOpenApi({inviteCode}, cb);
  1562. }
  1563. }).catch((err) => {
  1564. //DISCORD 接口 catch
  1565. Report.reportLog({
  1566. pageSource: Report.pageSource.publisherDialog,
  1567. businessType: Report.businessType.buttonClick,
  1568. objectType: Report.objectType.getDiscordGuildCatch
  1569. }, {
  1570. err: err
  1571. });
  1572. let errMsg = err;
  1573. if(typeof errMsg == 'object') {
  1574. errMsg = JSON.stringify(err);
  1575. }
  1576. if(errMsg.indexOf('code 404') > -1) {
  1577. discordInviteInfo.value = {};
  1578. iptErrMsgTxt.value = discordIptErrTxt;
  1579. } else {
  1580. getGuildInfoByOpenApi({inviteCode}, cb);
  1581. }
  1582. });
  1583. }
  1584. const getGuildInfoByOpenApi = (params, cb) => {
  1585. let { inviteCode } = params;
  1586. getInviteGuildInfoByOpenApi({
  1587. inviteCode
  1588. }).then(res => {
  1589. let resData = inviteGuildResHandler(res, {inviteCode, inviteUrl});
  1590. if(resData.data.guildId) {
  1591. cb && cb(resData);
  1592. } else {
  1593. //OPENAPI 接口未获取到服务器信息 resdata
  1594. Report.reportLog({
  1595. pageSource: Report.pageSource.publisherDialog,
  1596. businessType: Report.businessType.buttonClick,
  1597. objectType: Report.objectType.getDiscordGuildOpenApiNoData
  1598. }, {
  1599. resData: resData
  1600. });
  1601. }
  1602. }).catch((err) => {
  1603. // OPENAPI 接口 catch 限频
  1604. Report.reportLog({
  1605. pageSource: Report.pageSource.publisherDialog,
  1606. businessType: Report.businessType.buttonClick,
  1607. objectType: Report.objectType.getDiscordGuildOpenApiCatch
  1608. }, {
  1609. err: err
  1610. });
  1611. if(iptErrMsgTxt.value && iptErrType == 'discord') {
  1612. iptErrMsgTxt.value = '';
  1613. iptErrType = '';
  1614. }
  1615. });
  1616. }
  1617. const inviteGuildResHandler = (res, params) => {
  1618. let {inviteCode, inviteUrl} = params;
  1619. if(!res) {
  1620. res = {};
  1621. }
  1622. let {name, icon, id} = res.guild || {};
  1623. icon = icon && id ? `https://cdn.discordapp.com/icons/${id}/${icon}.png` : '';
  1624. let resData = {
  1625. inviteCode,
  1626. data: {
  1627. code: res.code,
  1628. guildId: id,
  1629. inviteUrl,
  1630. inviteCode,
  1631. expires: res.expires_at,
  1632. name,
  1633. icon,
  1634. }
  1635. }
  1636. if(res.code == inviteCode) {
  1637. discordInviteInfo.value = resData.data;
  1638. } else {
  1639. discordInviteInfo.value = {};
  1640. iptErrMsgTxt.value = discordIptErrTxt;
  1641. }
  1642. return resData;
  1643. };
  1644. /**
  1645. * 获取支付配置(paypalClientId)
  1646. */
  1647. const setPayConfig = () => {
  1648. getPayConfig({
  1649. params: {},
  1650. }).then((res) => {
  1651. if (res.code == 0) {
  1652. payConfig.value = res.data;
  1653. paypalClientId.value = res.data.paypalClientId;
  1654. }
  1655. });
  1656. };
  1657. /**
  1658. * 获取配置
  1659. */
  1660. const setFrontConfig = () => {
  1661. getFrontConfig({
  1662. params: {},
  1663. }).then((res) => {
  1664. if (res.code == 0) {
  1665. paypalHtml.value = res.data.paypalHtml;
  1666. lotteryMaxHourDuration = res.data.lotteryMaxHourDuration;
  1667. toolBoxPageData.postEditorLinkInputDescImage = res.data.postEditorLinkInputDescImage;
  1668. }
  1669. });
  1670. };
  1671. const goTransactionsList = () => {
  1672. window.open(`${chrome.runtime.getURL('/iframe/home.html#/transactions')}`)
  1673. }
  1674. /**
  1675. * 默认获取上次选中的货币信息
  1676. */
  1677. const getLocalCurrencyInfoByCode = () => {
  1678. if(!currentCurrencyInfo.value.currencyCode) {
  1679. getCurrencyInfo();
  1680. }
  1681. }
  1682. const getCurrencyInfo = async (_params) => {
  1683. let { loop = false} = _params || {};
  1684. let {accessToken = ''} = await getChromeStorage('userInfo') || {};
  1685. if (accessToken) {
  1686. getChromeStorage('selectCurrencyInfo', (res) => {
  1687. if(res && res.currencyCode) {
  1688. getCurrencyInfoByCode({
  1689. params: {
  1690. currencyCode: res.currencyCode
  1691. }
  1692. }).then(res => {
  1693. if(res.code == 0 && res.data) {
  1694. currentCurrencyInfo.value = res.data;
  1695. tempCurrentCurrencyInfo.value = res.data;
  1696. if(!loop) {
  1697. onIptSetErrorTxt();
  1698. }
  1699. }
  1700. });
  1701. }
  1702. })
  1703. getChromeStorage('selectCurrencyList', (res) => {
  1704. if (showCurrencySelect.value === false) {
  1705. tempCurrentCurrencyList.value = res;
  1706. }
  1707. })
  1708. }
  1709. }
  1710. const selectPublishMode = (params, index) => {
  1711. selectModeInfo.index = index;
  1712. selectModeInfo.type = params.type;
  1713. baseFormData.type = params.type;
  1714. setInputErrorMsg();
  1715. }
  1716. const clickLeftTab = (params, index) => {
  1717. publishType.value = params.type;
  1718. }
  1719. const onToolBoxPageChange = (params) => {
  1720. toolBoxPageData.activePage = params.page;
  1721. };
  1722. const toolBoxPublishFinish = (params) => {
  1723. toolBoxPageData.activePage = 'EDITOR';
  1724. emits("postPublishFinish", { publishRes: params.publishRes });
  1725. }
  1726. // 截图相关
  1727. const showDialog = () => {
  1728. cropperDialog.value = true;
  1729. }
  1730. const hiddenDialog = () => {
  1731. cropperDialog.value = false;
  1732. cropperLoading.value = false;
  1733. }
  1734. const selectImage = (option) => {
  1735. // 设置图片
  1736. cropperOption.value.img = option.file
  1737. // 选取比例
  1738. if (option && option.type && option.type == 2) {
  1739. cropperType.value = 'after';
  1740. cropperOption.value.fixedNumber = [1, 1];
  1741. } else {
  1742. cropperType.value = 'before';
  1743. cropperOption.value.fixedNumber = [16, 8.396];
  1744. }
  1745. nextTick(() => {
  1746. showDialog()
  1747. })
  1748. }
  1749. const confirmImage = () => {
  1750. let contentType = 'image/png';
  1751. cropperLoading.value = true;
  1752. if (refCropper.value) {
  1753. refCropper.value.getCropBlob(imgData => {
  1754. uploadSignature({
  1755. params: {
  1756. bizType: 1,
  1757. fileType: 1,
  1758. contentType: contentType,
  1759. fileSuffix: 'png',
  1760. }
  1761. }).then(res => {
  1762. let { code, data } = res;
  1763. if (code === 0) {
  1764. let reader = new FileReader()
  1765. reader.readAsArrayBuffer(imgData)
  1766. reader.onload = function(e) {
  1767. let execFile = e.target.result;
  1768. uploadFile({
  1769. url: data.url,
  1770. data: new Blob([execFile]),
  1771. headers: {
  1772. 'Authorization': data.authorization,
  1773. 'x-amz-date': data.date,
  1774. 'Content-Type': contentType
  1775. }
  1776. }).then(res => {
  1777. let { status } = res
  1778. if (status == 200) {
  1779. successImage(data)
  1780. }
  1781. }).finally(() => {
  1782. cropperLoading.value = false;
  1783. })
  1784. }
  1785. }
  1786. })
  1787. })
  1788. }
  1789. }
  1790. const successImage = (data) => {
  1791. hiddenDialog()
  1792. // setPosterInfo
  1793. customPosterInfo.value[cropperType.value] = data;
  1794. }
  1795. const confirmData = (data) => {
  1796. close()
  1797. customPosterData.value = customPosterInfo.value;
  1798. }
  1799. /**
  1800. * 显示通用奖品名称编辑框
  1801. */
  1802. const addCustomizedRewardHandle = () => {
  1803. showCurrencyPop.value = false;
  1804. showCustomizedRewardEditPopup.value = true;
  1805. }
  1806. const closeRewardPopup = () => {
  1807. showCustomizedRewardEditPopup.value = false;
  1808. }
  1809. const removeReward = () => {
  1810. showCustomizedRewardEditPopup.value = false;
  1811. resetFormIpt(false);
  1812. onIptSetErrorTxt();
  1813. }
  1814. // 提交通用奖品
  1815. const submitReward = (reward) => {
  1816. if(baseFormData.customizedReward !== reward) {
  1817. // 有修改时,重置之前已提交的数据
  1818. resetFormIpt(false);
  1819. }
  1820. baseFormData.rewardType = RewardType.custom;
  1821. baseFormData.customizedReward = reward;
  1822. showCustomizedRewardEditPopup.value = false;
  1823. currentCurrencyInfo.value = defaultCurrentCurrencyInfo;
  1824. setLocalSelectCurrencyInfo(defaultCurrentCurrencyInfo);
  1825. onIptSetErrorTxt();
  1826. }
  1827. onMounted(() => {
  1828. setFrontConfig();
  1829. setPayConfig();
  1830. getLocalCurrencyInfoByCode();
  1831. window.addEventListener('resize', function () {
  1832. setDialogStyle(true);
  1833. })
  1834. // showNewImage
  1835. getChromeStorage('custom_poster_guide', (info) => {
  1836. if (!info) {
  1837. customShowNewImage.value = true
  1838. }
  1839. })
  1840. });
  1841. </script>
  1842. <style lang="scss" scoped>
  1843. :deep() .ant-switch {
  1844. background-color: #E9ECEE;
  1845. height: 14px;
  1846. line-height: 16px;
  1847. min-width: 36px;
  1848. }
  1849. :deep() .ant-switch-checked {
  1850. background-color: #AED8F5 !important;
  1851. }
  1852. :deep() .ant-switch::after {
  1853. width: 20px;
  1854. height: 20px;
  1855. top: -4px;
  1856. left: -1px;
  1857. }
  1858. :deep() .ant-switch-checked::after {
  1859. background-color: #1D9BF0 !important;
  1860. margin-left: 3px;
  1861. left: 100% !important;
  1862. }
  1863. .overlay {
  1864. position: fixed;
  1865. top: 0;
  1866. right: 0;
  1867. bottom: 0;
  1868. left: 0;
  1869. z-index: 1000;
  1870. width: 100%;
  1871. height: 100%;
  1872. background-color: rgba(0, 0, 0, 0.5);
  1873. overflow: auto;
  1874. .content {
  1875. height: 620px;
  1876. background: #ffffff;
  1877. border-radius: 20px;
  1878. position: absolute;
  1879. left: 50%;
  1880. top: 50%;
  1881. transform: translate(-50%, -50%);
  1882. box-sizing: border-box;
  1883. z-index: 2000;
  1884. max-height: 825px;
  1885. .pop-mask {
  1886. width: 100%;
  1887. height:100%;
  1888. position: absolute;
  1889. z-index:900;
  1890. }
  1891. .head {
  1892. border-bottom: 1px solid #ececec;
  1893. height: 48px;
  1894. box-sizing: border-box;
  1895. display: flex;
  1896. align-items: center;
  1897. justify-content: space-between;
  1898. padding: 0 14px;
  1899. .left {
  1900. display: flex;
  1901. align-items: center;
  1902. .title {
  1903. font-size: 16px;
  1904. font-weight: 500;
  1905. }
  1906. .close-btn {
  1907. display: flex;
  1908. align-items: center;
  1909. width: max-content;
  1910. margin-right: 12px;
  1911. cursor: pointer;
  1912. }
  1913. }
  1914. .right {
  1915. .more {
  1916. cursor: pointer;
  1917. }
  1918. .area-option {
  1919. width: 100%;
  1920. height: 100%;
  1921. position: absolute;
  1922. top: 0;
  1923. left: 0;
  1924. z-index: 111;
  1925. .option {
  1926. position: absolute;
  1927. top: 43px;
  1928. right: 15px;
  1929. background: #fff;
  1930. filter: drop-shadow(0px 3px 20px rgba(0, 0, 0, 0.2));
  1931. width: 240px;
  1932. border-radius: 15px;
  1933. overflow: hidden;
  1934. .item {
  1935. width: 100%;
  1936. height: 50px;
  1937. display: flex;
  1938. align-items: center;
  1939. cursor: pointer;
  1940. border-top: 1px solid #E9E9E9;
  1941. img {
  1942. margin-left: 15px;
  1943. width: 30px;
  1944. height: 30px;
  1945. margin-right: 6px;
  1946. }
  1947. span {
  1948. font-weight: 500;
  1949. font-size: 14px;
  1950. }
  1951. }
  1952. .item:first-child {
  1953. border-top: 0;
  1954. }
  1955. .item:hover {
  1956. background: #F5F5F5;
  1957. }
  1958. }
  1959. }
  1960. }
  1961. }
  1962. .body {
  1963. box-sizing: border-box;
  1964. height: calc(100% - 48px);
  1965. display: flex;
  1966. position: relative;
  1967. .body-content {
  1968. display:flex;
  1969. width:100%;
  1970. }
  1971. .currency-pop {
  1972. position: absolute;
  1973. width: 375px;
  1974. height: 480px;
  1975. top: 85px;
  1976. left: 88px;
  1977. z-index: 1000;
  1978. box-shadow: 0px 4px 30px rgba(0, 0, 0, 0.3);
  1979. background-color: #fff;
  1980. border-radius: 20px;
  1981. overflow-y: auto;
  1982. }
  1983. .currency-pop-select {
  1984. position: absolute;
  1985. width: 375px;
  1986. max-height: 480px;
  1987. top: 85px;
  1988. left: 88px;
  1989. z-index: 1000;
  1990. box-shadow: 0px 4px 30px rgba(0, 0, 0, 0.3);
  1991. background-color: #fff;
  1992. border-radius: 20px;
  1993. overflow-y: scroll;
  1994. }
  1995. .left,
  1996. .right {
  1997. height: 100%;
  1998. }
  1999. .left {
  2000. width: 50px;
  2001. display: flex;
  2002. flex-direction: column;
  2003. align-items: center;
  2004. .tab-item {
  2005. width: 100%;
  2006. height: 55px;
  2007. display: flex;
  2008. align-items: center;
  2009. justify-content: center;
  2010. cursor: pointer;
  2011. }
  2012. .active-tab {
  2013. background-color: #D2EAFC;
  2014. }
  2015. .bottom {
  2016. .icon {
  2017. display: block;
  2018. margin-bottom: 26px;
  2019. }
  2020. }
  2021. }
  2022. .right {
  2023. width: calc(100% - 50px);
  2024. box-sizing: border-box;
  2025. position: relative;
  2026. border-left: 1px solid #ececec;
  2027. .form-wrapper {
  2028. padding: 18px 18px 18px 18px;
  2029. height: calc(100% - 80px);
  2030. overflow: auto;
  2031. box-sizing: border-box;
  2032. display: flex;
  2033. .task-wrapper {
  2034. width: 480px;
  2035. }
  2036. .form-cell-item {
  2037. height: 100%;
  2038. .title {
  2039. display: flex;
  2040. align-items: center;
  2041. font-weight: 500;
  2042. font-size: 15px;
  2043. .icon {
  2044. width: 20px;
  2045. height: 20px;
  2046. margin-right: 5px;
  2047. }
  2048. }
  2049. .form-cell-content {
  2050. margin-top: 12px;
  2051. box-sizing: border-box;
  2052. }
  2053. }
  2054. .base-form-wrapper {
  2055. width: 450px;
  2056. margin-right: 30px;
  2057. .form-cell-content {
  2058. .select-mode-ele {
  2059. display: flex;
  2060. cursor: pointer;
  2061. img:first-child {
  2062. margin-right: 10px;
  2063. }
  2064. img {
  2065. -webkit-user-drag: none;
  2066. width: 220px;
  2067. height: 90px;
  2068. }
  2069. }
  2070. .form-base {
  2071. margin-top: 20px;
  2072. border: 1px solid #D1D9DD;
  2073. border-radius: 14px;
  2074. box-sizing: border-box;
  2075. padding-left: 14px;
  2076. .item {
  2077. box-sizing: border-box;
  2078. padding: 7px 0;
  2079. min-height: 76px;
  2080. display: flex;
  2081. align-items: center;
  2082. justify-content: space-between;
  2083. input {
  2084. width: 178px;
  2085. text-align: right;
  2086. font-weight: 700;
  2087. font-size: 26px;
  2088. border: none;
  2089. outline: none;
  2090. box-sizing: border-box;
  2091. }
  2092. input::placeholder {
  2093. color: #c5c5c5;
  2094. }
  2095. input:disabled {
  2096. color: #c5c5c5;
  2097. background-color: #fff;
  2098. }
  2099. input {
  2100. padding-right: 16px;
  2101. }
  2102. .label {
  2103. font-weight: 500;
  2104. font-size: 15px;
  2105. display: flex;
  2106. align-items: center;
  2107. .icon {
  2108. width: 20px;
  2109. height: 20px;
  2110. margin-right: 8px;
  2111. }
  2112. }
  2113. }
  2114. .currency-select-wrapper {
  2115. overflow: hidden;
  2116. .currency-select {
  2117. cursor: pointer;
  2118. background: #1D9BF0;
  2119. padding: 6px 10px;
  2120. border-radius: 12px;
  2121. color: #fff;
  2122. width: max-content;
  2123. max-width: 234px;
  2124. .text {
  2125. word-break: break-all;
  2126. }
  2127. .arrow {
  2128. margin-left: 5px;
  2129. }
  2130. }
  2131. .selected {
  2132. background: #F4F4F4 !important;
  2133. color: #000 !important;
  2134. }
  2135. }
  2136. .winners-count-input {
  2137. border-top: 1px solid #D1D9DD;
  2138. .msg {
  2139. font-weight: 400;
  2140. font-size: 12px;
  2141. color: #A39F9F;
  2142. margin-top: 8px
  2143. }
  2144. }
  2145. .automatically-input {
  2146. border-top: 1px solid #D1D9DD;
  2147. .input-wrapper {
  2148. margin-right: 16px;
  2149. box-sizing: border-box;
  2150. input {
  2151. padding-right: 4px !important;
  2152. }
  2153. .unit {
  2154. font-weight: 700;
  2155. font-size: 26px;
  2156. opacity: 0.5;
  2157. }
  2158. }
  2159. }
  2160. }
  2161. }
  2162. }
  2163. .currency-operation {
  2164. position: relative;
  2165. box-sizing: border-box;
  2166. display: flex;
  2167. align-items: center;
  2168. margin-top: 8px;
  2169. .balance,
  2170. .amount {
  2171. display: flex;
  2172. align-items: center;
  2173. }
  2174. .amount {
  2175. font-weight: 400;
  2176. font-size: 12px;
  2177. color: #A39F9F;
  2178. img {
  2179. margin-left: 6px;
  2180. cursor: pointer;
  2181. }
  2182. }
  2183. .top-up {
  2184. font-weight: 500;
  2185. font-size: 12px;
  2186. color: #1D9BF0;
  2187. cursor: pointer;
  2188. margin-left: 4px;
  2189. }
  2190. }
  2191. .form-label {
  2192. margin-top: 14px;
  2193. margin-bottom: 10px;
  2194. font-weight: 500;
  2195. font-size: 14px;
  2196. display: flex;
  2197. align-items: center;
  2198. justify-content: space-between;
  2199. .icon-add-task {
  2200. cursor: pointer;
  2201. }
  2202. }
  2203. .form-require {
  2204. box-sizing: border-box;
  2205. border-radius: 15px;
  2206. border: 1px solid #D1D9DD;
  2207. .form-item {
  2208. min-height: 54px;
  2209. display: flex;
  2210. align-items: center;
  2211. justify-content: space-between;
  2212. margin: 0 16px;
  2213. border-bottom: 1px solid #ececec;
  2214. padding: 8px 0;
  2215. box-sizing: border-box;
  2216. .item-left {
  2217. display: flex;
  2218. }
  2219. .label {
  2220. min-width: 76px;
  2221. display: flex;
  2222. align-items: center;
  2223. font-size: 15px;
  2224. font-weight: 500;
  2225. .icon {
  2226. margin-right: 10px;
  2227. }
  2228. }
  2229. .control {
  2230. min-width: 258px;
  2231. margin-left: 6px;
  2232. box-sizing: border-box;
  2233. position: relative;
  2234. .discord-address {
  2235. border: none;
  2236. outline: none;
  2237. color: #1D9BF0;
  2238. font-weight: 500;
  2239. font-size: 14px;
  2240. width: 100%;
  2241. height: 34px;
  2242. padding-left: 15px;
  2243. }
  2244. .discord-address::placeholder {
  2245. color: #c5c5c5;
  2246. }
  2247. .discord-invite-info {
  2248. position: absolute;
  2249. top: 40px;
  2250. left: 0;
  2251. box-shadow: 0px 4px 30px rgba(0, 0, 0, 0.3);
  2252. background: #fff;
  2253. border-radius: 16px;
  2254. padding: 16px;
  2255. box-sizing: border-box;
  2256. display: flex;
  2257. align-items: center;
  2258. cursor: pointer;
  2259. .icon {
  2260. width: 40px;
  2261. height: 40px;
  2262. margin-right: 10px;
  2263. border-radius: 50%;
  2264. }
  2265. .name {
  2266. font-weight: 600;
  2267. font-size: 16px;
  2268. color: #101419;
  2269. width: 193px;
  2270. height: 20px;
  2271. overflow: hidden;
  2272. white-space: nowrap;
  2273. text-overflow: ellipsis;
  2274. display: inline-block;
  2275. }
  2276. }
  2277. }
  2278. .icon-task-close {
  2279. margin-left: 6px;
  2280. cursor: pointer;
  2281. }
  2282. }
  2283. .border-hide {
  2284. border-bottom: none !important;
  2285. }
  2286. }
  2287. }
  2288. .giveaway-poster {
  2289. display: flex;
  2290. align-items: center;
  2291. flex-direction: row;
  2292. cursor: pointer;
  2293. height: 84px;
  2294. margin-top: 20px;
  2295. border-radius: 14px;
  2296. border: 1px solid #D1D9DD;
  2297. .show-img {
  2298. display: flex;
  2299. align-items: center;
  2300. justify-content: center;
  2301. width: 45px;
  2302. height: 60px;
  2303. margin-left: 14px;
  2304. margin-right: 14px;
  2305. position: relative;
  2306. }
  2307. .show-font {
  2308. position: relative;
  2309. font-size: 15px;
  2310. font-weight: 500;
  2311. .new {
  2312. width: 40px;
  2313. height: 18px;
  2314. margin-left: 10px;
  2315. }
  2316. }
  2317. .show-placeholder {
  2318. flex: 1;
  2319. color: #1D9BF0;
  2320. font-size: 15px;
  2321. font-weight: 500;
  2322. text-align: right;
  2323. }
  2324. .arrow {
  2325. width: 18px;
  2326. height: 24px;
  2327. margin-left: 2px;
  2328. margin-right: 12px;
  2329. }
  2330. }
  2331. .tips-wrapper {
  2332. margin: 16px 0 0 12px !important;
  2333. padding: 0px !important;
  2334. .title,
  2335. .row {
  2336. font-weight: 400;
  2337. font-size: 12px;
  2338. color: #A39F9F;
  2339. }
  2340. .row {
  2341. box-sizing: border-box;
  2342. line-height: 16px;
  2343. }
  2344. }
  2345. .submit-btn-wrapper {
  2346. width: 100%;
  2347. background: #fff;
  2348. position: absolute;
  2349. bottom: 18px;
  2350. left: 0;
  2351. box-sizing: border-box;
  2352. padding: 16px 18px 0 18px;
  2353. .submit-btn {
  2354. width: 100%;
  2355. height: 46px;
  2356. text-align: center;
  2357. background: #4a99e9;
  2358. border-radius: 100px;
  2359. color: #fff;
  2360. display: flex;
  2361. align-items: center;
  2362. justify-content: center;
  2363. font-size: 16px;
  2364. font-weight: 500;
  2365. cursor: pointer;
  2366. .icon-loading {
  2367. width: 20px;
  2368. height: 20px;
  2369. margin-right: 3px;
  2370. }
  2371. }
  2372. .disabled-submit {
  2373. background-color: #D9D9D9;
  2374. }
  2375. }
  2376. }
  2377. .fill-right {
  2378. width: 100% !important;
  2379. border-bottom-left-radius: 16px;
  2380. }
  2381. }
  2382. }
  2383. }
  2384. .preview {
  2385. padding: 30px 40px;
  2386. height: calc(100% - 80px);
  2387. overflow-y: auto;
  2388. .card {
  2389. float: left;
  2390. width: 480px;
  2391. position: relative;
  2392. .flash {
  2393. overflow: hidden;
  2394. height: 600px;
  2395. border-radius: 26px;
  2396. border: solid 1px #ECECEC;
  2397. }
  2398. &.center {
  2399. margin-left: 50%;
  2400. transform: translateX(-50%);
  2401. }
  2402. }
  2403. .card-title {
  2404. height: 32px;
  2405. .img {
  2406. float: left;
  2407. width: 20px;
  2408. height: 20px;
  2409. margin-right: 8px;
  2410. }
  2411. .font {
  2412. float: left;
  2413. font-size: 17px;
  2414. font-weight: 500;
  2415. span {
  2416. color: #0091e9;
  2417. }
  2418. }
  2419. }
  2420. .card-content {
  2421. float: right;
  2422. width: 500px;
  2423. }
  2424. .card-amount {
  2425. overflow: hidden;
  2426. display: flex;
  2427. height: 80px;
  2428. align-items: center;
  2429. padding: 20px;
  2430. border-radius: 20px;
  2431. border: 1px solid #E6E6E6;
  2432. .icon {
  2433. width: 40px;
  2434. height: 40px;
  2435. }
  2436. .con {
  2437. flex: 1;
  2438. padding: 0 10px;
  2439. .desc {
  2440. color: rgba($color: #000000, $alpha: 0.5);
  2441. font-size: 12px;
  2442. margin-bottom: 4px;
  2443. }
  2444. .price {
  2445. font-size: 16px;
  2446. font-weight: bold;
  2447. word-break: break-all;
  2448. }
  2449. }
  2450. .refresh {
  2451. cursor: pointer;
  2452. width: 30px;
  2453. height: 30px;
  2454. margin-top: -5px;
  2455. }
  2456. }
  2457. .card-list {
  2458. padding: 20px;
  2459. border-radius: 20px;
  2460. border: 1px solid #E6E6E6;
  2461. .item {
  2462. display: flex;
  2463. justify-content: space-between;
  2464. align-items: center;
  2465. height: 47px;
  2466. font-size: 14px;
  2467. font-weight: 500;
  2468. box-shadow: inset 0px -1px 0px #EAEAEA;
  2469. }
  2470. }
  2471. }
  2472. .icon-refresh-rotate {
  2473. transform: rotate(360deg);
  2474. transition-duration: 1s;
  2475. }
  2476. .payment {
  2477. .balance {
  2478. display: flex;
  2479. margin-right: 20px;
  2480. .icon {
  2481. width: 40px;
  2482. height: 40px;
  2483. }
  2484. .con {
  2485. padding: 0 5px;
  2486. .desc {
  2487. color: rgba($color: #000000, $alpha: 0.5);
  2488. font-size: 12px;
  2489. margin-bottom: 4px;
  2490. }
  2491. .price {
  2492. font-size: 14px;
  2493. font-weight: bold;
  2494. word-break: break-all;
  2495. }
  2496. }
  2497. .refresh {
  2498. width: 40px;
  2499. cursor: pointer;
  2500. margin-left: -5px;
  2501. }
  2502. }
  2503. .btn-wrap {
  2504. width: 100%;
  2505. height: 80px;
  2506. background-color: #fff;
  2507. position: absolute;
  2508. left: 0;
  2509. bottom: 0;
  2510. box-shadow: 0px -1px 0px #ececec;
  2511. border-bottom-right-radius: 16px;
  2512. padding: 12px 30px;
  2513. box-sizing: border-box;
  2514. display: flex;
  2515. align-items: center;
  2516. justify-content: flex-end;
  2517. border-bottom-left-radius: 16px;
  2518. z-index: 999;
  2519. .custom-submit {
  2520. width: 200px;
  2521. height: 50px;
  2522. background: #1D9BF0;
  2523. border-radius: 50px;
  2524. font-weight: 700;
  2525. font-size: 18px;
  2526. line-height: 50px;
  2527. text-align: center;
  2528. letter-spacing: 0.3px;
  2529. color: #FFFFFF;
  2530. cursor: pointer;
  2531. }
  2532. }
  2533. }
  2534. .dialog {
  2535. position: absolute;
  2536. z-index: 2002;
  2537. top: 50%;
  2538. left: 50%;
  2539. transform: translate(-50%, -50%);
  2540. width: 800px;
  2541. height: calc(100% - 100px);
  2542. border-radius: 20px;
  2543. background-color: #ffffff;
  2544. .corp-title {
  2545. display: flex;
  2546. height: 48px;
  2547. align-items: center;
  2548. .back {
  2549. cursor: pointer;
  2550. width: 24px;
  2551. height: 24px;
  2552. margin: 0 12px;
  2553. }
  2554. span {
  2555. font-size: 16px;
  2556. font-weight: 500;
  2557. }
  2558. }
  2559. .corp-content {
  2560. width: 472px;
  2561. margin: auto;
  2562. height: calc(100% - 130px);
  2563. }
  2564. .corp-footer {
  2565. display: flex;
  2566. align-items: center;
  2567. justify-content: right;
  2568. height: 80px;
  2569. text-align: right;
  2570. padding-right: 30px;
  2571. .confirm {
  2572. cursor: pointer;
  2573. border: 0;
  2574. width: 200px;
  2575. height: 50px;
  2576. color: #ffffff;
  2577. font-size: 18px;
  2578. font-weight: 700;
  2579. border-radius: 25px;
  2580. background: #1D9BF0;
  2581. &.disable {
  2582. background: #D9D9D9;
  2583. img {
  2584. width: 20px;
  2585. margin-right: 10px;
  2586. }
  2587. }
  2588. }
  2589. }
  2590. }
  2591. .dialog-mask {
  2592. position: absolute;
  2593. z-index: 2001;
  2594. top: 0;
  2595. left: 0;
  2596. width: 100%;
  2597. height: 100%;
  2598. background-color: rgba(0, 0, 0, 0.5);
  2599. }
  2600. :deep() .vue-cropper {
  2601. background-image: none;
  2602. }
  2603. :deep() .cropper-modal {
  2604. background: rgba(0, 0, 0, .05);
  2605. }
  2606. </style>