strategyList.vue 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083
  1. <template>
  2. <div class="toutiaoBatch">
  3. <div>
  4. <p class="breadcrumb">
  5. <a-breadcrumb style="display:block;width:100%">
  6. <a-breadcrumb-item ><span class="muen" @click="goPlantForm()">策略</span></a-breadcrumb-item>
  7. <!-- <a-breadcrumb-item>订单列表</a-breadcrumb-item> -->
  8. </a-breadcrumb>
  9. </p>
  10. </div>
  11. <div class="toolbox-automate-rules-create-content_title">
  12. <h3>广告策略</h3>
  13. <a-button type='primary' @click="goCreateStrategy" class="goCreateStrategy">新建策略</a-button>
  14. </div>
  15. <div class="topOptions">
  16. <div>
  17. <!-- <Treeselect :appId.sync="accountId" :multiple="false" request="2" reqUrl='/ctop/projectMember/getProjectAccountByUserId' ref="treeSelect" style="margin-bottom:8px;width:600px " /> -->
  18. <a-select mode="multiple"
  19. v-model="accountIds"
  20. style="width: 600px"
  21. placeholder="请选择账户"
  22. :maxTagCount='1'
  23. allowClear
  24. show-search
  25. option-filter-prop="children"
  26. :filter-option="filterOption"
  27. >
  28. <a-select-option v-for="item in accountList" :key="item.account_id" :value='item.account_id'>
  29. {{ item.auth_name+'_('+(item.project_name||"无所属项目")+')' }}
  30. </a-select-option>
  31. </a-select>
  32. </div>
  33. <!-- <span class="OptinItem ">
  34. reqUrl='/ctop/userAllocation/getAccountIdListByUserId'
  35. <Treeselect :appId.sync="accountIds" :multiple="true" request="2,4" reqUrl='/ctop/userAllocation/getAccountIdsByUserId' ref="treeSelect" style="margin-bottom:8px " />
  36. </span> -->
  37. <span class="OptinItem">
  38. <a-select style="width: 180px" v-model="strategyState" @change="statusChange" placeholder="请选择策略状态">
  39. <a-select-option :value='3' >
  40. 不限
  41. </a-select-option>
  42. <a-select-option :value="1" >
  43. 投放中
  44. </a-select-option>
  45. <a-select-option :value="2">
  46. 已关停
  47. </a-select-option>
  48. </a-select>
  49. </span>
  50. <span class="OptinItem">
  51. <a-input-search placeholder="策略名称" v-model="strategyName" style="width: 280px" />
  52. </span>
  53. <span class="OptinItem">
  54. <a-input-search placeholder="策略ID" v-model="strategyId" style="width: 280px" />
  55. </span>
  56. <!-- <span class="OptinItem">
  57. <a-input-search placeholder="所属账户" v-model="accountId" style="width: 300px" />
  58. </span> -->
  59. <span class="optionBtn">
  60. <a-button type='primary' @click="search" class="searchBtn">查询</a-button>
  61. <!-- <a-button type='default' @click="reset">重置</a-button> -->
  62. </span>
  63. </div>
  64. <div class="tableArea">
  65. <div class="tableOption">
  66. <span class="OptinItem">
  67. <a-tooltip>
  68. <template slot="title" >
  69. 这里可以批量启动、暂停、删除你的选择哦~
  70. </template>
  71. <!-- <a-button type="link" @click="changeSelectStatus">批量操作</a-button> -->
  72. <span >批量操作:</span>
  73. </a-tooltip>
  74. </span>
  75. <span class="OptinItem">
  76. <a-select style="width: 120px" @change="optChange" v-model="optValue" placeholder="请选择批量操作" :disabled='selectedRowKeys.length<=0'>
  77. <a-select-option value="open" >
  78. 启动
  79. </a-select-option>
  80. <a-select-option value="pause">
  81. 暂停
  82. </a-select-option>
  83. <!-- <a-select-option value="delete">
  84. 删除
  85. </a-select-option> -->
  86. </a-select>
  87. </span>
  88. <span class="OptinItem">
  89. <a-popconfirm
  90. title="确定要删除选择的内容吗?"
  91. ok-text="删除"
  92. cancel-text="取消"
  93. @confirm="confirm"
  94. @cancel="cancel"
  95. v-if="optValue=='delete'"
  96. >
  97. <a-button type='primary' @click="isOkHandle" class="ok">确定</a-button>
  98. </a-popconfirm>
  99. <a-button type='primary' @click="isOkHandle" class="ok" v-else>确定</a-button>
  100. </span>
  101. </div>
  102. <div class="table">
  103. <a-table
  104. :columns="columns"
  105. :data-source="data"
  106. :rowSelection="{selectedRowKeys: selectedRowKeys,...rowSelection}"
  107. bordered
  108. :pagination="ipagination"
  109. :loading="loading"
  110. @change="sort"
  111. :scroll="{'x':scrollX}"
  112. >
  113. <span slot="switchStatus" slot-scope="text,record">
  114. <a-spin :spinning="record.spin" size="small" >
  115. <div class="spin-content">
  116. <a-switch size="default" :checked=text @change="switchChange(text,record)"/>
  117. </div>
  118. </a-spin>
  119. </span>
  120. <span slot="createImg" slot-scope="text,record">
  121. <a-popover placement="right">
  122. <template slot="content">
  123. <video :src="record.videoId_dictText" style="width:250px" controls ></video>
  124. </template>
  125. <template slot="title">
  126. </template>
  127. <img :src="record.imageId_dictText" alt="" style="width:100px">
  128. </a-popover>
  129. </span>
  130. <span slot="status" slot-scope="text">
  131. {{text |handlerStatus}}
  132. </span>
  133. <span slot="parentGroup" slot-scope="text">
  134. <a href="javascript:;" >{{text}}</a>
  135. </span>
  136. <span slot="budget" slot-scope="text">
  137. {{text || '不限'}}
  138. </span>
  139. <span slot="parentPlan" slot-scope="text">
  140. <a href="javascript:;" >{{text}}</a>
  141. </span>
  142. <span slot="time" slot-scope="text,record">
  143. {{record.startTime}}至{{record.endTime}}
  144. </span>
  145. <span slot="operator" slot-scope="text,record">
  146. <a href="javascript:;" @click="goPlanList(record)">详情</a>
  147. </span>
  148. <span slot="scenes" slot-scope="text">
  149. <span>{{text|scensFilter}}</span>
  150. </span>
  151. <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
  152. <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
  153. <span slot="clickMaterial" slot-scope="clickMaterial">{{ clickMaterial | formatCurrency }}</span>
  154. <span slot="showMaterial" slot-scope="showMaterial">{{ showMaterial | formatCurrency }}</span>
  155. <span slot="convertMaterial" slot-scope="convertMaterial">{{ convertMaterial | formatCurrency }}</span>
  156. <span slot="play25FeedBreak" slot-scope="play25FeedBreak">{{ play25FeedBreak | formatCurrency }}</span>
  157. <span slot="play50FeedBreak" slot-scope="play50FeedBreak">{{ play50FeedBreak | formatCurrency }}</span>
  158. <span slot="play75FeedBreak" slot-scope="play75FeedBreak">{{ play75FeedBreak | formatCurrency }}</span>
  159. <span slot="play100FeedBreak" slot-scope="play100FeedBreak">{{ play100FeedBreak | formatCurrency }}</span>
  160. <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
  161. <span slot="downloadFinish" slot-scope="downloadFinish">{{ downloadFinish | formatCurrency }}</span>
  162. <span slot="downloadStart" slot-scope="downloadStart">{{ downloadStart | formatCurrency }}</span>
  163. <span slot="likeMaterial" slot-scope="likeMaterial">{{ likeMaterial | formatCurrency }}</span>
  164. <span slot="shareMaterial" slot-scope="shareMaterial">{{ shareMaterial | formatCurrency }}</span>
  165. <span slot="register" slot-scope="register">{{ register | formatCurrency }}</span>
  166. <span slot="follow" slot-scope="follow">{{ follow | formatCurrency }}</span>
  167. <span slot="formCount" slot-scope="formCount">{{ formCount | formatCurrency }}</span>
  168. <span slot="formCountCost" slot-scope="formCountCost">{{ formCountCost | decimalsHandle }}</span>
  169. <span slot="aClick" slot-scope="aClick">{{ aClick | formatCurrency }}</span>
  170. <span slot="photoShow" slot-scope="photoShow">{{ photoShow | formatCurrency }}</span>
  171. <span slot="photoClick" slot-scope="photoClick">{{ photoClick | formatCurrency }}</span>
  172. <span slot="bClick" slot-scope="bClick">{{ bClick | formatCurrency }}</span>
  173. <span slot="active" slot-scope="active">{{ active | formatCurrency }}</span>
  174. <span slot="submit" slot-scope="submit">{{ submit | formatCurrency }}</span>
  175. <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
  176. <span slot="eventCreditGrantLandingPage" slot-scope="eventCreditGrantLandingPage">{{ eventCreditGrantLandingPage | formatCurrency }}</span>
  177. <span slot="submitCost" slot-scope="submitCost">{{ submitCost | decimalsHandle }}</span>
  178. <span slot="eventCreditGrantLandingPageCost" slot-scope="eventCreditGrantLandingPageCost">{{ eventCreditGrantLandingPageCost | decimalsHandle }}</span>
  179. <span slot="submitRate" slot-scope="submitRate">{{ submitRate | toPercentage }}</span>
  180. <span slot="eventCreditGrantLandingPageRate" slot-scope="eventCreditGrantLandingPageRate">{{ eventCreditGrantLandingPageRate | toPercentage }}</span>
  181. <span
  182. slot="play25FeedBreakRate"
  183. slot-scope="play25FeedBreakRate"
  184. >{{ play25FeedBreakRate | toPercentage }}</span>
  185. <span slot="playOverRate" slot-scope="playOverRate">{{ playOverRate | toPercentage }}</span>
  186. <!-- 新加数据 -->
  187. <span slot="convertRate" slot-scope="convertRate">{{ convertRate | toPercentage }}</span>
  188. <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
  189. <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
  190. <span slot="cpc" slot-scope="cpc">{{ cpc | decimalsHandle }}</span>
  191. <span slot="cpm" slot-scope="cpm">{{ cpm | decimalsHandle }}</span>
  192. <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
  193. <span
  194. slot="installFinishRate"
  195. slot-scope="installFinishRate"
  196. >{{ installFinishRate | toPercentage }}</span>
  197. <span slot="validPlayRate" slot-scope="validPlayRate">{{ validPlayRate | toPercentage }}</span>
  198. <span slot="activePayCost" slot-scope="activePayCost">{{ activePayCost | decimalsHandle }}</span>
  199. <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
  200. <span slot="validPlayCost" slot-scope="validPlayCost">{{ validPlayCost | decimalsHandle }}</span>
  201. <span slot="activeCost" slot-scope="activeCost">{{ activeCost | decimalsHandle }}</span>
  202. <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
  203. <span
  204. slot="gameAddictionCost"
  205. slot-scope="gameAddictionCost"
  206. >{{ gameAddictionCost | decimalsHandle }}</span>
  207. <span
  208. slot="downloadFinishCost"
  209. slot-scope="downloadFinishCost"
  210. >{{ downloadFinishCost | decimalsHandle }}</span>
  211. <span
  212. slot="downloadStartCost"
  213. slot-scope="downloadStartCost"
  214. >{{ downloadStartCost | decimalsHandle }}</span>
  215. <span
  216. slot="installFinishCost"
  217. slot-scope="installFinishCost"
  218. >{{ installFinishCost | decimalsHandle }}</span>
  219. <span slot="convertCost" slot-scope="convertCost">{{ convertCost | decimalsHandle }}</span>
  220. <!-- -->
  221. <span
  222. slot="downloadStartRate"
  223. slot-scope="downloadStartRate"
  224. >{{ downloadStartRate | toPercentage }}</span>
  225. <span
  226. slot="downloadFinishRate"
  227. slot-scope="downloadFinishRate"
  228. >{{ downloadFinishRate | toPercentage }}</span>
  229. <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
  230. <span
  231. slot="activeRegisterRate"
  232. slot-scope="activeRegisterRate"
  233. >{{ activeRegisterRate | toPercentage }}</span>
  234. <span
  235. slot="gameAddictionRate"
  236. slot-scope="gameAddictionRate"
  237. >{{ gameAddictionRate | toPercentage }}</span>
  238. <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
  239. <!-- <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span> -->
  240. </a-table>
  241. </div>
  242. </div>
  243. <!-- </a-spin> -->
  244. </div>
  245. </template>
  246. <script>
  247. import moment from 'moment';
  248. import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
  249. // import { JeecgListMixin } from '@/mixins/ipagination'
  250. // import editableCell from './editableCell'
  251. import Treeselect from '@/views/modules/Statistics/components/Treeselect.vue'
  252. import qs from 'qs'
  253. let typeValue='预算'
  254. const strategyColumns = [
  255. {
  256. title: '开关',
  257. dataIndex: 'switchStatus',
  258. key: 'switchStatus',
  259. align: 'center',
  260. scopedSlots: { customRender: 'switchStatus' },
  261. width:80,
  262. fixed: 'left' ,
  263. },
  264. {
  265. title: '广告策略名称',
  266. dataIndex: 'strategyName',
  267. key: 'strategyName',
  268. align: 'center',
  269. scopedSlots: { customRender: 'strategyName' },
  270. width:150,
  271. fixed: 'left' ,
  272. },
  273. {
  274. title: '广告策略ID',
  275. dataIndex: 'id',
  276. key: 'id',
  277. align: 'center',
  278. scopedSlots: { customRender: 'id' },
  279. width:100,
  280. fixed: 'left' ,
  281. },
  282. {
  283. title: '操作',
  284. dataIndex: 'operator',
  285. key: 'operator',
  286. align: 'center',
  287. scopedSlots: { customRender: 'operator' },
  288. width:100,
  289. fixed: 'left' ,
  290. },
  291. {
  292. title: '创建时间',
  293. dataIndex: 'createTime',
  294. key: 'createTime',
  295. align: 'center',
  296. scopedSlots: { customRender: 'createTime' },
  297. },
  298. {
  299. title: '所属账户名称',
  300. dataIndex: 'authName',
  301. key: 'authName',
  302. align: 'center',
  303. scopedSlots: { customRender: 'authName' },
  304. width:200
  305. },
  306. {
  307. title: '所属账户ID',
  308. dataIndex: 'accountId',
  309. key: 'accountId',
  310. align: 'center',
  311. scopedSlots: { customRender: 'accountId' },
  312. },
  313. {
  314. title: '状态',
  315. dataIndex: 'status',
  316. key: 'status',
  317. align: 'center',
  318. scopedSlots: { customRender: 'status' },
  319. },
  320. {
  321. title: '创建场景',
  322. dataIndex: 'scenes',
  323. key: 'scenes',
  324. align: 'center',
  325. scopedSlots: { customRender: 'scenes' },
  326. },
  327. {
  328. title: '策略预算',
  329. dataIndex: 'budget',
  330. key: 'budget',
  331. align: 'center',
  332. scopedSlots: { customRender: 'budget' },
  333. },
  334. ];
  335. const publicColumns = [
  336. {
  337. title: '消耗(元)',
  338. dataIndex: 'cost',
  339. width:150,
  340. tip: '广告在投放期间的花费总额',
  341. align: 'center',
  342. scopedSlots: { customRender: 'cost' },
  343. // sorter: () => {}
  344. },
  345. {
  346. title: '封面曝光数',
  347. dataIndex: 'photoShow',
  348. tip: '广告在瀑布流被观看次数',
  349. align: 'center',
  350. scopedSlots: { customRender: 'photoShow' },
  351. // sorter:() => {}
  352. },
  353. {
  354. title: '封面点击数',
  355. dataIndex: 'photoClick',
  356. tip: '用户点击封面进入视频播放页的次数(数据会进行反作弊去重)',
  357. align: 'center',
  358. scopedSlots: { customRender: 'photoClick' },
  359. // sorter: () => {}
  360. },
  361. {
  362. title: '素材曝光数',
  363. dataIndex: 'aclick',
  364. tip: '用户进入视频播放页观看的次数(数据会进行反作弊去重)',
  365. align: 'center',
  366. scopedSlots: { customRender: 'aClick' },
  367. // sorter:() => {}
  368. },
  369. {
  370. title: '行为数',
  371. dataIndex: 'bclick',
  372. tip: '用户在视频播放页单击转化按钮的次数/展示数*100%',
  373. align: 'center',
  374. scopedSlots: { customRender: 'bClick' },
  375. // sorter:() => {}
  376. },
  377. {
  378. title: '封面点击率',
  379. dataIndex: 'clickRate',
  380. tip: '封面点击数占封面展示数百分比',
  381. align: 'center',
  382. scopedSlots: { customRender: 'clickRate' },
  383. // sorter:() => {}
  384. },
  385. {
  386. title: '行为率',
  387. dataIndex: 'bClickRate',
  388. tip: '行为数占素材曝光数百分比',
  389. align: 'center',
  390. scopedSlots: { customRender: 'bClickRate' },
  391. // sorter:() => {}
  392. },
  393. {
  394. title: '平均千次封面曝光花费(元)',
  395. dataIndex: 'cpm',
  396. tip: '花费/封面曝光数*1000',
  397. align: 'center',
  398. scopedSlots: { customRender: 'cpm' },
  399. // sorter:() => {}
  400. },
  401. {
  402. title: '平均封面点击单价(元)',
  403. dataIndex: 'cpc',
  404. tip: '花费/封面点击数',
  405. align: 'center',
  406. scopedSlots: { customRender: 'cpc' },
  407. // sorter:() => {}
  408. },
  409. {
  410. title: '激活数',
  411. dataIndex: 'active',
  412. tip: '广告主回传的应用激活次数',
  413. align: 'center',
  414. scopedSlots: { customRender: 'active' },
  415. // sorter:() => {}
  416. },
  417. {
  418. title: '激活单价',
  419. dataIndex: 'activeCost',
  420. tip: '花费/激活数',
  421. align: 'center',
  422. scopedSlots: { customRender: 'activeCost' },
  423. // sorter:() => {}
  424. },
  425. {
  426. title: '下载完成激活率',
  427. dataIndex: 'activeRate',
  428. tip: '激活数/安卓下载完成数',
  429. align: 'center',
  430. scopedSlots: { customRender: 'activeRate' },
  431. // sorter:() => {}
  432. },
  433. {
  434. title: '注册数',
  435. dataIndex: 'register',
  436. tip: '付费金额/当日消耗',
  437. align: 'center',
  438. scopedSlots: { customRender: 'register' },
  439. // sorter:() => {}
  440. },
  441. {
  442. title: '注册成本',
  443. dataIndex: 'activeRegisterCost',
  444. tip: '当日消耗/当日回传注册数',
  445. align: 'center',
  446. scopedSlots: { customRender: 'activeRegisterCost' },
  447. // sorter:() => {}
  448. },
  449. {
  450. title: '注册率',
  451. dataIndex: 'activeRegisterRate',
  452. tip: '当日回传注册数/当日激活数',
  453. align: 'center',
  454. scopedSlots: { customRender: 'activeRegisterRate' },
  455. // sorter:() => {}
  456. },
  457. {
  458. title: '次留数',
  459. dataIndex: 'nextDayOpen',
  460. tip: '前一日激活用户在次日继续访问的PV',
  461. align: 'center',
  462. scopedSlots: { customRender: 'nextDayOpen' },
  463. // sorter:() => {}
  464. },
  465. {
  466. title: '次留率',
  467. dataIndex: 'nextDayOpenRate',
  468. tip: '前一日激活用户在次日继续访问的PV/前一日激活数',
  469. align: 'center',
  470. scopedSlots: { customRender: 'nextDayOpenRate' },
  471. // sorter:() => {}
  472. },
  473. ]
  474. export default {
  475. name:'strategy-list',
  476. components: {
  477. // editableCell,
  478. Treeselect,
  479. },
  480. // mixins: [JeecgListMixin],
  481. data() {
  482. return {
  483. accountId:[],
  484. accountList:[],
  485. strategyState:undefined,
  486. strategyName:'',
  487. strategyId:undefined,
  488. accountIds:[],
  489. scrollX:3500,
  490. ipagination: {
  491. current: 1,
  492. pageSize: 10,
  493. // pageSizeOptions: ['10', '20', '30'],
  494. showTotal: (total, range) => {
  495. return range[0] + "-" + range[1] + " 共" + total + "条"
  496. },
  497. showQuickJumper: true,
  498. showSizeChanger:true,
  499. pageSizeOptions: ['10', '30', '50'],
  500. total: 0,
  501. onChange: (current, pageSize) => {
  502. // 切换分页时的回调,
  503. // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
  504. this.ipagination.current = current;
  505. this.ipagination.pageSize= pageSize;
  506. }
  507. },
  508. spinning:false,
  509. moment,
  510. optionId:'',//input输入的id或关键词
  511. selectDisable:true,
  512. optValue:undefined,//操作设置的值 删除 暂停 开启
  513. visible: false,//出价里的弹出框
  514. //主页的表格
  515. data:[],
  516. columns:[...strategyColumns,...publicColumns],
  517. selectedRowKeys:[],
  518. selectedRows:[],
  519. loading:false,
  520. editID:0,
  521. url: {
  522. planList: "/ai/list/pageCampaign",
  523. groupList:'/ai/list/pageUnit',
  524. strategyList:'/ai/list/pageStrategy'
  525. },
  526. xiugaiData:[],//存分别修改时候的数组
  527. }
  528. },
  529. computed: {
  530. rowSelection(){
  531. return {
  532. onChange: (selectedRowKeys, selectedRows) => {
  533. // console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
  534. this.selectedRowKeys=selectedRowKeys;
  535. this.selectedRows=selectedRows;
  536. },
  537. onSelect: (record, selected, selectedRows) => {
  538. // console.log(record, selected, selectedRows);
  539. this.modifyTableData=selectedRows;
  540. this.selectedRows=selectedRows;
  541. },
  542. onSelectAll: (selected, selectedRows, changeRows) => {
  543. // console.log(selected, selectedRows, changeRows);
  544. this.modifyTableData=selectedRows
  545. this.selectedRows=selectedRows;
  546. },
  547. }
  548. },
  549. },
  550. methods: {
  551. goCreateStrategy(){
  552. this.$router.push('/autoLaunch/newStrategy')
  553. },
  554. goPlanList(record){
  555. console.log(record)
  556. this.$parent.currentStrategyId=record.id;
  557. this.$parent.currentTabComponent='planList'
  558. },
  559. filterOption(input, option) {
  560. return (
  561. option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  562. );
  563. },
  564. //状态改变
  565. statusChange(value){
  566. console.log(value);
  567. },
  568. //查询按钮事件
  569. search(){
  570. this.ipagination.current=1;
  571. this.getStrategyList()
  572. },
  573. //点击分页
  574. sort(pagination, filters, sorter, { currentDataSource }){
  575. console.log(pagination)
  576. this.ipagination.current=pagination.current;
  577. this.ipagination.pageSize=pagination.pageSize;
  578. this.getStrategyList()
  579. },
  580. //状态改变
  581. switchChange(text,record){
  582. // this.spinning=true;
  583. console.log(text,record)
  584. record.spin=true;
  585. let ids=record.id;
  586. let state=text?'2':'1';
  587. postAction('/kuaishouStrategy/edit',{
  588. ids:[record.id],
  589. state
  590. }).then((res)=>{
  591. record.spin=false;
  592. if(res.success){
  593. this.getStrategyList()
  594. this.$message.success(res.message)
  595. }else{
  596. this.$message.error(res.message)
  597. }
  598. })
  599. },
  600. //改变批量操作的按钮
  601. changeSelectStatus(){
  602. this.selectDisable=false;
  603. },
  604. //批量操作下的启动 删除 暂停
  605. optChange(value){
  606. // console.log(value)
  607. this.optValue=value;
  608. },
  609. //批量操作的确定按钮
  610. isOkHandle(){
  611. console.log(this.optValue,this.selectedRowKeys)
  612. if(this.optValue&&this.selectedRowKeys.length>0){
  613. // this.selectedRows.forEach(item=>{
  614. // item.spin=true;
  615. // })
  616. let params ={}
  617. if(this.optValue=='pause'){
  618. this.loading=true;
  619. // if(this.selectedRowKeys.length>0){
  620. // this.selectedRows.forEach((item)=>{
  621. // item.optStatus='AD_STATUS_DISABLE'
  622. // })
  623. // }
  624. params['ids']= this.selectedRowKeys
  625. params.state='2'
  626. this.batchEditHttp(params)
  627. }else if(this.optValue=='open'){
  628. this.loading=true;
  629. // if(this.selectedRowKeys.length>0){
  630. // this.selectedRows.forEach((item)=>{
  631. // item.optStatus='AD_STATUS_ENABLE'
  632. // })
  633. // }
  634. params['ids']= this.selectedRowKeys
  635. params.state='1'
  636. this.batchEditHttp(params)
  637. }
  638. }
  639. },
  640. //确定删除
  641. confirm(e) {
  642. // console.log(e);
  643. this.loading=true;
  644. if(this.optValue=='delete'){
  645. // if(this.selectedRowKeys.length>0){
  646. // this.selectedRows.forEach((item)=>{
  647. // item.optStatus='AD_STATUS_DELETE'
  648. // })
  649. // }
  650. this.batchEditHttp(this.selectedRows)
  651. this.$message.success('删除成功');
  652. }
  653. },
  654. batchEditHttp(params){
  655. postAction(`/kuaishouStrategy/edit`,params).then((res)=>{
  656. // console.log(res);
  657. this.optValue=undefined;
  658. if(res.success){
  659. this.getStrategyList()
  660. // params.spin=false;
  661. // params.forEach(item=>{
  662. // item.spin=false;
  663. // })
  664. this.optValue=undefined;
  665. this.selectedRowKeys=[];
  666. this.$message.success(res.message)
  667. }else{
  668. // params.spin=false;
  669. // params.forEach(item=>{
  670. // item.spin=false;
  671. // })
  672. this.loading=false;
  673. this.getStrategyList()
  674. this.$message.error(res.message)
  675. }
  676. })
  677. },
  678. getStrategyList(){
  679. this.loading = true
  680. console.log(this.accountId)
  681. postAction(this.url.strategyList,{
  682. strategyId:this.strategyId==undefined?null:this.strategyId,
  683. strategyName:this.strategyName,
  684. strategyState:this.strategyState==3?null:this.strategyState,
  685. accountIds:this.accountIds,
  686. pageNo:this.ipagination.current,
  687. pageSize:this.ipagination.pageSize
  688. }).then((res)=>{
  689. this.data=[]
  690. console.log(res)
  691. this.loading = false
  692. if(res.success){
  693. this.ipagination.total = res.result.total
  694. res.result.list.forEach((item)=>{
  695. item.key=item.id
  696. })
  697. this.data = res.result.list.map(item=>{
  698. return {
  699. ...item,
  700. spin:false,
  701. switchStatus:item.strategyState=='1'?true:false,
  702. }
  703. });
  704. // console.log(this.data)
  705. this.selectedRowKeys=[];
  706. }
  707. })
  708. },
  709. getAccountList(){
  710. let userInfo=localStorage.getItem('pro__Login_Userinfo');
  711. let userId=''
  712. if(userInfo){
  713. userId=JSON.parse(userInfo).value.id
  714. }
  715. getAction('/ctop/userAllocation/getAccountIdsByUserId',{
  716. userId,
  717. }).then(res=>{
  718. console.log(res)
  719. if(res.success){
  720. this.accountList=res.result
  721. }
  722. })
  723. }
  724. },
  725. mounted() {
  726. this.getAccountList()
  727. this.getStrategyList()
  728. },
  729. activated() {
  730. this.getStrategyList()
  731. },
  732. beforeDestroy() {
  733. },
  734. filters: {
  735. toPercentage(val) {
  736. if(val){
  737. if(typeof val != 'string'){
  738. return (val * 100).toFixed(2) + '%'
  739. }else{
  740. return val
  741. }
  742. }else if(typeof val =='string'){
  743. return val
  744. }
  745. else{
  746. return 0
  747. }
  748. },
  749. //保留两位小数并且变成货币格式
  750. decimalsHandle(val){
  751. if(val && typeof val !='string'){
  752. if(val>=0){
  753. val=parseFloat(val).toFixed(2);
  754. let numberStr = val.toString()
  755. let str = numberStr.split('.')
  756. let str0=str[0].split('').reverse();
  757. for (let i = 0; i < str0.length; i++) {
  758. if ((i + 1) % 4 === 0) {
  759. str0.splice(i, 0, ',')
  760. }
  761. }
  762. str0.reverse()
  763. let handleResult = ''
  764. for (let j = 0; j < str0.length; j++) {
  765. handleResult += str0[j]
  766. }
  767. return handleResult+'.'+str[1]
  768. }else{
  769. val=parseFloat(val).toFixed(2);
  770. let numberStr = val.toString()
  771. let str = numberStr.split('.')
  772. let str0=str[0].substr(1).split('').reverse();
  773. for (let i = 0; i < str0.length; i++) {
  774. if ((i + 1) % 4 === 0) {
  775. str0.splice(i, 0, ',')
  776. }
  777. }
  778. str0.reverse()
  779. let handleResult = ''
  780. for (let j = 0; j < str0.length; j++) {
  781. handleResult += str0[j]
  782. }
  783. return '-'+handleResult+'.'+str[1]
  784. }
  785. }else if(typeof val =='string'){
  786. return val
  787. }
  788. else{
  789. return 0
  790. }
  791. },
  792. //变成货币格式
  793. formatCurrency(val){
  794. if((val||val==0)&& typeof val !='string'){
  795. let numberStr = val.toString()
  796. let str = numberStr.split('').reverse()
  797. for (let i = 0; i < str.length; i++) {
  798. if ((i + 1) % 4 === 0) {
  799. str.splice(i, 0, ',')
  800. }
  801. }
  802. str.reverse()
  803. let handleResult = ''
  804. for (let j = 0; j < str.length; j++) {
  805. handleResult += str[j]
  806. }
  807. return handleResult
  808. }else if(typeof val =='string'){
  809. return val
  810. }
  811. else{
  812. return '-'
  813. }
  814. },
  815. scensFilter(val){
  816. let str='';
  817. switch (val) {
  818. case '1':
  819. str='素材+出价'
  820. break;
  821. case '2':
  822. str='素材+定向'
  823. break;
  824. case '3':
  825. str='时间+出价'
  826. break;
  827. default:
  828. break;
  829. }
  830. return str
  831. },
  832. handlerStatus(val){
  833. let str=''
  834. if(val){
  835. switch (val) {
  836. case 1:
  837. str='投放中'
  838. break;
  839. case 2:
  840. str='已暂停'
  841. break;
  842. // case 3:
  843. // str='已删除'
  844. // break;
  845. // case 3:
  846. // str='已删除'
  847. // break;
  848. // case 3:
  849. // str='已删除'
  850. // break;
  851. default:
  852. break;
  853. }
  854. return str
  855. }else{
  856. return '-'
  857. }
  858. }
  859. }
  860. }
  861. </script>
  862. <style lang="scss">
  863. #closeIcon{
  864. color: #0E74D2;
  865. }
  866. .toutiaoBatch{
  867. .ant-tag .anticon-close {
  868. color: #1890ff;
  869. }
  870. .ant-tag .anticon-close:hover{
  871. color: rgba(0, 0, 0, 0.85);
  872. }
  873. }
  874. .ant-tooltip-inner,.ant-tooltip,.ant-tooltip-arrow::before{
  875. background-color: #fff;
  876. color: #333;
  877. }
  878. #batchModal{
  879. .rules,.totalPrice{
  880. font-weight: 600;
  881. }
  882. .selectePlan{
  883. font-size: 14px;
  884. font-weight: 700;
  885. color: #333;
  886. padding: 20px 0;
  887. }
  888. .totalPrice{
  889. margin-left: 20px;
  890. }
  891. .modifyTable{
  892. margin-top: 20px;
  893. width: 100%;
  894. height: 400px;
  895. overflow: auto;
  896. font-weight: 600;
  897. }
  898. }
  899. #copyModal{
  900. .ant-modal-header{
  901. text-align: center;
  902. }
  903. .copyTip{
  904. font-size: 12px;
  905. color: #999;
  906. }
  907. .copyName{
  908. width: 118px;
  909. display: inline-block;
  910. text-align: right;
  911. .copyKeyStart{
  912. color: red;
  913. }
  914. }
  915. // font-weight: 600;
  916. }
  917. </style>
  918. <style lang="scss" scoped>
  919. .toutiaoBatch{
  920. .breadcrumb{
  921. height: 22px;
  922. font-size: 12px;
  923. font-family: PingFangSC-Regular, PingFang SC;
  924. font-weight: 400;
  925. color: #000000;
  926. line-height: 22px;
  927. }
  928. background-color: #fff;
  929. padding: 10px 20px;
  930. position: relative;
  931. width: 100%;
  932. .OptinItem{
  933. display: inline-block;
  934. margin-right: 15px;
  935. margin-top: 15px;
  936. .ok{
  937. margin-right: 15px;
  938. }
  939. }
  940. .OptinItem:first-child{
  941. margin-right: 10px;
  942. }
  943. .topOptions{
  944. padding: 15px 0;
  945. .topOpt{
  946. width: 100%;
  947. margin-bottom: 10px;
  948. }
  949. }
  950. .optionBtn{
  951. // display: inline-block;
  952. float: right;
  953. .searchBtn{
  954. // margin-right: 10px;
  955. }
  956. }
  957. .tableArea{
  958. .tableOption{
  959. padding: 20px 0;
  960. }
  961. }
  962. .toolbox-automate-rules-create-content_title {
  963. background-color: #fff;
  964. display: flex;
  965. flex-flow: row nowrap;
  966. justify-content: flex-start;
  967. align-items: center;
  968. margin-bottom: 28px;
  969. position: relative;
  970. h3 {
  971. font-size: 22px;
  972. margin: 0;
  973. font-weight: 400;
  974. height: 30px;
  975. line-height: 30px;
  976. }
  977. .goCreateStrategy{
  978. position: absolute;
  979. right: 0;
  980. top: 4px;
  981. }
  982. }
  983. }
  984. </style>