configLaunchList.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. <template>
  2. <div class="toutiaoBatch">
  3. <div class="toolbox-automate-rules-create-content_title">
  4. <h3>账户配置信息</h3>
  5. <a-button type='primary' @click="goNewConfigInfo" class="goNewConfigInfo">新建配置信息</a-button>
  6. </div>
  7. <div class="topOptions">
  8. <div >
  9. <Treeselect :appId.sync="accountId" :multiple="false" request="2,4" ref="treeSelect" style="margin-bottom:8px;width:600px " />
  10. </div>
  11. <span class="optionBtn">
  12. <a-button type='primary' @click="search" class="searchBtn">查询</a-button>
  13. </span>
  14. </div>
  15. <div class="tableArea">
  16. <!-- <div class="tableOption" v-if="selectedRowKeys.length">
  17. :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
  18. </div> -->
  19. <div class="table">
  20. <a-table
  21. :columns="columns"
  22. :data-source="data"
  23. bordered
  24. :pagination="ipagination"
  25. :loading="loading"
  26. @change="sort"
  27. :scroll="{'x':scrollX}"
  28. >
  29. <span slot="status" slot-scope="text,record">
  30. <a-spin :spinning="record.spin" size="small" >
  31. <div class="spin-content">
  32. <a-switch size="default" :checked='text==1' @change="switchChange(text,record)"/>
  33. </div>
  34. </a-spin>
  35. </span>
  36. <span slot="openProgramCreate" slot-scope="text,record">
  37. <a-spin :spinning="record.openProgramCreateSpin" size="small" >
  38. <div class="spin-content">
  39. <a-switch size="default" :checked='text==1' @change="openProgramCreateSwitchChange(text,record)"/>
  40. </div>
  41. </a-spin>
  42. </span>
  43. <span slot="cpaBid" slot-scope="text">
  44. {{text/1000}}
  45. </span>
  46. <span slot="authName" slot-scope="text">
  47. <!-- <a href="javascript:;" >{{text}}</a> -->
  48. {{text || '-'}}
  49. </span>
  50. <span slot="time" slot-scope="text,record">
  51. {{record.startTime}}至{{record.endTime}}
  52. </span>
  53. <span slot="operator" slot-scope="text,record">
  54. <a href="javascript:;" @click="goPlanList(record)">编辑</a>
  55. <a-divider type="vertical" />
  56. <a href="javascript:;" @click="deleteRecord(record)">删除</a>
  57. <a-divider type="vertical" />
  58. <a-popover v-model="record.show" trigger="click" placement="topRight" @visibleChange='visibleChange'>
  59. <div slot="content">
  60. <span style='font-weight:700;margin-right:15px;font-size:15px'>修改后重提</span>
  61. <a-radio-group v-model="examineAgainType" >
  62. <a-radio :value="1">修改广告语</a-radio>
  63. <a-radio :value="0">修改封面</a-radio>
  64. </a-radio-group>
  65. <a-button type='default' @click="examineAgainCancel(record)" size='small' style='margin-right:10px'>取消</a-button>
  66. <a-button type='primary' @click="examineAgainOk(record)" size='small' class="ok">重提</a-button>
  67. </div>
  68. <a href="javascript:;" type='primary' @click="()=>{record.show=true}">一键重提</a>
  69. </a-popover>
  70. <a-divider type="vertical" />
  71. <a-popover v-model="record.visible" trigger="click" placement="topLeft" @visibleChange='visibleChange'>
  72. <span slot="title">出价</span>
  73. <template slot="content" style="width:300px;">
  74. <div style="margin:5px 0 0">
  75. <span ><a-input-number :min="0" v-model="newBid" :step="0.1" placeholder="请输入出价" size="small" style='margin-right:20px;width:120px' /></span>
  76. <p style="color:red;font-size:12px;height:16px;padding:5px 0">{{bidErrorMessage}}</p>
  77. </div>
  78. <div>
  79. <a-button type='default' @click="bidChangeCancel(record)" size='small' style='margin-right:10px'>取消</a-button>
  80. <a-button type='primary' @click="bidChangeOk(record)" size='small' class="ok">修改</a-button>
  81. </div>
  82. </template>
  83. <a href="javascript:;" type='primary' @click="()=>{record.visible=true}">修改出价</a>
  84. </a-popover>
  85. </span>
  86. </a-table>
  87. </div>
  88. </div>
  89. <!-- </a-spin> -->
  90. </div>
  91. </template>
  92. <script>
  93. import moment from 'moment';
  94. import { getAction, postAction, downFile, downFilePost,deleteAction } from '@/api/manage';
  95. // import { JeecgListMixin } from '@/mixins/ipagination'
  96. // import editableCell from './editableCell'
  97. import Treeselect from '@/views/modules/Statistics/components/Treeselect.vue'
  98. import qs from 'qs'
  99. let typeValue='预算'
  100. const strategyColumns = [
  101. {
  102. title: '开关',
  103. dataIndex: 'status',
  104. key: 'status',
  105. align: 'center',
  106. scopedSlots: { customRender: 'status' },
  107. width:110,
  108. },
  109. {
  110. title: '所属账户名称',
  111. dataIndex: 'authName',
  112. key: 'authName',
  113. align: 'center',
  114. scopedSlots: { customRender: 'authName' },
  115. width:300
  116. },
  117. {
  118. title: '所属账户ID',
  119. dataIndex: 'accountId',
  120. key: 'accountId',
  121. align: 'center',
  122. scopedSlots: { customRender: 'accountId' },
  123. },
  124. {
  125. title: '创建时间',
  126. dataIndex: 'createTime',
  127. key: 'createTime',
  128. align: 'center',
  129. scopedSlots: { customRender: 'createTime' },
  130. },
  131. {
  132. title: '出价',
  133. dataIndex: 'cpaBid',
  134. align: 'center',
  135. scopedSlots: { customRender: 'cpaBid' },
  136. // sorter:() => {}
  137. },
  138. // {
  139. // title: '是否开启程序化创建',
  140. // dataIndex: 'openProgramCreate',
  141. // align: 'center',
  142. // scopedSlots: { customRender: 'openProgramCreate' },
  143. // sorter:() => {},
  144. // width:180,
  145. // },
  146. {
  147. title: '操作',
  148. dataIndex: 'operator',
  149. key: 'operator',
  150. align: 'center',
  151. scopedSlots: { customRender: 'operator' },
  152. width:350,
  153. },
  154. ];
  155. const publicColumns = [
  156. ]
  157. export default {
  158. name:'strategy-list',
  159. components: {
  160. // editableCell,
  161. Treeselect,
  162. },
  163. // mixins: [JeecgListMixin],
  164. data() {
  165. return {
  166. selectedRecord:{},
  167. bidErrorMessage:'',
  168. examineAgainType:1,
  169. newBid:undefined,
  170. examineAgain:false,
  171. accountId:[],
  172. accountList:[],
  173. strategyState:undefined,
  174. strategyName:'',
  175. strategyId:undefined,
  176. accountId:[],
  177. scrollX:0,
  178. ipagination: {
  179. current: 1,
  180. pageSize: 10,
  181. // pageSizeOptions: ['10', '20', '30'],
  182. showTotal: (total, range) => {
  183. return range[0] + "-" + range[1] + " 共" + total + "条"
  184. },
  185. showQuickJumper: true,
  186. showSizeChanger:true,
  187. pageSizeOptions: ['10', '30', '50'],
  188. total: 0,
  189. onChange: (current, pageSize) => {
  190. // 切换分页时的回调,
  191. // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
  192. this.ipagination.current = current;
  193. this.ipagination.pageSize= pageSize;
  194. }
  195. },
  196. spinning:false,
  197. moment,
  198. optionId:'',//input输入的id或关键词
  199. selectDisable:true,
  200. optValue:undefined,//操作设置的值 删除 暂停 开启
  201. visible: false,//出价里的弹出框
  202. //主页的表格
  203. data:[],
  204. columns:[...strategyColumns,...publicColumns],
  205. selectedRowKeys:[],
  206. loading:false,
  207. editID:0,
  208. url: {
  209. list:'/ctop/aiKuaishouAdvertiserStrategy/list',
  210. delete:'/ctop/aiKuaishouAdvertiserStrategy/delete',
  211. },
  212. xiugaiData:[],//存分别修改时候的数组
  213. }
  214. },
  215. computed: {
  216. hasSelected() {
  217. return this.selectedRowKeys.length > 0;
  218. },
  219. },
  220. methods: {
  221. //状态改变
  222. switchChange(text,record){
  223. // this.spinning=true;
  224. console.log(text,record)
  225. record.spin=true;
  226. let status=text==1?0:1;
  227. getAction(`/ctop/aiKuaishouAdvertiserStrategy/oprateStatus`,{
  228. id:record.id,
  229. status
  230. }).then((res)=>{
  231. record.spin=false;
  232. if(res.success){
  233. this.getStrategyList()
  234. this.$message.success(res.message)
  235. }else{
  236. this.$message.error(res.message)
  237. }
  238. })
  239. },
  240. //是否开启程序化创意状态改变
  241. openProgramCreateSwitchChange(text,record){
  242. // this.spinning=true;
  243. console.log(text,record)
  244. record.openProgramCreateSpin=true;
  245. let status=text==1?0:1;
  246. getAction(`/ctop/aiKuaishouAdvertiserStrategy/oprateCreativeStatus`,{
  247. id:record.id,
  248. status
  249. }).then((res)=>{
  250. record.openProgramCreateSpin=false;
  251. if(res.success){
  252. this.getStrategyList()
  253. this.$message.success(res.message)
  254. }else{
  255. this.$message.error(res.message)
  256. }
  257. })
  258. },
  259. examineAgainMethod(record){
  260. console.log(record)
  261. this.examineAgain=true;
  262. this.selectedRecord=record
  263. },
  264. visibleChange(){
  265. this.bidErrorMessage='';
  266. this.examineAgainType=1;
  267. this.newBid=undefined;
  268. },
  269. bidChangeCancel(record){
  270. record.visible=false;
  271. this.newBid=undefined;
  272. this.bidErrorMessage=''
  273. },
  274. bidChangeOk(record){
  275. if(this.newBid){
  276. record.visible=false;
  277. postAction('/ai/batchUpdate/updateGroupBid',{
  278. accountId:record.accountId,
  279. bid:this.newBid*1000
  280. }).then(res=>{
  281. console.log(res)
  282. if(res.code==0){
  283. this.$message.success(res.message)
  284. this.newBid=undefined;
  285. this.getStrategyList()
  286. }
  287. })
  288. }else{
  289. this.bidErrorMessage='请正确填写出价'
  290. // this.$message.error('请正确填写出价')
  291. }
  292. },
  293. examineAgainCancel(record){
  294. record.show=false;
  295. this.examineAgainType=1
  296. },
  297. examineAgainOk(record){
  298. record.show=false;
  299. postAction('/kuaishou/creative/again',{
  300. accountId:record.accountId,
  301. updateType:this.examineAgainType
  302. }).then(res=>{
  303. console.log(res);
  304. if(res.code==0){
  305. this.$message.success('正在重提中,您可稍后查看结果')
  306. }else{
  307. this.$message.success(res.message)
  308. }
  309. this.examineAgainType=1
  310. })
  311. },
  312. onSelectChange(selectedRowKeys) {
  313. console.log('selectedRowKeys changed: ', selectedRowKeys);
  314. this.selectedRowKeys = selectedRowKeys;
  315. },
  316. goNewConfigInfo(){
  317. this.$router.push('/autoLaunch/configLaunchInfo')
  318. },
  319. goPlanList(record){
  320. console.log(record)
  321. this.$parent.currentStrategyId=record.id;
  322. this.$router.push(`/autoLaunch/configLaunchInfo?id=${record.id}`)
  323. },
  324. deleteRecord(record){
  325. this.loading=true
  326. deleteAction(this.url.delete,{
  327. id:record.id
  328. }).then(res=>{
  329. this.loading=false
  330. if(res.success){
  331. this.$message.success(res.message);
  332. this.getStrategyList()
  333. }else{
  334. this.$message.success(res.message);
  335. }
  336. })
  337. },
  338. filterOption(input, option) {
  339. return (
  340. option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  341. );
  342. },
  343. //查询按钮事件
  344. search(){
  345. this.ipagination.current=1;
  346. this.getStrategyList()
  347. },
  348. //点击分页
  349. sort(pagination, filters, sorter, { currentDataSource }){
  350. console.log(pagination)
  351. this.ipagination.current=pagination.current;
  352. this.ipagination.pageSize=pagination.pageSize;
  353. this.getStrategyList()
  354. },
  355. getStrategyList(){
  356. this.loading = true
  357. console.log(this.accountId)
  358. getAction(this.url.list,{
  359. strategyId:this.strategyId==undefined?null:this.strategyId,
  360. accountId:this.accountId,
  361. pageNo:this.ipagination.current,
  362. pageSize:this.ipagination.pageSize
  363. }).then((res)=>{
  364. this.data=[]
  365. console.log(res)
  366. this.loading = false
  367. if(res.success){
  368. this.ipagination.total = res.result.total
  369. res.result.records.forEach((item)=>{
  370. item.key=item.id;
  371. item.show=false;
  372. item.visible=false;
  373. item.spin=false;
  374. item.openProgramCreateSpin=false;
  375. })
  376. this.data = res.result.records;
  377. this.selectedRowKeys=[];
  378. }
  379. })
  380. },
  381. },
  382. mounted() {
  383. this.getStrategyList()
  384. },
  385. activated() {
  386. this.getStrategyList()
  387. },
  388. beforeDestroy() {
  389. },
  390. filters: {
  391. toPercentage(val) {
  392. if(val){
  393. if(typeof val != 'string'){
  394. return (val * 100).toFixed(2) + '%'
  395. }else{
  396. return val
  397. }
  398. }else if(typeof val =='string'){
  399. return val
  400. }
  401. else{
  402. return 0
  403. }
  404. },
  405. //保留两位小数并且变成货币格式
  406. decimalsHandle(val){
  407. if(val && typeof val !='string'){
  408. if(val>=0){
  409. val=parseFloat(val).toFixed(2);
  410. let numberStr = val.toString()
  411. let str = numberStr.split('.')
  412. let str0=str[0].split('').reverse();
  413. for (let i = 0; i < str0.length; i++) {
  414. if ((i + 1) % 4 === 0) {
  415. str0.splice(i, 0, ',')
  416. }
  417. }
  418. str0.reverse()
  419. let handleResult = ''
  420. for (let j = 0; j < str0.length; j++) {
  421. handleResult += str0[j]
  422. }
  423. return handleResult+'.'+str[1]
  424. }else{
  425. val=parseFloat(val).toFixed(2);
  426. let numberStr = val.toString()
  427. let str = numberStr.split('.')
  428. let str0=str[0].substr(1).split('').reverse();
  429. for (let i = 0; i < str0.length; i++) {
  430. if ((i + 1) % 4 === 0) {
  431. str0.splice(i, 0, ',')
  432. }
  433. }
  434. str0.reverse()
  435. let handleResult = ''
  436. for (let j = 0; j < str0.length; j++) {
  437. handleResult += str0[j]
  438. }
  439. return '-'+handleResult+'.'+str[1]
  440. }
  441. }else if(typeof val =='string'){
  442. return val
  443. }
  444. else{
  445. return 0
  446. }
  447. },
  448. //变成货币格式
  449. formatCurrency(val){
  450. if((val||val==0)&& typeof val !='string'){
  451. let numberStr = val.toString()
  452. let str = numberStr.split('').reverse()
  453. for (let i = 0; i < str.length; i++) {
  454. if ((i + 1) % 4 === 0) {
  455. str.splice(i, 0, ',')
  456. }
  457. }
  458. str.reverse()
  459. let handleResult = ''
  460. for (let j = 0; j < str.length; j++) {
  461. handleResult += str[j]
  462. }
  463. return handleResult
  464. }else if(typeof val =='string'){
  465. return val
  466. }
  467. else{
  468. return '-'
  469. }
  470. },
  471. }
  472. }
  473. </script>
  474. <style lang="scss">
  475. #closeIcon{
  476. color: #0E74D2;
  477. }
  478. .toutiaoBatch{
  479. .ant-tag .anticon-close {
  480. color: #1890ff;
  481. }
  482. .ant-tag .anticon-close:hover{
  483. color: rgba(0, 0, 0, 0.85);
  484. }
  485. }
  486. .ant-tooltip-inner,.ant-tooltip,.ant-tooltip-arrow::before{
  487. background-color: #fff;
  488. color: #333;
  489. }
  490. #batchModal{
  491. .rules,.totalPrice{
  492. font-weight: 600;
  493. }
  494. .selectePlan{
  495. font-size: 14px;
  496. font-weight: 700;
  497. color: #333;
  498. padding: 20px 0;
  499. }
  500. .totalPrice{
  501. margin-left: 20px;
  502. }
  503. .modifyTable{
  504. margin-top: 20px;
  505. width: 100%;
  506. height: 400px;
  507. overflow: auto;
  508. font-weight: 600;
  509. }
  510. }
  511. #copyModal{
  512. .ant-modal-header{
  513. text-align: center;
  514. }
  515. .copyTip{
  516. font-size: 12px;
  517. color: #999;
  518. }
  519. .copyName{
  520. width: 118px;
  521. display: inline-block;
  522. text-align: right;
  523. .copyKeyStart{
  524. color: red;
  525. }
  526. }
  527. // font-weight: 600;
  528. }
  529. </style>
  530. <style lang="scss" scoped>
  531. .toutiaoBatch{
  532. .breadcrumb{
  533. height: 22px;
  534. font-size: 12px;
  535. font-family: PingFangSC-Regular, PingFang SC;
  536. font-weight: 400;
  537. color: #000000;
  538. line-height: 22px;
  539. }
  540. background-color: #fff;
  541. padding: 10px 20px;
  542. position: relative;
  543. width: 100%;
  544. .OptinItem{
  545. display: inline-block;
  546. margin-right: 15px;
  547. margin-top: 15px;
  548. .ok{
  549. margin-right: 15px;
  550. }
  551. }
  552. .OptinItem:first-child{
  553. margin-right: 10px;
  554. }
  555. .topOptions{
  556. padding: 15px 0;
  557. display: flex;
  558. justify-content: space-between;
  559. .topOpt{
  560. width: 100%;
  561. margin-bottom: 10px;
  562. }
  563. }
  564. .optionBtn{
  565. // display: inline-block;
  566. float: right;
  567. // .searchBtn{
  568. // margin-right: 10px;
  569. // }
  570. }
  571. .tableArea{
  572. .tableOption{
  573. padding: 20px 0;
  574. }
  575. }
  576. .toolbox-automate-rules-create-content_title {
  577. background-color: #fff;
  578. display: flex;
  579. flex-flow: row nowrap;
  580. justify-content: flex-start;
  581. align-items: center;
  582. margin-bottom: 28px;
  583. position: relative;
  584. h3 {
  585. font-size: 22px;
  586. margin: 0;
  587. font-weight: 400;
  588. height: 30px;
  589. line-height: 30px;
  590. }
  591. .goNewConfigInfo{
  592. position: absolute;
  593. right: 0;
  594. top: 4px;
  595. }
  596. }
  597. }
  598. </style>