index.vue 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600
  1. <style lang="scss" scoped>
  2. .search-bar {
  3. display: flex;
  4. align-items: center;
  5. }
  6. .search-box p {
  7. display: inline-block;
  8. border: 1px solid #f2f2f2;
  9. border-radius: 5px;
  10. margin-right: 10px;
  11. padding: 5px 10px;
  12. cursor: pointer;
  13. }
  14. .card-person-drawer {
  15. width: 100%;
  16. height: 90%;
  17. overflow: hidden;
  18. padding: 10px 0px;
  19. display: flex;
  20. flex-wrap: wrap;
  21. margin-right: -10px;
  22. justify-content: space-between;
  23. /deep/ .ant-card-body {
  24. padding: 0;
  25. }
  26. /deep/ .ant-card-head {
  27. padding: 0 5px;
  28. }
  29. .card-item {
  30. width: calc(25% - 10px);
  31. margin-bottom: 10px;
  32. float: left;
  33. }
  34. .card-item-else {
  35. width: calc(20% - 10px);
  36. margin-bottom: 10px;
  37. float: left;
  38. }
  39. }
  40. </style>
  41. <style scoped>
  42. .showNumBox {
  43. margin: 10px 0;
  44. }
  45. .showNumBox .ant-card-body {
  46. display: flex;
  47. justify-content: center;
  48. }
  49. .showNumBox p,
  50. .showNumBox span {
  51. text-align: center;
  52. line-height: 40px;
  53. font-size: 30px;
  54. font-weight: 600;
  55. color: red;
  56. margin: 0;
  57. }
  58. .search-box .ant-card-body {
  59. padding: 5px 15px;
  60. }
  61. .showNumBox .ant-card-body .styleElse {
  62. line-height: 60px;
  63. height: 40px;
  64. font-size: 16px;
  65. font-weight: 400;
  66. margin-left: 10px;
  67. }
  68. .ant-modal-wrap .yincang .ant-modal-content .ant-modal-footer {
  69. display: none !important;
  70. }
  71. .yincang .ant-col-6 p {
  72. text-align: left;
  73. color: red;
  74. font-size: 16px;
  75. font-weight: 500;
  76. }
  77. .ant-table-thead div {
  78. font-weight: 700;
  79. }
  80. .tool-tip {
  81. position: absolute;
  82. top: 65px;
  83. right: 10px;
  84. }
  85. </style>
  86. <style lang="less" scoped>
  87. .ant-card-head .ant-tabs-bar {
  88. padding: 0;
  89. }
  90. .search-box .ant-card-body {
  91. padding: 5px 15px;
  92. }
  93. .search-box {
  94. padding: 15px 10px;
  95. }
  96. .search-box p {
  97. display: inline-block;
  98. border: 1px solid #f2f2f2;
  99. border-radius: 5px;
  100. margin-right: 10px;
  101. padding: 5px 10px;
  102. cursor: pointer;
  103. }
  104. .statistics .ant-col-6 .ant-card-body .styleElse {
  105. line-height: 60px;
  106. height: 40px;
  107. font-size: 16px;
  108. font-weight: 400;
  109. margin-left: 10px;
  110. }
  111. .ant-modal-wrap .yincang .ant-modal-content .ant-modal-footer {
  112. display: none !important;
  113. }
  114. .yincang .ant-col-6 p {
  115. text-align: left;
  116. color: red;
  117. font-size: 16px;
  118. font-weight: 500;
  119. }
  120. .ant-table-thead div {
  121. font-weight: 700;
  122. }
  123. .tool-tip {
  124. position: absolute;
  125. top: 65px;
  126. right: 10px;
  127. }
  128. .statistics {
  129. .ant-card-bordered {
  130. border: none;
  131. }
  132. .ant-card-head .ant-tabs {
  133. clear: both;
  134. margin-bottom: -13px;
  135. color: rgba(0, 0, 0, 0.65);
  136. font-weight: normal;
  137. font-size: 14px;
  138. }
  139. .duibi {
  140. position: absolute;
  141. right: 24px;
  142. top: 15px;
  143. }
  144. p {
  145. margin-bottom: 0;
  146. }
  147. }
  148. </style>
  149. <style lang="less" scoped>
  150. .middle-button {
  151. margin: 0 8px;
  152. }
  153. .newPlanStatic {
  154. .divider {
  155. height: 62px;
  156. }
  157. .showNumBox {
  158. background: white;
  159. overflow: hidden;
  160. margin: 15px 0;
  161. padding: 30px 0;
  162. text-align: center;
  163. .ant-card-body {
  164. padding-top: 0;
  165. }
  166. .title {
  167. font-size: 14px;
  168. font-family: PingFangSC-Regular, PingFang SC;
  169. font-weight: 400;
  170. color: #999999;
  171. line-height: 22px;
  172. display: inline-block;
  173. }
  174. }
  175. .tabbody {
  176. background: white;
  177. padding: 0 24px;
  178. margin-bottom: 15px;
  179. .ant-tabs-bar {
  180. margin: 0;
  181. }
  182. }
  183. .chartBox {
  184. background: white;
  185. padding: 20px 0;
  186. }
  187. .tableBody {
  188. background: white;
  189. padding: 20px;
  190. }
  191. }
  192. </style>
  193. <template>
  194. <div class="newPlanStatic config-project">
  195. <div class="tabbody">
  196. <a-tabs v-model="tabKey" @change="tabChange">
  197. <a-tab-pane :key="1" tab="素材测试配置信息"> </a-tab-pane>
  198. <!-- <a-tab-pane :key="2" tab="账户"> </a-tab-pane> -->
  199. <a-button slot="tabBarExtraContent" type="primary" @click="newCreat(null)">
  200. 创建投放策略
  201. </a-button>
  202. </a-tabs>
  203. </div>
  204. <a-card>
  205. <div class="table-page-search-wrapper">
  206. <a-form layout="inline" :form="form" hide-required-mark :selfUpdate="true" @submit="handleQueryList">
  207. <a-row :gutter="24" v-if="tabKey === 1">
  208. <a-col :md="8" :sm="8" :xxl="6">
  209. <a-form-item label="策略名称">
  210. <a-input
  211. v-decorator="['strategyName']"
  212. type="text"
  213. placeholder="请输入需要搜索的策略名称"
  214. />
  215. </a-form-item>
  216. </a-col>
  217. <!-- -->
  218. <a-col :md="8" :sm="8" :xxl="6">
  219. <a-form-item label="数据周期">
  220. <a-range-picker
  221. :disabled-date="disabledDate"
  222. format="YYYY-MM-DD"
  223. v-decorator="['timeRange', { initialValue: [moment(), moment()] }]"
  224. />
  225. </a-form-item>
  226. </a-col>
  227. <a-col :md="8" :sm="8" :xxl="6">
  228. <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
  229. <a-button type="primary" icon="search" @click="handleQueryList">查询</a-button>
  230. <a-button type="primary" @click="handleResetForm" icon="reload" class="middle-button"
  231. >重置</a-button
  232. >
  233. </span>
  234. </a-col>
  235. </a-row>
  236. </a-form>
  237. </div>
  238. </a-card>
  239. <a-row style="margin-bottom:15px;margin-top:12px">
  240. <a-col :span="24">
  241. <div class="tableBody" style="min-height:200px;padding-bottom: 50px">
  242. <a-table
  243. :columns="columns"
  244. :dataSource="dataSource"
  245. :pagination="false"
  246. :loading="dataLoading"
  247. bordered
  248. @change="tableChange"
  249. :scroll="{ x: 2500 }"
  250. size="middle"
  251. style="word-break: break-all;font-size:16px;font-weight:600"
  252. id="outTable"
  253. ref="accountTable"
  254. >
  255. <span slot="strategyStatus" slot-scope="text, record">
  256. <a-switch
  257. :checked="text == 0"
  258. @change="onChangeStatus(text, record, 'strategyStatus')"
  259. :loading="spinning"
  260. />
  261. </span>
  262. <span slot="projectStrategy" slot-scope="text, record">
  263. <a-switch
  264. :checked="text == 1"
  265. @change="onChangeStatus(text, record, 'projectStrategy')"
  266. :loading="spinning"
  267. v-if="record.projectName !== '-'"
  268. />
  269. </span>
  270. <span slot="statDate" slot-scope="text, record">
  271. {{ record.projectName !== '-' ? text : '-' }}
  272. </span>
  273. <span slot="projectName" slot-scope="text, record">
  274. <a @click="toAccountDetail(record)" v-if="tabKey === 1 && text !== '-'">{{ text }}</a>
  275. <span v-else> {{ text }} </span>
  276. </span>
  277. <span slot="allAccountCount" slot-scope="text, record">
  278. {{ record.successCount + '/' + text }}
  279. </span>
  280. <span slot="action" slot-scope="text, record">
  281. <div v-if="record.projectName !== '-'">
  282. <a @click="editPrice(record)">出价</a>
  283. <a-divider type="vertical" />
  284. <a @click="newCreat(record.id)">编辑</a>
  285. <a-divider type="vertical" />
  286. <a @click="matchingAccount(record)">变量条件</a>
  287. <a-divider type="vertical" />
  288. <a @click="selectMaterial(record)">选择素材</a>
  289. <a-divider type="vertical" />
  290. <a @click="lookPreview(record)">预览</a>
  291. </div>
  292. <div v-else>
  293. -
  294. </div>
  295. </span>
  296. <span slot="charge" slot-scope="text, record">{{
  297. record.reportData.charge | decimalsHandle
  298. }}</span>
  299. <span slot="play3sRate" slot-scope="text, record">{{ record.reportData.play3sRate }}</span>
  300. <span slot="impression1kCost" slot-scope="text, record">{{
  301. record.reportData.impression1kCost
  302. }}</span>
  303. <span slot="photoClick" slot-scope="text, record">{{
  304. record.reportData.photoClick | formatCurrency
  305. }}</span>
  306. <span slot="bclick" slot-scope="text, record">{{
  307. record.reportData.bclick | formatCurrency
  308. }}</span>
  309. <span slot="eventRegister" slot-scope="text, record">{{
  310. record.reportData.eventRegister | decimalsHandle
  311. }}</span>
  312. <span slot="bclickPrice" slot-scope="text, record">{{
  313. record.reportData.bclickPrice | decimalsHandle
  314. }}</span>
  315. <span slot="photoShow" slot-scope="text, record">{{
  316. record.reportData.photoShow | formatCurrency
  317. }}</span>
  318. <span slot="aclick" slot-scope="text, record">{{
  319. record.reportData.aclick | formatCurrency
  320. }}</span>
  321. <span slot="activation" slot-scope="text, record">{{ record.reportData.activation }}</span>
  322. <span slot="eventRegisterPrice" slot-scope="text, record">{{
  323. record.reportData.eventRegisterPrice | decimalsHandle
  324. }}</span>
  325. <span slot="bclickRate" slot-scope="text, record">{{ record.reportData.bclickRate }}</span>
  326. </a-table>
  327. <a-pagination
  328. size="small"
  329. :showTotal="ipagination.showTotal"
  330. style="float: right;margin-top:10px"
  331. v-if="dataSource.length > 0"
  332. showQuickJumper
  333. :pageSize.sync="ipagination.pageSize"
  334. :total="ipagination.total"
  335. v-model="ipagination.current"
  336. @change="getDataSource"
  337. />
  338. </div>
  339. </a-col>
  340. </a-row>
  341. <!-- 修改出价 -->
  342. <a-modal
  343. title="修改出价"
  344. v-if="modifyPriceVisible"
  345. :visible="modifyPriceVisible"
  346. :confirm-loading="modifyPriceLoading"
  347. dialog-class="push-modal"
  348. @ok="handleOkPrice"
  349. @cancel="handleCancelPrice"
  350. >
  351. <a-form
  352. :form="priceForm"
  353. :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
  354. :wrapperCol="{ lg: { span: 17 }, sm: { span: 17 } }"
  355. v-if="modifyPriceDetail"
  356. >
  357. <a-form-item label="策略名称"> {{ modifyPriceDetail.strategyName }} </a-form-item>
  358. <a-form-item label="优化目标">
  359. <a-button type="primary">{{ modifyPriceDetail.bidType | bidType }}</a-button></a-form-item
  360. >
  361. <a-form-item label="转化目标"> {{ modifyPriceDetail.ocpxActionType | ocpxActionType }}</a-form-item>
  362. <a-form-item label="计费方式">
  363. <a-button type="primary">{{
  364. modifyPriceDetail.bidType === 2 ? '点击计费(CPC)' : '按展示付费(oCPM)'
  365. }}</a-button>
  366. </a-form-item>
  367. <a-form-item label="转化目标出价">
  368. <a-input
  369. style="width:200px;ime-mode:disabled"
  370. v-decorator="['cpaBid', { rules: [{ required: true, validator: cpaBidValid }] }]"
  371. >
  372. </a-input>
  373. <br />
  374. <span style="color:red"
  375. >单出价请输入单数字,阶梯出价请用/隔开 例如10/12,区间出价请用-链接 例如20-25</span
  376. >
  377. </a-form-item>
  378. </a-form>
  379. </a-modal>
  380. <a-modal
  381. title="变量条件"
  382. :width="800"
  383. v-if="accountVisible"
  384. :visible="accountVisible"
  385. @ok="handleOkVariable"
  386. @cancel="accountVisible = false"
  387. dialog-class="push-modal"
  388. :confirm-loading="variableLoading"
  389. >
  390. <div style="height:600px;overflow:auto">
  391. <a-form
  392. :form="variableForm"
  393. :labelCol="{ lg: { span: 5 }, sm: { span: 5 } }"
  394. :wrapperCol="{ lg: { span: 19 }, sm: { span: 19 } }"
  395. v-if="accountProjectDetail"
  396. >
  397. <a-form-item label="策略名称">{{ accountProjectDetail.strategyName }} </a-form-item>
  398. <a-form-item label="地区">
  399. <checkBoxGroup
  400. :options="regionData"
  401. v-decorator="['region', { initialValue: [] }]"
  402. @change="setData($event, 'region')"
  403. />
  404. </a-form-item>
  405. <a-form-item label="年龄">
  406. <checkBoxGroup
  407. :options="[
  408. { label: '不限', value: 'unlimited' },
  409. { label: '18-23岁', value: '18' },
  410. { label: '24-30岁', value: '24' },
  411. { label: '31-40岁', value: '31' },
  412. { label: '41-49岁', value: '41' },
  413. { label: '50-100岁', value: '50' }
  414. ]"
  415. v-decorator="['agesRange', { initialValue: [] }]"
  416. @change="setData($event, 'agesRange')"
  417. />
  418. </a-form-item>
  419. <a-form-item label="性别">
  420. <checkBoxGroup
  421. :options="[
  422. { label: '不限', value: 'unlimited' },
  423. { label: '女', value: '1' },
  424. { label: '男', value: '0' }
  425. ]"
  426. v-decorator="['gender', { initialValue: [] }]"
  427. @change="setData($event, 'gender')"
  428. />
  429. </a-form-item>
  430. <a-form-item label="行为意向">
  431. <checkBoxGroup
  432. :options="[
  433. { label: '不限', value: 'unlimited' },
  434. { label: '系统优选', value: '1' }
  435. ]"
  436. v-decorator="['intentionTarget', { initialValue: [] }]"
  437. />
  438. </a-form-item>
  439. <a-form-item label="APP行为">
  440. <checkBoxGroup
  441. :options="[
  442. { label: '不限', value: 'unlimited' },
  443. { label: '按App名称', value: '1', disabled: !accountProjectDetail.accountId }
  444. ]"
  445. v-decorator="['appIds', { initialValue: [] }]"
  446. @change="setData($event, 'appIds')"
  447. />
  448. <el-select
  449. v-if="getElseData('appIds') ? getElseData('appIds').includes('1') : false"
  450. v-model="appIds"
  451. multiple
  452. filterable
  453. remote
  454. reserve-keyword
  455. placeholder="请输入关键词"
  456. :remote-method="remoteMethod"
  457. style="margin-top:10px"
  458. >
  459. <el-option
  460. v-for="item in appOptions"
  461. :key="item.value"
  462. :label="item.label"
  463. :value="item.value"
  464. >
  465. </el-option>
  466. </el-select>
  467. </a-form-item>
  468. <a-form-item label="智能扩量">
  469. <checkBoxGroup
  470. :options="[
  471. { label: '关闭', value: '0' },
  472. { label: '开启', value: '1' },
  473. {
  474. label: '不可突破年龄',
  475. value: '2',
  476. disabled: getElseData('agesRange')
  477. ? getElseData('agesRange').includes('18') ||
  478. getElseData('agesRange').includes('24') ||
  479. getElseData('agesRange').includes('31') ||
  480. getElseData('agesRange').includes('41') ||
  481. getElseData('agesRange').includes('50')
  482. ? false
  483. : true
  484. : true
  485. },
  486. {
  487. label: '不可突破性别',
  488. value: '3',
  489. disabled: getElseData('gender')
  490. ? getElseData('gender').includes('0') || getElseData('gender').includes('1')
  491. ? false
  492. : true
  493. : true
  494. },
  495. {
  496. label: '不可突破地域',
  497. value: '4',
  498. disabled: getElseData('region')
  499. ? getElseData('region').includes('1') || getElseData('region').includes('2')
  500. ? false
  501. : true
  502. : true
  503. }
  504. ]"
  505. v-decorator="['intelliExtend', { initialValue: [] }]"
  506. />
  507. </a-form-item>
  508. <a-form-item label="投放时段">
  509. <a-button type="primary" @click="addSchedule">新增变量</a-button>
  510. </a-form-item>
  511. <div style="width:100%">
  512. <div v-for="(item, index) in scheduleTimeData" style="margin-bottom:15px;display:flex">
  513. <selectCheckAll
  514. style="width:100%;margin-right:5px"
  515. :scheduleTime.sync="item.scheduleTime"
  516. ref="selectCheck"
  517. />
  518. <a-icon type="delete" v-if="scheduleTimeData.length > 1" @click="deleteSchedule(index)" />
  519. </div>
  520. </div>
  521. </a-form>
  522. </div>
  523. </a-modal>
  524. <!-- 选择素材 -->
  525. <a-modal
  526. title="选择素材"
  527. :width="1000"
  528. v-if="materialVisible"
  529. :visible="materialVisible"
  530. :confirm-loading="materialLoading"
  531. dialog-class="push-modal"
  532. @ok="handleOkMaterial"
  533. @cancel="
  534. materialVisible = false
  535. checkPersonElse = []
  536. checkVideo = []
  537. checkPersonOne = ''
  538. sumContent = 0
  539. "
  540. >
  541. <div style="width:100%;display:flex;">
  542. <span></span>
  543. <span>已选择:{{ sumContent }}</span>
  544. </div>
  545. <a-checkbox-group v-model="checkVideo" style="width: 100%;" @change="setVideoDataAll">
  546. <div class="card-person-drawer info-detail">
  547. <a-card class="card-person card-item" v-for="(item, index) in dataVideoList" :key="index">
  548. <div
  549. slot="title"
  550. style=" overflow: hidden;
  551. text-overflow: ellipsis;
  552. white-space: nowrap;"
  553. >
  554. {{ item.photoName }}
  555. </div>
  556. <div slot="extra">
  557. <a-checkbox :value="item.photoId" @change="setVideoData(item.photoId)"></a-checkbox>
  558. </div>
  559. <div style="width:100%;border: 1px solid #f2f2f2;position:relative">
  560. <img :src="item.coverUrl" style="width:100%" alt="" />
  561. <a-tag color="blue" v-if="item.useStatus == 0" style="position:absolute;top:5px;right:0px">
  562. 已测试
  563. </a-tag>
  564. </div>
  565. </a-card>
  566. </div>
  567. </a-checkbox-group>
  568. <div style="text-align:right">
  569. <a-pagination
  570. size="small"
  571. :showTotal="ipaginationVideo.showTotal"
  572. style="float:right"
  573. v-if="dataVideoList.length > 0"
  574. showQuickJumper
  575. :pageSize.sync="ipaginationVideo.pageSize"
  576. :total="ipaginationVideo.total"
  577. v-model="ipaginationVideo.current"
  578. @change="getDataVideo"
  579. />
  580. </div>
  581. </a-modal>
  582. </div>
  583. </template>
  584. <script>
  585. import { TreeSelect } from 'ant-design-vue'
  586. const SHOW_PARENT = TreeSelect.SHOW_PARENT
  587. import ARow from 'ant-design-vue/es/grid/Row'
  588. import ACol from 'ant-design-vue/es/grid/Col'
  589. import moment from 'moment'
  590. import pick from 'lodash.pick'
  591. import { getKsAccountReport, getKsDetail, getReportList } from '@api/video.js'
  592. import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
  593. import checkBoxGroup from '@/components/formComponents/checkBoxGroup'
  594. import selectCheckAll from '@/views/modules/kuaishouapp/account/stepForm/stepModule/test'
  595. import qs from 'qs'
  596. function tqFun(qcArr1) {
  597. var tempArr = []
  598. function bbFun(qcArr) {
  599. for (var i = 0; i < qcArr.length; i++) {
  600. if (qcArr[i] instanceof Array) {
  601. bbFun(qcArr[i])
  602. } else {
  603. tempArr.push(qcArr[i])
  604. }
  605. }
  606. return tempArr
  607. }
  608. return bbFun(qcArr1)
  609. }
  610. let TTcolumns = [
  611. {
  612. title: '开关',
  613. dataIndex: 'strategyStatus',
  614. scopedSlots: { customRender: 'strategyStatus' },
  615. align: 'center',
  616. key: 'strategyStatus'
  617. },
  618. {
  619. title: '策略名称',
  620. dataIndex: 'strategyName',
  621. scopedSlots: { customRender: 'strategyName' },
  622. align: 'center',
  623. key: 'strategyName'
  624. },
  625. {
  626. title: '策略日期',
  627. dataIndex: 'createTime',
  628. scopedSlots: { customRender: 'createTime' },
  629. align: 'center',
  630. key: 'createTime'
  631. },
  632. {
  633. title: '操作',
  634. dataIndex: 'action',
  635. scopedSlots: { customRender: 'action' },
  636. align: 'center',
  637. key: 'action',
  638. width: '300px'
  639. },
  640. {
  641. title: '消耗',
  642. dataIndex: 'charge',
  643. scopedSlots: { customRender: 'charge' },
  644. align: 'center',
  645. key: 'charge',
  646. sorter: () => {}
  647. },
  648. {
  649. title: '封面曝光数',
  650. dataIndex: 'photoShow',
  651. scopedSlots: { customRender: 'photoShow' },
  652. align: 'center',
  653. key: 'photoShow',
  654. sorter: () => {}
  655. },
  656. {
  657. title: '封面点击数',
  658. dataIndex: 'photoClick',
  659. scopedSlots: { customRender: 'photoClick' },
  660. align: 'center',
  661. key: 'photoClick',
  662. sorter: () => {}
  663. },
  664. {
  665. title: '素材曝光数',
  666. dataIndex: 'aclick',
  667. scopedSlots: { customRender: 'aclick' },
  668. align: 'center',
  669. key: 'aclick',
  670. sorter: () => {}
  671. },
  672. {
  673. title: '行为数',
  674. dataIndex: 'bclick',
  675. scopedSlots: { customRender: 'bclick' },
  676. align: 'center',
  677. key: 'bclick',
  678. sorter: () => {}
  679. },
  680. {
  681. title: '行为率',
  682. dataIndex: 'bclickRate',
  683. scopedSlots: { customRender: 'bclickRate' },
  684. align: 'center',
  685. key: 'bclickRate',
  686. sorter: () => {}
  687. },
  688. {
  689. title: '平均千次封面曝光花费(元)',
  690. dataIndex: 'impression1kCost',
  691. scopedSlots: { customRender: 'impression1kCost' },
  692. align: 'center',
  693. key: 'impression1kCost',
  694. sorter: () => {}
  695. },
  696. {
  697. title: '平均行为单价(元)',
  698. dataIndex: 'bclickPrice',
  699. scopedSlots: { customRender: 'bclickPrice' },
  700. align: 'center',
  701. key: 'bclickPrice',
  702. sorter: () => {}
  703. },
  704. {
  705. title: '注册数',
  706. dataIndex: 'eventRegister',
  707. scopedSlots: { customRender: 'eventRegister' },
  708. align: 'center',
  709. key: 'eventRegister',
  710. sorter: () => {}
  711. },
  712. {
  713. title: '注册单价',
  714. dataIndex: 'eventRegisterPrice',
  715. scopedSlots: { customRender: 'eventRegisterPrice' },
  716. align: 'center',
  717. key: 'eventRegisterPrice',
  718. sorter: () => {}
  719. }
  720. ]
  721. let KScolumns = []
  722. export default {
  723. components: {
  724. ACol,
  725. ARow,
  726. checkBoxGroup,
  727. selectCheckAll
  728. },
  729. data() {
  730. return {
  731. appIds: [],
  732. appOptions: [],
  733. materialVisible: false,
  734. materialLoading: false,
  735. scheduleTimeData: [{ scheduleTime: '' }],
  736. indexAll: 0,
  737. spinning: false,
  738. form: this.$form.createForm(this),
  739. priceForm: this.$form.createForm(this),
  740. variableForm: this.$form.createForm(this),
  741. variableLoading: false,
  742. exportloading: false,
  743. dateRange: [moment().subtract(1, 'weeks'), moment()],
  744. noImg: require('@/assets/noImg.png'),
  745. validationRules: {
  746. bid: [
  747. {
  748. required: true,
  749. message: '出价信息必须填写'
  750. // validator: this.validateBid,
  751. }
  752. ]
  753. },
  754. ipagination: {
  755. current: 1,
  756. pageSize: 10,
  757. // pageSizeOptions: ['10', '20', '30'],
  758. showTotal: (total, range) => {
  759. return range[0] + '-' + range[1] + ' 共' + total + '条'
  760. },
  761. showQuickJumper: true,
  762. showSizeChanger: true,
  763. pageSizeOptions: ['10', '30', '50'],
  764. total: 0,
  765. onChange: (current, pageSize) => {
  766. // 切换分页时的回调,
  767. // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
  768. this.ipagination.current = current
  769. this.ipagination.pageSize = pageSize
  770. }
  771. },
  772. ipaginationVideo: {
  773. current: 1,
  774. pageSize: 8,
  775. id: '',
  776. accountId: '',
  777. // pageSizeOptions: ['10', '20', '30'],
  778. showTotal: (total, range) => {
  779. return range[0] + '-' + range[1] + ' 共' + total + '条'
  780. },
  781. showQuickJumper: true,
  782. // showSizeChanger: true,
  783. total: 0,
  784. onChange: current => {
  785. // 切换分页时的回调,
  786. // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
  787. this.ipaginationVideo.current = current
  788. }
  789. },
  790. value: 'valid',
  791. KSaccountList: [],
  792. TTaccountList: [],
  793. KSdesignList: [],
  794. TTdesignList: [],
  795. operateDisabled: false,
  796. duration: 1000,
  797. //treeselect的参数
  798. treeValue: [],
  799. treeData: [],
  800. SHOW_PARENT,
  801. type: 3,
  802. dateValue: [moment().subtract(7, 'days'), moment()],
  803. operate: '',
  804. designList: [],
  805. tabKey: 1,
  806. loading: false,
  807. TTcolumns,
  808. KScolumns,
  809. columns: [...TTcolumns],
  810. dataSource: [],
  811. dataVideoList: [],
  812. checkVideo: [],
  813. checkPersonOne: '',
  814. checkPersonElse: [],
  815. sumContent: 0,
  816. tableTab: 1,
  817. newPlan: 0,
  818. effectPlan: 0,
  819. openOptions: false,
  820. target: 'createTime',
  821. order: 'descend',
  822. projectId: undefined,
  823. projectIdAll: undefined,
  824. dataLoading: false,
  825. url: '/kuaishouProjectStrategy/queryProjectList',
  826. modifyPriceVisible: false,
  827. modifyPriceLoading: false,
  828. modifyPriceDetail: null,
  829. accountVisible: false,
  830. againLoading: false,
  831. accountProjectDetail: null,
  832. regionData: [{ label: '不限', value: 'unlimited' }]
  833. }
  834. },
  835. methods: {
  836. moment,
  837. setData(e, type) {
  838. if (type == 'region') {
  839. if (e.includes('1') || e.includes('2')) {
  840. } else {
  841. let region = this.getElseData('intelliExtend')
  842. let regionIndex = region.findIndex(item => item === '4')
  843. if (regionIndex > -1) {
  844. region.splice(regionIndex, 1)
  845. this.variableForm.setFieldsValue({ intelliExtend: region })
  846. }
  847. }
  848. } else if (type == 'agesRange') {
  849. if (e.includes('18') || e.includes('24') || e.includes('31') || e.includes('41') || e.includes('50')) {
  850. } else {
  851. let agesRange = this.getElseData('intelliExtend')
  852. let agesRangeIndex = agesRange.findIndex(item => item === '2')
  853. if (agesRangeIndex > -1) {
  854. agesRange.splice(agesRangeIndex, 1)
  855. this.variableForm.setFieldsValue({ intelliExtend: agesRange })
  856. }
  857. }
  858. } else if (type == 'gender') {
  859. if (e.includes('1') || e.includes('0')) {
  860. } else {
  861. let gender = this.getElseData('intelliExtend')
  862. let genderIndex = gender.findIndex(item => item === '3')
  863. if (genderIndex > -1) {
  864. gender.splice(genderIndex, 1)
  865. this.variableForm.setFieldsValue({ intelliExtend: gender })
  866. }
  867. }
  868. } else if (type == 'appIds') {
  869. if (e.includes('1')) {
  870. } else {
  871. this.appIds = []
  872. }
  873. }
  874. },
  875. newCreat(id) {
  876. if (id) {
  877. this.$router.push({
  878. path: '/autoLaunch/creatMaterialTest?id=' + id
  879. })
  880. } else {
  881. // window.open('/creat-material-test', '_blank')
  882. this.$router.push({
  883. path: '/autoLaunch/creatMaterialTest'
  884. })
  885. }
  886. },
  887. remoteMethod(query) {
  888. if (query !== '') {
  889. getAction('/kuaishou/batch/getAppSearch', {
  890. accountId: this.accountProjectDetail.accountId,
  891. appName: query
  892. }).then(res => {
  893. if (res.result) {
  894. this.appOptions = res.result.map(item => {
  895. return {
  896. value: item.appId,
  897. label: item.appName
  898. }
  899. })
  900. } else {
  901. }
  902. })
  903. } else {
  904. this.appOptions = []
  905. }
  906. },
  907. addSchedule() {
  908. this.scheduleTimeData.push({ scheduleTime: '' })
  909. },
  910. deleteSchedule(index) {
  911. this.scheduleTimeData.splice(index, 1)
  912. },
  913. handleOkVariable() {
  914. this.variableForm.validateFields((err, values) => {
  915. if (!err) {
  916. this.variableLoading = true
  917. let params = { ...values }
  918. params.agesRange = JSON.stringify(values.agesRange)
  919. values.appIds = values.appIds.includes('1') ? ['unlimited'] : ['unlimited']
  920. params.appIds =
  921. this.appIds.length > 0
  922. ? JSON.stringify([values.appIds, this.appIds])
  923. : JSON.stringify([values.appIds])
  924. params.gender = JSON.stringify(values.gender)
  925. params.intelliExtend = JSON.stringify(values.intelliExtend)
  926. params.intentionTarget = JSON.stringify(values.intentionTarget)
  927. params.region = JSON.stringify(values.region)
  928. params.scheduleTime = JSON.stringify(
  929. this.scheduleTimeData.map(item => {
  930. return item.scheduleTime
  931. })
  932. )
  933. if (this.accountProjectDetail.editId) {
  934. params.id = this.accountProjectDetail.editId
  935. this.postDataAction('/dimension/kuaiShouDimensionVariable/edit', params).then(res => {
  936. console.log(res)
  937. if (res.success) {
  938. this.accountVisible = false
  939. this.variableLoading = false
  940. this.variableForm.resetFields()
  941. this.scheduleTimeData = [{ scheduleTime: '' }]
  942. } else {
  943. this.variableLoading = false
  944. this.$message.error('修改失败')
  945. }
  946. })
  947. } else {
  948. params.strategyId = this.accountProjectDetail.id
  949. this.postDataAction('/dimension/kuaiShouDimensionVariable/add', params).then(res => {
  950. console.log(res)
  951. if (res.success) {
  952. this.accountVisible = false
  953. this.variableLoading = false
  954. this.variableForm.resetFields()
  955. this.scheduleTimeData = [{ scheduleTime: '' }]
  956. } else {
  957. this.variableLoading = false
  958. this.$message.error('添加失败')
  959. }
  960. })
  961. }
  962. }
  963. })
  964. },
  965. editPrice(item) {
  966. this.modifyPriceVisible = true
  967. this.modifyPriceDetail = { ...item }
  968. this.$nextTick(() => {
  969. let cpaBid = ''
  970. let changeBid =
  971. this.modifyPriceDetail.bidType === 2 ? this.modifyPriceDetail.bid : this.modifyPriceDetail.cpaBid
  972. if ((changeBid + '').includes('/')) {
  973. let bidArr = changeBid.split('/')
  974. for (let index = 0; index < bidArr.length; index++) {
  975. bidArr[index] = bidArr[index] / 1000
  976. }
  977. cpaBid = bidArr.join('/')
  978. } else if ((changeBid + '').includes('-')) {
  979. let bidArr = changeBid.split('-')
  980. for (let index = 0; index < bidArr.length; index++) {
  981. bidArr[index] = bidArr[index] / 1000
  982. }
  983. cpaBid = bidArr.join('-')
  984. } else {
  985. cpaBid = changeBid / 1000
  986. }
  987. let deepConversionBid = undefined
  988. if (this.modifyPriceDetail.deepConversionBid && this.modifyPriceDetail.deepConversionBid != '') {
  989. if ((this.modifyPriceDetail.deepConversionBid + '').includes('/')) {
  990. let bidArr = this.modifyPriceDetail.deepConversionBid.split('/')
  991. for (let index = 0; index < bidArr.length; index++) {
  992. bidArr[index] = bidArr[index] / 1000
  993. }
  994. deepConversionBid = bidArr.join('/')
  995. } else if ((this.modifyPriceDetail.deepConversionBid + '').includes('-')) {
  996. let bidArr = this.modifyPriceDetail.deepConversionBid.split('-')
  997. for (let index = 0; index < bidArr.length; index++) {
  998. bidArr[index] = bidArr[index] / 1000
  999. }
  1000. deepConversionBid = bidArr.join('-')
  1001. } else {
  1002. deepConversionBid = this.modifyPriceDetail.deepConversionBid / 1000
  1003. }
  1004. }
  1005. this.priceForm.setFieldsValue({
  1006. cpaBid: cpaBid,
  1007. deepConversionBid: deepConversionBid
  1008. })
  1009. })
  1010. },
  1011. handleOkPrice() {
  1012. this.priceForm.validateFields((err, values) => {
  1013. //console.log(values)
  1014. if (!err) {
  1015. this.modifyPriceLoading = true
  1016. if (values.cpaBid) {
  1017. if ((values.cpaBid + '').includes('/')) {
  1018. let bidArr = values.cpaBid.split('/')
  1019. for (let index = 0; index < bidArr.length; index++) {
  1020. bidArr[index] = bidArr[index] * 1000
  1021. }
  1022. values.cpaBid = bidArr.join('/')
  1023. } else if ((values.cpaBid + '').includes('-')) {
  1024. let bidArr = values.cpaBid.split('-')
  1025. for (let index = 0; index < bidArr.length; index++) {
  1026. bidArr[index] = bidArr[index] * 1000
  1027. }
  1028. values.cpaBid = bidArr.join('-')
  1029. } else {
  1030. values.cpaBid = values.cpaBid * 1000
  1031. }
  1032. } else {
  1033. values.cpaBid = 0
  1034. }
  1035. if (values.deepConversionBid) {
  1036. if ((values.deepConversionBid + '').includes('/')) {
  1037. let bidArr = values.deepConversionBid.split('/')
  1038. for (let index = 0; index < bidArr.length; index++) {
  1039. bidArr[index] = bidArr[index] * 1000
  1040. }
  1041. values.deepConversionBid = bidArr.join('/')
  1042. } else if ((values.deepConversionBid + '').includes('-')) {
  1043. let bidArr = values.deepConversionBid.split('-')
  1044. for (let index = 0; index < bidArr.length; index++) {
  1045. bidArr[index] = bidArr[index] * 1000
  1046. }
  1047. values.deepConversionBid = bidArr.join('-')
  1048. } else {
  1049. values.deepConversionBid = values.deepConversionBid * 1000
  1050. }
  1051. } else {
  1052. values.deepConversionBid = 0
  1053. }
  1054. // this.modifyPriceDetail
  1055. let params = {}
  1056. if (this.modifyPriceDetail.bidType === 2) {
  1057. params.bid = values.cpaBid
  1058. if (values.deepConversionBid) {
  1059. params.deepConversionBid = values.deepConversionBid
  1060. }
  1061. } else {
  1062. params = { ...values }
  1063. }
  1064. postAction('/dimension/kuaiShouDimensionStrategy/edit', {
  1065. ...params,
  1066. id: this.modifyPriceDetail.id
  1067. }).then(res => {
  1068. this.modifyPriceLoading = false
  1069. if (res.success) {
  1070. this.handleCancelPrice()
  1071. const paramsData = this.form.getFieldsValue()
  1072. this.handleGetTableList(paramsData)
  1073. } else {
  1074. this.$message.error(res.message)
  1075. }
  1076. })
  1077. } else {
  1078. this.$message.error('请正确填写必填项目')
  1079. }
  1080. })
  1081. },
  1082. handleCancelPrice() {
  1083. this.priceForm.resetFields()
  1084. this.modifyPriceVisible = false
  1085. },
  1086. cpaBidValid(rule, value, callback) {
  1087. let z = /-/g
  1088. let a = /\//g
  1089. let d = /\./g
  1090. if (value === '' || value === undefined) {
  1091. callback('出价必须填写')
  1092. } else if (value.startsWith('.') || value.endsWith('.')) {
  1093. callback('请填写正确出价')
  1094. } else if (value.startsWith('-') || value.endsWith('-')) {
  1095. callback('请填写正确出价')
  1096. } else if (value.match(a) && value.match(z)) {
  1097. callback('不允许出现除"-"和"/"之外的所有字符,并且二者不可同时出现')
  1098. } else if (value.match(/[^0-9+-\/]/g)) {
  1099. callback('请填写正确出价')
  1100. } else {
  1101. callback()
  1102. }
  1103. },
  1104. btKeyUp(e) {
  1105. //没有显示‘破折号’和 '.' 需要的可以手动加上
  1106. // this.priceForm.setFieldsValue({
  1107. // cpaBid: e.target.value.replace(/[^0-9+-\/]/g, '')
  1108. // })
  1109. // (
  1110. // /[\u4e00-\u9fa5/\s+/]|[`~!@#$%^&*() \+ =<>?"{}|, \/ ;' \\ [ \] ·~!@#¥%……&*()—— \+ ={}|《》?:“”【】、;‘’,。、]/g,
  1111. // ''
  1112. // )
  1113. },
  1114. getData(className) {
  1115. return this.priceForm.getFieldValue(className)
  1116. },
  1117. getElseData(className) {
  1118. return this.variableForm.getFieldValue(className)
  1119. },
  1120. againAccount() {
  1121. this.againLoading = true
  1122. this.getAction('/ai/projectCreate/projectAutomaticCreates', {
  1123. id: this.accountProjectDetail.id,
  1124. operationType: 1
  1125. }).then(res => {
  1126. this.againLoading = false
  1127. if (res.success) {
  1128. this.$message.success('重新匹配成功')
  1129. } else {
  1130. this.$message.error(res.message)
  1131. }
  1132. })
  1133. },
  1134. matchingAccount(item) {
  1135. this.accountVisible = true
  1136. this.accountProjectDetail = { ...item }
  1137. getAction('/dimension/kuaiShouDimensionAccount/getStrategyBindAccount', {
  1138. strategyId: item.id
  1139. }).then(res => {
  1140. console.log(res)
  1141. if (res.success) {
  1142. this.accountProjectDetail.accountId = res.result
  1143. } else {
  1144. this.accountProjectDetail.accountId = null
  1145. }
  1146. })
  1147. getAction('/dimension/kuaiShouDimensionVariable/selectVariableByStrategyId', { strategyId: item.id }).then(
  1148. res => {
  1149. if (res.success) {
  1150. getAction('/dimension/kuaiShouDimensionVariable/queryByStrategyId', {
  1151. strategyId: item.id
  1152. }).then(res => {
  1153. if (res.success) {
  1154. if (res.result) {
  1155. this.accountProjectDetail.editId = res.result.id
  1156. let data = {}
  1157. data.region = JSON.parse(res.result.region)
  1158. data.agesRange = JSON.parse(res.result.agesRange)
  1159. data.gender = JSON.parse(res.result.gender)
  1160. data.intentionTarget = JSON.parse(res.result.intentionTarget)
  1161. data.appIds = tqFun(JSON.parse(res.result.appIds))
  1162. if (data.appIds.length >= 2) {
  1163. console.log(this.appIds)
  1164. this.appIds = tqFun(JSON.parse(res.result.appIds))
  1165. console.log(this.appIds)
  1166. let index = this.appIds.findIndex(item => item == 'unlimited')
  1167. this.appIds.splice(index, 1)
  1168. data.appIds = ['unlimited', '1']
  1169. }
  1170. data.intelliExtend = JSON.parse(res.result.intelliExtend)
  1171. this.$nextTick(() => {
  1172. this.scheduleTimeData = JSON.parse(res.result.scheduleTime).map(item => {
  1173. return { scheduleTime: item }
  1174. })
  1175. this.variableForm.setFieldsValue(
  1176. pick(
  1177. data,
  1178. 'region',
  1179. 'agesRange',
  1180. 'gender',
  1181. 'intentionTarget',
  1182. 'appIds',
  1183. 'intelliExtend'
  1184. )
  1185. )
  1186. })
  1187. }
  1188. } else {
  1189. this.accountProjectDetail.editId = null
  1190. }
  1191. })
  1192. }
  1193. }
  1194. )
  1195. },
  1196. selectMaterial(item) {
  1197. getAction('/dimension/kuaiShouDimensionAccount/getStrategyBindAccount', {
  1198. strategyId: item.id
  1199. }).then(res => {
  1200. if (res.success) {
  1201. this.ipaginationVideo.id = item.id
  1202. this.ipaginationVideo.accountId = res.result
  1203. this.ipaginationVideo.current = 1
  1204. postAction('/dimension/kuaiShouDimensionMaterial/getVideoList', {
  1205. id: this.ipaginationVideo.id,
  1206. accountId: this.ipaginationVideo.accountId,
  1207. pageSize: this.ipaginationVideo.pageSize,
  1208. pageNo: this.ipaginationVideo.current
  1209. }).then(resNei => {
  1210. if (resNei.success) {
  1211. this.materialVisible = true
  1212. this.dataVideoList = resNei.result.list
  1213. this.ipaginationVideo.total = resNei.result.total
  1214. }
  1215. })
  1216. } else {
  1217. }
  1218. })
  1219. },
  1220. lookPreview(item) {
  1221. this.$router.push({
  1222. path: '/autoLaunch/lookPreview?id=' + item.id
  1223. })
  1224. // getAction('/dimension/kuaiShouDimensionUnit/previewByStrategyId', { strategyId: item.id }).then(res => {})
  1225. },
  1226. getDataVideo(current, pageSize) {
  1227. // 切换分页时的回调,
  1228. // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
  1229. this.ipaginationVideo.current = current
  1230. this.ipaginationVideo.pageSize = pageSize
  1231. this.checkVideo = this.checkPersonElse
  1232. postAction('/dimension/kuaiShouDimensionMaterial/getVideoList', {
  1233. id: this.ipaginationVideo.id,
  1234. accountId: this.ipaginationVideo.accountId,
  1235. pageSize: this.ipaginationVideo.pageSize,
  1236. pageNo: this.ipaginationVideo.current
  1237. }).then(resNei => {
  1238. if (resNei.success) {
  1239. this.materialVisible = true
  1240. this.dataVideoList = resNei.result.list
  1241. this.ipaginationVideo.total = resNei.result.total
  1242. }
  1243. })
  1244. },
  1245. getDataSource(current, pageSize) {
  1246. // 切换分页时的回调,
  1247. // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
  1248. this.ipagination.current = current
  1249. this.ipagination.pageSize = pageSize
  1250. const paramsData = this.form.getFieldsValue()
  1251. this.handleGetTableList(paramsData)
  1252. },
  1253. handleOkMaterial() {
  1254. let dataAll = this.checkPersonElse
  1255. this.checkVideo = dataAll
  1256. this.materialLoading = true
  1257. this.postDataAction('/dimension/kuaiShouDimensionStrategy/create', {
  1258. id: this.ipaginationVideo.id,
  1259. materialArray: this.checkVideo
  1260. }).then(res => {
  1261. this.materialLoading = false
  1262. if (res.success) {
  1263. this.materialVisible = false
  1264. this.checkPersonElse = []
  1265. this.checkVideo = []
  1266. this.checkPersonOne = ''
  1267. this.sumContent = 0
  1268. }
  1269. })
  1270. },
  1271. setVideoData(data) {
  1272. this.checkPersonOne = data
  1273. },
  1274. setVideoDataAll(data) {
  1275. // checkPerson: [],
  1276. // checkPersonAll: [],
  1277. if (data.findIndex(item => item === this.checkPersonOne) > -1) {
  1278. this.checkPersonElse.push(...data)
  1279. this.checkPersonElse = [...new Set(this.checkPersonElse)]
  1280. } else {
  1281. data.findIndex(item => item === this.checkPersonOne) > -1
  1282. this.checkPersonElse.splice(
  1283. this.checkPersonElse.findIndex(item => item === this.checkPersonOne),
  1284. 1
  1285. )
  1286. }
  1287. this.sumContent = this.checkPersonElse.length
  1288. // var dataCount = 20
  1289. // if (this.sumContent > dataCount) {
  1290. // this.$message.error('最多选择' + dataCount + '个定向')
  1291. // this.checkPerson.pop()
  1292. // this.checkPersonElse.splice(
  1293. // this.checkPersonElse.findIndex(item => item === this.checkPersonOne),
  1294. // 1
  1295. // )
  1296. // this.sumContent--
  1297. // // this.checkPersonAll[this.ipagination.current - 1] = this.checkPerson
  1298. // }
  1299. },
  1300. onChangeStatus(text, rescord, type) {
  1301. let status = text === 0 ? 1 : 0
  1302. let url = ''
  1303. let params = {}
  1304. params.id = rescord.id
  1305. params.strategyStatus = status
  1306. url = '/dimension/kuaiShouDimensionStrategy/edit'
  1307. this.postDataAction(url, params).then(res => {
  1308. if (res.success) {
  1309. const paramsData = this.form.getFieldsValue()
  1310. this.handleGetTableList(paramsData)
  1311. } else {
  1312. this.$message.error(res.message)
  1313. }
  1314. })
  1315. },
  1316. handleQueryList(event) {
  1317. this.ipagination.current = 1
  1318. event.preventDefault()
  1319. const paramsData = this.form.getFieldsValue()
  1320. this.handleGetTableList(paramsData)
  1321. },
  1322. handleResetForm() {
  1323. this.ipagination.current = 1
  1324. this.form.resetFields()
  1325. if (this.tabKey == 1) {
  1326. this.projectId = undefined
  1327. this.projectIdAll = undefined
  1328. }
  1329. const paramsData = this.form.getFieldsValue()
  1330. this.handleGetTableList(paramsData)
  1331. },
  1332. handleGetTableList(data) {
  1333. let paramsData = {
  1334. strategyName: data.strategyName,
  1335. // startTime:
  1336. // data.timeRange && data.timeRange.length === 2
  1337. // ? moment(data.timeRange[0]).format('YYYY-MM-DD')
  1338. // : null,
  1339. // endTime:
  1340. // data.timeRange && data.timeRange.length === 2
  1341. // ? moment(data.timeRange[1]).format('YYYY-MM-DD')
  1342. // : null,
  1343. pageNo: this.ipagination.current,
  1344. pageSize: this.ipagination.pageSize
  1345. }
  1346. this.dataSource = []
  1347. this.dataLoading = true
  1348. this.getAction('/dimension/kuaiShouDimensionStrategy/list', paramsData)
  1349. .then(result => {
  1350. this.dataLoading = false
  1351. if (result.success) {
  1352. this.dataSource = result.result.records || []
  1353. // if (result.result.total) {
  1354. // this.dataSource.unshift(result.result.total)
  1355. // }
  1356. this.ipagination.total = result.result.total || 0
  1357. // result.result.total
  1358. } else {
  1359. this.$message.error(result.message)
  1360. }
  1361. })
  1362. .catch(error => {
  1363. this.dataLoading = false
  1364. console.log(error, 'eeee')
  1365. })
  1366. },
  1367. getAccountNoProject() {
  1368. this.projectId = undefined
  1369. const paramsData = this.form.getFieldsValue()
  1370. this.handleGetTableList(paramsData)
  1371. },
  1372. toAccountDetail(item) {
  1373. this.tabKey = 2
  1374. this.projectId = { id: item.projectId, name: item.projectName }
  1375. this.url =
  1376. this.tabKey == 1
  1377. ? '/kuaishouProjectStrategy/queryProjectList'
  1378. : '/kuaishouProjectStrategy/queryAccountList'
  1379. this.$nextTick(() => {
  1380. this.columns = this.tabKey == 1 ? [...TTcolumns] : [...KScolumns]
  1381. this.target = this.tabKey == 1 ? 'createTime' : 'statDate'
  1382. const paramsData = this.form.getFieldsValue()
  1383. this.handleGetTableList(paramsData)
  1384. })
  1385. },
  1386. disabledDate(current) {
  1387. // Can not select days before today and today
  1388. return current && current > moment().endOf('day')
  1389. },
  1390. dateChange(date, dateString) {
  1391. // console.log(date,dateString)
  1392. },
  1393. filterOption(input, option) {
  1394. // console.log(input, option)
  1395. return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  1396. },
  1397. // 快手头条的切换
  1398. tabChange(key) {
  1399. this.ipagination.current = 1
  1400. this.columns = this.tabKey == 1 ? [...TTcolumns] : [...KScolumns]
  1401. this.url =
  1402. this.tabKey == 1
  1403. ? '/kuaishouProjectStrategy/queryProjectList'
  1404. : '/kuaishouProjectStrategy/queryAccountList'
  1405. this.target = this.tabKey == 1 ? 'createTime' : 'statDate'
  1406. this.projectId = undefined
  1407. const paramsData = this.form.getFieldsValue()
  1408. this.handleGetTableList(paramsData)
  1409. },
  1410. operateChange(value) {
  1411. console.log(value)
  1412. if (value) {
  1413. this.accountDisabled = true
  1414. this.accountId = ''
  1415. } else {
  1416. this.accountDisabled = false
  1417. }
  1418. },
  1419. tableChange(pagination, filters, sorter, { currentDataSource }) {
  1420. this.ipagination.current = pagination.current
  1421. this.ipagination.pageSize = pagination.pageSize
  1422. if (sorter.order) {
  1423. this.order = sorter.order ? sorter.order : 'descend'
  1424. this.target = sorter.columnKey
  1425. const paramsData = this.form.getFieldsValue()
  1426. this.handleGetTableList({
  1427. ...paramsData,
  1428. target: sorter.columnKey,
  1429. order: sorter.order ? sorter.order : 'descend'
  1430. })
  1431. }
  1432. },
  1433. // table区域的tab切换
  1434. tableTabChange(key) {
  1435. if (key == 1) {
  1436. this.columns = this.tabKey == 1 ? [...TTcolumns] : [...KScolumns]
  1437. this.target = 'new'
  1438. } else {
  1439. this.columns = this.tabKey == 1 ? [...TTcolumns] : [...KScolumns]
  1440. this.target = 'valid'
  1441. }
  1442. },
  1443. // 获取所有运营
  1444. getAllOperator(key) {
  1445. let url = '/sys/user/getAllUserListV1'
  1446. this.designList = []
  1447. getAction(url, {}).then(res => {
  1448. if (res.success) {
  1449. this.designList = res.result
  1450. }
  1451. })
  1452. }
  1453. },
  1454. watch: {
  1455. dateValue(newName, oldName) {
  1456. this.search()
  1457. }
  1458. },
  1459. computed: {
  1460. newDate() {
  1461. var myDate = new Date()
  1462. myDate.getYear() //获取当前年份(2位)
  1463. var n = myDate.getFullYear() //获取完整的年份(4位,1970-????)
  1464. var m = myDate.getMonth() //获取当前月份(0-11,0代表1月)
  1465. var d = myDate.getDate() //获取当前日(1-31)
  1466. var day = myDate.getHours()
  1467. return day
  1468. }
  1469. },
  1470. mounted() {
  1471. const paramsData = this.form.getFieldsValue()
  1472. this.handleGetTableList(paramsData)
  1473. this.getAllOperator()
  1474. this.getAction('/dimension/kuaiShouDimensionRegionConfig/list').then(res => {
  1475. if (res.success) {
  1476. let data = res.result.map(item => {
  1477. return {
  1478. label: item.regionGroupName,
  1479. value: item.regionGroupId
  1480. }
  1481. })
  1482. this.regionData.push(...data)
  1483. }
  1484. })
  1485. },
  1486. activated: function() {},
  1487. filters: {
  1488. toPercentage(val) {
  1489. if (typeof val != 'string') {
  1490. return (val * 100).toFixed(2) + '%'
  1491. } else {
  1492. return val
  1493. }
  1494. },
  1495. //保留两位小数并且变成货币格式
  1496. decimalsHandle(val) {
  1497. if (val && typeof val != 'string') {
  1498. if (val >= 0) {
  1499. val = parseFloat(val).toFixed(2)
  1500. let numberStr = val.toString()
  1501. let str = numberStr.split('.')
  1502. let str0 = str[0].split('').reverse()
  1503. for (let i = 0; i < str0.length; i++) {
  1504. if ((i + 1) % 4 === 0) {
  1505. str0.splice(i, 0, ',')
  1506. }
  1507. }
  1508. str0.reverse()
  1509. let handleResult = ''
  1510. for (let j = 0; j < str0.length; j++) {
  1511. handleResult += str0[j]
  1512. }
  1513. return handleResult + '.' + str[1]
  1514. } else {
  1515. val = parseFloat(val).toFixed(2)
  1516. let numberStr = val.toString()
  1517. let str = numberStr.split('.')
  1518. let str0 = str[0]
  1519. .substr(1)
  1520. .split('')
  1521. .reverse()
  1522. for (let i = 0; i < str0.length; i++) {
  1523. if ((i + 1) % 4 === 0) {
  1524. str0.splice(i, 0, ',')
  1525. }
  1526. }
  1527. str0.reverse()
  1528. let handleResult = ''
  1529. for (let j = 0; j < str0.length; j++) {
  1530. handleResult += str0[j]
  1531. }
  1532. return '-' + handleResult + '.' + str[1]
  1533. }
  1534. } else if (typeof val == 'string') {
  1535. return val
  1536. } else {
  1537. return 0
  1538. }
  1539. },
  1540. //变成货币格式
  1541. formatCurrency(val) {
  1542. if (val) {
  1543. let numberStr = val.toString()
  1544. let str = numberStr.split('').reverse()
  1545. for (let i = 0; i < str.length; i++) {
  1546. if ((i + 1) % 4 === 0) {
  1547. str.splice(i, 0, ',')
  1548. }
  1549. }
  1550. str.reverse()
  1551. let handleResult = ''
  1552. for (let j = 0; j < str.length; j++) {
  1553. handleResult += str[j]
  1554. }
  1555. return handleResult
  1556. } else {
  1557. return '-'
  1558. }
  1559. }
  1560. }
  1561. }
  1562. </script>