Step4.vue 89 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665
  1. <style lang="scss">
  2. .chouzhen span {
  3. display: inline-block;
  4. }
  5. .check-video .ant-tabs-nav-container {
  6. text-align: center;
  7. font-size: 20px;
  8. }
  9. .step3-image {
  10. span {
  11. padding: 0;
  12. }
  13. .ant-checkbox {
  14. position: absolute;
  15. top: 0;
  16. left: 0;
  17. z-index: 100;
  18. }
  19. }
  20. .step3-modal {
  21. .ant-checkbox {
  22. position: absolute;
  23. top: 0;
  24. right: 0;
  25. z-index: 100;
  26. }
  27. }
  28. .onlny-click-track {
  29. .ant-list-item-content {
  30. width: 60%;
  31. overflow: hidden;
  32. text-overflow: ellipsis;
  33. white-space: nowrap;
  34. }
  35. }
  36. .step4-else .ant-input,
  37. .with-limit-textarea > .ant-input {
  38. margin-bottom: 20px;
  39. border: none;
  40. box-shadow: none;
  41. }
  42. .step4-else textarea.ant-input {
  43. max-width: 100%;
  44. height: auto;
  45. vertical-align: bottom;
  46. transition: all 0.3s, height 0s;
  47. min-height: 32px;
  48. }
  49. .step4-else textarea {
  50. resize: none;
  51. border: none;
  52. outline: 0;
  53. box-shadow: none;
  54. }
  55. .sticker-styles .ant-checkbox-wrapper + .ant-checkbox-wrapper {
  56. margin-left: 0;
  57. }
  58. .display-none-selset {
  59. display: none !important;
  60. }
  61. </style>
  62. <style scoped lang="scss">
  63. .actor-photo-list {
  64. display: flex;
  65. padding-left: 0;
  66. li {
  67. width: 20%;
  68. margin: 10px;
  69. position: relative;
  70. height: 380px;
  71. border: 1px solid #f2f2f2;
  72. list-style: none;
  73. img,
  74. video {
  75. width: 100%;
  76. }
  77. }
  78. }
  79. .chouzhen {
  80. border-style: solid;
  81. border-width: 1px;
  82. border-color: #e4e4e4;
  83. width: calc(20% - 10px);
  84. padding: 10px;
  85. margin-right: 10px;
  86. margin-bottom: 10px;
  87. display: flex;
  88. align-items: center;
  89. background: #fff;
  90. position: relative;
  91. z-index: 99;
  92. float: left;
  93. }
  94. li.chouzhen.first:before {
  95. font-size: 12px;
  96. content: '首帧';
  97. position: absolute;
  98. top: 7px;
  99. left: 5px;
  100. width: 36px;
  101. height: 20px;
  102. color: rgb(255, 255, 255);
  103. line-height: 20px;
  104. text-align: center;
  105. background: rgba(0, 0, 0, 0.5);
  106. border-radius: 2px;
  107. z-index: 1000;
  108. }
  109. .actor-photo-list {
  110. display: flex;
  111. padding-left: 0;
  112. li {
  113. width: 25%;
  114. margin: 10px;
  115. position: relative;
  116. height: 250px;
  117. border: 1px solid #f2f2f2;
  118. list-style: none;
  119. img,
  120. video {
  121. width: 100%;
  122. margin-top: auto;
  123. margin-bottom: auto;
  124. top: 0;
  125. bottom: 0;
  126. position: absolute;
  127. max-height: 250px;
  128. }
  129. }
  130. }
  131. </style>
  132. <template>
  133. <a-card :body-style="{ padding: '24px 32px' }" :bordered="false" class="only-step3">
  134. <a-tabs style="width: 50%; margin: 0 auto" type="editable-card" hideAdd @edit="remove">
  135. <a-tab-pane
  136. v-for="(pane, bestIndex) in pans"
  137. :tab="pane.tab"
  138. :key="pane.key"
  139. v-model="pansKey"
  140. disabled
  141. :closable="pane.closable"
  142. >
  143. <a-form @submit="handleSubmit" :form="form" style="margin-top: 20px" :hideRequiredMark="true">
  144. <a-form-item label="广告组名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
  145. <a-input v-model="pane.tab" read-only></a-input>
  146. </a-form-item>
  147. <a-form-item label="创意类型" :labelCol="labelCol" :wrapperCol="wrapperCol">
  148. <a-radio-group buttonStyle="solid" default-value="1" disabled>
  149. <a-radio-button value="1">程序化创意</a-radio-button>
  150. </a-radio-group>
  151. </a-form-item>
  152. <a-form-item label="素材类型" :labelCol="labelCol" :wrapperCol="wrapperCol">
  153. <a-radio-group
  154. buttonStyle="solid"
  155. v-decorator="['creativeMaterialType', { initialValue: '1' }]"
  156. @change="changeType(bestIndex)"
  157. >
  158. <a-radio-button value="1">竖版视频</a-radio-button>
  159. <a-radio-button value="2">横版视频</a-radio-button>
  160. </a-radio-group>
  161. ({{ (horizontalPhoto[0].videoList.length+verticalPhoto[0].videoList.length) + '/5' }})
  162. <!-- {{verticalPhoto}}/{{horizontalPhoto}} -->
  163. </a-form-item>
  164. <!-- <a-form-item label="素材同步" :labelCol="labelCol" :wrapperCol="wrapperCol">
  165. </a-form-item>-->
  166. <a-form-item label="创意内容" :labelCol="labelCol" :wrapperCol="wrapperCol">
  167. <a-layout>
  168. <a-layout-content style="padding: 10px">
  169. <!-- <div :style="{ marginBottom: '16px' }" style="float: right">
  170. <a-button @click="addCreative(bestIndex)" :disabled="videoCount >= 5 || listCheck">添加创意</a-button>
  171. </div> -->
  172. <a-row>
  173. <a-col :span="24" v-for="(item, index) of pane.list" :key="index">
  174. <a-card title :ref="item">
  175. <!-- <a-icon
  176. type="close"
  177. style="float: right; cursor: pointer"
  178. @click="deleteCreative(bestIndex, index)"
  179. /> -->
  180. <div style="clear: both"></div>
  181. <div class="dynamically_add_form_item">
  182. <a-form-item label>
  183. <a @click="getVideoList('video', index, item, bestIndex)">选择视频</a>
  184. <!-- <a @click="uploadVideo(index, bestIndex)" style="margin-left: 10px">上传视频</a> -->
  185. <br />
  186. <!-- <video
  187. :src="item.videoList.url"
  188. controls="controls"
  189. style="width: 25%"
  190. v-if="item.videoList"
  191. ></video> -->
  192. <span
  193. v-for="(item, deleteIndex) of item.videoList"
  194. style="position: relative"
  195. :key="deleteIndex"
  196. >
  197. <!-- <video :src="item.url" controls="controls" style="width: 18%; margin: 1%"></video> -->
  198. <img :src="item.coverUrl" style="width: 18%; margin: 1%" :key="item.url" />
  199. <a-icon
  200. type="close-circle"
  201. @click="deleteVideo(index, bestIndex, deleteIndex)"
  202. style="position: absolute; right: 0px"
  203. />
  204. </span>
  205. </a-form-item>
  206. </div>
  207. </a-card>
  208. </a-col>
  209. </a-row>
  210. </a-layout-content>
  211. </a-layout>
  212. </a-form-item>
  213. <a-form-item label="封面" :labelCol="labelCol" :wrapperCol="wrapperCol">
  214. <a-layout>
  215. <a-layout-content style="padding: 10px">
  216. <!-- <div :style="{ marginBottom: '16px' }" style="float: right">
  217. <a-button @click="addCreative(bestIndex)" :disabled="videoCount >= 5 || listCheck">添加创意</a-button>
  218. </div> -->
  219. <a-row>
  220. <a-col :span="24" v-for="(item, index) of pane.imageList" :key="index">
  221. <a-card title :ref="item">
  222. <!-- <a-icon
  223. type="close"
  224. style="float: right; cursor: pointer"
  225. @click="deleteCreative(bestIndex, index)"
  226. /> -->
  227. <div style="clear: both"></div>
  228. <a-form-item label>
  229. <a
  230. @click="getVideoList('image', index, item, bestIndex)"
  231. :disabled="item.imageList.length >= 4"
  232. >选择封面</a
  233. >
  234. <a
  235. @click="uploadImages(index, bestIndex)"
  236. style="margin-left: 10px"
  237. :disabled="item.imageList.length >= 4"
  238. >上传封面</a
  239. >
  240. <a
  241. @click="showImages(index, bestIndex)"
  242. style="margin-left: 10px"
  243. :disabled="item.imageList.length >= 4"
  244. >推荐封面</a
  245. >
  246. <br />
  247. <span v-for="(item, deleteIndex) of item.imageList" style="position: relative">
  248. <img :src="item.url" style="width: 18%; margin: 1%" :key="item.url" />
  249. <a-icon
  250. type="close-circle"
  251. @click="deleteData(index, bestIndex, deleteIndex)"
  252. style="position: absolute; right: 0px"
  253. />
  254. </span>
  255. </a-form-item>
  256. </div>
  257. </a-card>
  258. </a-col>
  259. </a-row>
  260. </a-layout-content>
  261. </a-layout>
  262. </a-form-item>
  263. <a-form-item label="广告语" :labelCol="labelCol" :wrapperCol="wrapperCol" class="step4-else">
  264. <a @click="addCaptions('captionsList')" :disabled="captionsList.length >= 3">添加广告语</a>
  265. ({{ captionsCount + '/3' }})
  266. <a style="margin:0 10px" @click="collection('captionsList')" :disabled="captionsCount==0">收藏</a>
  267. <a @click="showCunTitle('captionsList')">收藏列表</a>
  268. <div
  269. v-for="(item, index) in captionsList"
  270. style="
  271. display: inline-block;
  272. position: relative;
  273. border-radius: 4px;
  274. border: 1px solid #d9d9d9;
  275. width: 95%;
  276. "
  277. :style="{ marginBottom: index == captionsList.length - 1 ? '0px' : '20px' }"
  278. >
  279. <a-textarea
  280. class="rending"
  281. placeholder="请输入广告语"
  282. v-model.trim="item.captions"
  283. :autosize="{ minRows: 2, maxRows: 6 }"
  284. :max-length="30"
  285. ></a-textarea>
  286. <p
  287. style="
  288. font-size: 12px;
  289. color: #b6bbc7;
  290. letter-spacing: 0.3px;
  291. text-align: right;
  292. line-height: 20px;
  293. position: absolute;
  294. bottom: 0;
  295. right: 6px;
  296. width: 100%;
  297. margin-bottom: 0;
  298. "
  299. >
  300. {{ item.captions.length + '/30' }}
  301. </p>
  302. <a-icon
  303. type="delete"
  304. @click="deleteCaptions(index,'captionsList')"
  305. style="position: absolute; bottom: 0; right: -30px"
  306. :style="{ display: captionsList.length == 1 ? 'none' : 'block' }"
  307. />
  308. </div>
  309. </a-form-item>
  310. <!-- stickerStyles -->
  311. <!-- coverSlogansList -->
  312. <!-- {{stickerStyles}} -->
  313. <a-form-item label="封面贴纸" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="stickerStyles.length>0" class="sticker-styles">
  314. <a-checkbox-group v-model="stickerStylesValue">
  315. <a-checkbox v-for="(item,index) in stickerStyles" :key="index" :value="item.id" :disabled="stickerStylesValue.filter(i=>i==item.id).length==0&&stickerStylesValue.length>=6">
  316. <img :src="item.url.overlay_preview_url" alt="" style="width:100px;margin:10px;opacity: 0.5;">
  317. </a-checkbox>
  318. </a-checkbox-group>
  319. </a-form-item>
  320. <a-form-item label="封面广告语" :labelCol="labelCol" :wrapperCol="wrapperCol" class="step4-else" v-if="stickerStyles.length>0">
  321. <a @click="addCaptions('coverSlogansList')" :disabled="coverCount >= 6">添加封面广告语</a>
  322. ({{ coverCount + '/6' }})
  323. <a style="margin:0 10px" @click="collection('coverSlogansList')" :disabled="coverCount==0">收藏</a>
  324. <a @click="showCunTitle('coverSlogansList')">收藏列表</a>
  325. <div
  326. v-for="(item, index) in coverSlogansList"
  327. style="
  328. display: inline-block;
  329. position: relative;
  330. border-radius: 4px;
  331. border: 1px solid #d9d9d9;
  332. width: 95%;
  333. "
  334. :style="{ marginBottom: index == coverSlogansList.length - 1 ? '0px' : '20px' }"
  335. >
  336. <a-textarea
  337. placeholder="请输入封面广告语"
  338. v-model.trim="item.coverSlogans"
  339. :autosize="{ minRows: 2, maxRows: 2 }"
  340. :max-length="14"
  341. ></a-textarea>
  342. <p
  343. style="
  344. font-size: 12px;
  345. color: #b6bbc7;
  346. letter-spacing: 0.3px;
  347. text-align: right;
  348. line-height: 20px;
  349. position: absolute;
  350. bottom: 0;
  351. right: 6px;
  352. width: 100%;
  353. margin-bottom: 0;
  354. "
  355. >
  356. {{ item.coverSlogans.length + '/14' }}
  357. </p>
  358. <a-icon
  359. type="delete"
  360. @click="deleteCaptions(index,'coverSlogansList')"
  361. style="position: absolute; bottom: 0; right: -30px"
  362. :style="{ display: coverSlogansList.length == 1 ? 'none' : 'block' }"
  363. />
  364. </div>
  365. </a-form-item>
  366. <a-form-item label="创意分类" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="creativeCategorySwitch">
  367. <a-cascader
  368. :options="createOptions"
  369. v-decorator="['creativeCategory',{ rules: [{ required: true, message: '创意分类必选' }] }]"
  370. :fieldNames="fieldNames"
  371. placeholder="请选择创意分类"
  372. />
  373. </a-form-item>
  374. <a-form-item label="创意标签" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="creativeCategorySwitch">
  375. <a-select
  376. mode="tags"
  377. style="width: 100%"
  378. placeholder="按回车生成标签"
  379. v-decorator="['creativeTag',{ rules: [{ required: true, message: '创意标签必填' }] }]"
  380. dropdownClassName="display-none-selset"
  381. :token-separators="[',',' ',',']"
  382. >
  383. </a-select>
  384. <span v-if="getData('creativeTag')&&getData('creativeTag').length > 10" style="color:red">创意标签最多填写10个,请删减</span>
  385. <br>
  386. <a-popconfirm @confirm="getInfo(record)">
  387. <div slot="title">
  388. <div>
  389. 分类名称:
  390. <a-input placeholder="请输入" v-model="tagName" style="display: inline-block;width: 300px;" />
  391. </div>
  392. </div>
  393. <!-- <a-button slot="okText" type="primary" :disabled="refuseReason == ''">确定</a-button> -->
  394. <!-- <a @click="setData(record)">复制</a> -->
  395. <a style="margin-right:10px" :disabled="!getData('creativeTag')">收藏</a>
  396. <!-- @click="collection('creativeTag')" -->
  397. </a-popconfirm>
  398. <a @click="showCunTitle('creativeTag')">收藏列表</a>
  399. </a-form-item>
  400. <a-form-item label="行动号召" :labelCol="labelCol" :wrapperCol="wrapperCol">
  401. <a-select
  402. v-decorator="['actionBarText', { rules: [{ required: true, message: '行动号召按钮文案' }] }]"
  403. showSearch
  404. allowClear
  405. placeholder="选择行动号召按钮文案"
  406. optionFilterProp="children"
  407. :filterOption="filterOption"
  408. >
  409. <a-select-option v-for="appModel in appList" :key="appModel.id" :value="appModel.actionBarText">{{
  410. appModel.actionBarText
  411. }}</a-select-option>
  412. </a-select>
  413. </a-form-item>
  414. <a-form-item label="下载详情" v-if="showSite" :labelCol="labelCol" :wrapperCol="wrapperCol">
  415. <a-select
  416. v-decorator="['siteId']"
  417. showSearch
  418. allowClear
  419. placeholder="选择应用下载详情页"
  420. optionFilterProp="children"
  421. :filterOption="filterOption"
  422. >
  423. <a-select-option v-for="appModel in siteList" :key="appModel.siteId" :value="appModel.siteId">{{
  424. appModel.name
  425. }}</a-select-option>
  426. </a-select>
  427. </a-form-item>
  428. <!-- , { validator: handleConfirmValue } -->
  429. <a-form-item label="第三方点击监测链接" :labelCol="labelCol" :wrapperCol="wrapperCol">
  430. <a-input
  431. v-decorator="[
  432. 'clickUrl',
  433. {
  434. rules: [{ message: '请输入第三方点击监测链接' }],
  435. },
  436. ]"
  437. placeholder="请输入第三方点击监测链接"
  438. ></a-input>
  439. <a
  440. v-if="getData('clickUrl')"
  441. @click="
  442. clickTrackUrlShow = true
  443. clickTrackUrlShowType == '1'
  444. "
  445. style="margin-right: 10px"
  446. >收藏监测链接</a
  447. >
  448. <a
  449. @click="
  450. getClickTrackUrlList('1')
  451. clickTrackUrlShowType = '1'
  452. "
  453. >监测链接列表</a
  454. >
  455. </a-form-item>
  456. <!-- , { validator: handleConfirmValue } -->
  457. <a-form-item label="第三方ActionBar点击监控链接" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="actionbarClickUrlSwitch">
  458. <a-input
  459. v-decorator="[
  460. 'actionbarClickUrl',
  461. {
  462. rules: [{ message: '请输入第三方点击监控链接' }],
  463. },
  464. ]"
  465. placeholder="请输入第三方点击监控链接"
  466. >
  467. </a-input>
  468. <span style="color:red;position: relative;top: -10px;">仅加白使用</span>
  469. <br />
  470. <a
  471. v-if="getData('actionbarClickUrl')"
  472. @click="
  473. clickTrackUrlShow = true
  474. clickTrackUrlShowType = '2'
  475. "
  476. style="margin-right: 10px; position: relative; top: -20px"
  477. >收藏监测链接</a
  478. >
  479. <a
  480. @click="
  481. getClickTrackUrlList('2')
  482. clickTrackUrlShowType = '2'
  483. "
  484. style="margin-right: 10px; position: relative; top: -20px"
  485. >监测链接列表</a
  486. >
  487. </a-form-item>
  488. <a-form-item label="创意标题" :labelCol="labelCol" :wrapperCol="wrapperCol">
  489. <a-input
  490. v-decorator="['packageName', { rules: [{ required: true, message: '创意标题必填' }] }]"
  491. :maxLength="100"
  492. ></a-input>
  493. </a-form-item>
  494. </a-form>
  495. </a-tab-pane>
  496. </a-tabs>
  497. <a-form-item :wrapperCol="{ span: 24 }" style="text-align: center">
  498. <a-button type="primary" @click="handleSubmit" :loading="loading">提交</a-button>
  499. </a-form-item>
  500. <checkMatemal ref="check" @showVideo="showData"></checkMatemal>
  501. <!-- <a-modal :maskClosable="false" v-model="visible" title="广告创意创建情况">
  502. <div style="font-size: 24px">
  503. {{ allForm.success }}
  504. </div>
  505. <div v-if="allForm.fail">失败原因:{{ allForm.fail }}</div>
  506. <template slot="footer">
  507. <a-button key="back" @click="handleCancel">关闭</a-button>
  508. <a-button key="submit" type="primary" @click="handleOk">返回列表</a-button>
  509. </template>
  510. </a-modal> -->
  511. <a-modal :maskClosable="false" v-model="visible" :footer="null" :width="520">
  512. <div style="width: 100%; height: 329px; display: flex; flex-flow: column">
  513. <main
  514. class="container"
  515. style="width: 100%; text-align: center; margin: 66px auto 24px; font-size: 30px; font-weight: 100"
  516. >
  517. <h2 data-splitting class="headline headline--yell" style="color: red">起量</h2>
  518. </main>
  519. <div style="width: 100%; text-align: center; font-size: 24px; margin-bottom: 65px">
  520. <img src="@/assets/success.png" alt="" style="width: 24px; margin-right: 10px" />创建成功
  521. </div>
  522. <div style="width: 100%; margin-bottom: 43px; display: flex; justify-content: center">
  523. <a-button key="submit" type="primary" @click="handleOk" style="margin-right: 8px"> 返回列表 </a-button>
  524. <a-button key="back" @click="handleCancel">关闭</a-button>
  525. </div>
  526. </div>
  527. </a-modal>
  528. <a-modal
  529. :maskClosable="false"
  530. title="封面上传"
  531. @cancel="closeImage"
  532. @afterClose="closeImage"
  533. v-model="addImageVisible"
  534. >
  535. <template slot="footer">
  536. <a-button key="back" @click="closeImage">取消</a-button>
  537. <a-button type="primary" @click="handleOkImage" :loading="loadingImage">确定</a-button>
  538. </template>
  539. <a-form-item label class="add-image-material">
  540. <uploadFile
  541. v-if="addImageVisible"
  542. :value.sync="urlListImage.url"
  543. :checkFile="fileWater"
  544. @overUpload="overUploadImage"
  545. @removeUpload="deleteImage"
  546. :fileCount="4"
  547. uploadType="image"
  548. />
  549. <!--
  550. <upload-to-ali style="width:100%" v-model="urlListImage.url" :customDomain="customDomain" :multiple="true"
  551. preview :region="region" :bucket="bucket" :accept="acceptImage" :max="15" :size="2048"
  552. :accessKeyId="accessKeyId" :accessKeySecret="accessKeySecret" :before-upload="fileWater" :dir="dirImg"
  553. @delete='deleteImage' @loaded="overUploadImage"></upload-to-ali>-->
  554. <span
  555. v-if="material.filter((item) => item == false).length > 0 && urlListImage.url.length > 0"
  556. style="color: red"
  557. >
  558. 上传素材的尺寸不符,请修改(
  559. <span v-for="(item, index) of material" :key="index" v-show="!item">第{{ index + 1 }}张</span>出错)
  560. </span>
  561. <span
  562. v-else-if="urlListImage.url.length > 0 && material.filter((item) => item == false).length == 0"
  563. style="color: green"
  564. >上传成功</span
  565. >
  566. </a-form-item>
  567. </a-modal>
  568. <a-modal
  569. :maskClosable="false"
  570. title="视频上传"
  571. @cancel="closeVideo"
  572. @afterClose="closeVideo"
  573. v-model="addVideoVisible"
  574. >
  575. <template slot="footer">
  576. <a-button key="back" @click="closeVideo">取消</a-button>
  577. <a-button type="primary" @click="handleOkVideo" :loading="loadingVideo">确定</a-button>
  578. </template>
  579. <a-form-item label class="add-image-material">
  580. <uploadFile
  581. v-if="addVideoVisible"
  582. :checkFile="file"
  583. :value.sync="urlList.url"
  584. @overUpload="overUpload"
  585. :fileCount="10"
  586. uploadType="video"
  587. :multiple="false"
  588. />
  589. <!-- <upload-to-ali v-model="urlList.url" :customDomain="customDomain" preview :region="region" :bucket="bucket"
  590. :accept="acceptVideo" :max="10" :size="1024000" :accessKeyId="accessKeyId" :accessKeySecret="accessKeySecret"
  591. :before-upload="file" :dir="dirVideo" @loaded="overUpload">
  592. </upload-to-ali>-->
  593. <span v-if="messageTip" style="color: red">{{ messageTip }}</span>
  594. </a-form-item>
  595. </a-modal>
  596. <a-modal :maskClosable="false" title="抽帧展示" v-model="chouzhen" :width="1000">
  597. <template slot="footer">
  598. <a-button key="back" @click="chouzhen = false">关闭</a-button>
  599. <a-button type="primary" @click="handleOkChouzhen">确定</a-button>
  600. </template>
  601. <!-- <a-button type="primary" @click="onCheckAllChange">全选</a-button> -->
  602. <!-- </a-checkbox> -->
  603. <ul v-if="chouzhenList.length > 0" style="height: 600px; overflow: auto; padding-left: 0" class="step3-modal">
  604. <a-checkbox-group v-model="checkList" @change="onChange" style="width: 100%">
  605. <li
  606. v-for="(item, index) of chouzhenList"
  607. :key="index"
  608. class="chouzhen"
  609. style="height: 320px"
  610. :class="{ first: index == 0 }"
  611. >
  612. <a-checkbox
  613. :value="item.signature"
  614. style="position: absolute; z-index: 100; width: 100%; height: 100%; right: 0; top: 0; float: right"
  615. :disabled="checkList.filter(i=>i==item.signature).length==0&&checkList.length>=4"
  616. >
  617. <img :src="item.url" alt style="width: 100%" />
  618. </a-checkbox>
  619. <a
  620. style="position: absolute; bottom: 0; width: 100%; text-align: center; margin-left: -10px; z-index: 100"
  621. @click.stop="
  622. showImageStr = item.url
  623. showImageChouzhen = true
  624. "
  625. >查看封面</a
  626. >
  627. </li>
  628. </a-checkbox-group>
  629. </ul>
  630. </a-modal>
  631. <a-modal title="抽帧详情" v-model="showImageChouzhen" :width="400" :footer="null">
  632. <img :src="showImageStr" style="width: 100%" />
  633. </a-modal>
  634. <a-modal :maskClosable="false" title="选择素材" v-model="visibleMatemal" @ok="handleOkShow" :width="1000">
  635. <a-tabs type="card" @change="callback" v-model="active" class="check-video">
  636. <a-tab-pane :tab="item.label" v-for="item of tab" :key="item.value">
  637. <a-range-picker name="buildTime" style="width: 400px; margin: 10px 0" v-model="time" />
  638. <ul v-if="dataSource.length > 0" style="overflow: auto; padding-left: 0">
  639. <a-checkbox-group v-model="checkVideo" @change="onChangeVideo" style="width: 100%">
  640. <li v-for="(item, index) of dataSource" :key="index" class="chouzhen" style="height: 350px">
  641. <!-- <video class="video" :src="item.url" controls="controls" style="width:100%">
  642. 您的浏览器不支持 video 标签。
  643. </video>-->
  644. <a-checkbox :value="item" style="width: 100%; position: absolute; z-index: 100; right: 0; top: 0">
  645. <img :src="item.coverUrl" alt style="width: 100%; margin-bottom: 10px" />
  646. </a-checkbox>
  647. <a @click="matemalVideo(item, index)" style="position: absolute; z-index: 100; right: 56px; bottom: 5px"
  648. >查看视频</a
  649. >
  650. </li>
  651. </a-checkbox-group>
  652. </ul>
  653. <div v-else style="width: 100%; height: 400px; display: flex; justify-content: center; align-items: center">
  654. <img
  655. src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1575627350102&di=02972956f2243933bffc0d85099adbfe&imgtype=jpg&src=http%3A%2F%2Fimg0.imgtn.bdimg.com%2Fit%2Fu%3D1095310825%2C1528244349%26fm%3D214%26gp%3D0.jpg"
  656. alt
  657. v-if="!loadingVideoList"
  658. />
  659. <img v-else src="@/views/modules/material/loading.gif" />
  660. </div>
  661. </a-tab-pane>
  662. <a-button slot="tabBarExtraContent" type="primary" @click="tongbu()" :loading="tongbuLoading"
  663. >刷新素材</a-button
  664. >
  665. </a-tabs>
  666. <!-- <ul class="actor-photo-list">
  667. <a-checkbox-group v-model="checkArr" style="width:100%; display: flex;padding-left: 0;"
  668. @change="onChangeCheck">
  669. <li v-for="(item, index) of dataSource" :key="index">
  670. <a-checkbox :value="item" style="position:absolute;z-index:100;padding-right:30px">
  671. </a-checkbox>
  672. </li>
  673. </a-checkbox-group>
  674. </ul>-->
  675. <div style="text-align: right">
  676. <a-pagination
  677. size="small"
  678. :showTotal="ipagination.showTotal"
  679. style="float: right"
  680. v-if="dataSource.length > 0"
  681. showQuickJumper
  682. :pageSize.sync="ipagination.pageSize"
  683. :total="ipagination.total"
  684. v-model="ipagination.current"
  685. @change="getDataSource"
  686. />
  687. </div>
  688. </a-modal>
  689. <a-modal title="查看视频" v-model="visibleVideo" :width="400" :footer="null">
  690. <video class="video" :src="videoUrlShow" controls="controls" style="width: 100%">
  691. 您的浏览器不支持 video 标签。
  692. </video>
  693. </a-modal>
  694. <a-modal title="推荐标题" v-model="titleVisible" :width="1000" :footer="null">
  695. <a-row :gutter="10">
  696. <a-col :sm="10" style="margin-bottom: 20px; z-index: 10">
  697. <a-card class="search-box" style="min-height: 500px">
  698. <div style="margin-bottom: 30px">
  699. <span style="display: inline-block; width: 80px">行业</span>
  700. <a-cascader
  701. style="margin-top: 1rem; width: 300px"
  702. v-model="dataOne"
  703. :options="options"
  704. :showSearch="{ filter }"
  705. expandTrigger="hover"
  706. @change="onChangeTitle"
  707. placeholder="请选择行业"
  708. >
  709. <a-icon type="smile" slot="suffixIcon" class="test" />
  710. </a-cascader>
  711. </div>
  712. <div style="margin-bottom: 30px">
  713. <span style="display: inline-block; width: 80px">关键词</span>
  714. <a-input placeholder="请输入关键词" v-model="value" style="width: 300px" />
  715. </div>
  716. <span style="display: inline-block; width: 80px; float: left"></span>
  717. <a-button type="primary" @click="searchQuery" :disabled="value == ''">生成</a-button>
  718. </a-card>
  719. </a-col>
  720. <a-col :sm="14" style="margin-bottom: 20px; z-index: 10">
  721. <a-card class="search-box" style="over-flow: auto">
  722. <a-list size="large" bordered :dataSource="title">
  723. <a-list-item slot="renderItem" slot-scope="item">
  724. <a slot="actions" @click="okTitle(item)">选择</a>
  725. {{ item }}
  726. </a-list-item>
  727. </a-list>
  728. </a-card>
  729. </a-col>
  730. </a-row>
  731. </a-modal>
  732. <!-- :load="loadOptions"
  733. lazy -->
  734. <a-modal title="收藏标题" v-model="creativeTagVisible" :width="1000" @ok="okTag">
  735. <el-tree
  736. :data="optionsTag"
  737. show-checkbox
  738. node-key="id"
  739. :props="defaultProps"
  740. :check-strictly="true"
  741. ref="tree"
  742. >
  743. </el-tree>
  744. </a-modal>
  745. <a-modal title="收藏标题" v-model="cunTitleVisible" :width="1000" @ok="okTitleCun">
  746. <a-row :gutter="10">
  747. <a-col :sm="24" style="margin-bottom: 20px; z-index: 10">
  748. <a-card class="search-box" style="over-flow: auto">
  749. <a-checkbox-group v-model="guanggao" style="width:100%">
  750. <a-list size="large" bordered :dataSource="cunTitleList">
  751. <a-list-item slot="renderItem" slot-scope="item">
  752. <div slot="actions">
  753. <!-- <a @click="okTitleCun(item)">选择</a>
  754. <a-divider type="vertical" /> -->
  755. <a @click="removeTitleCun(item)">删除</a>
  756. </div>
  757. <a-checkbox :value="item">
  758. {{ item.captions?item.captions:item.coverSlogans?item.coverSlogans:item.tag }}
  759. </a-checkbox>
  760. </a-list-item>
  761. </a-list>
  762. </a-checkbox-group>
  763. </a-card>
  764. </a-col>
  765. </a-row>
  766. </a-modal>
  767. <a-modal title="监测链接名称" v-model="clickTrackUrlShow">
  768. <template slot="footer">
  769. <a-button :disabled="trackUrlName == '' && !showTrackUrlNameElse" type="primary" @click="clickTrackUrlOk"
  770. >确定</a-button
  771. >
  772. </template>
  773. <a-input placeholder="请输入监测链接名称" v-model="trackUrlName" @blur="changeTrackUrlName" style="width: 100%" />
  774. <span style="color: red" v-if="!showTrackUrlNameElse">名称重复</span>
  775. </a-modal>
  776. <a-modal title="监测链接列表" v-model="clickTrackUrlList" :width="1000" :footer="null">
  777. <a-spin :spinning="spinning">
  778. <a-row :gutter="10" class="onlny-click-track">
  779. <a-col :sm="24" style="margin-bottom: 20px; z-index: 10">
  780. <a-card class="search-box" style="over-flow: auto">
  781. <!-- <a-input v-model="trackName"></a-input> -->
  782. <a-input-search
  783. placeholder="请输入监测链接名称"
  784. enter-button="Search"
  785. size="large"
  786. @search="onSearch"
  787. style="width: 40%; margin-bottom: 20px"
  788. v-model="trackName"
  789. />
  790. <a-list size="large" bordered :dataSource="trackUrlList">
  791. <a-list-item slot="renderItem" slot-scope="item" :title="item.trackUrl" style="line-height: 50px">
  792. <div slot="actions">
  793. <a @click="okClickTrackUrl(item)">选择</a>
  794. <a-divider type="vertical" />
  795. <a @click="removeClickTrackUrl(item)">删除</a>
  796. </div>
  797. {{ item.trackName }}
  798. <a-input v-model="item.trackUrl" read-only style="margin: 10px; width: 70%"></a-input>
  799. </a-list-item>
  800. </a-list>
  801. </a-card>
  802. </a-col>
  803. </a-row>
  804. </a-spin>
  805. </a-modal>
  806. </a-card>
  807. </template>
  808. <script>
  809. import { getAction, postAction, deleteAction } from '@/api/manage'
  810. import { mapGetters } from 'vuex'
  811. import UploadToAli from '@femessage/upload-to-ali'
  812. import moment from 'moment'
  813. import VuePreview from 'vue-preview'
  814. import jq from 'jquery'
  815. import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl' // 停止除当前外的其他视频播放,及停止所有视频播放的方法
  816. import checkMatemal from './stepModule/checkMatemal'
  817. import BMF from 'browser-md5-file'
  818. import uploadFile from '@/components/uploadFile.vue'
  819. let nowIndex = 0
  820. let bestIndex = 0
  821. let showRemove = false
  822. function tqFun(qcArr1) {
  823. var tempArr = []
  824. function bbFun(qcArr) {
  825. for (var i = 0; i < qcArr.length; i++) {
  826. if (qcArr[i] instanceof Array) {
  827. bbFun(qcArr[i])
  828. } else {
  829. tempArr.push(qcArr[i])
  830. }
  831. }
  832. return tempArr
  833. }
  834. return bbFun(qcArr1)
  835. }
  836. export default {
  837. name: 'BaseForm',
  838. components: {
  839. UploadToAli,
  840. VuePreview,
  841. checkMatemal,
  842. uploadFile,
  843. },
  844. data() {
  845. return {
  846. creativeCategorySwitch: false,
  847. actionbarClickUrlSwitch: false,
  848. optionsTag: [],
  849. defaultProps: {
  850. children: 'children',
  851. label: 'label',
  852. id: 'id',
  853. },
  854. tagName: '',
  855. fieldNames: {
  856. label: 'category_name',
  857. value: 'category_id',
  858. children: 'child',
  859. },
  860. createOptions: [],
  861. guanggao: [],
  862. stickerStylesValue: [],
  863. coverSlogansList: [{ coverSlogans: '' }],
  864. stickerStyles: [],
  865. captionsList: [{ captions: '' }],
  866. horizontalPhoto: [
  867. {
  868. videoList: [],
  869. imageList: [],
  870. creativeMaterialType: '2',
  871. imageUrlList: [],
  872. checkArrImage: [],
  873. chouzhenShow: false,
  874. },
  875. ], //横板
  876. verticalPhoto: [
  877. {
  878. videoList: [],
  879. imageList: [],
  880. creativeMaterialType: '1',
  881. imageUrlList: [],
  882. checkArrImage: [],
  883. chouzhenShow: false,
  884. },
  885. ], //竖版
  886. trackName: '',
  887. showImageChouzhen: false,
  888. showImageStr: null,
  889. tongbuLoading: false,
  890. showTrackUrlNameElse: true,
  891. clickTrackUrlShow: false,
  892. clickTrackUrlShowType: '1',
  893. clickTrackUrlList: false,
  894. spinning: false,
  895. trackUrlList: [],
  896. trackUrlName: '',
  897. showSite: true,
  898. titleVisible: false,
  899. cunTitleVisible: false,
  900. creativeTagVisible: false,
  901. cunTitleList: [],
  902. options: [],
  903. data: [],
  904. value: '',
  905. dataOne: [],
  906. title: [],
  907. tags: [],
  908. visibleMatemal: false,
  909. visibleVideo: false,
  910. videoUrlShow: '',
  911. time: [],
  912. channelType: 0,
  913. checkVideo: [],
  914. dataSource: [],
  915. tab: [
  916. {
  917. value: 0,
  918. label: '内部',
  919. },
  920. {
  921. value: 1,
  922. label: '外部',
  923. },
  924. ],
  925. active: 0,
  926. ipagination: {
  927. current: 1,
  928. pageSize: 5,
  929. // pageSizeOptions: ['10', '20', '30'],
  930. showTotal: (total, range) => {
  931. return range[0] + '-' + range[1] + ' 共' + total + '条'
  932. },
  933. showQuickJumper: true,
  934. // showSizeChanger: true,
  935. total: 0,
  936. onChange: (current) => {
  937. // 切换分页时的回调,
  938. // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
  939. this.ipagination.current = current
  940. },
  941. },
  942. chouzhen: false,
  943. chouzhenList: [],
  944. checkList: [],
  945. indeterminate: true,
  946. checkAll: false,
  947. pans: [],
  948. pansKey: '',
  949. addImageVisible: false,
  950. addVideoVisible: false,
  951. loadingVideoList: false,
  952. loadingVideo: false,
  953. loadingImage: false,
  954. allForm: {
  955. videoList: '',
  956. imageList: [],
  957. fail: null,
  958. success: null,
  959. },
  960. form: this.$form.createForm(this),
  961. list: [],
  962. vertical: 'vertical',
  963. appList: [],
  964. siteList: [],
  965. labelCol: {
  966. lg: {
  967. span: 6,
  968. },
  969. sm: {
  970. span: 6,
  971. },
  972. xs: {
  973. span: 6,
  974. },
  975. md: {
  976. span: 6,
  977. },
  978. },
  979. wrapperCol: {
  980. lg: {
  981. span: 20,
  982. },
  983. sm: {
  984. span: 18,
  985. },
  986. xs: {
  987. span: 20,
  988. },
  989. md: {
  990. span: 20,
  991. },
  992. },
  993. visible: false,
  994. loading: false,
  995. imageUrlList: [],
  996. checkAllImage: false,
  997. checkArrImage: [],
  998. content: 0,
  999. urlListImage: {
  1000. url: [],
  1001. md5: [],
  1002. },
  1003. urlList: {
  1004. url: '',
  1005. md5: '',
  1006. photoId: '',
  1007. },
  1008. imageArrList: [],
  1009. material: [],
  1010. creativeCopywriter: '',
  1011. customDomain: '',
  1012. region: 'oss-cn-beijing',
  1013. bucket: 'ctop-media',
  1014. acceptVideo: 'video/mpeg,video/mp4',
  1015. acceptImage: 'image/jpeg,image/jpg',
  1016. accessKeyId: 'LTAIbNbqWzSOklQV',
  1017. accessKeySecret: '1rkPz7JNoXk8sJevPaeYHWqfkQXBGh',
  1018. messageTip: null,
  1019. }
  1020. },
  1021. methods: {
  1022. loadOptions(node, resolve) {
  1023. // Typically, do the AJAX stuff here.
  1024. // Once the server has responded,
  1025. // assign children options to the parent node & call the callback.
  1026. console.log(node)
  1027. var data = []
  1028. var id = node.label
  1029. if (node.level == 1) {
  1030. var params = {}
  1031. params.accountId = localStorage.getItem('accountId')
  1032. params.userId = this.userInfo().id
  1033. params.pageSize = 1000
  1034. params.pageNo = 1
  1035. params.id = id
  1036. getAction('/tag/kuaiShouCreativeTagCollection/list', params).then((res) => {
  1037. if (res.success) {
  1038. data = JSON.parse(res.result.records[0].tagArray).map((item) => {
  1039. return {
  1040. id: item,
  1041. label: item,
  1042. disabled: true,
  1043. }
  1044. })
  1045. resolve(data)
  1046. }
  1047. })
  1048. } else {
  1049. data = []
  1050. resolve(data)
  1051. }
  1052. },
  1053. getInfo(item) {
  1054. if (this.tagName == '') {
  1055. this.$message.error('请输入分类名称')
  1056. return
  1057. } else {
  1058. let params = {}
  1059. params.tagName = this.tagName
  1060. // params.campaignBudget = this.campaignBudget
  1061. params.tagArray = JSON.stringify(this.getData('creativeTag'))
  1062. params.userId = this.userInfo().id
  1063. params.accountId = localStorage.getItem('accountId')
  1064. postAction('/tag/kuaiShouCreativeTagCollection/add', params).then((res) => {
  1065. if (res.success) {
  1066. this.$message.success('添加成功')
  1067. this.tagName = ''
  1068. } else {
  1069. this.$message.error(res.message)
  1070. }
  1071. })
  1072. }
  1073. },
  1074. addCaptions(type) {
  1075. if (type == 'captionsList') {
  1076. this.captionsList.push({ captions: '' })
  1077. } else {
  1078. this.coverSlogansList.push({ coverSlogans: '' })
  1079. }
  1080. },
  1081. collection(type) {
  1082. var params = {}
  1083. params.userId = this.userInfo().id
  1084. params.accountId = localStorage.getItem('accountId')
  1085. if (type == 'captionsList') {
  1086. // this.captionsList.push({ captions: '' })
  1087. params.captionsList = this.captionsList
  1088. } else if (type == 'creativeTag') {
  1089. // this.coverSlogansList.push({ coverSlogans: '' })
  1090. params.creativeTag = this.getData('creativeTag').map((item) => {
  1091. return { tag: item }
  1092. })
  1093. } else {
  1094. params.coverSlogansList = this.coverSlogansList
  1095. }
  1096. postAction('/kuaishou/collectionSlogans/add', params).then((res) => {
  1097. console.log(res)
  1098. if (res.success) {
  1099. this.$message.success('收藏成功')
  1100. }
  1101. })
  1102. },
  1103. deleteCaptions(index, type) {
  1104. if (type == 'captionsList') {
  1105. this.captionsList.splice(index, 1)
  1106. } else if (type == 'creativeTag') {
  1107. } else {
  1108. this.coverSlogansList.splice(index, 1)
  1109. }
  1110. },
  1111. changeType(index) {
  1112. this.$forceUpdate()
  1113. this.$nextTick(() => {
  1114. console.log(this.getData('creativeMaterialType'))
  1115. if (this.getData('creativeMaterialType') == '1') {
  1116. if (this.verticalPhoto.length > 0) {
  1117. this.pans[index].list = this.verticalPhoto
  1118. } else {
  1119. this.addCreative(index)
  1120. }
  1121. } else {
  1122. if (this.horizontalPhoto.length > 0) {
  1123. this.pans[index].list = this.horizontalPhoto
  1124. } else {
  1125. this.addCreative(index)
  1126. }
  1127. }
  1128. // this.addCreative(index)
  1129. })
  1130. },
  1131. ...mapGetters(['nickname', 'avatar', 'userInfo']),
  1132. onSearch(value) {
  1133. console.log(value, this.trackName)
  1134. var params = {}
  1135. params.accountId = localStorage.getItem('accountId')
  1136. params.userId = this.userInfo().id
  1137. params.pageNo = 1
  1138. params.pageSize = 500
  1139. params.trackName = value
  1140. getAction('/kuaishou/kuaiShouTrackUrlCollection/list', params).then((res) => {
  1141. if (res.success) {
  1142. this.trackUrlList = res.result.records
  1143. } else {
  1144. this.$message.error(res.message)
  1145. }
  1146. })
  1147. },
  1148. changeTrackUrlName() {
  1149. var params = {}
  1150. params.accountId = localStorage.getItem('accountId')
  1151. params.userId = this.userInfo().id
  1152. params.trackName = this.trackUrlName
  1153. getAction('/kuaishou/kuaiShouTrackUrlCollection/checkTrackName', params).then((res) => {
  1154. this.showTrackUrlNameElse = res.result
  1155. })
  1156. },
  1157. clickTrackUrlOk() {
  1158. var params = {}
  1159. params.accountId = localStorage.getItem('accountId')
  1160. params.userId = this.userInfo().id
  1161. params.trackName = this.trackUrlName
  1162. params.trackType = this.clickTrackUrlShowType
  1163. params.trackUrl = this.clickTrackUrlShowType == '1' ? this.getData('clickUrl') : this.getData('actionbarClickUrl')
  1164. // params.trackUrl = this.getData('clickUrl')
  1165. postAction('/kuaishou/kuaiShouTrackUrlCollection/add', params).then((res) => {
  1166. if (res.success) {
  1167. this.clickTrackUrlShow = false
  1168. this.trackUrlName = ''
  1169. this.$message.success('添加成功')
  1170. } else {
  1171. this.$message.error(res.message)
  1172. }
  1173. })
  1174. },
  1175. okClickTrackUrl(item) {
  1176. this.clickTrackUrlList = false
  1177. if (this.clickTrackUrlShowType == '1') {
  1178. this.form.setFieldsValue({
  1179. clickUrl: item.trackUrl,
  1180. })
  1181. } else {
  1182. this.form.setFieldsValue({
  1183. actionbarClickUrl: item.trackUrl,
  1184. })
  1185. }
  1186. },
  1187. removeClickTrackUrl(item) {
  1188. deleteAction('/kuaishou/kuaiShouTrackUrlCollection/delete', {
  1189. id: item.id,
  1190. }).then((res) => {
  1191. if (res.success) {
  1192. this.getClickTrackUrlList(this.clickTrackUrlShowType)
  1193. }
  1194. })
  1195. },
  1196. getClickTrackUrlList(type) {
  1197. this.clickTrackUrlList = true
  1198. this.spinning = true
  1199. this.trackUrlList = []
  1200. var params = {}
  1201. params.accountId = localStorage.getItem('accountId')
  1202. params.userId = this.userInfo().id
  1203. params.trackType = type
  1204. params.pageNo = 1
  1205. params.pageSize = 500
  1206. getAction('/kuaishou/kuaiShouTrackUrlCollection/list', params).then((res) => {
  1207. if (res.success) {
  1208. this.trackUrlList = res.result.records
  1209. this.spinning = false
  1210. } else {
  1211. this.$message.error(res.message)
  1212. this.spinning = false
  1213. }
  1214. })
  1215. },
  1216. showTitle(index, bestIndex) {
  1217. nowIndex = index
  1218. bestIndex = bestIndex
  1219. this.titleVisible = true
  1220. this.getHangye()
  1221. },
  1222. okTitle(item) {
  1223. this.pans[bestIndex].list[nowIndex].description = item
  1224. this.titleVisible = false
  1225. this.dataOne = []
  1226. this.value = ''
  1227. this.title = []
  1228. },
  1229. cunTitle(nowIndex, lastIndex) {
  1230. if (this.pans[lastIndex].list[nowIndex].description == '') {
  1231. this.$message.error('请填写广告语后再进行收藏')
  1232. } else {
  1233. var params = {}
  1234. params.accountId = localStorage.getItem('accountId')
  1235. params.userId = this.userInfo().id
  1236. params.title = this.pans[lastIndex].list[nowIndex].description
  1237. postAction('/kuaishou/kuaiShouTitleCollection/add', params).then((res) => {
  1238. if (res.success) {
  1239. this.$message.success('收藏成功')
  1240. } else {
  1241. this.$message.error(res.message)
  1242. }
  1243. })
  1244. }
  1245. },
  1246. showCunTitle(type) {
  1247. if (type == 'creativeTag') {
  1248. this.creativeTagVisible = true
  1249. } else {
  1250. this.cunTitleVisible = true
  1251. }
  1252. this.getCunTitle(type)
  1253. },
  1254. getCunTitle(typeAdd) {
  1255. if (typeAdd == 'creativeTag') {
  1256. var params = {}
  1257. params.accountId = localStorage.getItem('accountId')
  1258. params.userId = this.userInfo().id
  1259. params.pageSize = 1000
  1260. params.pageNo = 1
  1261. getAction('/tag/kuaiShouCreativeTagCollection/list', params).then((res) => {
  1262. if (res.success) {
  1263. console.log(res.result)
  1264. this.optionsTag = res.result.records.map((item) => {
  1265. return {
  1266. id: item.id,
  1267. label: item.tagName,
  1268. children: JSON.parse(item.tagArray).map((item) => {
  1269. return {
  1270. id: item,
  1271. label: item,
  1272. disabled: true,
  1273. }
  1274. }),
  1275. }
  1276. })
  1277. }
  1278. })
  1279. } else {
  1280. var params = {}
  1281. params.accountId = localStorage.getItem('accountId')
  1282. params.userId = this.userInfo().id
  1283. params.type = typeAdd == 'captionsList' ? 2 : 1
  1284. // params.pageNo = 1
  1285. // params.pageSize = 500
  1286. // /kuaishou/collectionSlogans/getByUserId?userId=12312312321&accountId=12&type=1
  1287. getAction('/kuaishou/collectionSlogans/getByUserId', params).then((res) => {
  1288. if (res.success) {
  1289. console.log(res.result)
  1290. this.cunTitleList = res.result.value
  1291. }
  1292. })
  1293. }
  1294. },
  1295. removeTitleCun(item) {
  1296. console.log(item)
  1297. var typeAdd = null
  1298. if (item.captions) {
  1299. var index = this.cunTitleList.findIndex((v) => v.captions === item.captions)
  1300. this.cunTitleList.splice(index, 1)
  1301. var params = {}
  1302. params.userId = this.userInfo().id
  1303. params.accountId = localStorage.getItem('accountId')
  1304. params.captionsList = this.cunTitleList
  1305. params.type = 'delete'
  1306. typeAdd = 'captionsList'
  1307. } else if (item.tag) {
  1308. var index = this.cunTitleList.findIndex((v) => v.tag === item.tag)
  1309. this.cunTitleList.splice(index, 1)
  1310. var params = {}
  1311. params.userId = this.userInfo().id
  1312. params.accountId = localStorage.getItem('accountId')
  1313. params.creativeTag = this.cunTitleList
  1314. params.type = 'delete'
  1315. typeAdd = 'creativeTag'
  1316. } else {
  1317. var index = this.cunTitleList.findIndex((v) => v.coverSlogans === item.coverSlogans)
  1318. this.cunTitleList.splice(index, 1)
  1319. var params = {}
  1320. params.userId = this.userInfo().id
  1321. params.accountId = localStorage.getItem('accountId')
  1322. params.coverSlogansList = this.cunTitleList
  1323. params.type = 'delete'
  1324. typeAdd = 'coverSlogansList'
  1325. }
  1326. // var index = this.cunTitleList.findIndex((v) => v.captions === item.captions)
  1327. // this.cunTitleList.splice(index, 1)
  1328. // var params = {}
  1329. // params.userId = this.userInfo().id
  1330. // params.accountId = localStorage.getItem('accountId')
  1331. // params.captionsList = this.cunTitleList
  1332. // params.type = 'delete'
  1333. postAction('/kuaishou/collectionSlogans/add', params).then((res) => {
  1334. console.log(res)
  1335. if (res.success) {
  1336. this.$message.success('删除成功')
  1337. this.getCunTitle(typeAdd)
  1338. this.guanggao = []
  1339. }
  1340. })
  1341. // deleteAction('/kuaishou/kuaiShouTitleCollection/delete', {
  1342. // id: item.id,
  1343. // }).then((res) => {
  1344. // if (res.success) {
  1345. // this.getCunTitle()
  1346. // }
  1347. // })
  1348. },
  1349. creativeTagValid(rule, value, callback) {
  1350. if (value.length > 10) {
  1351. callback('创意标签最多填写10个,请删减')
  1352. } else {
  1353. callback()
  1354. }
  1355. },
  1356. okTag() {
  1357. var data = this.$refs.tree.getCheckedKeys()
  1358. if (data.length > 1) {
  1359. this.$message.error('只能选择一个选项')
  1360. // this.$refs.tree.setCheckedKeys([]);
  1361. } else {
  1362. var params = {}
  1363. params.accountId = localStorage.getItem('accountId')
  1364. params.userId = this.userInfo().id
  1365. params.pageSize = 1000
  1366. params.pageNo = 1
  1367. params.id = data[0]
  1368. getAction('/tag/kuaiShouCreativeTagCollection/list', params).then((res) => {
  1369. if (res.success) {
  1370. console.log(res.result)
  1371. this.form.setFieldsValue({
  1372. creativeTag: JSON.parse(res.result.records[0].tagArray).map((item) => {
  1373. return item
  1374. }),
  1375. })
  1376. this.form.validateFields(['creativeTag'])
  1377. this.creativeTagVisible = false
  1378. } else {
  1379. this.$message.error('选择出错,请稍后选择或自行手填')
  1380. }
  1381. })
  1382. }
  1383. console.log(data)
  1384. },
  1385. okTitleCun(item) {
  1386. if (this.guanggao.length > 0) {
  1387. if (this.guanggao[0].captions) {
  1388. if (this.guanggao.length > 3) {
  1389. this.$message.error('广告语最多选择3条')
  1390. return
  1391. }
  1392. this.captionsList = []
  1393. this.captionsList.push(...this.guanggao)
  1394. } else if (this.guanggao[0].tag) {
  1395. this.form.setFieldsValue({
  1396. creativeTag: this.guanggao.map((t) => {
  1397. return t.tag
  1398. }),
  1399. })
  1400. } else {
  1401. if (this.guanggao.length > 6) {
  1402. this.$message.error('封面广告语最多选择6条')
  1403. return
  1404. }
  1405. this.coverSlogansList = []
  1406. this.coverSlogansList.push(...this.guanggao)
  1407. }
  1408. }
  1409. this.cunTitleVisible = false
  1410. },
  1411. searchQuery() {
  1412. // /ctop/creativeTitle/titleSuggestion
  1413. console.log(this.value)
  1414. getAction('/ctop/creativeTitle/titleSearch', {
  1415. firstCategory: this.dataOne[0],
  1416. secondCategory: this.dataOne[1],
  1417. keywords: this.value,
  1418. }).then((res) => {
  1419. console.log(res)
  1420. this.title = res.result ? res.result : []
  1421. })
  1422. // firstCategory,secondCategory,keywords
  1423. },
  1424. getHangye() {
  1425. getAction('/ctop/creativeTitle/getTitleLabel', '').then((res) => {
  1426. console.log(res)
  1427. if (res.success) {
  1428. this.options = res.result.map((item) => {
  1429. return {
  1430. label: item.label,
  1431. value: item.value,
  1432. children:
  1433. item.children.length > 0
  1434. ? [
  1435. {
  1436. label: '不限',
  1437. value: 0,
  1438. },
  1439. ].concat(item.children)
  1440. : [
  1441. {
  1442. label: '不限',
  1443. value: 0,
  1444. },
  1445. ],
  1446. }
  1447. })
  1448. this.options = [
  1449. {
  1450. label: '不限',
  1451. value: 0,
  1452. },
  1453. ].concat(this.options)
  1454. if (this.dataOne.length > 0) {
  1455. return
  1456. } else {
  1457. this.dataOne = [0]
  1458. }
  1459. }
  1460. })
  1461. },
  1462. onChangeTitle(value, selectedOptions) {
  1463. console.log(value, selectedOptions)
  1464. this.dataOne = value
  1465. this.value = ''
  1466. this.title = []
  1467. },
  1468. filter(inputValue, path) {
  1469. return path.some((option) => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1)
  1470. },
  1471. handleSearch(value) {
  1472. if (this.dataOne.length > 0) {
  1473. const str = {
  1474. firstCategory: this.dataOne[0],
  1475. secondCategory: this.dataOne[1],
  1476. keyword: value,
  1477. }
  1478. getAction('/ctop/creativeTitle/titleSuggestion', str).then((d) => {
  1479. const result = d.result ? d.result : []
  1480. this.data = result.map((item) => {
  1481. return {
  1482. value: item,
  1483. text: item,
  1484. }
  1485. })
  1486. })
  1487. } else {
  1488. this.data = []
  1489. return
  1490. }
  1491. },
  1492. matemalVideo(item) {
  1493. this.visibleVideo = true
  1494. this.videoUrlShow = item.url
  1495. },
  1496. onChange(checkedList) {
  1497. this.indeterminate = !!checkedList.length && checkedList.length < this.chouzhenList.length
  1498. this.checkAll = checkedList.length === this.chouzhenList.length
  1499. },
  1500. onCheckAllChange(e) {
  1501. if (this.checkAll) {
  1502. this.checkList = []
  1503. } else {
  1504. this.checkList = this.chouzhenList.map((item) => {
  1505. return item.signature
  1506. })
  1507. }
  1508. this.checkAll = !this.checkAll
  1509. },
  1510. onCheckAllImageChange(index, item) {
  1511. if (this.pans[index].list[item.key].checkAllImage) {
  1512. this.pans[index].list[item.key].checkArrImage = []
  1513. } else {
  1514. this.pans[index].list[item.key].checkArrImage = this.pans[index].list[item.key].imageUrlList.map((item) => {
  1515. return item.code
  1516. })
  1517. }
  1518. this.pans[index].list[item.key].checkAllImage = !this.pans[index].list[item.key].checkAllImage
  1519. },
  1520. onChangeCheckImage(checkedList) {},
  1521. handleConfirmValue(rule, value, callback) {
  1522. if (/(http|https):\/\/([\w.]+\/?)\S*/.test(value) && value.length < 10000) {
  1523. callback()
  1524. } else {
  1525. callback('链接不能为空且开头为http://或https://,并且长度小于10000')
  1526. }
  1527. },
  1528. showData(item, type) {
  1529. var index = this.pans.findIndex((item) => item.key === this.pansKey)
  1530. // this.pans[index].list[item.key].imageList = []
  1531. if (type == 'video') {
  1532. this.pans[index].list[item.key].videoList = item.video
  1533. getAction('/kuaishou/batch/getCreativeCopywriter', {
  1534. code: item.video.signature,
  1535. accountId: localStorage.getItem('accountId'),
  1536. }).then((res) => {
  1537. if (res.success) {
  1538. this.pans[index].list[item.key].description = res.result ? res.result.creativeCopywriter : ''
  1539. }
  1540. })
  1541. getAction('/ctop/MaterialImageInfo/list', {
  1542. videoId: item.video.signature,
  1543. status: 1,
  1544. }).then((res) => {
  1545. // console.log(res)
  1546. if (res.success) {
  1547. this.pans[index].list[item.key].imageUrlList = res.result
  1548. this.pans[index].list[item.key].checkArrImage = res.result.map((item) => {
  1549. return item.code
  1550. })
  1551. }
  1552. })
  1553. var params = {
  1554. videoSignature: item.video.signature,
  1555. pageSize: 20,
  1556. pageNo: 1,
  1557. }
  1558. getAction('/cutFrame/material/list', params).then((res) => {
  1559. console.log(res)
  1560. if (res.success) {
  1561. if (res.result.records.length > 0) {
  1562. this.pans[index].list[item.key].chouzhenShow = true
  1563. } else {
  1564. this.pans[index].list[item.key].chouzhenShow = false
  1565. }
  1566. }
  1567. })
  1568. } else {
  1569. // this.pans[index].list[item.key].imageList.push(...item.image)
  1570. if (item.image.length + this.pans[index].imageList[item.key].imageList > 4) {
  1571. this.$message.error(
  1572. '当前选择封面' +
  1573. item.image.length +
  1574. '张,最多可选择' +
  1575. (4 - this.pans[index].imageList[item.key].imageList.length) +
  1576. '张'
  1577. )
  1578. return
  1579. } else {
  1580. this.pans[index].imageList[item.key].imageList.push(...item.image)
  1581. this.chouzhen = false
  1582. this.chouzhenList = []
  1583. this.checkList = []
  1584. this.checkAll = false
  1585. }
  1586. }
  1587. },
  1588. getData(className) {
  1589. return this.form.getFieldValue(className)
  1590. },
  1591. onChangeVideo() {
  1592. // if (this.checkVideo.length > 1) {
  1593. // this.checkVideo.shift()
  1594. // }
  1595. },
  1596. callback(key) {
  1597. this.channelType = key
  1598. this.checkVideo = []
  1599. this.ipagination.current = 1
  1600. this.time = []
  1601. // var params = {}
  1602. // params.channelType = key
  1603. // params.accountId = localStorage.getItem('accountId')
  1604. // params.materialType = this.getData('creativeMaterialType')
  1605. // params.pageSize = this.ipagination.pageSize
  1606. // params.pageNo = this.ipagination.current
  1607. // this.showVideoList('/kuaishou/batch/getVideoList', params)
  1608. },
  1609. getDataSource(page, pageSize) {
  1610. this.ipagination.current = page
  1611. var params = {}
  1612. params.accountId = localStorage.getItem('accountId')
  1613. params.materialType = this.getData('creativeMaterialType')
  1614. params.pageSize = this.ipagination.pageSize
  1615. params.pageNo = page
  1616. params.channelType = this.channelType
  1617. params.status = 0
  1618. if (this.time.length > 0) {
  1619. // params.startDate = moment(this.time[0]).format('YYYY-MM-DD')
  1620. // params.endDate = moment(this.time[1]).format('YYYY-MM-DD')
  1621. params.startDate = moment(this.time[0]).format('YYYY-MM-DD') + ' 00:00:00'
  1622. params.endDate = moment(this.time[1]).format('YYYY-MM-DD') + ' 23:59:59'
  1623. }
  1624. this.showVideoList('/kuaishou/batch/getVideoList', params)
  1625. },
  1626. showVideoList(url, params) {
  1627. this.dataSource = []
  1628. this.loadingVideoList = true
  1629. getAction(url, params).then((res) => {
  1630. if (res.success) {
  1631. this.dataSource = res.result.records
  1632. this.ipagination.total = res.result.total
  1633. this.loadingVideoList = false
  1634. } else {
  1635. this.loadingVideoList = false
  1636. }
  1637. })
  1638. },
  1639. getVideoList(type, index, item, bestIndex) {
  1640. if (type == 'video') {
  1641. nowIndex = index
  1642. bestIndex = bestIndex
  1643. this.visibleMatemal = true
  1644. this.checkVideo = []
  1645. this.active = 0
  1646. this.time = []
  1647. this.channelType = 0
  1648. } else {
  1649. this.$refs.check.showCheck(
  1650. this.getData('creativeMaterialType'),
  1651. '/kuaishou/batch/getImageList',
  1652. item.imageList,
  1653. type,
  1654. index
  1655. )
  1656. }
  1657. },
  1658. remove(targetKey) {
  1659. let activeKey = this.pansKey
  1660. let lastIndex
  1661. this.pans.forEach((pane, i) => {
  1662. if (pane.key === targetKey) {
  1663. lastIndex = i - 1
  1664. }
  1665. })
  1666. const panes = this.pans.filter((pane) => pane.key !== targetKey)
  1667. if (panes.length && activeKey === targetKey) {
  1668. if (lastIndex >= 0) {
  1669. activeKey = panes[lastIndex].key
  1670. } else {
  1671. activeKey = panes[0].key
  1672. }
  1673. }
  1674. this.pans = panes
  1675. this.pansKey = activeKey
  1676. this.form.resetFields()
  1677. if (this.pans.length == 0) {
  1678. this.$bus.$emit('remove', '/account/stepForm')
  1679. } else {
  1680. this.addCreative(0)
  1681. getAction('/kuaishou/batch/checkCreativeCount', {
  1682. unitId: this.pansKey,
  1683. accountId: localStorage.getItem('accountId'),
  1684. }).then((res) => {
  1685. console.log(res)
  1686. this.content = res.result
  1687. })
  1688. }
  1689. },
  1690. handleOk() {
  1691. this.remove(this.pansKey)
  1692. if (localStorage.getItem('originality')) {
  1693. this.$router.replace({
  1694. path: '/account/originality',
  1695. })
  1696. } else {
  1697. this.$router.replace({
  1698. path: '/account/accountIndex',
  1699. })
  1700. }
  1701. this.visible = false
  1702. },
  1703. handleCancel(e) {
  1704. this.visible = false
  1705. this.remove(this.pansKey)
  1706. },
  1707. handleSubmit(e) {
  1708. e.preventDefault()
  1709. this.form.validateFields((err, values) => {
  1710. if (!err) {
  1711. this.loading = true
  1712. var index = this.pans.findIndex((item) => item.key === this.pansKey)
  1713. var params = {
  1714. // dataJson: allJson,
  1715. ...values,
  1716. creativeCategory: values.creativeCategory
  1717. ? values.creativeCategory[values.creativeCategory.length - 1]
  1718. : null,
  1719. unitId: this.pansKey,
  1720. accountId: localStorage.getItem('accountId'),
  1721. content: this.content,
  1722. captions: this.captionsList.map((item) => {
  1723. return item.captions
  1724. }),
  1725. stickerStyles: this.stickerStylesValue,
  1726. coverSlogans:
  1727. this.stickerStylesValue.length > 0
  1728. ? this.coverSlogansList.map((item) => {
  1729. return item.coverSlogans
  1730. })
  1731. : [],
  1732. horizontalPhotoIds: this.horizontalPhoto[0].videoList.map((item) => {
  1733. return item.photoId
  1734. }),
  1735. verticalPhotoIds: this.verticalPhoto[0].videoList.map((item) => {
  1736. return item.photoId
  1737. }),
  1738. coverImageTokens: this.pans[index].imageList[0].imageList.map((i) => {
  1739. return i.signature
  1740. }),
  1741. }
  1742. console.log(params)
  1743. postAction('/ctop/kuaishouProgramCreative/createProgramCreative', params).then((res) => {
  1744. if (res.success) {
  1745. this.loading = false
  1746. this.visible = true
  1747. this.$nextTick(() => {
  1748. Splitting()
  1749. })
  1750. } else {
  1751. this.loading = false
  1752. this.$message.error(res.message)
  1753. }
  1754. })
  1755. }
  1756. })
  1757. },
  1758. nextStep() {
  1759. var that = this
  1760. setTimeout(function () {
  1761. that.$emit('nextStep')
  1762. }, 1500)
  1763. },
  1764. prevStep() {
  1765. this.$emit('prevStep')
  1766. },
  1767. addCreative(index) {
  1768. if (this.getData('creativeMaterialType') == '1') {
  1769. // this.verticalPhoto.push({
  1770. // videoList: [],
  1771. // imageList: [],
  1772. // creativeMaterialType: '1',
  1773. // imageUrlList: [],
  1774. // checkArrImage: [],
  1775. // })
  1776. this.pans[index].list = this.verticalPhoto
  1777. } else if (this.getData('creativeMaterialType') == '2') {
  1778. // this.horizontalPhoto.push({
  1779. // videoList: [],
  1780. // imageList: [],
  1781. // creativeMaterialType: '2',
  1782. // imageUrlList: [],
  1783. // checkArrImage: [],
  1784. // })
  1785. this.pans[index].list = this.horizontalPhoto
  1786. }
  1787. },
  1788. addAdList(index) {
  1789. this.$nextTick(() => {
  1790. this.pans[index].imageList.push({
  1791. imageList: [],
  1792. creativeMaterialType: '1',
  1793. chouzhenShow: false,
  1794. })
  1795. })
  1796. },
  1797. deleteCreative(bestIndex, index) {
  1798. this.pans[bestIndex].list.splice(index, 1)
  1799. },
  1800. filterOption(input, option) {
  1801. return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  1802. },
  1803. uploadVideo(index, bestIndex) {
  1804. console.log(index, bestIndex)
  1805. nowIndex = index
  1806. bestIndex = bestIndex
  1807. this.addVideoVisible = true
  1808. },
  1809. tongbu() {
  1810. this.tongbuLoading = true
  1811. getAction('/kuaishou/batch/syncVideo', {
  1812. accountId: localStorage.getItem('accountId'),
  1813. }).then((res) => {
  1814. if (res.success) {
  1815. this.$message.success(res.message)
  1816. this.tongbuLoading = false
  1817. var params = {}
  1818. params.accountId = localStorage.getItem('accountId')
  1819. params.materialType = this.getData('creativeMaterialType')
  1820. params.pageSize = this.ipagination.pageSize
  1821. params.pageNo = 1
  1822. params.status = 0
  1823. params.channelType = this.channelType
  1824. if (this.time.length > 0) {
  1825. // params.startDate = moment(this.time[0]).format('YYYY-MM-DD')
  1826. // params.endDate = moment(this.time[1]).format('YYYY-MM-DD')
  1827. params.startDate = moment(this.time[0]).format('YYYY-MM-DD') + ' 00:00:00'
  1828. params.endDate = moment(this.time[1]).format('YYYY-MM-DD') + ' 23:59:59'
  1829. }
  1830. this.showVideoList('/kuaishou/batch/getVideoList', params)
  1831. } else {
  1832. this.$message.error(res.message)
  1833. this.tongbuLoading = false
  1834. }
  1835. })
  1836. },
  1837. handleOkChouzhen(e) {
  1838. var arr = []
  1839. for (let i = 0; i < this.chouzhenList.length; i++) {
  1840. for (let j = 0; j < this.checkList.length; j++) {
  1841. if (this.chouzhenList[i].signature == this.checkList[j]) {
  1842. arr.push(this.chouzhenList[i])
  1843. }
  1844. }
  1845. }
  1846. if (arr.length + this.pans[bestIndex].imageList[nowIndex].imageList.length > 4) {
  1847. this.$message.error(
  1848. '当前选择封面' +
  1849. arr.length +
  1850. '张,最多可选择' +
  1851. (4 - this.pans[bestIndex].imageList[nowIndex].imageList.length) +
  1852. '张'
  1853. )
  1854. return
  1855. } else {
  1856. this.pans[bestIndex].imageList[nowIndex].imageList.push(...arr)
  1857. this.chouzhen = false
  1858. this.chouzhenList = []
  1859. this.checkList = []
  1860. this.checkAll = false
  1861. }
  1862. },
  1863. showImages(index, bestIndex) {
  1864. this.chouzhen = true
  1865. this.chouzhenList = []
  1866. nowIndex = index
  1867. bestIndex = bestIndex
  1868. var params = {
  1869. md5Arr: this.pans[bestIndex].list[nowIndex].videoList.map((item) => {
  1870. return item.signature
  1871. }),
  1872. }
  1873. postAction('/ctop/kuaishouProgramCreative/getProgramCreativeCover', params).then((res) => {
  1874. console.log(res)
  1875. if (res.success) {
  1876. this.chouzhenList.push(...res.result)
  1877. }
  1878. })
  1879. },
  1880. uploadImages(index, bestIndex) {
  1881. nowIndex = index
  1882. bestIndex = bestIndex
  1883. this.addImageVisible = true
  1884. this.loadingImage = false
  1885. },
  1886. closeImage() {
  1887. this.addImageVisible = false
  1888. this.urlListImage = {
  1889. url: [],
  1890. md5: [],
  1891. }
  1892. this.imageArrList = []
  1893. nowIndex = 0
  1894. bestIndex = 0
  1895. this.loadingImage = false
  1896. },
  1897. closeVideo() {
  1898. this.addVideoVisible = false
  1899. this.urlList = {
  1900. url: '',
  1901. md5: '',
  1902. photoId: '',
  1903. }
  1904. nowIndex = 0
  1905. bestIndex = 0
  1906. this.messageTip = null
  1907. },
  1908. handleOkImage(e) {
  1909. this.loadingImage = true
  1910. var params = {
  1911. accountId: localStorage.getItem('accountId'),
  1912. uploadImageArr: this.imageArrList,
  1913. }
  1914. postAction('/kusiShouUpload/image', params).then((res) => {
  1915. if (res.success) {
  1916. if (res.result.length + this.pans[bestIndex].imageList[nowIndex].imageList > 4) {
  1917. this.$message.error(
  1918. '当前上传封面' +
  1919. res.result.length +
  1920. '张,最多可上传' +
  1921. (4 - this.pans[bestIndex].imageList[nowIndex].imageList.length) +
  1922. '张'
  1923. )
  1924. this.loadingImage = false
  1925. return
  1926. } else {
  1927. this.pans[bestIndex].imageList[nowIndex].imageList.push(...res.result)
  1928. this.closeImage()
  1929. this.loadingImage = false
  1930. }
  1931. } else {
  1932. this.$message.error('封面上传失败')
  1933. this.loadingImage = false
  1934. }
  1935. })
  1936. },
  1937. deleteImage(url) {
  1938. console.log(url, this.urlListImage.url)
  1939. var index = this.imageArrList.findIndex((v) => v.url === url)
  1940. this.imageArrList.splice(index, 1)
  1941. console.log(index)
  1942. },
  1943. overUploadImage(urlAll) {
  1944. var that = this
  1945. that.material = []
  1946. that.imageArrList = []
  1947. var img
  1948. if (urlAll.length > 0) {
  1949. for (var i = 0; i < urlAll.length; i++) {
  1950. that.imageArrList.push({
  1951. signature: this.urlListImage.md5[i],
  1952. url: urlAll[i].url,
  1953. })
  1954. img = new Image()
  1955. img.src = urlAll[i].url
  1956. // if (img.complete) {
  1957. // // 打印
  1958. // if (img.width == 720) {
  1959. // if (img.height == 1280) {
  1960. // that.material.push(true)
  1961. // } else {
  1962. // that.material.push(false)
  1963. // }
  1964. // } else if (img.width == 1080) {
  1965. // if (img.height == 1920) {
  1966. // that.material.push(true)
  1967. // } else {
  1968. // that.material.push(false)
  1969. // }
  1970. // } else if (img.width == 1280) {
  1971. // if (img.height == 720) {
  1972. // that.material.push(true)
  1973. // } else {
  1974. // that.material.push(false)
  1975. // }
  1976. // } else if (img.width == 1920) {
  1977. // if (img.height == 1080) {
  1978. // that.material.push(true)
  1979. // } else {
  1980. // that.material.push(false)
  1981. // }
  1982. // } else {
  1983. // that.material.push(false)
  1984. // }
  1985. // } else {
  1986. // img.onload = () => {
  1987. // if (img.width == 720) {
  1988. // if (img.height == 1280) {
  1989. // that.material.push(true)
  1990. // } else {
  1991. // that.material.push(false)
  1992. // }
  1993. // } else if (img.width == 1080) {
  1994. // if (img.height == 1920) {
  1995. // that.material.push(true)
  1996. // } else {
  1997. // that.material.push(false)
  1998. // }
  1999. // } else if (img.width == 1280) {
  2000. // if (img.height == 720) {
  2001. // that.material.push(true)
  2002. // } else {
  2003. // that.material.push(false)
  2004. // }
  2005. // } else if (img.width == 1920) {
  2006. // if (img.height == 1080) {
  2007. // that.material.push(true)
  2008. // } else {
  2009. // that.material.push(false)
  2010. // }
  2011. // } else {
  2012. // that.material.push(false)
  2013. // }
  2014. // }
  2015. // }
  2016. }
  2017. }
  2018. },
  2019. fileWater(file) {
  2020. var bmf = new BMF()
  2021. var that = this
  2022. // this.urlListImage = {
  2023. // url: [],
  2024. // md5: []
  2025. // }
  2026. return new Promise(function (resolve, reject) {
  2027. bmf.md5(file, (err, md5) => {
  2028. that.urlListImage.md5.push(md5)
  2029. resolve()
  2030. })
  2031. })
  2032. },
  2033. overUpload(urlAll) {
  2034. console.log(this.urlList)
  2035. },
  2036. file(file) {
  2037. var bmf = new BMF()
  2038. var that = this
  2039. return new Promise(function (resolve, reject) {
  2040. bmf.md5(file, (err, md5) => {
  2041. getAction('/kusiShouUpload/checkVideo', {
  2042. signature: md5,
  2043. accountId: localStorage.getItem('accountId'),
  2044. }).then((res) => {
  2045. if (res.code == 0) {
  2046. if (res.result.isExistence) {
  2047. showRemove = res.result.isExistence
  2048. that.urlList.md5 = res.result.signature
  2049. that.urlList.url = res.result.videoUrl
  2050. that.urlList.photoId = res.result.photoId
  2051. reject()
  2052. } else {
  2053. showRemove = res.result.isExistence
  2054. that.urlList.md5 = md5
  2055. resolve()
  2056. }
  2057. } else {
  2058. reject()
  2059. }
  2060. })
  2061. })
  2062. })
  2063. },
  2064. handleOkVideo(e) {
  2065. this.loadingVideo = true
  2066. if (showRemove) {
  2067. this.pans[bestIndex].list[nowIndex].videoList = {
  2068. photoId: this.urlList.photoId,
  2069. url: this.urlList.url,
  2070. }
  2071. this.loadingVideo = false
  2072. var params = {
  2073. videoSignature: this.urlList.md5,
  2074. pageSize: 20,
  2075. pageNo: 1,
  2076. }
  2077. getAction('/cutFrame/material/list', params).then((res) => {
  2078. console.log(res)
  2079. if (res.success) {
  2080. if (res.result.records.length > 0) {
  2081. this.pans[bestIndex].list[nowIndex].chouzhenShow = true
  2082. } else {
  2083. this.pans[bestIndex].list[nowIndex].chouzhenShow = false
  2084. }
  2085. }
  2086. })
  2087. this.closeVideo()
  2088. } else {
  2089. var params = {
  2090. url: this.urlList.url,
  2091. type: this.getData('creativeMaterialType'),
  2092. signature: this.urlList.md5,
  2093. accountId: localStorage.getItem('accountId'),
  2094. }
  2095. postAction('/kusiShouUpload/video', params).then((res) => {
  2096. console.log(res)
  2097. if (res.success) {
  2098. this.pans[bestIndex].list[nowIndex].videoList.push({
  2099. photoId: res.result.photoId,
  2100. url: this.urlList.url,
  2101. coverUrl: res.result.coverUrl,
  2102. })
  2103. this.loadingVideo = false
  2104. this.closeVideo()
  2105. } else {
  2106. this.messageTip = res.message
  2107. this.loadingVideo = false
  2108. this.urlList = {
  2109. url: '',
  2110. md5: '',
  2111. photoId: '',
  2112. }
  2113. nowIndex = 0
  2114. bestIndex = 0
  2115. }
  2116. })
  2117. }
  2118. },
  2119. deleteData(index, bestIndex, deleteIndex) {
  2120. this.pans[index].imageList[bestIndex].imageList.splice(deleteIndex, 1)
  2121. },
  2122. deleteVideo(index, bestIndex, deleteIndex) {
  2123. this.pans[index].list[bestIndex].videoList.splice(deleteIndex, 1)
  2124. },
  2125. handleOkShow(e) {
  2126. //
  2127. this.pans[bestIndex].list[nowIndex].imageList = []
  2128. if (this.pans[bestIndex].list[nowIndex].videoList.length >= 5) {
  2129. this.$message.error('最多选择五个视频')
  2130. return
  2131. }
  2132. this.pans[bestIndex].list[nowIndex].videoList = this.pans[bestIndex].list[nowIndex].videoList.concat(
  2133. this.checkVideo
  2134. )
  2135. this.ipagination.current = 1
  2136. this.visibleMatemal = false
  2137. },
  2138. judge(item) {
  2139. var re = /[(.*?)]/g
  2140. var array = []
  2141. var temp
  2142. while ((temp = re.exec(item.text))) {
  2143. array.push(temp[1])
  2144. }
  2145. console.log(array)
  2146. item.countTag = array.length
  2147. },
  2148. getChange(item, tag, index) {
  2149. console.log(item)
  2150. this.judge(item)
  2151. var node = document.getElementsByClassName('rending')[index]
  2152. var v = '[' + tag.name + ']'
  2153. if (document.selection) {
  2154. //IE
  2155. node.focus()
  2156. var sel = document.selection.createRange()
  2157. sel.text = v
  2158. sel.select()
  2159. item.description = v
  2160. } else if (node.selectionStart || node.selectionStart == '0') {
  2161. //MOZILLA/GOOGLE
  2162. var startPos = node.selectionStart
  2163. var endPos = node.selectionEnd
  2164. var restoreTop = node.scrollTop
  2165. node.value = node.value.substring(0, startPos) + v + node.value.substring(endPos, node.value.length)
  2166. if (restoreTop > 0) {
  2167. node.scrollTop = restoreTop
  2168. }
  2169. item.text = node.value
  2170. node.focus()
  2171. node.selectionStart = startPos + v.length
  2172. node.selectionEnd = startPos + v.length
  2173. item.description = node.value
  2174. } else {
  2175. //OTHER
  2176. node.value += v
  2177. item.text = node.value
  2178. node.focus()
  2179. item.description = node.value
  2180. }
  2181. },
  2182. getAppList(appId) {
  2183. getAction('/kuaishou/batch/getPageList', {
  2184. accountId: localStorage.getItem('accountId'),
  2185. appId: appId,
  2186. viewComp: 7,
  2187. }).then((res) => {
  2188. if (res.success) {
  2189. console.log(res)
  2190. this.siteList = res.result
  2191. }
  2192. })
  2193. },
  2194. },
  2195. computed: {
  2196. captionsCount() {
  2197. var data = this.captionsList.filter((item) => {
  2198. return item.captions != ''
  2199. })
  2200. return data.length
  2201. },
  2202. coverCount() {
  2203. var data = this.coverSlogansList.filter((item) => {
  2204. return item.coverSlogans != ''
  2205. })
  2206. return data.length
  2207. },
  2208. videoCount() {
  2209. // this.verticalPhoto.videoList
  2210. // return 0
  2211. // return this.horizontalPhoto[0].videoList.length+ this.verticalPhoto[0].videoList.length
  2212. },
  2213. dirImg() {
  2214. let date = new Date()
  2215. let y = date.getFullYear()
  2216. let MM = date.getMonth() + 1
  2217. MM = MM < 10 ? '0' + MM : MM
  2218. let d = date.getDate()
  2219. d = d < 10 ? '0' + d : d
  2220. return 'image/' + y + '-' + MM + '-' + d + '/'
  2221. },
  2222. dirVideo() {
  2223. let date = new Date()
  2224. let y = date.getFullYear()
  2225. let MM = date.getMonth() + 1
  2226. MM = MM < 10 ? '0' + MM : MM
  2227. let d = date.getDate()
  2228. d = d < 10 ? '0' + d : d
  2229. return 'video/' + y + '-' + MM + '-' + d + '/'
  2230. },
  2231. contentAll() {
  2232. var count,
  2233. arr = []
  2234. if (this.pans[0].list.length > 0) {
  2235. for (let i = 0; i < this.pans[0].list.length; i++) {
  2236. arr.push(...this.pans[0].list[i].checkArrImage, ...this.pans[0].list[i].imageList)
  2237. }
  2238. return arr.length + this.content
  2239. } else {
  2240. return 0
  2241. }
  2242. },
  2243. listCheck() {
  2244. if (this.pans[0].list.length > 0) {
  2245. if (
  2246. this.pans[0].list[this.pans[0].list.length - 1].imageUrlList.length == 0 &&
  2247. this.pans[0].list[this.pans[0].list.length - 1].imageList.length == 0
  2248. ) {
  2249. return true
  2250. } else {
  2251. return false
  2252. }
  2253. } else {
  2254. return false
  2255. }
  2256. },
  2257. },
  2258. watch: {
  2259. cunTitleVisible(n, o) {
  2260. if (!n) {
  2261. this.guanggao = []
  2262. this.cunTitleList = []
  2263. }
  2264. },
  2265. time(n, o) {
  2266. console.log(n)
  2267. if (n.length > 0) {
  2268. var params = {}
  2269. params.accountId = localStorage.getItem('accountId')
  2270. params.materialType = this.getData('creativeMaterialType')
  2271. params.pageSize = this.ipagination.pageSize
  2272. params.pageNo = 1
  2273. params.status = 0
  2274. params.channelType = this.channelType
  2275. params.startDate = moment(n[0]).format('YYYY-MM-DD') + ' 00:00:00'
  2276. params.endDate = moment(n[1]).format('YYYY-MM-DD') + ' 23:59:59'
  2277. this.showVideoList('/kuaishou/batch/getVideoList', params)
  2278. } else {
  2279. var params = {}
  2280. params.accountId = localStorage.getItem('accountId')
  2281. params.materialType = this.getData('creativeMaterialType')
  2282. params.pageSize = this.ipagination.pageSize
  2283. params.pageNo = 1
  2284. params.status = 0
  2285. params.channelType = this.channelType
  2286. this.ipagination.current = 1
  2287. this.showVideoList('/kuaishou/batch/getVideoList', params)
  2288. }
  2289. },
  2290. visibleVideo(n, o) {
  2291. if (!n) {
  2292. closeAllVideoFun()
  2293. }
  2294. },
  2295. clickTrackUrlList(n, o) {
  2296. if (!n) {
  2297. this.trackName = ''
  2298. }
  2299. },
  2300. },
  2301. mounted: function () {
  2302. this.$nextTick(() => {
  2303. if (localStorage.getItem('pans')) {
  2304. this.pans = JSON.parse(localStorage.getItem('pans')).map((item) => {
  2305. return {
  2306. ...item,
  2307. list: [],
  2308. imageList: [],
  2309. }
  2310. })
  2311. this.pansKey = this.pans[0].key
  2312. setTimeout(() => {
  2313. this.addCreative(0)
  2314. this.addAdList(0)
  2315. }, 0)
  2316. getAction('/kuaishou/batch/checkCreativeCount', {
  2317. unitId: this.pansKey,
  2318. accountId: localStorage.getItem('accountId'),
  2319. }).then((res) => {
  2320. console.log(res)
  2321. this.content = res.result
  2322. })
  2323. getAction('/kuaishou/batch/getActionBarText', {
  2324. campaignId: localStorage.getItem('campaignId')
  2325. ? localStorage.getItem('campaignId')
  2326. : localStorage.getItem('advertisingGroupKey'),
  2327. }).then((res) => {
  2328. if (res.success) {
  2329. this.appList = res.result
  2330. }
  2331. })
  2332. if (localStorage.getItem('appId')) {
  2333. this.showSite = true
  2334. this.getAppList(localStorage.getItem('appId'))
  2335. } else {
  2336. getAction('/kuaishou/batch/getAppId', {
  2337. accountId: localStorage.getItem('accountId'),
  2338. unitId: this.pansKey,
  2339. }).then((res) => {
  2340. if (res.success) {
  2341. if (res.result) {
  2342. this.showSite = true
  2343. this.getAppList(res.result)
  2344. } else {
  2345. this.showSite = false
  2346. }
  2347. }
  2348. })
  2349. }
  2350. }
  2351. getAction('/kuaishou/batch/creativeWord', {
  2352. accountId: localStorage.getItem('accountId'),
  2353. }).then((res) => {
  2354. if (res.success) {
  2355. this.tags = res.result
  2356. }
  2357. })
  2358. getAction('/kuaishou/batch/getCreativeCategory', {
  2359. accountId: localStorage.getItem('accountId'),
  2360. }).then((res) => {
  2361. if (res.success) {
  2362. console.log(res)
  2363. this.createOptions = res.result
  2364. }
  2365. })
  2366. getAction('/kuaishou/batch/getCreativeWordStyles', {
  2367. accountId: localStorage.getItem('accountId'),
  2368. }).then((res) => {
  2369. if (res.success) {
  2370. if (res.result) {
  2371. this.stickerStyles = res.result.map((item) => {
  2372. return {
  2373. id: item.sticker_style_id,
  2374. url: item.sticker_styles[0],
  2375. }
  2376. })
  2377. } else {
  2378. this.stickerStyles = []
  2379. }
  2380. } else {
  2381. this.stickerStyles = []
  2382. }
  2383. })
  2384. getAction('/kuaishou/batch/getWhiteList', {
  2385. accountId: localStorage.getItem('accountId'),
  2386. }).then((res) => {
  2387. if (res.success) {
  2388. // console.log(res)
  2389. if (res.result) {
  2390. this.creativeCategorySwitch = res.result.creative_category_switch == 1 ? true : false
  2391. this.actionbarClickUrlSwitch = res.result.actionbar_click_url_switch == 1 ? true : false
  2392. // if (res.result.alliance_account == 1) {
  2393. // this.allianceAccount = true
  2394. // } else {
  2395. // this.allianceAccount = false
  2396. // }
  2397. } else {
  2398. this.creativeCategorySwitch = false
  2399. this.actionbarClickUrlSwitch = false
  2400. }
  2401. }
  2402. })
  2403. })
  2404. },
  2405. }
  2406. </script>
  2407. <style lang="scss" scope>
  2408. $colors: #f9ca24, #3498db, #ff7979, #1abc9c, #e74c3c, #f8c291;
  2409. /* Recommended styles for Splitting */
  2410. .splitting .word,
  2411. .splitting .char {
  2412. display: inline-block;
  2413. }
  2414. /* Psuedo-element chars */
  2415. .splitting .char {
  2416. position: relative;
  2417. }
  2418. /**
  2419. * Populate the psuedo elements with the character to allow for expanded effects
  2420. * Set to `display: none` by default; just add `display: block` when you want
  2421. * to use the psuedo elements
  2422. */
  2423. .splitting .char::before,
  2424. .splitting .char::after {
  2425. content: attr(data-char);
  2426. position: absolute;
  2427. top: 0;
  2428. left: 0;
  2429. visibility: hidden;
  2430. transition: inherit;
  2431. user-select: none;
  2432. }
  2433. /* Expanded CSS Variables */
  2434. .splitting {
  2435. /* The center word index */
  2436. --word-center: calc((var(--word-total) - 1) / 2);
  2437. /* The center character index */
  2438. --char-center: calc((var(--char-total) - 1) / 2);
  2439. /* The center character index */
  2440. --line-center: calc((var(--line-total) - 1) / 2);
  2441. }
  2442. .splitting .word {
  2443. /* Pecent (0-1) of the word's position */
  2444. --word-percent: calc(var(--word-index) / var(--word-total));
  2445. /* Pecent (0-1) of the line's position */
  2446. --line-percent: calc(var(--line-index) / var(--line-total));
  2447. }
  2448. .splitting .char {
  2449. /* Percent (0-1) of the char's position */
  2450. --char-percent: calc(var(--char-index) / var(--char-total));
  2451. /* Offset from center, positive & negative */
  2452. --char-offset: calc(var(--char-index) - var(--char-center));
  2453. /* Absolute distance from center, only positive */
  2454. --distance: calc((var(--char-offset) * var(--char-offset)) / var(--char-center));
  2455. /* Distance from center where -1 is the far left, 0 is center, 1 is far right */
  2456. --distance-sine: calc(var(--char-offset) / var(--char-center));
  2457. /* Distance from center where 1 is far left/far right, 0 is center */
  2458. --distance-percent: calc((var(--distance) / var(--char-center)));
  2459. }
  2460. * {
  2461. box-sizing: border-box;
  2462. }
  2463. * {
  2464. margin: 0;
  2465. padding: 0;
  2466. }
  2467. // html, body {
  2468. // height: 100%;
  2469. // }
  2470. .headline {
  2471. align-items: center;
  2472. // background-color: var(--color);
  2473. display: flex;
  2474. font-family: 'Lexend Deca', sans-serif;
  2475. font-weight: 400;
  2476. // font-size: calc(1rem + 15vmin);
  2477. height: 72px;
  2478. justify-content: center;
  2479. // overflow: hidden;
  2480. perspective: 1000px;
  2481. scroll-snap-align: start;
  2482. width: 100%;
  2483. }
  2484. .word,
  2485. .char {
  2486. animation-delay: var(--del);
  2487. animation-direction: var(--dir, normal);
  2488. animation-duration: var(--dur);
  2489. animation-iteration-count: infinite;
  2490. animation-name: var(--name);
  2491. animation-timing-function: var(--tf);
  2492. display: inline-block;
  2493. position: relative;
  2494. transform-origin: 50% 100%;
  2495. z-index: 1;
  2496. }
  2497. // =========================
  2498. // Headline animations
  2499. // =========================
  2500. .headline--yell .char {
  2501. --name: yell;
  2502. --dur: 2s;
  2503. --tf: ease;
  2504. -webkit-transform-origin: 50% 100%;
  2505. transform-origin: 50% 100%;
  2506. }
  2507. @-webkit-keyframes yell {
  2508. 3% {
  2509. -webkit-transform: scale(calc(1 * var(--distance-percent) + 1.5)) rotate(calc(15deg * var(--distance-sine)))
  2510. translateY(-10%);
  2511. transform: scale(calc(1 * var(--distance-percent) + 1.5)) rotate(calc(15deg * var(--distance-sine)))
  2512. translateY(-10%);
  2513. }
  2514. 6% {
  2515. -webkit-transform: scale(calc(1 * var(--distance-percent) + 1.2)) rotate(calc(15deg * var(--distance-sine)))
  2516. translateY(-10%);
  2517. transform: scale(calc(1 * var(--distance-percent) + 1.2)) rotate(calc(15deg * var(--distance-sine)))
  2518. translateY(-10%);
  2519. }
  2520. 12% {
  2521. -webkit-transform: scale(calc(1 * var(--distance-percent) + 1.5)) rotate(calc(15deg * var(--distance-sine)))
  2522. translateY(-10%);
  2523. transform: scale(calc(1 * var(--distance-percent) + 1.5)) rotate(calc(15deg * var(--distance-sine)))
  2524. translateY(-10%);
  2525. }
  2526. 18% {
  2527. -webkit-transform: scaleY(1) translateY(-2%);
  2528. transform: scaleY(1) translateY(-2%);
  2529. }
  2530. 25% {
  2531. -webkit-transform: scaleY(0.98);
  2532. transform: scaleY(0.98);
  2533. }
  2534. 50% {
  2535. -webkit-transform: scaleY(1);
  2536. transform: scaleY(1);
  2537. }
  2538. 75% {
  2539. -webkit-transform: scale(0.98);
  2540. transform: scale(0.98);
  2541. }
  2542. }
  2543. @keyframes yell {
  2544. 3% {
  2545. -webkit-transform: scale(calc(1 * var(--distance-percent) + 1.5)) rotate(calc(15deg * var(--distance-sine)))
  2546. translateY(-10%);
  2547. transform: scale(calc(1 * var(--distance-percent) + 1.5)) rotate(calc(15deg * var(--distance-sine)))
  2548. translateY(-10%);
  2549. }
  2550. 6% {
  2551. -webkit-transform: scale(calc(1 * var(--distance-percent) + 1.2)) rotate(calc(15deg * var(--distance-sine)))
  2552. translateY(-10%);
  2553. transform: scale(calc(1 * var(--distance-percent) + 1.2)) rotate(calc(15deg * var(--distance-sine)))
  2554. translateY(-10%);
  2555. }
  2556. 12% {
  2557. -webkit-transform: scale(calc(1 * var(--distance-percent) + 1.5)) rotate(calc(15deg * var(--distance-sine)))
  2558. translateY(-10%);
  2559. transform: scale(calc(1 * var(--distance-percent) + 1.5)) rotate(calc(15deg * var(--distance-sine)))
  2560. translateY(-10%);
  2561. }
  2562. 18% {
  2563. -webkit-transform: scaleY(1) translateY(-2%);
  2564. transform: scaleY(1) translateY(-2%);
  2565. }
  2566. 25% {
  2567. -webkit-transform: scaleY(0.98);
  2568. transform: scaleY(0.98);
  2569. }
  2570. 50% {
  2571. -webkit-transform: scaleY(1);
  2572. transform: scaleY(1);
  2573. }
  2574. 75% {
  2575. -webkit-transform: scale(0.98);
  2576. transform: scale(0.98);
  2577. }
  2578. }
  2579. </style>