newGroup.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. <template>
  2. <div class="newGroup">
  3. <div class="currentOPt">
  4. <div class="currentAccount">
  5. 选择账号:
  6. <a-tree-select
  7. show-search
  8. allow-clear
  9. dropdownMatchSelectWidth
  10. v-model="accountID"
  11. style="width: 60%"
  12. :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
  13. :tree-data="treeData"
  14. placeholder="请选择具体账户"
  15. :filterOption='filterOption'
  16. treeNodeFilterProp='title'
  17. @change='accountIDChange'
  18. >
  19. </a-tree-select>
  20. </div>
  21. <div class="tabBody">
  22. <a-tabs default-active-key="create" @change="tabChange">
  23. <a-tab-pane key="create" tab="新建广告组">
  24. <a-form :form="form">
  25. <a-form-item label="推广目的" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
  26. <a-radio-group v-decorator="['landingType',{initialValue:'APP' }]" @change="landingTypeChange">
  27. <a-radio-button value="APP">应用推广</a-radio-button>
  28. <a-radio-button value="LINK">销售线索收集</a-radio-button>
  29. </a-radio-group>
  30. </a-form-item>
  31. <a-form-item label="广告组预算" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
  32. <a-radio-group v-decorator="['budgetMode',{initialValue:'BUDGET_MODE_INFINITE' }]">
  33. <a-radio-button value="BUDGET_MODE_INFINITE">不限</a-radio-button>
  34. <a-radio-button value="BUDGET_MODE_DAY">指定日预算</a-radio-button>
  35. </a-radio-group>
  36. </a-form-item>
  37. <a-form-item v-if="getFormData('budgetMode')=='BUDGET_MODE_DAY'" label="日预算" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
  38. <a-input-number :max="9999999.99" :step="1" v-decorator="['budget',{initialValue:1000 }]" @change="budgetChange" @blur='budgetBlur' />
  39. <span class="tip" v-if="getFormData('budget')<1000">预算不少于1000.00元,不超过9999999.99元,请正确输入</span>
  40. </a-form-item>
  41. <a-form-item label="广告组名称" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
  42. <a-input v-decorator="['campaignName', { rules: [{ required: true ,message: '广告组名称必须填写'}] }]" />
  43. </a-form-item>
  44. <a-form-item label="广告组状态" :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol">
  45. <a-radio-group v-decorator="['operation',{initialValue:'enable' }]">
  46. <a-radio-button value="enable">开</a-radio-button>
  47. <a-radio-button value="disable">关</a-radio-button>
  48. </a-radio-group>
  49. </a-form-item>
  50. </a-form>
  51. </a-tab-pane>
  52. <a-tab-pane key="exist" tab="选择已有广告组" forceRender>
  53. <div class="selectedExist">
  54. <a-input v-model="selectedCampaignValue" class="input" placeholder="请输入广告组id或名称" @change="selectedCampaign">
  55. <a-icon slot="addonAfter" type="search" />
  56. </a-input>
  57. <div class="campaign-have-list">
  58. <div class="campaign-have-header">列表</div>
  59. <div class="hasAccountID" v-if="accountID">
  60. <a-spin :spinning="spinning">
  61. <ul v-if="campaignHaveList.length>0">
  62. <li class="ad-d-flex ad-d-flex-between" v-for="(item,index) in campaignHaveList" :key="index" @click="goPlan(item)">
  63. <span class="info">{{item.name}}</span>
  64. <span class="landing-type">信息流_{{item.landingType_dictText}}</span>
  65. </li>
  66. </ul>
  67. <div v-else class="noAccountID">
  68. 暂无数据
  69. </div>
  70. </a-spin>
  71. </div>
  72. <div class="noAccountID" v-else>
  73. 选择账户后,才能选择已有广告组
  74. </div>
  75. </div>
  76. <div class="fenye" v-if="totalPage">
  77. <a-pagination :current='currentPage' size='small' :total='totalPage' :pageSize='10' @change="pageNoChange" />
  78. </div>
  79. </div>
  80. </a-tab-pane>
  81. </a-tabs>
  82. </div>
  83. <div class="creatBody">
  84. <a-button type='default' class="goback" @click="goback">返回</a-button>
  85. <a-button type='primary' @click="goShowTable" style="margin-right:20px">保存并返回</a-button>
  86. <a-button type='danger' @click="nextHandle" :loading='nextLoading'>创建并下一步</a-button>
  87. </div>
  88. </div>
  89. </div>
  90. </template>
  91. <script>
  92. import moment from 'moment';
  93. import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
  94. import qs from 'qs'
  95. const formItemLayout = {
  96. labelCol: { span: 2 },
  97. wrapperCol: { span: 8 },
  98. };
  99. export default {
  100. data() {
  101. return {
  102. nextLoading:false,
  103. tabKey:'create',
  104. accountID:undefined,
  105. treeData:[],
  106. formItemLayout,
  107. form: this.$form.createForm(this),
  108. selectedCampaignValue:undefined,
  109. spinning:false,
  110. campaignHaveList:[],
  111. currentPage:1,
  112. totalPage:0
  113. }
  114. },
  115. methods: {
  116. tabChange(key){
  117. console.log(key);
  118. this.tabKey=key;
  119. },
  120. accountIDChange(val){
  121. console.log(val,this.accountID);
  122. let currentData=this.treeData.filter((item)=>{
  123. return item.value==val
  124. })
  125. // console.log(currentData);
  126. if(currentData.length>0){
  127. this.accountID=undefined;
  128. this.openID=val
  129. }
  130. this.getExsitGroupList();
  131. console.log(this.treeData)
  132. this.treeData.forEach((item)=>{
  133. item.children.forEach(ele=>{
  134. if(ele.value==val){
  135. let accountInfo=JSON.stringify(ele)
  136. localStorage.setItem('accountInfo',accountInfo)
  137. }
  138. })
  139. })
  140. },
  141. getExsitGroupList(){
  142. this.spinning=true;
  143. getAction('/ctop/byteDanceCampaign/list',{
  144. accountId:this.accountID,
  145. pageNo:this.currentPage,
  146. name:this.selectedCampaignValue
  147. }).then(res=>{
  148. console.log(res)
  149. if(res.success){
  150. this.spinning=false;
  151. this.totalPage=res.result.total;
  152. this.campaignHaveList=res.result.records;
  153. }
  154. })
  155. },
  156. filterOption(input, option){
  157. console.log(input, option)
  158. return (
  159. option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  160. );
  161. },
  162. //请求项目和账户内容
  163. accountHttp(){
  164. this.treeData=[];
  165. this.accountID=undefined;
  166. getAction('/ctop/projectMember/getProjectAccountByUserId', {}).then(res => {
  167. if(res.success){
  168. // console.log(res);
  169. if(res.result){
  170. res.result.forEach((element,index) => {
  171. if(element){
  172. this.treeData.push({});
  173. this.treeData[index].title=element.project.projectName +'_('+ element.project.advertiserName +')';
  174. this.treeData[index].value='project'+element.project.projectId;
  175. this.treeData[index].key=element.project.projectId;
  176. this.treeData[index].mediaId=element.project.mediaId;
  177. this.treeData[index].children=[];
  178. if(element.account.length){
  179. element.account.forEach((ele,i)=>{
  180. this.treeData[index].children.push({});
  181. this.treeData[index].children[i].title=ele.userName+'_'+ele.authName;
  182. this.treeData[index].children[i].value=ele.accountId;
  183. this.treeData[index].children[i].key=ele.accountId;
  184. })
  185. }
  186. }
  187. });
  188. // console.log(this.treeData)
  189. }
  190. }
  191. })
  192. },
  193. //获取表单的某一个属性值
  194. getFormData(className) {
  195. return this.form.getFieldValue(className)
  196. },
  197. //推广目的改变
  198. landingTypeChange(e){
  199. console.log(e.target)
  200. if(e.target.value=='APP'){
  201. this.form.setFieldsValue({
  202. campaignName:`应用推广_${moment().format('MM_DD_HH:SS')}`
  203. })
  204. }else if(e.target.value=='LINK'){
  205. this.form.setFieldsValue({
  206. campaignName:`销售线索收集_${moment().format('MM_DD_HH:SS')}`
  207. })
  208. }
  209. },
  210. //预算改变
  211. budgetChange(val){
  212. console.log(val)
  213. var strRegex = /^[0-9](.)+$/
  214. var re = new RegExp(strRegex)
  215. // console.log(re.test(res))
  216. if (re.test(val)) {
  217. return true
  218. } else {
  219. // return false
  220. this.$message.error('请勿输入非数字!')
  221. // let num = val.splice(val.length-2,1)
  222. // this.form.setFieldsValue({
  223. // budget:1000
  224. // })
  225. }
  226. },
  227. budgetBlur(e){
  228. console.log(e.target.value)
  229. if(e.target.value==0){
  230. this.form.setFieldsValue({
  231. budget:1000.0
  232. })
  233. }
  234. },
  235. nextHandle(){
  236. if(this.accountID){
  237. this.form.validateFields((err, values) => {
  238. if (!err) {
  239. this.nextLoading=true;
  240. console.log('Received values of form: ', values);
  241. if(values.budgetMode== "BUDGET_MODE_DAY" && (values.budget<1000||values.budget>9999999.99 )){
  242. this.$message.error('日预算不少于1000.00元,不超过9999999.99元,请正确输入')
  243. }else{
  244. postAction('/ctop/byteDanceCampaign/add',qs.stringify({
  245. accountId:this.accountID,
  246. ...values
  247. })).then(res=>{
  248. console.log(res)
  249. if(res.success){
  250. this.nextLoading=false;
  251. this.$message.success('广告组创建成功,1s后将跳转到新建计划页面');
  252. values.id=res.campaign_id;
  253. values.accountId=this.accountID
  254. let groupInfo=JSON.stringify(values)
  255. localStorage.setItem('groupInfo',groupInfo)
  256. setTimeout(() => {
  257. this.$router.push('/modules/BatchCreate/newPlan')
  258. },1000);
  259. }else{
  260. this.nextLoading=false;
  261. this.$message.error(res.message)
  262. }
  263. })
  264. }
  265. }else{
  266. this.$message.error('请正确填写必填选项')
  267. }
  268. });
  269. }else{
  270. this.$message.error('请选择具体的账户')
  271. }
  272. },
  273. goback(){
  274. this.$router.push('/modules/BatchCreate/TouTiaoBatch')
  275. this.$bus.$emit('remove', '/modules/BatchCreate/newGroup')
  276. },
  277. selectedCampaign(e){
  278. // console.log(e.target.value,this.selectedCampaignValue);
  279. if(this.accountID){
  280. this.getExsitGroupList();
  281. }else{
  282. this.$message.warning('请选择账户后重试!')
  283. this.selectedCampaignValue=undefined;
  284. }
  285. },
  286. goPlan(item){
  287. console.log(item)
  288. let groupInfo=JSON.stringify(item)
  289. localStorage.setItem('groupInfo',groupInfo)
  290. this.$router.replace(`/modules/BatchCreate/newPlan`)
  291. },
  292. //分页页码改变
  293. pageNoChange(val){
  294. console.log(val);
  295. this.currentPage=val;
  296. this.selectedCampaign()
  297. },
  298. goShowTable(){
  299. if(this.accountID){
  300. this.form.validateFields((err, values) => {
  301. if (!err) {
  302. this.nextLoading=true;
  303. console.log('Received values of form: ', values);
  304. if(values.budgetMode== "BUDGET_MODE_DAY" && (values.budget<1000||values.budget>9999999.99 )){
  305. this.$message.error('日预算不少于1000.00元,不超过9999999.99元,请正确输入')
  306. }else{
  307. postAction('/ctop/byteDanceCampaign/add',qs.stringify({
  308. accountId:this.accountID,
  309. ...values
  310. })).then(res=>{
  311. console.log(res)
  312. if(res.success){
  313. this.nextLoading=false;
  314. this.$message.success('广告组创建成功,即将返回批量页面');
  315. values.id=res.campaign_id;
  316. values.accountId=this.accountID
  317. let groupInfo=JSON.stringify(values)
  318. localStorage.setItem('groupInfo',groupInfo)
  319. setTimeout(() => {
  320. this.$router.push('/modules/BatchCreate/TouTiaoBatch')
  321. },1000);
  322. }else{
  323. this.nextLoading=false;
  324. this.$message.error(res.message)
  325. }
  326. })
  327. }
  328. }else{
  329. // console.log(err)
  330. this.$message.error('请正确填写必填选项')
  331. }
  332. });
  333. }else{
  334. this.$message.error('请选择具体的账户')
  335. }
  336. },
  337. },
  338. mounted() {
  339. this.accountHttp();
  340. let name=this.getFormData('landingType')
  341. if(name=='APP'){
  342. this.form.setFieldsValue({
  343. campaignName:`应用推广_${moment().format('MM_DD_HH:SS')}`
  344. })
  345. }else{
  346. this.form.setFieldsValue({
  347. campaignName:`销售线索收集_${moment().format('MM_DD_HH:SS')}`
  348. })
  349. }
  350. },
  351. // beforeCreate() {
  352. // this.form = this.$form.createForm(this, { name: 'validate_other' });
  353. // },
  354. }
  355. </script>
  356. <style lang="scss">
  357. .newGroup{
  358. .ant-btn-danger {
  359. background-color: #ff4d4f !important;
  360. }
  361. }
  362. </style>
  363. <style lang="scss" scoped>
  364. .newGroup{
  365. ul, li {
  366. list-style: none;
  367. padding: 0;
  368. margin: 0;
  369. }
  370. // background: rgb(249,249,249);
  371. // padding: 20px;
  372. .currentOPt{
  373. .currentAccount{
  374. height: 70px;
  375. padding: 20px 30px;
  376. background: #fff;
  377. margin-bottom: 20px;
  378. }
  379. .tabBody{
  380. background: #fff;
  381. margin-bottom: 20px;
  382. padding: 20px 30px;
  383. .tip{
  384. font-size: 12px;
  385. color: tomato;
  386. display: block;
  387. margin-top: 5px;
  388. height: 20px;
  389. line-height: 20px;
  390. }
  391. .selectedExist{
  392. width: 600px;
  393. .input{
  394. margin-bottom:16px ;
  395. }
  396. .campaign-have-list{
  397. font-family: PingFangSC-Regular;
  398. font-size: 14px;
  399. color: #333;
  400. border: 1px solid #DADFE3;
  401. border-radius: 4px;
  402. margin-bottom: 16px;
  403. height: 388px;
  404. .campaign-have-header {
  405. height: 38px;
  406. width: 100%;
  407. padding-left: 13px;
  408. line-height: 38px;
  409. background: #f8f9fa;
  410. border-radius: 4px 4px 0px 0px;
  411. border-bottom: 1px solid #DADFE3;
  412. }
  413. .campaign-have-list ul {
  414. width: 100%;
  415. height: 350px;
  416. padding-top: 6px;
  417. }
  418. li{
  419. padding: 6px 10px;
  420. cursor: pointer;
  421. }
  422. li:hover{
  423. background: #EDF1F5;
  424. }
  425. .ad-d-flex-between {
  426. justify-content: space-between !important;
  427. }
  428. .ad-d-flex, .ad-btn {
  429. display: flex;
  430. align-items: center;
  431. }
  432. .byted-loading-v {
  433. position: absolute;
  434. top: 0;
  435. right: 0;
  436. bottom: 0;
  437. left: 0;
  438. z-index: 996;
  439. background-color: hsla(0,0%,96%,.9);
  440. }
  441. .info{
  442. width: 60%;
  443. overflow: hidden;
  444. text-overflow: ellipsis;
  445. white-space: nowrap;
  446. }
  447. .landing-type {
  448. color: #999;
  449. font-size: 12px;
  450. white-space: nowrap;
  451. }
  452. }
  453. .noAccountID{
  454. font-size: 14px;
  455. text-align: center;
  456. color: #999;
  457. line-height: 388px;
  458. }
  459. .fenye{
  460. height: 60px;
  461. padding-top: 12px;
  462. text-align: right;
  463. }
  464. }
  465. }
  466. .creatBody{
  467. background: #fff;
  468. margin-bottom: 20px;
  469. padding: 20px 30px;
  470. text-align: right;
  471. .goback{
  472. margin-right: 20px;
  473. }
  474. }
  475. }
  476. }
  477. </style>