Browse Source

骄阳提交

朱鑫波 4 năm trước cách đây
mục cha
commit
b366eadccb
100 tập tin đã thay đổi với 34928 bổ sung1828 xóa
  1. BIN
      dist.zip
  2. 3 3
      package.json
  3. BIN
      public/avatar2.jpg
  4. BIN
      public/feishu.png
  5. BIN
      public/goright.png
  6. 1 1
      public/index.html
  7. 37 0
      public/splitting.js
  8. 1 0
      src/App.vue
  9. 36 0
      src/components/bigImg.vue
  10. 524 0
      src/components/calendar/calendar.js
  11. 809 0
      src/components/calendar/calendar.vue
  12. 2 1
      src/components/ctop/propModal.vue
  13. 323 0
      src/components/editableTree.vue
  14. 38 2
      src/components/formComponents/selectGroup.vue
  15. 2 4
      src/components/formComponents/selectRegion.vue
  16. 1 0
      src/components/formComponents/toutiaoTime.vue
  17. 12 4
      src/components/layouts/UserLayout.vue
  18. 31 26
      src/components/uploadFile.vue
  19. 348 0
      src/components/uploadFileMd5Push.vue
  20. 3735 0
      src/components/vend-ztree.all.js
  21. 266 0
      src/components/youtTable/YoutTable.vue
  22. 300 0
      src/components/youtTable/customColumn.vue
  23. 240 0
      src/components/youtTable/selectComponent.vue
  24. 240 0
      src/components/youtTable/selectComponentKS.vue
  25. 13 3
      src/config/router.config.js
  26. 98 0
      src/directive.js
  27. 371 0
      src/filters.js
  28. 6 1
      src/main.js
  29. 10 0
      src/mixins/JeecgListMixin.js
  30. 16 12
      src/permission.js
  31. 7 7
      src/router/index.js
  32. 1323 0
      src/utils/columnConst/accountConst.js
  33. 0 0
      src/utils/columnConst/videoConst.js
  34. 1 0
      src/utils/request.js
  35. 20 97
      src/views/dashboard/Analysis.vue
  36. 0 9
      src/views/modules/BatchCreate/newCreate.vue
  37. 3 3
      src/views/modules/BatchCreate/newDirectedPackage.vue
  38. 2 1
      src/views/modules/Statistics/KSAccountReport.vue
  39. 87 52
      src/views/modules/Statistics/components/Treeselect.vue
  40. 19 4
      src/views/modules/Statistics/components/ratioModal.vue
  41. 509 0
      src/views/modules/Statistics/materialReport/materialReport.vue
  42. 19 2
      src/views/modules/Statistics/materialStatistics.vue
  43. 233 29
      src/views/modules/Statistics/newPlanStatic/newPlanStatic.vue
  44. 902 0
      src/views/modules/Statistics/popularVideo.vue
  45. 38 9
      src/views/modules/Statistics/refuseDataCreat.vue
  46. 39 11
      src/views/modules/Statistics/refuseDataCreatNew.vue
  47. 49 16
      src/views/modules/advertiser/AdvertiserList.vue
  48. 7 1
      src/views/modules/advertiser/ProjectList.vue
  49. 23 5
      src/views/modules/advertiser/ProjectMemberList.vue
  50. 27 5
      src/views/modules/advertiser/modules/AdvertiserModal.vue
  51. 77 30
      src/views/modules/advertiser/modules/ProjectModal.vue
  52. 1 0
      src/views/modules/advertiser/modules/Treeselect.vue
  53. 12 3
      src/views/modules/advertiser/modules/projectListModal.vue
  54. 647 0
      src/views/modules/autoLaunch/appIdList.vue
  55. 47 0
      src/views/modules/autoLaunch/autoLaunchList.vue
  56. 2155 0
      src/views/modules/autoLaunch/autoLaunchReport.vue
  57. 124 0
      src/views/modules/autoLaunch/autoReportIndex.vue
  58. 3 5
      src/views/modules/autoLaunch/components/MultiCheckBox.vue
  59. 249 0
      src/views/modules/autoLaunch/components/Treeselect.vue
  60. 107 66
      src/views/modules/autoLaunch/components/linkMultiSelect.vue
  61. 1045 0
      src/views/modules/autoLaunch/components/materialList.vue
  62. 712 0
      src/views/modules/autoLaunch/components/platForm.vue
  63. 5 5
      src/views/modules/autoLaunch/radioCheck.vue
  64. 2642 0
      src/views/modules/autoLaunch/configLaunchInfo.vue
  65. 673 0
      src/views/modules/autoLaunch/configLaunchList.vue
  66. 18 2
      src/views/modules/autoLaunch/createStrategy.vue
  67. 1086 0
      src/views/modules/autoLaunch/groupList.vue
  68. 3 2
      src/views/modules/autoLaunch/index.vue
  69. 2153 0
      src/views/modules/autoLaunch/materialAndBid.vue
  70. 495 0
      src/views/modules/autoLaunch/newAppId.vue
  71. 1098 0
      src/views/modules/autoLaunch/planList.vue
  72. 861 0
      src/views/modules/autoLaunch/previewStrategy.vue
  73. 599 88
      src/views/modules/autoLaunch/setDirectional.vue
  74. 1090 0
      src/views/modules/autoLaunch/strategyList.vue
  75. 1 1
      src/views/modules/autoRules/newBlankRule.vue
  76. 8 0
      src/views/modules/columnConst/accountConst.js
  77. 117 47
      src/views/modules/earlyWarningRules/configRules.vue
  78. 249 0
      src/views/modules/earlyWarningRules/historyWarning.vue
  79. 2 2
      src/views/modules/earlyWarningRules/index.vue
  80. 21 0
      src/views/modules/earlyWarningRules/pushTreeSelect.vue
  81. 91 116
      src/views/modules/earlyWarningRules/ruleModule.vue
  82. 13 8
      src/views/modules/earlyWarningRules/switchConfig.vue
  83. 122 42
      src/views/modules/earlyWarningRules/useRuleList.vue
  84. 922 804
      src/views/modules/kuaishouapp/account/accountIndex.vue
  85. 22 8
      src/views/modules/kuaishouapp/account/advertisingGroup.vue
  86. 1223 0
      src/views/modules/kuaishouapp/account/copyAllUnit.vue
  87. 14 1
      src/views/modules/kuaishouapp/account/newMould.vue
  88. 1 1
      src/views/modules/kuaishouapp/account/stepForm/Step1.vue
  89. 63 25
      src/views/modules/kuaishouapp/account/stepForm/Step2.vue
  90. 59 35
      src/views/modules/kuaishouapp/account/stepForm/Step3.vue
  91. 59 9
      src/views/modules/kuaishouapp/account/stepForm/Step4.vue
  92. 54 31
      src/views/modules/kuaishouapp/account/stepForm/stepModule/targetedPopulation.vue
  93. 44 38
      src/views/modules/kuaishouapp/account/stepForm/stepModule/test.vue
  94. 102 55
      src/views/modules/kuaishouapp/batchCreation/campaignList.vue
  95. 3 3
      src/views/modules/kuaishouapp/batchCreation/creat/creatCampaign.vue
  96. 247 83
      src/views/modules/kuaishouapp/batchCreation/creat/creatUnit.vue
  97. 1 3
      src/views/modules/kuaishouapp/crossAccount/createUnit.vue
  98. 31 7
      src/views/modules/kuaishouapp/crossAccount/templateModal.vue
  99. 4786 0
      src/views/modules/kuaishouapp/newBatch/index.vue
  100. 0 0
      src/views/modules/kuaishouapp/newBatch/lookPreview.vue

BIN
dist.zip


+ 3 - 3
package.json

@@ -25,7 +25,7 @@
     "codemirror": "^5.46.0",
     "cos-js-sdk-v5": "^0.5.26",
     "dayjs": "^1.8.0",
-    "echarts": "^4.3.0",
+    "echarts": "^4.9.0",
     "element-ui": "^2.13.0",
     "enquire.js": "^2.1.6",
     "html2canvas": "^1.0.0-rc.3",
@@ -48,6 +48,7 @@
     "vue-i18n": "^8.7.0",
     "vue-infinite-scroll": "^2.0.2",
     "vue-layer": "^1.0.2",
+    "vue-lazyload": "^1.3.3",
     "vue-loader": "^15.7.0",
     "vue-ls": "^3.2.0",
     "vue-oss-uploader": "^0.1.10",
@@ -61,8 +62,7 @@
     "vue-waterfall-easy": "^2.4.3",
     "vuedraggable": "^2.20.0",
     "vuex": "^3.0.1",
-    "vuex-class": "^0.3.1",
-    "vue-lazyload": "^1.3.3"
+    "vuex-class": "^0.3.1"
   },
   "devDependencies": {
     "@babel/polyfill": "^7.2.5",

BIN
public/avatar2.jpg


BIN
public/feishu.png


BIN
public/goright.png


+ 1 - 1
public/index.html

@@ -284,7 +284,7 @@
     window._CONFIG['imgDomainURL'] = 'http://139.186.31.213:8804/jeecg-boot/sys/common/view';
     window._CONFIG['pdfDomainURL'] = 'http://139.186.31.213:8804/jeecg-boot/sys/common/pdf/pdfPreviewIframe';
   </script>
-  <script src="https://unpkg.com/splitting/dist/splitting.min.js"></script>
+  <script src="<%= BASE_URL %>splitting.js"></script>
 
 </head>
 

+ 37 - 0
public/splitting.js

@@ -0,0 +1,37 @@
+!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.Splitting=t()}(this,function(){"use strict"
+var u=document,l=u.createTextNode.bind(u)
+function d(n,t,e){n.style.setProperty(t,e)}function f(n,t){return n.appendChild(t)}function p(n,t,e,r){var i=u.createElement("span")
+return t&&(i.className=t),e&&(!r&&i.setAttribute("data-"+t,e),i.textContent=e),n&&f(n,i)||i}function h(n,t){return n.getAttribute("data-"+t)}function m(n,t){return n&&0!=n.length?n.nodeName?[n]:[].slice.call(n[0].nodeName?n:(t||u).querySelectorAll(n)):[]}function o(n){for(var t=[];n--;)t[n]=[]
+return t}function g(n,t){n&&n.some(t)}function c(t){return function(n){return t[n]}}var a={}
+function n(n,t,e,r){return{by:n,depends:t,key:e,split:r}}function e(n){return function t(e,n,r){var i=r.indexOf(e)
+if(-1==i)r.unshift(e),g(a[e].depends,function(n){t(n,e,r)})
+else{var u=r.indexOf(n)
+r.splice(i,1),r.splice(u,0,e)}return r}(n,0,[]).map(c(a))}function t(n){a[n.by]=n}function v(n,r,i,u,o){n.normalize()
+var c=[],a=document.createDocumentFragment()
+u&&c.push(n.previousSibling)
+var s=[]
+return m(n.childNodes).some(function(n){if(!n.tagName||n.hasChildNodes()){if(n.childNodes&&n.childNodes.length)return s.push(n),void c.push.apply(c,v(n,r,i,u,o))
+var t=n.wholeText||"",e=t.trim()
+e.length&&(" "===t[0]&&s.push(l(" ")),g(e.split(i),function(n,t){t&&o&&s.push(p(a,"whitespace"," ",o))
+var e=p(a,r,n)
+c.push(e),s.push(e)})," "===t[t.length-1]&&s.push(l(" ")))}else s.push(n)}),g(s,function(n){f(a,n)}),n.innerHTML="",f(n,a),c}var s=0
+var i="words",r=n(i,s,"word",function(n){return v(n,"word",/\s+/,0,1)}),y="chars",w=n(y,[i],"char",function(n,e,t){var r=[]
+return g(t[i],function(n,t){r.push.apply(r,v(n,"char","",e.whitespace&&t))}),r})
+function b(t){var f=(t=t||{}).key
+return m(t.target||"[data-splitting]").map(function(a){var s=a["🍌"]
+if(!t.force&&s)return s
+s=a["🍌"]={el:a}
+var n=e(t.by||h(a,"splitting")||y),l=function(n,t){for(var e in t)n[e]=t[e]
+return n}({},t)
+return g(n,function(n){if(n.split){var t=n.by,e=(f?"-"+f:"")+n.key,r=n.split(a,l,s)
+e&&(i=a,c=(o="--"+e)+"-index",g(u=r,function(n,t){Array.isArray(n)?g(n,function(n){d(n,c,t)}):d(n,c,t)}),d(i,o+"-total",u.length)),s[t]=r,a.classList.add(t)}var i,u,o,c}),a.classList.add("splitting"),s})}function N(n,t,e){var r=m(t.matching||n.children,n),i={}
+return g(r,function(n){var t=Math.round(n[e]);(i[t]||(i[t]=[])).push(n)}),Object.keys(i).map(Number).sort(x).map(c(i))}function x(n,t){return n-t}b.html=function(n){var t=(n=n||{}).target=p()
+return t.innerHTML=n.content,b(n),t.outerHTML},b.add=t
+var T=n("lines",[i],"line",function(n,t,e){return N(n,{matching:e[i]},"offsetTop")}),L=n("items",s,"item",function(n,t){return m(t.matching||n.children,n)}),k=n("rows",s,"row",function(n,t){return N(n,t,"offsetTop")}),A=n("cols",s,"col",function(n,t){return N(n,t,"offsetLeft")}),C=n("grid",["rows","cols"]),M="layout",S=n(M,s,s,function(n,t){var e=t.rows=+(t.rows||h(n,"rows")||1),r=t.columns=+(t.columns||h(n,"columns")||1)
+if(t.image=t.image||h(n,"image")||n.currentSrc||n.src,t.image){var i=m("img",n)[0]
+t.image=i&&(i.currentSrc||i.src)}t.image&&d(n,"background-image","url("+t.image+")")
+for(var u=e*r,o=[],c=p(s,"cell-grid");u--;){var a=p(c,"cell")
+p(a,"cell-inner"),o.push(a)}return f(n,c),o}),H=n("cellRows",[M],"row",function(n,t,e){var r=t.rows,i=o(r)
+return g(e[M],function(n,t,e){i[Math.floor(t/(e.length/r))].push(n)}),i}),O=n("cellColumns",[M],"col",function(n,t,e){var r=t.columns,i=o(r)
+return g(e[M],function(n,t){i[t%r].push(n)}),i}),j=n("cells",["cellRows","cellColumns"],"cell",function(n,t,e){return e[M]})
+return t(r),t(w),t(T),t(L),t(k),t(A),t(C),t(S),t(H),t(O),t(j),b})

+ 1 - 0
src/App.vue

@@ -51,6 +51,7 @@ export default {
 <style>
 #app {
   height: 100%;
+  min-width: 1280px;
 }
 
 body {

+ 36 - 0
src/components/bigImg.vue

@@ -0,0 +1,36 @@
+<template>
+  <!-- 过渡动画 -->
+  <a-modal title="查看封面" v-model="showImageChouzhen" :width="400" :footer="null">
+    <img :src="showImageStr" style="width: 100%" v-if="showType == 'inage'" />
+    <video class="video" :src="showImageStr" controls="controls" style="width: 100%" v-else>
+      您的浏览器不支持 video 标签。
+    </video>
+  </a-modal>
+</template>
+<script>
+export default {
+  props: {
+    imgSrc: {
+      type: String,
+      default: '',
+    },
+  },
+  data() {
+    return {
+      scale: 1,
+      showType: 'image',
+      showImageChouzhen: false,
+      showImageStr:''
+    }
+  },
+  methods: {
+    showImg(type,url) {
+      this.showType = type
+      this.showImageStr = url
+      this.showImageChouzhen = true
+    },
+  },
+}
+</script>
+
+

+ 524 - 0
src/components/calendar/calendar.js

@@ -0,0 +1,524 @@
+/**
+* @1900-2100区间内的公历、农历互转
+* @charset UTF-8
+* @Author  Jea杨(JJonline@JJonline.Cn) 
+* @Time    2014-7-21
+* @Time    2016-8-13 Fixed 2033hex、Attribution Annals
+* @Time    2016-9-25 Fixed lunar LeapMonth Param Bug
+* @Version 1.0.2
+* @公历转农历:calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
+* @农历转公历:calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
+*/
+var calendar = {
+
+    /**
+      * 农历1900-2100的润大小信息表
+      * @Array Of Property
+      * @return Hex 
+      */
+    lunarInfo:[0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909
+            0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919
+            0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929
+            0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939
+            0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949
+            0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959
+            0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969
+            0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979
+            0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989
+            0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,//1990-1999
+            0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009
+            0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019
+            0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029
+            0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039
+            0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049
+            /**Add By JJonline@JJonline.Cn**/
+            0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059
+            0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069
+            0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079
+            0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089
+            0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099
+            0x0d520],//2100
+
+    /**
+      * 公历每个月份的天数普通表
+      * @Array Of Property
+      * @return Number 
+      */
+    solarMonth:[31,28,31,30,31,30,31,31,30,31,30,31],
+
+    /**
+      * 天干地支之天干速查表
+      * @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
+      * @return Cn string 
+      */
+    Gan:["\u7532","\u4e59","\u4e19","\u4e01","\u620a","\u5df1","\u5e9a","\u8f9b","\u58ec","\u7678"],
+
+    /**
+      * 天干地支之地支速查表
+      * @Array Of Property 
+      * @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
+      * @return Cn string 
+      */
+    Zhi:["\u5b50","\u4e11","\u5bc5","\u536f","\u8fb0","\u5df3","\u5348","\u672a","\u7533","\u9149","\u620c","\u4ea5"],
+
+    /**
+      * 天干地支之地支速查表<=>生肖
+      * @Array Of Property 
+      * @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
+      * @return Cn string 
+      */
+    Animals:["\u9f20","\u725b","\u864e","\u5154","\u9f99","\u86c7","\u9a6c","\u7f8a","\u7334","\u9e21","\u72d7","\u732a"],
+
+    /**
+      * 24节气速查表
+      * @Array Of Property 
+      * @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
+      * @return Cn string 
+      */
+    solarTerm:["\u5c0f\u5bd2","\u5927\u5bd2","\u7acb\u6625","\u96e8\u6c34","\u60ca\u86f0","\u6625\u5206","\u6e05\u660e","\u8c37\u96e8","\u7acb\u590f","\u5c0f\u6ee1","\u8292\u79cd","\u590f\u81f3","\u5c0f\u6691","\u5927\u6691","\u7acb\u79cb","\u5904\u6691","\u767d\u9732","\u79cb\u5206","\u5bd2\u9732","\u971c\u964d","\u7acb\u51ac","\u5c0f\u96ea","\u5927\u96ea","\u51ac\u81f3"],
+
+    /**
+      * 1900-2100各年的24节气日期速查表
+      * @Array Of Property 
+      * @return 0x string For splice
+      */
+    sTermInfo:['9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f',
+              '97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
+              '97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa',
+              '97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f',
+              'b027097bd097c36b0b6fc9274c91aa','9778397bd19801ec9210c965cc920e','97b6b97bd19801ec95f8c965cc920f',
+              '97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd197c36c9210c9274c91aa',
+              '97b6b97bd19801ec95f8c965cc920e','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2',
+              '9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bcf97c3598082c95f8e1cfcc920f',
+              '97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e',
+              '97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
+              '97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722',
+              '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f',
+              '97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
+              '97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
+              '97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd07f595b0b6fc920fb0722',
+              '9778397bd097c36b0b6fc9210c8dc2','9778397bd19801ec9210c9274c920e','97b6b97bd19801ec95f8c965cc920f',
+              '97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
+              '97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
+              '9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bd07f1487f595b0b0bc920fb0722',
+              '7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
+              '97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
+              '97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
+              '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722',
+              '7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
+              '97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
+              '97b6b97bd19801ec9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
+              '9778397bd097c36b0b6fc9210c91aa','97b6b97bd197c36c9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722',
+              '7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
+              '97b6b7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
+              '9778397bd097c36b0b70c9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
+              '7f0e397bd097c35b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
+              '7f0e27f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
+              '97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
+              '9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
+              '7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
+              '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9274c91aa',
+              '97b6b7f0e47f531b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
+              '9778397bd097c36b0b6fc9210c91aa','97b6b7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
+              '7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','977837f0e37f149b0723b0787b0721',
+              '7f07e7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c35b0b6fc9210c8dc2',
+              '977837f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
+              '7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
+              '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd',
+              '7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
+              '977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
+              '7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
+              '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd',
+              '7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
+              '977837f0e37f14998082b0723b06bd','7f07e7f0e37f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
+              '7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721',
+              '7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f595b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5',
+              '7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f531b0b0bb0b6fb0722',
+              '7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
+              '7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
+              '7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35',
+              '7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
+              '7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721',
+              '7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd',
+              '7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35',
+              '7ec967f0e37f14998082b0723b06bd','7f07e7f0e37f14998083b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
+              '7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14898082b0723b02d5','7f07e7f0e37f14998082b0787b0721',
+              '7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66aa89801e9808297c35','665f67f0e37f14898082b0723b02d5',
+              '7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66a449801e9808297c35',
+              '665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
+              '7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
+              '7f07e7f0e47f531b0723b0b6fb0721','7f0e26665b66a449801e9808297c35','665f67f0e37f1489801eb072297c35',
+              '7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722'],
+
+    /**
+      * 数字转中文速查表
+      * @Array Of Property 
+      * @trans ['日','一','二','三','四','五','六','七','八','九','十']
+      * @return Cn string 
+      */
+    nStr1:["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341"],
+
+    /**
+      * 日期转农历称呼速查表
+      * @Array Of Property 
+      * @trans ['初','十','廿','卅']
+      * @return Cn string 
+      */
+    nStr2:["\u521d","\u5341","\u5eff","\u5345"],
+
+    /**
+      * 月份转农历称呼速查表
+      * @Array Of Property 
+      * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
+      * @return Cn string 
+      */
+    nStr3:["\u6b63","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u51ac","\u814a"],
+
+    /**
+      * 返回农历y年一整年的总天数
+      * @param lunar Year
+      * @return Number
+      * @eg:var count = calendar.lYearDays(1987) ;//count=387
+      */
+    lYearDays:function(y) {
+        var i, sum = 348;
+        for(i=0x8000; i>0x8; i>>=1) { sum += (calendar.lunarInfo[y-1900] & i)? 1: 0; }
+        return(sum+calendar.leapDays(y));
+    },
+
+    /**
+      * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
+      * @param lunar Year
+      * @return Number (0-12)
+      * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
+      */
+    leapMonth:function(y) { //闰字编码 \u95f0
+        return(calendar.lunarInfo[y-1900] & 0xf);
+    },
+
+    /**
+      * 返回农历y年闰月的天数 若该年没有闰月则返回0
+      * @param lunar Year
+      * @return Number (0、29、30)
+      * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
+      */
+    leapDays:function(y) {
+        if(calendar.leapMonth(y))  { 
+            return((calendar.lunarInfo[y-1900] & 0x10000)? 30: 29); 
+        }
+        return(0);
+    },
+
+    /**
+      * 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
+      * @param lunar Year
+      * @return Number (-1、29、30)
+      * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
+      */
+    monthDays:function(y,m) {
+        if(m>12 || m<1) {return -1}//月份参数从1至12,参数错误返回-1
+        return( (calendar.lunarInfo[y-1900] & (0x10000>>m))? 30: 29 );
+    },
+
+    /**
+      * 返回公历(!)y年m月的天数
+      * @param solar Year
+      * @return Number (-1、28、29、30、31)
+      * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
+      */
+    solarDays:function(y,m) {
+        if(m>12 || m<1) {return -1} //若参数错误 返回-1
+        var ms = m-1;
+        if(ms==1) { //2月份的闰平规律测算后确认返回28或29
+            return(((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28);
+        }else {
+            return(calendar.solarMonth[ms]);
+        }
+    },
+
+    /**
+     * 农历年份转换为干支纪年
+     * @param  lYear 农历年的年份数
+     * @return Cn string
+     */
+    toGanZhiYear:function(lYear) {
+        var ganKey = (lYear - 3) % 10;
+        var zhiKey = (lYear - 3) % 12;
+        if(ganKey == 0) ganKey = 10;//如果余数为0则为最后一个天干
+        if(zhiKey == 0) zhiKey = 12;//如果余数为0则为最后一个地支
+        return calendar.Gan[ganKey-1] + calendar.Zhi[zhiKey-1];
+        
+    },
+
+    /**
+     * 公历月、日判断所属星座
+     * @param  cMonth [description]
+     * @param  cDay [description]
+     * @return Cn string
+     */
+    toAstro:function(cMonth,cDay) {
+        var s   = "\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf";
+        var arr = [20,19,21,21,21,22,23,23,23,23,22,22];
+        return s.substr(cMonth*2 - (cDay < arr[cMonth-1] ? 2 : 0),2) + "\u5ea7";//座
+    },
+
+    /**
+      * 传入offset偏移量返回干支
+      * @param offset 相对甲子的偏移量
+      * @return Cn string
+      */
+    toGanZhi:function(offset) {
+        return calendar.Gan[offset%10] + calendar.Zhi[offset%12];
+    },
+
+    /**
+      * 传入公历(!)y年获得该年第n个节气的公历日期
+      * @param y公历年(1900-2100);n二十四节气中的第几个节气(1~24);从n=1(小寒)算起 
+      * @return day Number
+      * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
+      */
+    getTerm:function(y,n) {
+        if(y<1900 || y>2100) {return -1;}
+        if(n<1 || n>24) {return -1;}
+        var _table = calendar.sTermInfo[y-1900];
+        var _info = [
+            parseInt('0x'+_table.substr(0,5)).toString() ,
+            parseInt('0x'+_table.substr(5,5)).toString(),
+            parseInt('0x'+_table.substr(10,5)).toString(),
+            parseInt('0x'+_table.substr(15,5)).toString(),
+            parseInt('0x'+_table.substr(20,5)).toString(),
+            parseInt('0x'+_table.substr(25,5)).toString()
+        ];
+        var _calday = [
+            _info[0].substr(0,1),
+            _info[0].substr(1,2),
+            _info[0].substr(3,1),
+            _info[0].substr(4,2),
+            
+            _info[1].substr(0,1),
+            _info[1].substr(1,2),
+            _info[1].substr(3,1),
+            _info[1].substr(4,2),
+            
+            _info[2].substr(0,1),
+            _info[2].substr(1,2),
+            _info[2].substr(3,1),
+            _info[2].substr(4,2),
+            
+            _info[3].substr(0,1),
+            _info[3].substr(1,2),
+            _info[3].substr(3,1),
+            _info[3].substr(4,2),
+            
+            _info[4].substr(0,1),
+            _info[4].substr(1,2),
+            _info[4].substr(3,1),
+            _info[4].substr(4,2),
+            
+            _info[5].substr(0,1),
+            _info[5].substr(1,2),
+            _info[5].substr(3,1),
+            _info[5].substr(4,2),
+        ];
+        return parseInt(_calday[n-1]);
+    },
+
+    /**
+      * 传入农历数字月份返回汉语通俗表示法
+      * @param lunar month
+      * @return Cn string
+      * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
+      */
+    toChinaMonth:function(m) { // 月 => \u6708
+        if(m>12 || m<1) {return -1} //若参数错误 返回-1
+        var s = calendar.nStr3[m-1];
+        s+= "\u6708";//加上月字
+        return s;
+    },
+
+    /**
+      * 传入农历日期数字返回汉字表示法
+      * @param lunar day
+      * @return Cn string
+      * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
+      */
+    toChinaDay:function(d){ //日 => \u65e5
+        var s;
+        switch (d) {
+            case 10:
+            s = '\u521d\u5341'; break;
+        case 20:
+            s = '\u4e8c\u5341'; break;
+            break;
+        case 30:
+            s = '\u4e09\u5341'; break;
+            break;
+        default :
+            s = calendar.nStr2[Math.floor(d/10)];
+            s += calendar.nStr1[d%10];
+        }
+        return(s);
+    },
+
+    /**
+      * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”
+      * @param y year
+      * @return Cn string
+      * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
+      */
+    getAnimal: function(y) {
+        return calendar.Animals[(y - 4) % 12]
+    },
+
+    /**
+      * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON
+      * @param y  solar year
+      * @param m  solar month
+      * @param d  solar day
+      * @return JSON object
+      * @eg:console.log(calendar.solar2lunar(1987,11,01));
+      */
+    solar2lunar:function (y,m,d) { //参数区间1900.1.31~2100.12.31
+        if(y<1900 || y>2100) {return -1;}//年份限定、上限
+        if(y==1900&&m==1&&d<31) {return -1;}//下限
+        if(!y) { //未传参  获得当天
+            var objDate = new Date();
+        }else {
+            var objDate = new Date(y,parseInt(m)-1,d)
+        }
+        var i, leap=0, temp=0;
+        //修正ymd参数
+        var y = objDate.getFullYear(),m = objDate.getMonth()+1,d = objDate.getDate();
+        var offset   = (Date.UTC(objDate.getFullYear(),objDate.getMonth(),objDate.getDate()) - Date.UTC(1900,0,31))/86400000;
+        for(i=1900; i<2101 && offset>0; i++) { temp=calendar.lYearDays(i); offset-=temp; }
+        if(offset<0) { offset+=temp; i--; }
+        
+        //是否今天
+        var isTodayObj = new Date(),isToday=false;
+        if(isTodayObj.getFullYear()==y && isTodayObj.getMonth()+1==m && isTodayObj.getDate()==d) {
+            isToday = true;
+        }
+        //星期几
+        var nWeek = objDate.getDay(),cWeek = calendar.nStr1[nWeek];
+        if(nWeek==0) {nWeek =7;}//数字表示周几顺应天朝周一开始的惯例
+        //农历年
+        var year = i;
+        
+        var leap = calendar.leapMonth(i); //闰哪个月
+        var isLeap = false;
+        
+        //效验闰月
+        for(i=1; i<13 && offset>0; i++) {
+            //闰月
+            if(leap>0 && i==(leap+1) && isLeap==false){ 
+                --i;
+                isLeap = true; temp = calendar.leapDays(year); //计算农历闰月天数
+            }
+            else{
+                temp = calendar.monthDays(year, i);//计算农历普通月天数
+            }
+            //解除闰月
+            if(isLeap==true && i==(leap+1)) { isLeap = false; }
+            offset -= temp;
+        }
+        
+        if(offset==0 && leap>0 && i==leap+1)
+        if(isLeap){
+            isLeap = false;
+        }else{ 
+            isLeap = true; --i;
+        }
+        if(offset<0){ offset += temp; --i; }
+        //农历月
+        var month   = i;
+        //农历日
+        var day     = offset + 1;
+        
+        //天干地支处理
+        var sm      =   m-1;
+        var gzY     =   calendar.toGanZhiYear(year);
+        
+        //月柱 1900年1月小寒以前为 丙子月(60进制12)
+        var firstNode   = calendar.getTerm(year,(m*2-1));//返回当月「节」为几日开始
+        var secondNode  = calendar.getTerm(year,(m*2));//返回当月「节」为几日开始
+        
+        //依据12节气修正干支月
+        var gzM     =   calendar.toGanZhi((y-1900)*12+m+11);
+        if(d>=firstNode) {
+            gzM     =   calendar.toGanZhi((y-1900)*12+m+12);
+        }
+        
+        //传入的日期的节气与否
+        var isTerm = false;
+        var Term   = null;
+        if(firstNode==d) {
+            isTerm  = true;
+            Term    = calendar.solarTerm[m*2-2];
+        }
+        if(secondNode==d) {
+            isTerm  = true;
+            Term    = calendar.solarTerm[m*2-1];
+        }
+        //日柱 当月一日与 1900/1/1 相差天数
+        var dayCyclical = Date.UTC(y,sm,1,0,0,0,0)/86400000+25567+10;
+        var gzD = calendar.toGanZhi(dayCyclical+d-1);
+        //该日期所属的星座
+        var astro = calendar.toAstro(m,d);
+        
+        return {'lYear':year,'lMonth':month,'lDay':day,'Animal':calendar.getAnimal(year),'IMonthCn':(isLeap?"\u95f0":'')+calendar.toChinaMonth(month),'IDayCn':calendar.toChinaDay(day),'cYear':y,'cMonth':m,'cDay':d,'gzYear':gzY,'gzMonth':gzM,'gzDay':gzD,'isToday':isToday,'isLeap':isLeap,'nWeek':nWeek,'ncWeek':"\u661f\u671f"+cWeek,'isTerm':isTerm,'Term':Term,'astro':astro};
+    },
+
+    /**
+      * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON
+      * @param y  lunar year
+      * @param m  lunar month
+      * @param d  lunar day
+      * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
+      * @return JSON object
+      * @eg:console.log(calendar.lunar2solar(1987,9,10));
+      */
+    lunar2solar:function(y,m,d,isLeapMonth) {   //参数区间1900.1.31~2100.12.1
+        var isLeapMonth = !!isLeapMonth;
+        var leapOffset  = 0;
+        var leapMonth   = calendar.leapMonth(y);
+        var leapDay     = calendar.leapDays(y);
+        if(isLeapMonth&&(leapMonth!=m)) {return -1;}//传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
+        if(y==2100&&m==12&&d>1 || y==1900&&m==1&&d<31) {return -1;}//超出了最大极限值 
+        var day  = calendar.monthDays(y,m); 
+        var _day = day;
+        //bugFix 2016-9-25 
+        //if month is leap, _day use leapDays method 
+        if(isLeapMonth) {
+            _day = calendar.leapDays(y,m);
+        }
+        if(y < 1900 || y > 2100 || d > _day) {return -1;}//参数合法性效验
+        
+        //计算农历的时间差
+        var offset = 0;
+        for(var i=1900;i<y;i++) {
+            offset+=calendar.lYearDays(i);
+        }
+        var leap = 0,isAdd= false;
+        for(var i=1;i<m;i++) {
+            leap = calendar.leapMonth(y);
+            if(!isAdd) {//处理闰月
+                if(leap<=i && leap>0) {
+                    offset+=calendar.leapDays(y);isAdd = true;
+                }
+            }
+            offset+=calendar.monthDays(y,i);
+        }
+        //转换闰月农历 需补充该年闰月的前一个月的时差
+        if(isLeapMonth) {offset+=day;}
+        //1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
+        var stmap   =   Date.UTC(1900,1,30,0,0,0);
+        var calObj  =   new Date((offset+d-31)*86400000+stmap);
+        var cY      =   calObj.getUTCFullYear();
+        var cM      =   calObj.getUTCMonth()+1;
+        var cD      =   calObj.getUTCDate();
+
+        return calendar.solar2lunar(cY,cM,cD);
+    }
+};
+
+export default calendar

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 809 - 0
src/components/calendar/calendar.vue


+ 2 - 1
src/components/ctop/propModal.vue

@@ -117,8 +117,9 @@
         that.form.resetFields();
         that.model = Object.assign({}, record);
         that.visible = true;
-        that.imageUrl = record.coverUrl?[record.coverUrl]:[]
+        
         that.$nextTick(() => {
+          that.imageUrl = record.coverUrl?[record.coverUrl]:[]
           that.form.setFieldsValue(pick(this.model, 'name', 'desc'))
           //时间格式化
         });

+ 323 - 0
src/components/editableTree.vue

@@ -0,0 +1,323 @@
+<template>
+  <div id="areaTree" class="addrTree">
+    <ul :id="treeId" class="ztree"></ul>
+  </div>
+</template>
+
+<script>
+import $ from 'jquery'
+export default {
+  name: 'editableTree',
+  components: {},
+  props: {
+    treeData: {
+      // 树 data
+      type: Array,
+      default() {
+        return []
+      },
+    },
+    editable: {
+      // 是否可编辑
+      type: Boolean,
+      default: true,
+    },
+    btn: {
+      // 按钮集合
+      type: Array,
+      default() {
+        return ['add', 'del']
+      },
+    },
+    selectFirstNode: {
+      // 是否默认选中第一个节点
+      type: Boolean,
+      default: false,
+    },
+    pIdKey: {
+      type: String,
+      default: 'parentId',
+    },
+  },
+  data() {
+    return {
+      treeId: 'treeDemo' + new Date().getTime(),
+      setting: {
+        view: {
+          addHoverDom: this.editable && this.showBtn('add') && this.addHoverDom,
+          showIcon: false,
+          showLine: true,
+          selectedMulti: false,
+        },
+        edit: {
+          enable: this.editable,
+          showRemoveBtn: this.showBtn('del') && this.showRemoveBtn,
+          showRenameBtn: this.showBtn('edit') && this.showRenameBtn,
+          removeTitle: '删除',
+          renameTitle: '修改',
+        },
+        data: {
+          simpleData: {
+            enable: true,
+            idKey: 'id',
+            pIdKey: this.pIdKey,
+            rootPId: 0,
+          },
+        },
+        callback: {
+          onClick: this.zTreeOnClick,
+          beforeDrag: this.beforeDrag,
+          onExpand: this.onExpand,
+          beforeRemove: this.beforeRemove,
+          beforeEditName: this.beforeEditName,
+          beforeRename: this.beforeRename,
+          onRename: this.onRename,
+          onRemove: this.onRemove,
+        },
+      },
+      zNodes: [],
+      log: '',
+      className: 'dark',
+      newCount: 1,
+      curDragNodes: '',
+      autoExpandNode: '',
+      action: 'add',
+    }
+  },
+  methods: {
+    zTreeOnClick(event, treeId, treeNode) {
+      this.$emit('treeNodeClick', treeNode)
+    },
+    beforeDrag(treeId, treeNodes) {
+      return false
+    },
+    onExpand(event, treeId, treeNode) {
+      if (treeNode === this.autoExpandNode) {
+        this.className = this.className === 'dark' ? '' : 'dark'
+        this.showLog('[ ' + this.getTime() + ' onExpand ]&nbsp;&nbsp;&nbsp;&nbsp;' + treeNode.name)
+      }
+    },
+    remove() {
+      // 移除节点
+      var zTree = $.fn.zTree.getZTreeObj(this.treeId),
+        nodes = zTree.getSelectedNodes(),
+        treeNode = nodes[0]
+      this.$emit('delTreeNode', treeNode)
+    },
+    beforeRemove(treeId, treeNode) {
+      if (treeNode.id) {
+        console.log('delete:', treeNode)
+        this.$emit('deleteNode', treeNode) // 触发删除
+      }
+      return false
+    },
+    onRemove(e, treeId, treeNode) {
+      this.showLog('[ ' + this.getTime() + ' onRemove ]&nbsp;&nbsp;&nbsp;&nbsp; ' + treeNode.name)
+    },
+    onRename(event, treeId, treeNode, isCancel) {
+      console.log('rename')
+      this.$emit('treeInfoEvent', treeNode, event)
+    },
+    beforeRename(treeId, treeNode, newName) {
+      if (newName.length == 0) {
+        alert('节点名称不能为空.')
+        var zTree = $.fn.zTree.getZTreeObj(this.treeId)
+        setTimeout(function () {
+          zTree.editName(treeNode)
+        }, 10)
+        return false
+      } else if (newName.length > 20) {
+        alert('节点名称不能大于20个字符.')
+        var zTree = $.fn.zTree.getZTreeObj(this.treeId)
+        setTimeout(function () {
+          zTree.editName(treeNode)
+        }, 10)
+        return false
+      }
+      return true
+    },
+    showLog(str) {
+      if (!this.log) this.log = $('#log')
+      this.log.append("<li class='" + this.className + "'>" + str + '</li>')
+      if (this.log.children('li').length > 8) {
+        this.log.get(0).removeChild(this.log.children('li')[0])
+      }
+    },
+    getTime() {
+      var now = new Date(),
+        h = now.getHours(),
+        m = now.getMinutes(),
+        s = now.getSeconds(),
+        ms = now.getMilliseconds()
+      return h + ':' + m + ':' + s + ' ' + ms
+    },
+    addHoverDom(treeId, treeNode) {
+      if (treeNode.addDis != true) {
+        let _this = this
+        var sObj = $('#' + treeNode.tId + '_span')
+        if (treeNode.editNameFlag || $('#addBtn_' + treeNode.tId).length > 0) return
+        var addStr =
+          "<span class='button add' id='addBtn_" + treeNode.tId + "' title='新增' onfocus='this.blur();'>新增</span>"
+        sObj.after(addStr)
+        var btn = $('#addBtn_' + treeNode.tId)
+        if (btn)
+          btn.bind('click', function () {
+            _this.add(treeNode)
+          })
+      }
+    },
+    add(treeNode) {
+      // 增加子节点
+      this.action = 'add' // 切换为add
+      var zTree = $.fn.zTree.getZTreeObj(this.treeId)
+      var isParent = false
+      var nodes = zTree.getSelectedNodes()
+      var treeNode2 = nodes[0]
+      if (treeNode) {
+        treeNode2 = zTree.addNodes(treeNode, {
+          id: '',
+          pId: treeNode.id,
+          sysCode: treeNode.sysCode || treeNode.valStr,
+          isParent: isParent,
+          name: '新子节点' + this.newCount++,
+        })
+      } else {
+        treeNode2 = zTree.addNodes(null, { id: '', pId: 0, isParent: isParent, name: '新节点' + this.newCount++ })
+      }
+      if (treeNode2) {
+        zTree.editName(treeNode2[0])
+      } else {
+        alert('叶子节点被锁定,无法增加子节点')
+      }
+    },
+    addTopNodes() {
+      this.action = 'add'
+      var zTree = $.fn.zTree.getZTreeObj(this.treeId)
+      var treeNode = zTree.addNodes(null, { id: '', pId: 0, isParent: true, name: '新节点' + this.newCount++ })
+      zTree.editName(treeNode[0])
+      this.treeNodeMessage = zTree.getNodes() //Root节点信息
+      this.$emit('RootNodes', this.treeNodeMessage)
+    },
+    showRemoveBtn(treeId, treeNode) {
+      if (treeNode.removeDis == true) return false
+      return true
+    },
+    showRenameBtn(treeId, treeNode) {
+      if (treeNode.renameDis == true) return true
+      return false
+    },
+    showBtn(button) {
+      if (this.btn && this.btn.length > 0) {
+        if (this.btn.findIndex((v) => v == button) > -1) {
+          return true
+        } else {
+          return false
+        }
+      } else {
+        return false
+      }
+    },
+    selectFirstNodeFun() {
+      // 选中第一个节点
+      if (this.selectFirstNode) {
+        const treeObj = $.fn.zTree.getZTreeObj(this.treeId)
+        console.log(treeObj)
+        let nodes = treeObj.getNodes()
+        if (nodes.length > 0) {
+          treeObj.selectNode(nodes[0])
+        }
+      }
+    },
+    selectNode(node) {
+      const treeObj = $.fn.zTree.getZTreeObj(this.treeId)
+      treeObj.selectNode(node)
+    },
+    queryTreeFun(data) {
+      this.searchTree(data)
+    },
+    searchTree(info) {
+      var treeObj = $.fn.zTree.getZTreeObj(this.treeId)
+      if (info.val == '') {
+        $.fn.zTree.init($('#' + this.treeId), this.setting, this.treeData)
+      } else {
+        function filter(node) {
+          return node.name.indexOf(info.val) > -1
+        }
+        let nodes = treeObj.transformToArray(this.treeData)
+        nodes = JSON.parse(JSON.stringify(nodes))
+        nodes.map((item) => {
+          if (item.hasOwnProperty('children')) {
+            delete item.children
+          }
+          return item
+        })
+
+        nodes = nodes.filter((v) => v.name.indexOf(info.val) > -1)
+        nodes = treeObj.transformTozTreeNodes(nodes)
+        $.fn.zTree.init($('#' + this.treeId), this.setting, nodes)
+        treeObj.expandAll(true)
+      }
+    },
+  },
+  watch: {
+    treeData(val) {
+      $.fn.zTree.init($('#' + this.treeId), this.setting, val)
+      this.selectFirstNodeFun()
+    },
+  },
+  mounted() {
+    this.$nextTick(() => {
+      $.fn.zTree.init($('#' + this.treeId), this.setting, this.treeData)
+      this.selectFirstNodeFun()
+    })
+  },
+}
+</script>
+<style lang="scss" scope>
+.addrTree {
+  position: relative;
+  height: 100%;
+  background: #fff;
+  .tree_title {
+    height: 30px;
+    line-height: 30px;
+    padding: 0 10px;
+    background: #fafafa;
+    button {
+      float: right;
+      margin: 4px 4px 0 0;
+    }
+  }
+  .ztree {
+    height: 100%;
+    overflow: auto;
+    padding: 5px;
+    li span.button.add {
+      background-position: -143px 0;
+    }
+  }
+  [treenode_a] {
+    vertical-align: middle;
+    .button.add {
+      margin-right: 2px;
+      display: none;
+    }
+    &:hover {
+      .button.add {
+        display: inline-block;
+      }
+    }
+    span {
+      vertical-align: middle !important;
+    }
+  }
+  [treenode_a].curSelectedNode {
+    .button.add {
+      display: inline-block;
+    }
+  }
+  [treenode_switch] {
+    vertical-align: middle;
+  }
+}
+</style>

+ 38 - 2
src/components/formComponents/selectGroup.vue

@@ -31,6 +31,11 @@ export default {
       type: String,
       default: '',
     },
+    requestUrl: {
+      // 字典代码
+      type: String,
+      default: '',
+    },
     require: {
       type: Boolean,
       default() {
@@ -216,8 +221,11 @@ export default {
     this.$nextTick(() => {
       if (this.code && this.options.length == 0) {
         // 如果code值不为空且options.lengt==0, 则去请求字典项
-        this.getOptions()
-      } else {
+        this.getOptions(this.requestUrl)
+      } else if(this.requestUrl && this.options.length == 0){
+        this.getOptionsByURrl(this.requestUrl)
+        
+      }else {
         // 否则将外部传入的options显示到下拉框中
         this.selectOption.splice(0, this.selectOption.length)
         this.selectOption.push(...this.options)
@@ -229,6 +237,34 @@ export default {
     filterOptionAll(input, option) {
       return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
     },
+    getOptionsByURrl(url){
+      getAction(url,{}).then((res) => {
+        if (res.success && isArray(res.result)) {
+          let data = res.result
+          data = data.map((v) => {
+            return {
+              ...v,
+              label: v.tagName,
+              value: v.tagId+"",
+            }
+          })
+          if (!this.multiple && !this.require) {
+            data.unshift({ label: '不限', value: 'unlimited' })
+            if (this.value == ''|| this.value == null || this.value.length == 0 ) {
+              this.selectedVal = ['unlimited']
+            }
+          } else {
+            if (this.value == ''|| this.value == null || this.value.length == 0 ) {
+              this.selectedVal = []
+              this.$emit('clearValidate', this.selectedVal)
+            }
+          }
+          this.selectOption.splice(0, this.selectOption.length)
+          this.selectOption.push(...data)
+          this.setDefaultVal(this.selectOption)
+        }
+      })
+    },
     getOptions() {
       // 获取字典项
 

+ 2 - 4
src/components/formComponents/selectRegion.vue

@@ -168,8 +168,7 @@
     mounted() {
       this.$nextTick(() => {
         this.getData().then(() => {
-            console.log(this.dataValue)
-          if (this.dataValue.length>0&&this.dataValue[0].value) {
+          if (this.dataValue&&this.dataValue.length>0&&this.dataValue[0].value) {
             return
           } else {
             postAction('/kuaishou/batch/getRegionDetail', {
@@ -201,9 +200,8 @@
         deep: true,
         immediate: true, // immediate选项可以开启首次赋值监听
         handler(n, o) {
-          if (n.length > 0 && n[0].value) {
+          if (n&&n.length > 0 && n[0].value) {
             // this.getData().then(() => {
-            console.log(1)
             //   if (n.length > 0) {
             this.$nextTick(() => {
               this.checkData = n

+ 1 - 0
src/components/formComponents/toutiaoTime.vue

@@ -46,6 +46,7 @@ export default {
   },
   data() {
     return {
+      changeDataElse: ['1'],
       show: false,
       numData: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
       dateTime: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],

+ 12 - 4
src/components/layouts/UserLayout.vue

@@ -1,7 +1,7 @@
 <template>
   <div id="userLayout" :class="['user-layout-wrapper', device]">
-    <div class="container">
-      <div class="top" style="margin-bottom:30px">
+    <div class="container"  v-if="showTitle">
+      <div class="top" style="margin-bottom: 30px" >
         <div class="header">
           <a href="/">
             <img src="~@/assets/logo.png" class="logo" alt="logo" style="height: 50px" />
@@ -24,6 +24,7 @@
         <div class="copyright">Copyright &copy; 2019 上海有腾</div>
       </div>
     </div>
+    <route-view v-else></route-view>
   </div>
 </template>
 
@@ -36,14 +37,21 @@ export default {
   components: { RouteView },
   mixins: [mixinDevice],
   data() {
-    return {}
+    return {
+      showTitle: true,
+    }
   },
   mounted() {
     document.body.classList.add('userLayout')
+    if (this.$route.path == '/user/new-batch'||this.$route.path=='/user/lookPreview') {
+      this.showTitle = false
+    } else {
+      this.showTitle = true
+    }
   },
   beforeDestroy() {
     document.body.classList.remove('userLayout')
-  }
+  },
 }
 </script>
 

+ 31 - 26
src/components/uploadFile.vue

@@ -24,7 +24,7 @@
       </div>
     </a-upload>
     <div style="color: red" v-if="sizeCheck">
-      {{ uploadType == 'image' ? '请上传jpg格式的图片,并且大小在2m之内' : '请上传mp4格式,大小在100m之内' }}
+      {{ uploadType == 'image' ? '请上传jpg格式的图片,并且大小在2m之内' : '请上传mp4格式,大小在'+(size/1024)+'m之内' }}
     </div>
     <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
       <img alt="example" style="width: 100%" :src="previewImage" v-if="uploadType == 'image'" />
@@ -97,6 +97,9 @@ export default {
     },
     value: {
       required: true,
+      default() {
+        return ''
+      },
     },
     size: {
       type: Number,
@@ -141,35 +144,37 @@ export default {
     value: {
       immediate: true,
       handler(n, o) {
-        if (this.fileList&&this.fileList.length == 0) {
-          if (typeof n == 'object') {
-            this.fileList = n.map((item, index) => {
-              return {
-                uid: index + 1,
-                name: index + 1,
-                status: 'done',
-                url: item,
+        this.$nextTick(() => {
+          if (this.fileList && this.fileList.length == 0) {
+            if (typeof n == 'object') {
+              this.fileList = n.map((item, index) => {
+                return {
+                  uid: index + 1,
+                  name: index + 1,
+                  status: 'done',
+                  url: item,
+                }
+              })
+            } else {
+              if (n == '') {
+                this.fileList = []
+              } else {
+                this.fileList = [
+                  {
+                    uid: 1,
+                    name: 1,
+                    status: 'done',
+                    url: n,
+                  },
+                ]
               }
-            })
+            }
           } else {
-            if (n == '') {
-              this.fileList = []
-            } else {
-              this.fileList = [
-                {
-                  uid: 1,
-                  name: 1,
-                  status: 'done',
-                  url: n,
-                },
-              ]
+            if (n.length == 0 || n == '') {
+              this.clearAll()
             }
           }
-        } else {
-          if (n.length == 0 || n == '') {
-            this.clearAll()
-          }
-        }
+        })
       },
       deep: true,
     },

+ 348 - 0
src/components/uploadFileMd5Push.vue

@@ -0,0 +1,348 @@
+<style>
+</style>
+<style lang="scss">
+.md5-file {
+  width: 100%;
+  height: 100%;
+}
+.md5-file .ant-upload-picture-card-wrapper {
+  height: 100% !important;
+}
+.md5-file .ant-upload.ant-upload-select-picture-card {
+  height: 100% !important;
+  width: 100%;
+}
+
+</style>
+<template>
+  <div class="upload-file md5-file">
+    <a-upload
+      name="file"
+      :multiple="multiple"
+      list-type="picture-card"
+      class="avatar-uploader"
+      action="https://media-1301855440.cos.ap-chongqing.myqcloud.com/"
+      :before-upload="beforeUpload"
+      @change="handleChange"
+      :accept="uploadType + '/' + (uploadType == 'image' ? 'jpeg,image/jpg' : 'mp4')"
+      :file-list="fileList"
+      :remove="removeFile"
+      @preview="handlePreview"
+      :disabled="loadingElse || disabled"
+    >
+      <div v-if="fileList.length < fileCount || fileList.length < 1">
+        <a-progress v-if="loadingElse" :percent="percent" :show-info="false" />
+        <div>点击上传</div>
+      </div>
+    </a-upload>
+    <!-- <div style="color: red" v-if="sizeCheck">
+      {{ uploadType == 'image' ? '请上传jpg格式的图片,并且大小在2m之内' : '请上传mp4格式,大小在100m之内' }}
+    </div> -->
+    <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
+      <img alt="example" style="width: 100%" :src="previewImage" v-if="uploadType == 'image'" />
+      <video :src="previewImage" v-else style="width: 100%" controls="controls">您的浏览器不支持 video 标签。</video>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import { stopOtherVideo, closeAllVideoFun } from '@/utils/videoControl' // 停止除当前外的其他视频播放,及停止所有视频播放的方法
+import { mapGetters } from 'vuex'
+import moment from 'moment'
+
+import BMF from 'browser-md5-file'
+
+import qs from 'qs'
+var COS = require('cos-js-sdk-v5')
+var cos = new COS({
+  SecretId: 'AKIDE6IpMi8fJQRCg1iuWzFajjRs43kbbets',
+  SecretKey: 'tXzuwMfplTTK3c9GFUyETilasvQfePu9',
+})
+var i = 0
+const oneKB = 1024
+
+function getBase64(file) {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader()
+    reader.readAsDataURL(file)
+    reader.onload = () => resolve(reader.result)
+    reader.onerror = (error) => reject(error)
+  })
+}
+export default {
+  name: 'upload-file',
+  components: {},
+  props: {
+    uploadType: {
+      //上传类型  值为  image/video,同时目录名称也是这样
+      type: String,
+      default() {
+        return 'image'
+      },
+    },
+    multiple: {
+      // true 可以批量上传  false 不可以
+      type: Boolean,
+      default() {
+        return true
+      },
+    },
+    fileCount: {
+      //最大上传数量
+      type: Number,
+      default() {
+        return 10
+      },
+    },
+    checkFile: {
+      //返回promise方法,判读文件是否上传过,进行上传拦截
+      type: Function,
+      default() {
+        return Promise.resolve()
+      },
+    },
+    disabled: {
+      type: Boolean,
+      default() {
+        return false
+      },
+    },
+    value: {
+      required: true,
+      default() {
+        return ''
+      },
+    },
+    size: {
+      type: Number,
+      default() {
+        if (this.sizeCheck) {
+          if (this.uploadType == 'image') {
+            return 2048
+          } else {
+            return 102400
+          }
+        }
+      },
+    },
+    sizeCheck: {
+      type: Boolean,
+      default() {
+        return true
+      },
+    },
+    onOversize: {
+      type: Function,
+      default() {
+        alert(`请选择${this.size}KB内的文件!`)
+      },
+    },
+  },
+  data() {
+    return {
+      fileList: [],
+      loadingElse: false,
+      imageUrl: '',
+      percent: 0,
+      previewVisible: false,
+      previewImage: '',
+      md5: '',
+      accountId: '',
+    }
+  },
+  filters: {},
+  computed: {},
+  mounted() {},
+  watch: {
+    //    fileListAll
+    // value: {
+    //   immediate: true,
+    //   handler(n, o) {
+    //     this.$nextTick(() => {
+    //       if (this.fileList && this.fileList.length == 0) {
+    //         if (typeof n == 'object') {
+    //           this.fileList = n.map((item, index) => {
+    //             return {
+    //               uid: index + 1,
+    //               name: index + 1,
+    //               status: 'done',
+    //               url: item,
+    //             }
+    //           })
+    //         } else {
+    //           if (n == '') {
+    //             this.fileList = []
+    //           } else {
+    //             this.fileList = [
+    //               {
+    //                 uid: 1,
+    //                 name: 1,
+    //                 status: 'done',
+    //                 url: n,
+    //               },
+    //             ]
+    //           }
+    //         }
+    //       } else {
+    //         if (n.length == 0 || n == '') {
+    //           this.clearAll()
+    //         }
+    //       }
+    //     })
+    //   },
+    //   deep: true,
+    // },
+  },
+  methods: {
+    handleCancel() {
+      closeAllVideoFun()
+      this.previewVisible = false
+    },
+    handleChange(info) {
+      if (info.file.status === 'uploading') {
+        this.loading = true
+        return
+      }
+      if (info.file.status === 'done') {
+        // Get this url from response in real world.
+        getBase64(info.file.originFileObj, (imageUrl) => {
+          this.imageUrl = imageUrl
+          this.loading = false
+        })
+      }
+    },
+    removeFile(file) {
+      // console.log(file)
+      var index = this.fileList.findIndex((v) => v.uid === file.uid)
+      this.fileList.splice(index, 1)
+      this.$emit('removeUpload', file)
+    },
+    async handlePreview(file) {
+      if (!file.url && !file.preview) {
+        file.preview = await getBase64(file.originFileObj)
+      }
+      this.previewImage = file.url || file.preview
+      this.previewVisible = true
+    },
+    beforeUpload(file) {
+      this.percent = 0
+      this.loadingElse = true
+      const fileOvesize = file.size > this.size * oneKB
+      // console.log(fileOvesize)
+      if (fileOvesize && this.sizeCheck) {
+        this.onOversize()
+        this.loadingElse = false
+        return
+      } else {
+        this.checkFile(file)
+          .then((res) => {
+            this.md5 = res.md5
+            this.accountId = res.accountId
+            this.cosUpload(file)
+          })
+          .catch(() => {
+            this.loadingElse = false
+          })
+        return new Promise(function (resolve, reject) {
+          reject()
+        })
+      }
+    },
+    clearAll() {
+      this.fileList = []
+    },
+    cosUpload(file) {
+      var that = this
+      let date = new Date()
+      let y = date.getFullYear()
+      let MM = date.getMonth() + 1
+      MM = MM < 10 ? '0' + MM : MM
+      let d = date.getDate()
+      d = d < 10 ? '0' + d : d
+      var timeElse = new Date().getTime()
+      var arr = file.name.split('.')
+
+      var str = ''
+      for (let i = 0; i < arr.length; i++) {
+        if (i == arr.length - 1) {
+        } else {
+          if (i == arr.length - 2) {
+            str += arr[i]
+          } else {
+            str += arr[i] + '.'
+          }
+        }
+      }
+      // console.log(str + '-' + timeElse + '.' + arr[arr.length - 1])
+      cos.putObject(
+        {
+          Bucket: 'media-1301855440',
+          /* 必须 */
+          Region: 'ap-chongqing',
+          /* 存储桶所在地域,必须字段 */
+          Key: that.uploadType + '/' + y + '-' + MM + '-' + d + '/' + str + '-' + timeElse + '.' + arr[arr.length - 1],
+          /* 必须 */
+          StorageClass: 'STANDARD',
+          Body: file, // 上传文件对象
+          onProgress: function (progressData) {
+            //进度条方法
+
+            that.percent = progressData.percent * 100
+          },
+          onTaskReady: function (tid) {
+            // console.log('onTaskReady', tid);
+          },
+          onTaskStart: function (info) {
+            //开始上传
+            // console.log('onTaskStart', info);
+          },
+        },
+        function (err, data) {
+          if (err) {
+            that.loadingElse = false
+            that.$message.error('上传失败!!!' + err)
+            return
+          }
+          // alert('成功')
+          that.loadingElse = false
+          if (that.fileList.length < that.fileCount) {
+            that.fileList.push({
+              uid: file.name,
+              name: file.name,
+              status: 'done',
+              url: '//' + data.Location,
+            })
+
+            // that.$emit('overUpload', that.fileList.map(item => {
+            //                 return item.url
+            //               }))
+            that.$emit('overUpload', that.fileList)
+
+            if (that.multiple) {
+              that.$emit(
+                'update:value',
+                that.fileList.map((item) => {
+                  return item.url
+                })
+              )
+            } else {
+              that.$emit(
+                'update:value',
+                that.fileList.map((item) => {
+                  return { url: item.url, signature: that.md5 }
+                })[0]
+              )
+             
+            }
+          } else {
+            that.$message.error('上传已达上限' + that.fileCount + '张')
+          }
+        }
+      )
+    },
+  },
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3735 - 0
src/components/vend-ztree.all.js


+ 266 - 0
src/components/youtTable/YoutTable.vue

@@ -0,0 +1,266 @@
+
+<template>
+    <div class="youtTable">
+        <div class="yout-header">
+            <p class="headTitle">{{headTitle}}</p>
+            <div class="opt-btn">
+                <a-button type='default' v-if="isNeedCustomColumn" @click="customColumns" style="margin-right:15px">自定义列</a-button>
+                <a-button type='default' v-if='isNeedExport' @click="exportExcel" :loading="exportloading">导出报表</a-button>
+            </div>
+        </div>
+        <div class="tableBody">
+            <a-table
+                :size="size"
+                :columns="columns"
+                :dataSource="data"
+                bordered
+                id="outTable"
+                :pagination="pagination"
+                :scroll="{ x: scrollX, y: scrollY }"
+                :loading="loading"
+                ref="accountTable"
+                @change="change"                
+              >
+
+                <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
+                <span slot="cost" slot-scope="cost">{{ cost | decimalsHandle }}</span>
+                <span slot="clickMaterial" slot-scope="clickMaterial">{{ clickMaterial | formatCurrency }}</span>
+                <span slot="showMaterial" slot-scope="showMaterial">{{ showMaterial | formatCurrency }}</span>
+                <span slot="convertMaterial" slot-scope="convertMaterial">{{ convertMaterial | formatCurrency }}</span>
+                <span slot="play25FeedBreak" slot-scope="play25FeedBreak">{{ play25FeedBreak | formatCurrency }}</span>
+                <span slot="play50FeedBreak" slot-scope="play50FeedBreak">{{ play50FeedBreak | formatCurrency }}</span>
+                <span slot="play75FeedBreak" slot-scope="play75FeedBreak">{{ play75FeedBreak | formatCurrency }}</span>
+                <span slot="play100FeedBreak" slot-scope="play100FeedBreak">{{ play100FeedBreak | formatCurrency }}</span>
+                <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
+                <span slot="downloadFinish" slot-scope="downloadFinish">{{ downloadFinish | formatCurrency }}</span>
+                <span slot="downloadStart" slot-scope="downloadStart">{{ downloadStart | formatCurrency }}</span>
+                <span slot="likeMaterial" slot-scope="likeMaterial">{{ likeMaterial | formatCurrency }}</span>
+                <span slot="shareMaterial" slot-scope="shareMaterial">{{ shareMaterial | formatCurrency }}</span>
+                <span slot="register" slot-scope="register">{{ register | formatCurrency }}</span>
+                <span slot="follow" slot-scope="follow">{{ follow | formatCurrency }}</span>
+                <span slot="formCount" slot-scope="formCount">{{ formCount | formatCurrency }}</span>
+                <span slot="formCountCost" slot-scope="formCountCost">{{ formCountCost | decimalsHandle }}</span>
+                <span slot="aClick" slot-scope="aClick">{{ aClick | formatCurrency }}</span>
+                <span slot="photoShow" slot-scope="photoShow">{{ photoShow | formatCurrency }}</span>
+                <span slot="photoClick" slot-scope="photoClick">{{ photoClick | formatCurrency }}</span>
+                <span slot="bClick" slot-scope="bClick">{{ bClick | formatCurrency }}</span>
+                <span slot="active" slot-scope="active">{{ active | formatCurrency }}</span>
+                <span slot="submit" slot-scope="submit">{{ submit | formatCurrency }}</span>
+                <span slot="nextDayOpen" slot-scope="nextDayOpen">{{ nextDayOpen | formatCurrency }}</span>
+                <span slot="eventCreditGrantLandingPage" slot-scope="eventCreditGrantLandingPage">{{ eventCreditGrantLandingPage | formatCurrency }}</span>
+                <span slot="submitCost" slot-scope="submitCost">{{ submitCost | decimalsHandle }}</span>
+                <span slot="eventCreditGrantLandingPageCost" slot-scope="eventCreditGrantLandingPageCost">{{ eventCreditGrantLandingPageCost | decimalsHandle }}</span>
+                <span slot="submitRate" slot-scope="submitRate">{{ submitRate | toPercentage }}</span>
+                <span slot="eventCreditGrantLandingPageRate" slot-scope="eventCreditGrantLandingPageRate">{{ eventCreditGrantLandingPageRate | toPercentage }}</span>
+                <span
+                  slot="play25FeedBreakRate"
+                  slot-scope="play25FeedBreakRate"
+                >{{ play25FeedBreakRate | toPercentage }}</span>
+                <span slot="playOverRate" slot-scope="playOverRate">{{ playOverRate | toPercentage }}</span>
+                <!-- 新加数据 -->
+
+                <span slot="convertRate" slot-scope="convertRate">{{ convertRate | toPercentage }}</span>
+                <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
+                <span slot="ctr" slot-scope="ctr">{{ ctr | toPercentage }}</span>
+                <span slot="cpc" slot-scope="cpc">{{ cpc | decimalsHandle }}</span>
+                <span slot="cpm" slot-scope="cpm">{{ cpm | decimalsHandle }}</span>
+                <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
+                <span
+                  slot="installFinishRate"
+                  slot-scope="installFinishRate"
+                >{{ installFinishRate | toPercentage }}</span>
+                <span slot="validPlayRate" slot-scope="validPlayRate">{{ validPlayRate | toPercentage }}</span>
+                <span slot="activePayCost" slot-scope="activePayCost">{{ activePayCost | decimalsHandle }}</span>
+                <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
+                <span slot="validPlayCost" slot-scope="validPlayCost">{{ validPlayCost | decimalsHandle }}</span>
+                <span slot="activeCost" slot-scope="activeCost">{{ activeCost | decimalsHandle }}</span>
+                <span slot="nextDayOpenCost" slot-scope="nextDayOpenCost">{{ nextDayOpenCost | decimalsHandle }}</span>
+                <span
+                  slot="gameAddictionCost"
+                  slot-scope="gameAddictionCost"
+                >{{ gameAddictionCost | decimalsHandle }}</span>
+                <span
+                  slot="downloadFinishCost"
+                  slot-scope="downloadFinishCost"
+                >{{ downloadFinishCost | decimalsHandle }}</span>
+                <span
+                  slot="downloadStartCost"
+                  slot-scope="downloadStartCost"
+                >{{ downloadStartCost | decimalsHandle }}</span>
+                <span
+                  slot="installFinishCost"
+                  slot-scope="installFinishCost"
+                >{{ installFinishCost | decimalsHandle }}</span>
+                <span slot="convertCost" slot-scope="convertCost">{{ convertCost | decimalsHandle }}</span>
+
+                <!--  -->
+                <span
+                  slot="downloadStartRate"
+                  slot-scope="downloadStartRate"
+                >{{ downloadStartRate | toPercentage }}</span>
+                <span
+                  slot="downloadFinishRate"
+                  slot-scope="downloadFinishRate"
+                >{{ downloadFinishRate | toPercentage }}</span>
+                <span slot="activeRate" slot-scope="activeRate">{{ activeRate | toPercentage }}</span>
+                <span
+                  slot="activeRegisterRate"
+                  slot-scope="activeRegisterRate"
+                >{{ activeRegisterRate | toPercentage }}</span>
+                <span
+                  slot="gameAddictionRate"
+                  slot-scope="gameAddictionRate"
+                >{{ gameAddictionRate | toPercentage }}</span>
+                <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span>
+                <!-- <span slot="nextDayOpenRate" slot-scope="nextDayOpenRate">{{ nextDayOpenRate | toPercentage }}</span> -->
+
+
+                <slot name="customContext"></slot>
+                
+            </a-table>
+            <customColumn :visible='visible'  :listNum='listNum' :fiexColumn='columnsFixd' :mediaType='mediaType'  @closeCustomColumn='closeCustomColumn' @changeColumn='changeColumn' />
+        </div>
+    </div>
+</template>
+
+<script>
+import customColumn from './customColumn.vue'
+    export default {
+        components:{
+            
+            customColumn,
+        },
+        data() {
+            return {
+                exportloading:false,
+                visible:false,
+                listNum:[],
+            }
+        },
+        props:{
+            // 表格的标题
+            headTitle:{
+                type:String,
+                default:'',
+            },
+            // 是否需要自定义列
+            isNeedCustomColumn:{
+                type:Boolean,
+                default:false,
+            },
+            // 是否需要导出报表
+            isNeedExport:{
+                type:Boolean,
+                default:false,
+            },
+            
+            // 表格大小
+            size:{
+                type:String,
+                default:'middle'
+            },
+            columns:{
+                type:Array,
+                require:true,
+            },
+            columnsFixd:{
+                type:Array,
+                require:true,
+            },
+            data:{
+                type:Array,
+                default(){
+                    return []
+                }
+            },
+            pagination:{
+                default(){
+                    return false
+                }
+            },
+            loading:{
+                default:false,
+            },
+            scrollX:{
+                default:0
+            },
+            scrollY:{
+                default:0
+            },
+            mediaType:{
+                // 1-头条,2-快手
+                type:Number,
+                require:true,
+            },
+            
+
+        },
+        methods: {
+            exportExcel(){
+                this.$emit('exportExcel')
+            },
+            change(pagination, filters, sorter, { currentDataSource }){
+                this.$emit('tableChange',{pagination, filters, sorter,  currentDataSource })
+            },
+            closeCustomColumn(){
+                this.visible=false;
+            },
+            //自定义之后修改父元素表头
+            changeColumn(val){
+                this.columns=[...val];
+                this.columns=[...val];
+                if(this.columns.length> this.columnsFixd.length&&this.columns.length<8){
+                this.columns.forEach((element,index) => {
+                    if(index<this.columns.length-1){
+                    element.width='auto'
+                    element.fixed=false
+                    }             
+                });
+
+                // this.scrollX=2000+200*(this.columns.length-this.columnsFixd.length)
+                }else if(this.columns.length>=8){
+                this.columns.forEach((element,index) => {
+                    if(index<this.columnsFixd.length){
+                    element.width=200
+                    element.fixed='left'
+                    }             
+                });
+
+                this.scrollX=1000+200*(this.columns.length-this.columnsFixd.length)
+                } else{
+                this.scrollX=0;
+                this.columns.forEach(element => {
+                    element.width='auto'
+                    element.fixed=false
+                });
+                }
+            },
+            //弹出框打开,自定义列
+            customColumns() {
+                this.visible = true
+                this.listNum = [...this.columns]
+            },
+            
+        },
+    }
+</script>
+
+<style lang="scss" scoped>
+.youtTable{
+    background: white;
+    margin-bottom: 20px;
+    
+    .yout-header{       
+        padding: 20px ;
+        display: flex;
+        justify-content:space-between;
+        .headTitle{
+            margin-bottom: 0;
+            font-size: 15px;
+            font-weight: 600;
+            height: 32px;
+            line-height: 32px;
+        }
+    }
+}
+</style>

+ 300 - 0
src/components/youtTable/customColumn.vue

@@ -0,0 +1,300 @@
+<template>
+  <div class="customColumnKS">
+    <a-modal v-model="visibleOk" title="自定义列" on-ok="handleOk" @cancel="handleCancel" width="65%">
+      <template slot="footer">
+        <a-button key="back" @click="handleCancel">取消</a-button>
+        <a-button key="submit" type="primary" :loading="loading" @click="handleOk">应用</a-button>
+      </template>
+      <!-- <a-input-search placeholder="输入要添加的列的名称" style="width: 40%" enter-button @search="onSearch" /> -->
+      <div class="zhuti">
+        <div class="addlist">
+          <p>可添加的列</p>
+          <div class="selectionList">
+            <!--  v-for="(item,index) in addColumns" :key="index" -->
+            <!-- <div v-if="mediaType==1"> -->
+              <selectComponent
+              :showCol="mylistNum"
+              @getshowlist="getshowlist"
+              :fixedCol="fiexColumn"
+              :mediaType='mediaType'
+              
+              />
+            <!-- </div> -->
+            <!-- <div v-if="mediaType==2">
+              <selectComponentKS
+              :showCol="mylistNum"
+              @getshowlist="getshowlist"
+              :fixedCol="fiexColumn"
+              :mediaType='mediaType'
+              
+            />
+            </div> -->
+            
+          </div>
+        </div>
+        <div class="listNum">
+          <p>已选{{mylistNum.length}}列</p>
+          <a-button id="btn" type="link" @click="clearAllList">清空全部</a-button>
+          <ul class="selectlist">
+                <!-- draggable="true"
+                  @dragstart="handleDragStart($event, item.dataIndex)"
+                  @dragover.prevent="handleDragOver($event, item.dataIndex)"
+                  @dragenter="handleDragEnter($event, item.dataIndex)"
+                  @dragend="handleDragEnd($event, item.dataIndex)" -->
+            <li v-for="(item,index) in mylistNum" :key="index">
+              <span v-if=" index < fiexColumn.length">
+                <a-icon type="lock" />
+                <span class="listText">{{item.title}}</span>
+              </span>
+              <span v-else-if=" index >=fiexColumn.length"  >
+                <a-icon type="menu" style="color:#ccc" />
+                <span class="listText">{{item.title}}</span>
+                <a-icon
+                  type="close"
+                  @click="deleteCol(item,index)"
+                  id="closeStyle"
+                  style="fontSize:12px;"
+                />
+              </span>
+            </li>
+          </ul>
+        </div>
+      </div>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import selectComponent from './selectComponent'
+import selectComponentKS from './selectComponentKS'
+export default {
+  components: {
+    selectComponent,
+    selectComponentKS,
+  },
+  props: ['visible', 'listNum', 'fiexColumn','mediaType'],
+
+  data() {
+    return {
+      dragging: null,
+      dataKey: 0,
+      visibleOk: false,
+      mylistNum: [],
+      loading: false
+    }
+  },
+  watch: {
+    visible(n, o) {
+      // console.log(n,o)
+      this.visibleOk = this.visible
+    },
+    listNum: {
+      handler(newValue, oldValue) {
+        console.log(newValue, oldValue)
+        this.mylistNum = newValue
+      },
+      immediate: true
+      // deep: true
+    }
+  },
+  methods: {
+     //li展示里的关闭按钮 删除当前被选中的这一个列
+    deleteCol(item, index) {
+      this.mylistNum = this.mylistNum.filter((item1, num) => {
+        return num != index
+      })
+    },
+    handleDragStart(e, item) {
+      this.dragging = item
+    },
+    handleDragEnd(e, item) {
+      this.dragging = null
+    },
+    //首先把div变成可以放置的元素,即重写dragenter/dragover
+    handleDragOver(e) {
+      e.dataTransfer.dropEffect = 'move' // e.dataTransfer.dropEffect="move";//在dragenter中针对放置目标来设置!
+    },
+    handleDragEnter(e, item) {
+      e.dataTransfer.effectAllowed = 'move' //为需要移动的元素设置dragstart事件
+      if (item === this.dragging) {
+        return
+      }
+      const newItems = [...this.mylistNum]
+      console.log(newItems)
+      const src = newItems.findIndex(v => v.dataIndex === this.dragging)
+      const dst = newItems.findIndex(v => v.dataIndex === item)
+
+      newItems.splice(dst, 0, ...newItems.splice(src, 1))
+
+      this.mylistNum = newItems
+    },
+    //弹出框确定
+    handleOk(e) {
+      this.loading = false
+      this.visibleOk = false
+      this.$emit('closeCustomColumn', false)
+      this.$emit('changeColumn', this.mylistNum)
+    },
+    //取消按钮
+    handleCancel() {
+      this.visibleOk = false
+      this.$emit('closeCustomColumn', false)
+    },
+    //清空全部
+    clearAllList() {
+      this.mylistNum = [...this.fiexColumn]
+    },
+    //从自定义列拿选择的项
+    getshowlist(val) {
+      var arr = []
+
+      // console.log(val)
+      if (val.length) {
+        if (val.flag) {
+          let newArr = val.arr
+          newVal.map((item, index) => {
+            // if(JSON.stringify(this.listNum).indexOf(JSON.stringify(item))==-1){
+            //  this.listNum.push(item); // 进行动态的操作
+            // }
+            var result = this.listNum.some(items => {
+              if (items.dataIndex == item.dataIndex) {
+                return true
+              }
+            })
+
+            // console.log(result)
+            if (result) {
+              newArr.splice(index, 1)
+            }
+          })
+
+          this.mylistNum = [...this.mylistNum, ...newArr]
+        } else {
+          //取消全选  清楚listNum中的val里的值
+          val.arr.map((item, index) => {
+            var result = this.mylistNum.some(items => {
+              if (items.dataIndex == item.dataIndex) {
+                return true
+              }
+            })
+            // console.log(result)
+            if (result) {
+              this.mylistNum.splice(index, 1)
+            }
+          })
+        }
+      } else {
+        arr = this.mylistNum.filter((item, index) => {
+          return item.dataIndex == val.dataIndex
+        })
+      }
+      if (arr.length) {
+        var index
+        this.mylistNum.map((item, ind) => {
+          if (item.dataIndex == val.dataIndex) {
+            index = ind
+          }
+        })
+        console.log(index)
+        this.mylistNum.splice(index, 1)
+      } else {
+        this.mylistNum.push(val)
+      }
+    }
+  },
+  mounted() {}
+}
+</script>
+
+<style lang="scss" scoped>
+
+
+.addlist {
+  float: left;
+  width: 70%;
+  border: 1px solid #eee;
+  .selectionList {
+    padding: 10px 15px;
+    height: 450px;
+    overflow: auto;
+    .leibie {
+      .leiName {
+        font-size: 26px;
+        text-align: left;
+      }
+    }
+    .jutixiang {
+      display: inline-block;
+      width: 32%;
+      box-sizing: border-box;
+      padding: 10px 3px;
+    }
+  }
+}
+.listNum {
+  float: right;
+  width: 28%;
+  border: 1px solid #eee;
+  position: relative;
+}
+.zhuti {
+  margin-top: 15px;
+  overflow: hidden;
+
+  p {
+    height: 40px;
+    line-height: 20px;
+    padding: 10px 15px;
+
+    background: rgb(249, 250, 253);
+    border-bottom: 1px solid #eee;
+  }
+  #btn {
+    position: absolute;
+    right: 0;
+    top: 5px;
+  }
+  .selectlist {
+    width: 100%;
+    list-style: none;
+    margin: 0;
+    height: 450px;
+    padding: 0 15px 10px;
+    overflow: auto;
+
+    li {
+      width: 100%;
+      padding: 5px 8px;
+      margin: 6px 0;
+      border-radius: 10px;
+      background: rgb(248, 248, 248);
+      height: 32px;
+      position: relative;
+      span {
+        width: 80%;
+        height: 100%;
+        display: inline-block;
+        margin: 0 10px;
+        // overflow:hidden;
+        // text-overflow:ellipsis;
+        // white-space: nowrap;
+      }
+      .listText {
+        position: absolute;
+        top: 2;
+        left: 10;
+        width: 60%;
+        overflow: hidden;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+      }
+      #closeStyle {
+        position: absolute;
+        top: 9px;
+        right: 7px;
+      }
+    }
+  }
+}
+
+</style>

+ 240 - 0
src/components/youtTable/selectComponent.vue

@@ -0,0 +1,240 @@
+<template>
+  <div>
+    <div v-for="(item,index) in customFields" :key="index">
+      <div class="leibie">
+        <p class="leiName">{{item.title}}</p>
+        <!-- <span class="jutixiang">
+          <a-checkbox
+            :value="index"
+            name="type"
+            @change="isSelectAll($event,index)"
+            :checked="item.checkall"
+          >全选</a-checkbox>
+        </span> -->
+        <!-- {{item.form}} -->
+        <a-checkbox-group v-model="item.form" >
+          <span class="jutixiang" v-for="(zhi,num) in item.specificFields " :key="num">
+
+            <a-checkbox :value="zhi.dataIndex" :disabled="zhi.disabled"  name="type" @change="checkboxClick(zhi)">
+              <a-tooltip
+                class="select-component"
+                placement="top"
+                :title="zhi.tip"
+                :overlayClassName="tooltipShow"
+              >{{zhi.title}}</a-tooltip>
+            </a-checkbox>
+          </span>
+        </a-checkbox-group>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import  {TTcustomFields ,KScustomFields}  from '../../utils/columnConst/accountConst'
+// let customFields=customFields
+export default {
+  props: ['showCol','fixedCol','mediaType'],
+  data() {
+    return {
+        // customFields,
+      customFields:[],
+      quanxuanflag: [],
+      hovered: false,
+      tooltipShow: 'tooltipShow',
+      toParentArr: []
+    }
+  },
+  watch: {
+    
+    showCol(n) {
+      // console.log(n)
+      //
+      if (this.showCol.length == this.fixedCol.length) {
+
+        for (let i = 0; i < this.customFields.length; i++) {
+          this.customFields[i].form=[]          
+        }
+        this.showCol.map((item, index) => {
+          this.customFields.map((it, ind) => {
+            it.specificFields.map((i, d) => {
+              if (i.dataIndex === item.dataIndex) {
+                it.form.push(item.dataIndex)
+              }else{
+
+              }
+            })
+          })
+        })
+      } else {
+        
+       for (let i = 0; i < this.customFields.length; i++) {
+          this.customFields[i].form=[]
+          
+        }
+        n.map((item, index) => {
+          this.customFields.map((it, ind) => {
+            it.specificFields.map((i, d) => {
+              if (i.dataIndex === item.dataIndex) {
+                it.form.push(item.dataIndex)
+              }else{
+
+              }
+            })
+          })
+        })
+      }
+      // console.log(this.form)
+    },
+  
+  },
+  mounted() {
+    if(this.mediaType==1){
+      //头条自定义列
+      this.customFields=TTcustomFields
+    }else if(this.mediaType==2){
+      //快手自定义列
+      this.customFields=KScustomFields
+    }
+    for (let i = 0; i < this.customFields.length; i++) {
+      this.customFields[i].form=[]
+    }
+    // console.log(1)
+    this.showCol.map((item, index) => {
+      this.customFields.map((it, ind) => {
+        it.specificFields.map((i, d) => {
+          if (i.dataIndex === item.dataIndex) {
+            it.form.push(item.dataIndex)
+          }
+        })
+      })
+    })
+    this.fixedCol.map((item, index) => {
+      this.customFields.map((it, ind) => {
+        it.specificFields.map((i, d) => {
+          if (i.dataIndex === item.dataIndex) {
+            i.disabled=true;
+          }
+        })
+      })
+    })
+
+
+    // console.log(this.customFields);
+    
+  },
+  methods: {
+    hide() {
+      this.clicked = false
+      this.hovered = false
+    },
+    handleHoverChange(visible) {
+      this.clicked = false
+      this.hovered = visible
+    },
+    getPopupContainer() {
+      console.log(this)
+    },
+
+    //全选框   判断是否全选
+    isSelectAll(e, val) {
+      //像父元素传递
+      console.log(e, val)
+      let arr=JSON.parse(JSON.stringify(this.customFields[val].specificFields))
+      let valArr={
+        flag:true,
+        arr
+      }
+      this.customFields[val].checkall = e.target.checked
+      console.log(this.customFields[val].checkall)
+
+      if (this.customFields[val].checkall) {
+       
+        this.customFields[val].form=[]
+ 
+        this.customFields[val].specificFields.map((item, index) => {
+
+          this.customFields[val].form.push(item.dataIndex)
+
+        })
+        valArr.flag=true;
+        this.$emit('getshowlist', valArr)
+      } else {
+        console.log(this.customFields[val])
+        this.customFields[val].form=[];
+        valArr.flag=false;
+        console.log(this.customFields[val].form=[])
+        this.$emit('getshowlist', valArr)
+      }
+
+      console.log(this.form[val])
+    },
+
+    onChange(){
+        
+    },
+
+    //复选框的点击事件
+    checkboxClick(val) {
+      // console.log(val)
+    //   this.$emit('update:count',)
+      this.$emit('getshowlist', val)
+      // console.log(val,this.customFields[0].form)
+      // this.customFields[val].checkall=!this.customFields[val].checkall
+      // for (let i = 0; i < this.customFields.length; i++) {
+      //   // console.log(this.customFields[0].form,this.customFields[i].specificFields.length)
+      //   if(this.customFields[i].form.length==this.customFields[i].specificFields.length-1){
+      //       this.customFields[i].checkall=true;
+      //   }else{
+      //     this.customFields[i].checkall=false;
+      //   }
+          
+      //   }
+    }
+  }
+}
+</script>
+<style>
+.tooltipShow {
+  max-width: 30%;
+}
+.tooltipShow .ant-tooltip-content .ant-tooltip-inner {
+  background: white;
+  font-size: 10px;
+  color: #333;
+}
+.ant-tooltip-content .ant-tooltip-arrow::before {
+  background-color: white;
+}
+</style>
+<style lang="scss" scoped>
+.leibie {
+  width: 100%;
+  margin-bottom: 10px;
+  .leiName {
+    font-size: 20px;
+    text-align: left;
+    margin-bottom: 5px;
+    margin-top: 0px;
+  }
+}
+.jutixiang {
+  display: inline-block;
+  width: 32%;
+  box-sizing: border-box;
+  padding: 8px 3px;
+  height: 30px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.ant-tooltip-content .tooltipShow {
+  background: #eee;
+  font-size: 10px;
+  color: #333;
+}
+
+.ant-checkbox-group {
+  width: 100%;
+}
+</style>

+ 240 - 0
src/components/youtTable/selectComponentKS.vue

@@ -0,0 +1,240 @@
+<template>
+  <div>
+    <div v-for="(item,index) in customFields" :key="index">
+      <div class="leibie">
+        <p class="leiName">{{item.title}}</p>
+        <!-- <span class="jutixiang">
+          <a-checkbox
+            :value="index"
+            name="type"
+            @change="isSelectAll($event,index)"
+            :checked="item.checkall"
+          >全选</a-checkbox>
+        </span> -->
+        <!-- {{item.form}} -->
+        <a-checkbox-group v-model="item.form" >
+          <span class="jutixiang" v-for="(zhi,num) in item.specificFields " :key="num">
+
+            <a-checkbox :value="zhi.dataIndex" :disabled="zhi.disabled"  name="type" @change="checkboxClick(zhi)">
+              <a-tooltip
+                class="select-component"
+                placement="top"
+                :title="zhi.tip"
+                :overlayClassName="tooltipShow"
+              >{{zhi.title}}</a-tooltip>
+            </a-checkbox>
+          </span>
+        </a-checkbox-group>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import  {TTcustomFields ,KScustomFields}  from '../../utils/columnConst/accountConst'
+// let customFields=customFields
+export default {
+  props: ['showCol','fixedCol','mediaType'],
+  data() {
+    return {
+        // customFields,
+      customFields:[],
+      quanxuanflag: [],
+      hovered: false,
+      tooltipShow: 'tooltipShow',
+      toParentArr: []
+    }
+  },
+  watch: {
+    
+    showCol(n) {
+      // console.log(n)
+      //
+      if (this.showCol.length == this.fixedCol.length) {
+
+        for (let i = 0; i < this.customFields.length; i++) {
+          this.customFields[i].form=[]          
+        }
+        this.showCol.map((item, index) => {
+          this.customFields.map((it, ind) => {
+            it.specificFields.map((i, d) => {
+              if (i.dataIndex === item.dataIndex) {
+                it.form.push(item.dataIndex)
+              }else{
+
+              }
+            })
+          })
+        })
+      } else {
+        
+       for (let i = 0; i < this.customFields.length; i++) {
+          this.customFields[i].form=[]
+          
+        }
+        n.map((item, index) => {
+          this.customFields.map((it, ind) => {
+            it.specificFields.map((i, d) => {
+              if (i.dataIndex === item.dataIndex) {
+                it.form.push(item.dataIndex)
+              }else{
+
+              }
+            })
+          })
+        })
+      }
+      // console.log(this.form)
+    },
+  
+  },
+  mounted() {
+    if(this.mediaType==1){
+      //头条自定义列
+      this.customFields=TTcustomFields
+    }else if(this.mediaType==2){
+      //快手自定义列
+      this.customFields=KScustomFields
+    }
+    for (let i = 0; i < this.customFields.length; i++) {
+      this.customFields[i].form=[]
+    }
+    // console.log(1)
+    this.showCol.map((item, index) => {
+      this.customFields.map((it, ind) => {
+        it.specificFields.map((i, d) => {
+          if (i.dataIndex === item.dataIndex) {
+            it.form.push(item.dataIndex)
+          }
+        })
+      })
+    })
+    this.fixedCol.map((item, index) => {
+      this.customFields.map((it, ind) => {
+        it.specificFields.map((i, d) => {
+          if (i.dataIndex === item.dataIndex) {
+            i.disabled=true;
+          }
+        })
+      })
+    })
+
+
+    // console.log(this.customFields);
+    
+  },
+  methods: {
+    hide() {
+      this.clicked = false
+      this.hovered = false
+    },
+    handleHoverChange(visible) {
+      this.clicked = false
+      this.hovered = visible
+    },
+    getPopupContainer() {
+      console.log(this)
+    },
+
+    //全选框   判断是否全选
+    isSelectAll(e, val) {
+      //像父元素传递
+      console.log(e, val)
+      let arr=JSON.parse(JSON.stringify(this.customFields[val].specificFields))
+      let valArr={
+        flag:true,
+        arr
+      }
+      this.customFields[val].checkall = e.target.checked
+      console.log(this.customFields[val].checkall)
+
+      if (this.customFields[val].checkall) {
+       
+        this.customFields[val].form=[]
+ 
+        this.customFields[val].specificFields.map((item, index) => {
+
+          this.customFields[val].form.push(item.dataIndex)
+
+        })
+        valArr.flag=true;
+        this.$emit('getshowlist', valArr)
+      } else {
+        console.log(this.customFields[val])
+        this.customFields[val].form=[];
+        valArr.flag=false;
+        console.log(this.customFields[val].form=[])
+        this.$emit('getshowlist', valArr)
+      }
+
+      console.log(this.form[val])
+    },
+
+    onChange(){
+        
+    },
+
+    //复选框的点击事件
+    checkboxClick(val) {
+      // console.log(val)
+    //   this.$emit('update:count',)
+      this.$emit('getshowlist', val)
+      // console.log(val,this.customFields[0].form)
+      // this.customFields[val].checkall=!this.customFields[val].checkall
+      // for (let i = 0; i < this.customFields.length; i++) {
+      //   // console.log(this.customFields[0].form,this.customFields[i].specificFields.length)
+      //   if(this.customFields[i].form.length==this.customFields[i].specificFields.length-1){
+      //       this.customFields[i].checkall=true;
+      //   }else{
+      //     this.customFields[i].checkall=false;
+      //   }
+          
+      //   }
+    }
+  }
+}
+</script>
+<style>
+.tooltipShow {
+  max-width: 30%;
+}
+.tooltipShow .ant-tooltip-content .ant-tooltip-inner {
+  background: white;
+  font-size: 10px;
+  color: #333;
+}
+.ant-tooltip-content .ant-tooltip-arrow::before {
+  background-color: white;
+}
+</style>
+<style lang="scss" scoped>
+.leibie {
+  width: 100%;
+  margin-bottom: 10px;
+  .leiName {
+    font-size: 20px;
+    text-align: left;
+    margin-bottom: 5px;
+    margin-top: 0px;
+  }
+}
+.jutixiang {
+  display: inline-block;
+  width: 32%;
+  box-sizing: border-box;
+  padding: 8px 3px;
+  height: 30px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+.ant-tooltip-content .tooltipShow {
+  background: #eee;
+  font-size: 10px;
+  color: #333;
+}
+
+.ant-checkbox-group {
+  width: 100%;
+}
+</style>

+ 13 - 3
src/config/router.config.js

@@ -1,4 +1,4 @@
-import {UserLayout, TabLayout, RouteView, BlankLayout, PageView} from '@/components/layouts'
+import { UserLayout, TabLayout, RouteView, BlankLayout, PageView } from '@/components/layouts'
 
 /**
  * 走菜单,走权限控制
@@ -10,7 +10,7 @@ export const asyncRouterMap = [
     path: '/',
     name: 'dashboard',
     component: TabLayout,
-    meta: {title: '首页'},
+    meta: { title: '首页' },
     redirect: '/dashboard/workplace',
     children: []
   },
@@ -65,6 +65,16 @@ export const constantRouterMap = [
         name: 'FStransfer',
         component: () => import(/* webpackChunkName: "fail" */ '@/views/user/FStransfer')
       },
+      {
+        path: 'new-batch',
+        name: 'newBatch',
+        component: () => import(/* webpackChunkName: "fail" */ '@/views/modules/kuaishouapp/newBatch')
+      },
+      {
+        path: 'lookPreview',
+        name: 'lookPreview',
+        component: () => import(/* webpackChunkName: "fail" */ '@/views/modules/kuaishouapp/newBatch/lookPreview')
+      }
     ]
   },
 
@@ -90,5 +100,5 @@ export const constantRouterMap = [
     name: 'errorPage',
     component: () => import(/* webpackChunkName: "fail" */ '@/views/errorPage')
   },
-  
+
 ]

+ 98 - 0
src/directive.js

@@ -0,0 +1,98 @@
+const directives = {
+    'card': {
+        inserted(el, binding, vnode, oldVnode) {
+            el.classList.add('page-card');
+            el.style.height = window.innerHeight - 125 + 'px';
+
+            function heightHandler(e) {
+                el.style.height = window.innerHeight - 125 + 'px';
+            }
+            // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
+            el.__page_card__ = heightHandler;
+            window.addEventListener('resize', heightHandler);
+        },
+        unbind(el, binding) {
+            // 解除事件监听
+            window.removeEventListener('resize', el.__page_card__);
+            delete el.__page_card__;
+        }
+    },
+    'dialog-drag': { // 弹窗拖拽
+        bind(el, binding, vnode, oldVnode) {
+            const dialogHeaderEl = el.querySelector('.ant-modal-header');
+            const dragDom = el.querySelector('.ant-modal-content');
+            dialogHeaderEl.style.cursor = 'move';
+    
+            // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
+            const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
+            
+            dialogHeaderEl.onmousedown = (e) => {
+                // 鼠标按下,计算当前元素距离可视区的距离
+                const disX = e.clientX - dialogHeaderEl.offsetLeft;
+                const disY = e.clientY - dialogHeaderEl.offsetTop;
+                
+                // 获取到的值带px 正则匹配替换
+                let styL, styT;
+    
+                // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
+                if(sty.left.includes('%')) {
+                    styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100);
+                    styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100);
+                }else {
+                    styL = +sty.left.replace(/\px/g, '');
+                    styT = +sty.top.replace(/\px/g, '');
+                };
+                
+                document.onmousemove = function (e) {
+                    // 通过事件委托,计算移动的距离 
+                    const l = e.clientX - disX;
+                    const t = e.clientY - disY;
+                    // 移动当前元素  
+                    dragDom.style.left = `${l + styL}px`;
+                    dragDom.style.top = `${t + styT}px`;
+    
+                    //将此时的位置传出去
+                    //binding.value({x:e.pageX,y:e.pageY})
+                };
+    
+                document.onmouseup = function (e) {
+                    document.onmousemove = null;
+                    document.onmouseup = null;
+                };
+            }  
+        }
+    },
+    'clickoutside': {
+        // 初始化指令
+        bind(el, binding, vnode) {
+            function documentHandler(e) {
+                // 这里判断点击的元素是否是本身,是本身,则返回
+                if (el.contains(e.target)) {
+                    return false;
+                }
+                // 判断指令中是否绑定了函数
+                if (binding.expression) {
+                    // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
+                    binding.value(e);
+                }
+            }
+            // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
+            el.__vueClickOutside__ = documentHandler;
+            document.addEventListener('click', documentHandler);
+        },
+        update() {},
+        unbind(el, binding) {
+            // 解除事件监听
+            document.removeEventListener('click', el.__vueClickOutside__);
+            delete el.__vueClickOutside__;
+        },
+    }
+}
+
+export default {
+    install: function(Vue) {
+        Object.keys(directives).forEach(key => {
+            Vue.directive(key, directives[key]);
+        })
+    }
+}

+ 371 - 0
src/filters.js

@@ -0,0 +1,371 @@
+
+import moment from 'moment';
+function fixedZero(val) {
+    return val * 1 < 10 ? `0${val}` : val;
+}
+const filters = {
+    // 格式化时间展示多长时间之前
+    formatTime(time) {
+        let formatTime
+        const date = new Date(time)
+        const dateObj = {
+            year: date.getFullYear(),
+            month: date.getMonth(),
+            date: date.getDate(),
+            hours: date.getHours(),
+            minutes: date.getMinutes()
+        }
+        const newTime = new Date()
+        const diff = newTime.getTime() - time
+        if (newTime.getDate() === dateObj.date && diff < 60000) {
+            formatTime = '刚刚'
+        } else if (
+            newTime.getDate() === dateObj.date &&
+            diff > 60000 &&
+            diff < 3600000
+        ) {
+            formatTime = `${Math.floor(diff / 60000)}分钟前`
+        } else if (
+            newTime.getDate() === dateObj.date &&
+            diff > 3600000 &&
+            diff < 86400000
+        ) {
+            formatTime = `${addZero(dateObj.hours)}:${addZero(dateObj.minutes)}`
+        } else if (newTime.getDate() !== dateObj.date && diff < 86400000) {
+            formatTime = `昨天${addZero(dateObj.hours)}:${addZero(dateObj.minutes)}`
+        } else if (newTime.getFullYear() === dateObj.year) {
+            formatTime = `${dateObj.month + 1}月${dateObj.date}日`
+        } else {
+            formatTime = `${dateObj.year}年${dateObj.month + 1}月${dateObj.date}日`
+        }
+        return formatTime
+    },
+    //时间日期格式化
+    format(time) {
+        const hours = 60 * 60 * 1000;
+        const minutes = 60 * 1000;
+
+        const h = Math.floor(time / hours);
+        const m = Math.floor((time - h * hours) / minutes);
+        const s = Math.floor((time - h * hours - m * minutes) / 1000);
+        return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}`
+    },
+    //年月日格式化
+    getDate(value) {
+        let date = new Date(value)
+        let y = date.getFullYear()
+        let MM = date.getMonth() + 1
+        MM = MM < 10 ? '0' + MM : MM
+        let d = date.getDate()
+        d = d < 10 ? '0' + d : d
+        return y + '-' + MM + '-' + d
+    },
+    //年月日时分秒格式化
+    formatDate: function (value) {
+        let date = new Date(value)
+        let y = date.getFullYear()
+        let MM = date.getMonth() + 1
+        MM = MM < 10 ? '0' + MM : MM
+        let d = date.getDate()
+        d = d < 10 ? '0' + d : d
+        let h = date.getHours()
+        h = h < 10 ? '0' + h : h
+        let m = date.getMinutes()
+        m = m < 10 ? '0' + m : m
+        let s = date.getSeconds()
+        s = s < 10 ? '0' + s : s
+        return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s
+    },
+    //bidType类型
+    bidType(sta) {
+        var data = {
+            null: '-',
+            1: 'CPM',
+            2: '封面点击(CPC)',
+            6: 'OCPC',
+            10: '转化(OCPM)',
+        }
+        return data[sta]
+    },
+    //ocpxActionType类型
+    ocpxActionType(sta) {
+        var data = {
+            null: '-',
+            0: '封面点击',
+            2: '行为数',
+            10: '曝光',
+            11: '点击',
+            31: '下载完成',
+            53: '提交线索',
+            180: '激活',
+            190: '付费',
+            191: '首日ROI',
+            348: '有效线索',
+            383: '授信',
+            384: '完件',
+            394: '订单提交',
+            324: '唤起应用',
+            715: '微信复制优化目标',
+            716: '多转化事件',
+            396:'注册优化目标',
+            731:'广告观看5次',
+            732:'广告观看10次',
+        }
+        return data[sta]
+    },
+    //角色类型
+    roleCode(value) {
+        var state = {
+            clip: '剪辑',
+            shot: '拍摄',
+            plan: '策划',
+            plane: '平面',
+            admin: '管理员',
+            operator: '运营专员',
+            kuaishouOperationManager: '快手运营经理',
+            designTeamLeader: '设计组长',
+            planeLeader: '平面组长',
+            touTiaoOperationManager: '头条运营经理',
+            operationAssistant: '运营助理',
+        }
+
+        if (value) {
+            return state[value]
+        } else {
+            return '暂无'
+        }
+    },
+    //保留两位小数并且变成货币格式
+    decimalsHandle(val) {
+        if (val && typeof val != 'string') {
+            if (val >= 0) {
+                val = parseFloat(val).toFixed(2);
+                let numberStr = val.toString()
+                let str = numberStr.split('.')
+
+                let str0 = str[0].split('').reverse();
+                for (let i = 0; i < str0.length; i++) {
+                    if ((i + 1) % 4 === 0) {
+                        str0.splice(i, 0, ',')
+                    }
+                }
+                str0.reverse()
+                let handleResult = ''
+                for (let j = 0; j < str0.length; j++) {
+                    handleResult += str0[j]
+                }
+
+                return handleResult + '.' + str[1]
+            } else {
+                val = parseFloat(val).toFixed(2);
+                let numberStr = val.toString()
+                let str = numberStr.split('.')
+
+                let str0 = str[0].substr(1).split('').reverse();
+                for (let i = 0; i < str0.length; i++) {
+                    if ((i + 1) % 4 === 0) {
+                        str0.splice(i, 0, ',')
+                    }
+                }
+                str0.reverse()
+                let handleResult = ''
+                for (let j = 0; j < str0.length; j++) {
+                    handleResult += str0[j]
+                }
+
+                return '-' + handleResult + '.' + str[1]
+            }
+
+        } else if (typeof val == 'string') {
+            return val
+        }
+        else {
+            return 0
+        }
+    },
+    //变成货币格式
+    formatCurrency(val) {
+        if ((val || val == 0) && typeof val != 'string') {
+            let numberStr = val.toString()
+            let str = numberStr.split('').reverse()
+            for (let i = 0; i < str.length; i++) {
+                if ((i + 1) % 4 === 0) {
+                    str.splice(i, 0, ',')
+                }
+            }
+            str.reverse()
+            let handleResult = ''
+            for (let j = 0; j < str.length; j++) {
+                handleResult += str[j]
+            }
+            return handleResult
+        } else if (typeof val == 'string') {
+            return val
+        }
+        else {
+            return '-'
+        }
+
+    },
+    //加百分比
+    toPercentage(val) {
+        if (val) {
+            if (typeof val != 'string') {
+                return (val * 100).toFixed(2) + '%'
+            } else {
+                return val
+            }
+        } else if (typeof val == 'string') {
+            return val
+        }
+        else {
+            return 0
+        }
+    },
+    //媒体类型
+    handleMediaType(val) {
+        switch (val) {
+            case 1:
+                return '头条'
+                break
+
+            case 2:
+                return '快手'
+                break
+
+            case 3:
+                return '头条内广'
+                break
+
+            case 4:
+                return '快手内广'
+                break
+
+            default:
+                break
+        }
+    },
+    //文件大小
+    sizeShow(value) {
+        return (value / 1024).toFixed(2)
+    },
+    //预警计算符号
+    conditionName(val) {
+        var data = {
+            equal: '=',//'等于',
+            not_equal: '≠',//不等于,
+            greater: '>',//大于
+            less: '<',//小于
+            greater_equal: '≥',//大于等于
+            less_equal: '≤',//小于等于
+        }
+
+        return data[val]
+    },
+    //快手年龄
+    kuaishouAge(val) {
+        var data = {
+            18: '18-23岁',//'等于',
+            24: '24-30岁',//不等于,
+            31: '31-40岁',//大于
+            41: '41-49岁',//小于
+            50: '50+',//大于等于
+        }
+
+        return data[val]
+    },
+    //快手手机价格
+    kuaishouPrice(val) {
+        var data = {
+            1: '1500以下',
+            2: '1501~2000',
+            3: '2001~2500',
+            4: '2501~3000',
+            5: '3001~3500',
+            6: '3501~4000',
+            7: '4001~4500',
+            8: '4501~5000',
+            9: '5001~5500',
+            10: '5500以上',
+        }
+
+        return data[val]
+    },
+    //快手过滤以转化用户
+    kuaishouFilterConvertedLevel(val) {
+        var data = {
+            0: '不限',
+            1: '广告组',
+            2: '广告计划',
+            3: '本账户',
+            4: '公司主体',
+            5: 'APP'
+        }
+
+        return data[val]
+    },
+    //场景广告位
+    kuaishouSceneId(val) {
+        var data = {
+            1: '优选广告位',
+            3: '视频播放页广告',
+            6: '上下滑大屏广告',
+            7: '信息流广告',
+            5: "联盟广告"
+        }
+
+        return data[val]
+    },
+    platform(str) {
+        var data = {
+            1: 'Android应用下载',
+            2: 'Android网页游戏',
+            3: 'iOS应用下载',
+            4: 'iOS网页游戏'
+        }
+        return data[str]
+    }
+
+}
+
+// 获取当前月的第一天
+function getCurrentMonthFirst() {
+    let date = new Date();
+    date.setDate(1);
+    return date;
+}
+// 获取当前月的最后一天
+function getCurrentMonthLast() {
+    let date = new Date();
+    let currentMonth = date.getMonth();
+    let nextMonth = ++currentMonth;
+    let nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1);
+    let oneDay = 1000 * 60 * 60 * 24;
+    return new Date(nextMonthFirstDay - oneDay);
+}
+// 今日日期小于15号时和今日日期大于等于15号时
+function getCurrentMonthFifty() {
+    let date = new Date();
+    if (date.getDate() < 15) {
+        let bb = date.setTime(new Date().getTime() - 3600 * 1000 * 24 * 15);
+        return bb;
+    } else if (date.getDate() >= 15) {
+        let year = date.getFullYear();
+        let month = date.getMonth();
+        let myDate = new Date(year, month, 0);
+        let lastDay = year + "-" + month + "-" + myDate.getDate();//上个月的最后一天
+        return lastDay;
+    }
+
+}
+
+export default {
+    install: function (Vue) {
+        Object.keys(filters).forEach(key => {
+            Vue.filter(key, filters[key])
+        })
+    }
+
+}
+
+

+ 6 - 1
src/main.js

@@ -28,7 +28,10 @@ import 'vue-photo-preview/dist/skin.css'
 import VuePreview from 'vue-preview';
 import promiseFinally from 'promise.prototype.finally';
 promiseFinally.shim();
-
+import directive from './directive'
+import filters from './filters'
+Vue.use(directive)
+Vue.use(filters)
 import md5 from 'blueimp-md5';
 
 // import KFormDesign from 'k-form-design'
@@ -63,6 +66,8 @@ import JDictSelectTag from './components/dict/index.js'
 import hasPermission from '@/utils/hasPermission'
 import vueBus from '@/utils/vueBus';
 
+
+import '@/components/vend-ztree.all.js'
 import JeecgComponents from '@/components/jeecg/index'
 // import iView from 'iview'
 import '!style-loader!css-loader!less-loader!./theme/index.less'

+ 10 - 0
src/mixins/JeecgListMixin.js

@@ -121,6 +121,7 @@ export const JeecgListMixin = {
       this.loading = true;
       await getAction(this.url.list, params).then((res) => {
         if (res.success) {
+          this.loading = false;
           if(res.result){
             if(res.result.records){
               this.dataSource = res.result.records.map(item=>{
@@ -131,6 +132,15 @@ export const JeecgListMixin = {
                 }
               })
               this.ipagination.total = res.result.total;
+            }else if(res.result.list){
+              this.dataSource = res.result.list.map(item=>{
+                return {
+                    ...item,
+                    innerData:[],
+                    showVideo:false
+                }
+              })
+              this.ipagination.total = res.result.total;
             }else{
               this.dataSource = res.result.map(item=>{
                 return {

+ 16 - 12
src/permission.js

@@ -4,44 +4,48 @@ import store from './store'
 import NProgress from 'nprogress' // progress bar
 import 'nprogress/nprogress.css' // progress bar style
 import notification from 'ant-design-vue/es/notification'
-import {ACCESS_TOKEN} from '@/store/mutation-types'
-import {generateIndexRouter} from "@/utils/util"
+import { ACCESS_TOKEN } from '@/store/mutation-types'
+import { generateIndexRouter } from "@/utils/util"
 
-NProgress.configure({showSpinner: false}) // NProgress Configuration
+NProgress.configure({ showSpinner: false }) // NProgress Configuration
 
 
-const whiteList = ['/user/login', '/user/register', '/user/register-result', '/user/alteration','/user/transfer-local','/errorPage','http://192.168.0.111:8088/jeecg-boot/sys/feishu/url','/user/FStransfer'] // no redirect whitelist
+const whiteList = ['/user/login', '/user/register', '/user/register-result', '/user/alteration', '/user/transfer-local', '/errorPage', '/user/new-batch', '/user/lookPreview', 'http://192.168.0.111:8088/jeecg-boot/sys/feishu/url', '/user/FStransfer'] // no redirect whitelist
 
 router.beforeEach((to, from, next) => {
   NProgress.start() // start progress bar
-
+  //if (whiteList.indexOf(to.path) !== -1) {
+    // 在免登录白名单,直接进入
+   // next()
+ //}
   if (Vue.ls.get(ACCESS_TOKEN)) {
     /* has token */
+
     if (to.path === '/user/login') {
-      next({path: '/dashboard/workplace'})
+      next({ path: '/dashboard/workplace' })
       NProgress.done()
     } else {
       if (store.getters.permissionList.length === 0) {
         store.dispatch('GetPermissionList').then(res => {
           const menuData = res.result.menu;
-          localStorage.setItem("roleCode",res.result.roleCode)
+          localStorage.setItem("roleCode", res.result.roleCode)
           if (menuData === null || menuData === "" || menuData === undefined) {
             return;
           }
           let constRoutes = [];
           constRoutes = generateIndexRouter(menuData);
           // 添加主界面路由
-          store.dispatch('UpdateAppRouter', {constRoutes}).then(() => {
+          store.dispatch('UpdateAppRouter', { constRoutes }).then(() => {
             // 根据roles权限生成可访问的路由表
             // 动态添加可访问路由表
             router.addRoutes(store.getters.addRouters)
             const redirect = decodeURIComponent(from.query.redirect || to.path)
             if (to.path === redirect) {
               // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
-              next({...to, replace: true})
+              next({ ...to, replace: true })
             } else {
               // 跳转到目的路由
-              next({path: redirect})
+              next({ path: redirect })
             }
           })
         })
@@ -51,7 +55,7 @@ router.beforeEach((to, from, next) => {
                description: '请求用户信息失败,请重试!'
              })*/
             store.dispatch('Logout').then(() => {
-              next({path: '/user/login', query: {redirect: to.fullPath}})
+              next({ path: '/user/login', query: { redirect: to.fullPath } })
             })
           })
       } else {
@@ -63,7 +67,7 @@ router.beforeEach((to, from, next) => {
       // 在免登录白名单,直接进入
       next()
     } else {
-      next({path: '/user/login', query: {redirect: to.fullPath}})
+      next({ path: '/user/login', query: { redirect: to.fullPath } })
       NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
     }
   }

+ 7 - 7
src/router/index.js

@@ -1,14 +1,14 @@
 import Vue from 'vue'
 import Router from 'vue-router'
-import {constantRouterMap} from '@/config/router.config'
+import { constantRouterMap } from '@/config/router.config'
 
 try {
-    const originalPush = Router.prototype.push
-    Router.prototype.push = function push(location) {
-      return originalPush.call(this, location).catch(err => err)
-    }
-  } catch (e) {
+  const originalPush = Router.prototype.push
+  Router.prototype.push = function push(location) {
+    return originalPush.call(this, location).catch(err => err)
   }
+} catch (e) {
+}
 
 Vue.use(Router)
 
@@ -22,6 +22,6 @@ Vue.use(Router)
 export default new Router({
   mode: 'history',
   base: process.env.BASE_URL,
-  scrollBehavior: () => ({y: 0}),
+  scrollBehavior: () => ({ y: 0 }),
   routes: constantRouterMap
 })

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1323 - 0
src/utils/columnConst/accountConst.js


src/views/modules/autoLaunch/setCreate.vue → src/utils/columnConst/videoConst.js


+ 1 - 0
src/utils/request.js

@@ -9,6 +9,7 @@ const key = "1"
 
 if (process.env.NODE_ENV == 'development') { 
     axios.defaults.baseURL = '/jeecg-boot'
+    
 } 
 else if (process.env.NODE_ENV == 'debug') { 
 } 

+ 20 - 97
src/views/dashboard/Analysis.vue

@@ -237,81 +237,7 @@
          <a-icon type="notification" theme='twoTone'/> 更新通告
       </div>
       <div class="Updatecontent">
-        <div class="Updateitem">
-            <div class="Updatetime">
-                 <a-icon type="dashboard" theme='twoTone' class="updateicon" />
-                 <span class="updateSpan">{{updateTime[3]}}</span>
-            </div>
-            <div class="updateText">
-              <div class="updateBox">
-                <h3 class="textTitle">1.脚本库加word下载;</h3>
-              </div>
-              <div class="updateBox">
-                <h3 class="textTitle">2.上线媒介报表;</h3>
-                
-              </div>
-              <div class="updateBox">
-                <h3 class="textTitle">3.快手批量工具更新:</h3>
-                <ul class="updatelist">
-                  <li> <span class="circular"></span>创建组时--商业兴趣加智能推荐</li>
-                  <li><span class="circular"></span>在复制组时可选是否修改定向</li>
-                  <li><span class="circular"></span>计划、组、创意列表页加id、名称模糊搜索</li>
-                  <li><span class="circular"></span>复制组时连带组名一起复制,可对组名进行修改</li>
-                </ul>
-              </div>
-                      
-            </div>
-        </div>
-        <div class="Updateitem">
-            <div class="Updatetime">
-                 <a-icon type="dashboard" theme='twoTone' class="updateicon" />
-                 <span class="updateSpan">{{updateTime[2]}}</span>
-            </div>
-            <div class="updateText">
-              <div class="updateBox">
-                <h3 class="textTitle">1.快手批量工具更新:</h3>
-                <ul class="updatelist">
-                  <li> <span class="circular"></span> 批量创建创意页面加入推荐文案,可根据关键词匹配文案;</li>
-                  <li><span class="circular"></span>批量创建创意选择内部素材可根据时间排序、筛选(天维度);</li>
-                </ul>
-              </div>
-              <div class="updateBox">
-                <h3 class="textTitle">2.脚本库重磅上线(位置:素材管理--脚本库)</h3>
-                <ul class="updatelist">
-                  <li> <span class="circular"></span> 脚本可在线编辑,并实时保存;</li>
-                  <li><span class="circular"></span>可在线打印,支持导出脚本;</li>
-                  <li><span class="circular"></span>可在线打印,支持导出脚本;</li>
-                </ul>
-              </div>
-              <div class="updateBox">
-                <h3 class="textTitle">3.支持飞书扫码登录助手</h3>
-                
-              </div>
-                      
-            </div>
-        </div>
-        <div class="Updateitem">
-            <div class="Updatetime">
-                 <a-icon type="dashboard" theme='twoTone' class="updateicon" />
-                 <span class="updateSpan">{{updateTime[1]}}</span>
-            </div>
-            <div class="updateText">
-              <div class="updateBox">
-                <h3 class="textTitle">1.快手批量工具更新:</h3>
-                <ul class="updatelist">
-                  <li> <span class="circular"></span> 批量更改监测链接;</li>
-                  <li><span class="circular"></span>素材审核驳回在企业微信发消息提醒;</li>
-                  <li><span class="circular"></span>推送失败在企业微信发消息;</li>
-                  <li><span class="circular"></span>广告语加入动态词包;</li>
-                  <li><span class="circular"></span>屏蔽停投的账户;</li>
-                </ul>
-              </div>
-              <div class="updateBox">
-                <h3 class="textTitle">2.素材管理--视频素材-加素材名称搜索</h3>
-              </div>
-                      
-            </div>
-        </div>
+        
         <div class="Updateitem">
             <div class="Updatetime">
                  <a-icon type="dashboard" theme='twoTone' class="updateicon" />
@@ -319,25 +245,19 @@
             </div>
             <div class="updateText">
               <div class="updateBox">
-                <h3 class="textTitle">1.头条-账户报表上线通知</h3>
+                <h3 class="textTitle">1.新功能上线</h3>
                 <ul class="updatelist">
-                  <li><span class="circular"></span>点击“统计报表-头条报表-账户报表”查看模块</li>
-                  <li><span class="circular"></span>可根据项目账户筛选查看数据,支持时间筛选</li>
-                  <li><span class="circular"></span>支持报表导出</li>
-                </ul>
-              </div>
-              <div class="updateBox">
-                <h3 class="textTitle">2.快手批量工具更新</h3>
-                <ul>
-                  <li><span class="circular"></span>在创建创意模块加了时间维度筛选</li>
+                  <li><span class="circular"></span>快手新上计划组 支持导出;</li>
+                  <li><span class="circular"></span>批量创建:支持同时创建多广告计划、组、创意;</li>
                 </ul>
               </div>
-              <div class="updateBox">
-                <h3 class="textTitle">3.视频报表修改</h3>
+              <!-- <div class="updateBox">
+                <h3 class="textTitle">2.功能优化:</h3>
                 <ul>
-                  <li><span class="circular"></span>添加了视频上传时间字段</li>
+                  <li><span class="circular"></span>修复了相关BUG;</li>
                 </ul>
-              </div>
+              </div> -->
+
             </div>
         </div>
          
@@ -412,7 +332,7 @@
         indicator: <a-icon type="loading" style="font-size: 24px" spin />,
         roleCode: localStorage.getItem('roleCode'),
         visible:false,//更新通知消息提示框
-        updateTime:['2020-06-10','2020-06-17','2020-06-24','2020-07-01'],
+        updateTime:['2021-01-27'],
         versionId:0,//存储版本号 判断通知什么时候显示
       }
     },
@@ -457,14 +377,17 @@
 
     },
     mounted() {
-        //  postAction('/ctop/releaseViewRecord/check', {}).then(res => {
-        //     console.log(res)
-        //     if(res.success){
-        //        this.visible=res.showPopup;
-        //        this.versionId=res.data.id;
-        //     }
+         postAction('/ctop/releaseViewRecord/check', {}).then(res => {
+            console.log(res)
+            if(res.success){
+               this.visible=res.showPopup;
+               if(res.data){
+                this.versionId=res.data.id;
+               }
+               
+            }
            
-        // })
+        })
     },
   }
 </script>

+ 0 - 9
src/views/modules/BatchCreate/newCreate.vue

@@ -99,7 +99,6 @@
               </a-form-item>
             </div>
           </div>
-
           <div class="row-item">
             <div class="hint-item"></div>
             <div class="label-item">
@@ -129,7 +128,6 @@
             </div> -->
             <material ref="material" :creativeType="getFormData('creativeWay')"></material>
           </div>
-
           <div class="row-item">
             <div class="hint-item"></div>
             <div class="label-item">
@@ -145,7 +143,6 @@
               </a-form-item>
             </div>
           </div>
-
           <div class="row-item">
             <div class="hint-item"></div>
             <div class="label-item">
@@ -158,7 +155,6 @@
               </a-form-item>
             </div>
           </div>
-
           <div class="row-item">
             <div class="hint-item"></div>
             <div class="label-item">
@@ -178,7 +174,6 @@
               </a-form-item>
             </div>
           </div>
-
           <div class="row-item">
             <div class="hint-item"></div>
             <div class="label-item">
@@ -191,7 +186,6 @@
               </a-form-item>
             </div>
           </div>
-
           <div class="row-item">
             <div class="hint-item"></div>
             <div class="label-item">
@@ -204,7 +198,6 @@
               </a-form-item>
             </div>
           </div>
-
           <div class="row-item">
             <div class="hint-item"></div>
             <div class="label-item">
@@ -220,7 +213,6 @@
               </a-form-item>
             </div>
           </div>
-
           <div class="row-item">
             <div class="hint-item"></div>
             <div class="label-item">
@@ -678,7 +670,6 @@
                     // res.data.forEach((item)=>{
                     //   this.$message.error(item.message)
                     // })
-
                   } else {
                     this.loading=false;
                   }

+ 3 - 3
src/views/modules/BatchCreate/newDirectedPackage.vue

@@ -988,7 +988,7 @@ let ageArr=[
     {
         value:'AGE_BETWEEN_18_23',
         title:'	18-23岁',
-         checked:false,
+        checked:false,
     },
     {
         value:'AGE_BETWEEN_24_30',
@@ -1798,7 +1798,7 @@ export default {
         // console.log(accountInfo)
         if (accountInfo!='' && groupInfo!='') {
             this.accountInfo = JSON.parse(accountInfo)
-            if(this.accountInfo.value){
+            if(this.accountInfo){
                 getAction('/ctop/audience/list',{
                     accountId:this.accountInfo.value
                 }).then((res)=>{
@@ -1818,7 +1818,7 @@ export default {
 
         this.platformArr=JSON.parse(JSON.stringify(platformArr))
         // this.platformArr = [...platformArr]
-        // console.log(this.$route.query,this.id)
+        console.log(this.$route.query,this.id)
 
         if(this.$route.query.id||this.id){
             this.title='修改定向包';

+ 2 - 1
src/views/modules/Statistics/KSAccountReport.vue

@@ -1094,6 +1094,7 @@ export default {
     //请求table的数据
     tableHttp(params){
       this.loading=true;
+      this.tableData=[]
           postAction('/ctop/kuaishou/dailyPage/report/list', {
               mediaId:this.mediaId,
               discount:this.discount,
@@ -1341,7 +1342,7 @@ export default {
           }
       }else if(typeof val =='string'){
             return val
-        }
+      }
       else{
         return 0
       }    

+ 87 - 52
src/views/modules/Statistics/components/Treeselect.vue

@@ -8,6 +8,7 @@
     <treeselect
       :multiple="multiple"
       :disable-branch-nodes="!multiple"
+      :disable-fuzzy-matching="true"
       :options="options"
       :load-options="loadOptions"
       placeholder="请选择项目以及账户"
@@ -16,10 +17,11 @@
       :auto-load-root-options="false"
       @select="update"
       @input="emitValue"
-      :limit="2"
+      :limit="limit"
       :default-options="true"
+      :disabled="disabled"
       :limitText="
-        count => {
+        (count) => {
           return '隐藏' + count + '条'
         }
       "
@@ -50,6 +52,12 @@ export default {
     showLoading: 'loading...',
   }),
   props: {
+    oneData: {
+      type: Boolean,
+      default() {
+        return false
+      },
+    },
     //是否多选
     multiple: {
       type: Boolean,
@@ -58,7 +66,6 @@ export default {
       },
     },
     appId: {
-      
       default() {
         return ''
       },
@@ -77,27 +84,40 @@ export default {
         return '/ctop/projectMember/participateListByMediaId'
       },
     },
+    // 展示条数
+    limit: {
+      type: Number,
+      default() {
+        return 2
+      },
+    },
+    disabled:{
+      type: Boolean,
+      default() {
+        return false
+      },
+    }
   },
   components: {
     Treeselect,
   },
   watch: {
     $route(n, o) {},
-      appId: {
-        handler(n, o) {
-          console.log(n)
-          if (n.length == 0) {
-            if (this.multiple) {
-              this.value = []
-            } else {
-              this.value = undefined
-            }
-          }else{
-            this.value=this.appId
+    appId: {
+      handler(n, o) {
+        console.log(n)
+        if (n.length == 0) {
+          if (this.multiple) {
+            this.value = []
+          } else {
+            this.value = undefined
           }
-        },
-        deep: true
-      }
+        } else {
+          this.value = this.appId
+        }
+      },
+      deep: true,
+    },
   },
   methods: {
     ...mapGetters(['nickname', 'avatar', 'userInfo']),
@@ -165,13 +185,14 @@ export default {
       }
 
       if (this.reqUrl == '/ctop/projectMember/participateListByMediaId') {
-        if(this.options.length>0){
+        if (this.options.length > 0) {
           return
         }
         postAction(this.reqUrl, params).then((res) => {
           if (res.success) {
             this.options = res.result.map((item) => {
-              return {
+              
+                return {
                 id: item.projectId + 'projectId',
                 label: item.projectName + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' + item.advertiserName,
                 children: item.accountList
@@ -179,7 +200,11 @@ export default {
                       return {
                         id: i.accountId,
                         label:
-                          (i.userName.length==2?i.userName+'\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0':i.userName.length==3?i.userName+'\xa0\xa0\xa0\xa0':i.userName) +
+                          (i.userName.length == 2
+                            ? i.userName + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0'
+                            : i.userName.length == 3
+                            ? i.userName + '\xa0\xa0\xa0\xa0'
+                            : i.userName) +
                           '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' +
                           i.accountId +
                           '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' +
@@ -187,42 +212,52 @@ export default {
                       }
                     })
                   : [],
-              }
+                }
+              
+              
             })
+            if (this.oneData&&!this.multiple) {
+              var data = this.options.filter((item) => {
+                if (item.children&&item.children.length > 0) {
+                  return { ...item }
+                }
+              })
+              this.$emit('update:appId', data[0].children[0].id)
+            }
           }
         })
-      } else if(this.reqUrl == '/ctop/projectMember/getProjectAccountByUserId'){
-          getAction(this.reqUrl, {
-            mediaType: this.request,
-          }).then((res) => {
-            if (res.code == 0) {
-              if (res.result.length > 0) {
-                res.result.forEach((element,index) => {
-                  if(element){                  
-                      this.options.push({});                    
-                      this.options[index].label=element.project.projectName +'_('+ element.project.advertiserName +')';
-                      this.options[index].id='project'+element.project.projectId;
-                      this.options[index].key=element.project.projectId;
-                      this.options[index].mediaId=element.project.mediaId;
-                      this.options[index].children=[];
-                                          
-                      if(element.account.length){
-                        element.account.forEach((ele,i)=>{
-                            this.options[index].children.push({});
-                            this.options[index].children[i].label=ele.userName+'_'+ele.authName+'_'+element.project.projectName;
-                            this.options[index].children[i].id=ele.accountId;
-                            this.options[index].children[i].key=ele.accountId;
-                        })
-                          
-                      }                           
-                  }      
-                });
-              } else {
-                this.showLoading = '暂无数据'
-              }
+      } else if (this.reqUrl == '/ctop/projectMember/getProjectAccountByUserId') {
+        getAction(this.reqUrl, {
+          mediaType: this.request,
+        }).then((res) => {
+          if (res.code == 0) {
+            if (res.result.length > 0) {
+              res.result.forEach((element, index) => {
+                if (element) {
+                  this.options.push({})
+                  this.options[index].label = element.project.projectName + '_(' + element.project.advertiserName + ')'
+                  this.options[index].id = 'project' + element.project.projectId
+                  this.options[index].key = element.project.projectId
+                  this.options[index].mediaId = element.project.mediaId
+                  this.options[index].children = []
+
+                  if (element.account.length) {
+                    element.account.forEach((ele, i) => {
+                      this.options[index].children.push({})
+                      this.options[index].children[i].label =
+                        ele.userName + '_' + ele.authName + '_' + element.project.projectName
+                      this.options[index].children[i].id = ele.accountId
+                      this.options[index].children[i].key = ele.accountId
+                    })
+                  }
+                }
+              })
+            } else {
+              this.showLoading = '暂无数据'
             }
-          })
-      }else {
+          }
+        })
+      } else {
         getAction(this.reqUrl, {
           userId: this.userInfo().id,
         }).then((res) => {

+ 19 - 4
src/views/modules/Statistics/components/ratioModal.vue

@@ -5,7 +5,7 @@ th div {
 </style>
 <template>
   <div class="data-display-statistics">
-    <a-modal title="环比展示" v-model="visible" @ok="handleOk" width="90%">
+    <a-modal title="环比展示" v-model="visible" @ok="handleOk" width="90%" :footer='null'>
       <div v-if="url">
         <video class="video" :src="url" controls="controls" style="height:200px;" v-show="showVideo">
           您的浏览器不支持 video 标签。
@@ -42,6 +42,10 @@ th div {
             <span v-if="record.statDate == '环比'">{{ conversionPrice | getBo }}</span>
             <span v-else>{{ conversionPrice | toFixtwo }}</span>
           </span>
+           <span slot="play3sRate" slot-scope="play3sRate,record">
+             <span v-if="record.statDate == '环比'">{{ play3sRate }}</span>
+            <span v-else>{{ play3sRate | getBo }}</span>
+           </span>
         </a-table>
       </a-card>
     </a-modal>
@@ -145,7 +149,15 @@ const columnsDetail = [
     key: 'conversionPrice',
     scopedSlots: { customRender: 'conversionPrice' },
     align: 'center'
-  }
+  },
+  {
+    title: '3s播放率',
+    dataIndex: 'play3sRate',
+    key: 'play3sRate',
+    scopedSlots: { customRender: 'play3sRate' },
+    align: 'center',
+    
+  },
 ]
 export default {
   name: 'ration-modal',
@@ -227,7 +239,8 @@ export default {
               conversionPrice: res.result.chainRatio.conversionPriceProportion,
               actionRatio: res.result.chainRatio.actionRatioProportion,
               actionCost: res.result.chainRatio.actionCostProportion,
-              photoShow: (res.result.chainRatio.showProportion * 100).toFixed(2) + '%'
+              photoShow: (res.result.chainRatio.showProportion * 100).toFixed(2) + '%',
+              play3sRate: (res.result.chainRatio.conversionPlay3sRate * 100).toFixed(2) + '%'
             }
             this.dataDetail.push(now)
             this.dataDetail.push(yesterday)
@@ -240,7 +253,9 @@ export default {
         }
       })
     },
-    handleOk() {}
+    handleOk() {
+      this.visible = true
+    }
   },
   watch: {},
   distoryed() {}

+ 509 - 0
src/views/modules/Statistics/materialReport/materialReport.vue

@@ -0,0 +1,509 @@
+<template>
+    <div class="materialReport">
+        <div class="card-container">
+            <a-tabs type="card">
+            <a-tab-pane key="1" >
+                <span slot="tab">
+                    <a-icon type="apple" />
+                    大盘
+                </span>  
+            </a-tab-pane>
+            <a-tab-pane key="2" >
+                <span slot="tab">
+                    <a-icon type="apple" />
+                   快手
+                </span>
+            </a-tab-pane>
+            <a-tab-pane key="3" >
+                <span slot="tab">
+                    <a-icon type="apple" />
+                    头条
+                </span>
+            </a-tab-pane>
+            </a-tabs>
+            <div class="option">
+                <div class="item">
+                    <span>上传时间</span>
+                    <a-range-picker
+                    v-model="dateValue"
+                    :ranges="dateRanges"
+                    
+                    :disabled-date="disabledDate"
+                    style="width:250px"
+                    />
+                </div>
+                <div class="item">
+                    <span>数据日期</span>
+                    <a-range-picker
+                    v-model="dateValue"
+                    :ranges="dateRanges"
+                    
+                    :disabled-date="disabledDate"
+                    style="width:250px"
+                    />
+                </div>
+                <div class="item">
+                    <span>数据维度</span>
+                    <a-radio-group v-model="dataDimension" @change="dataDimensionChange">
+                        <a-radio-button value="a">媒体</a-radio-button>
+                        <a-radio-button value="b">组别</a-radio-button>
+                        <a-radio-button value="c">项目</a-radio-button>
+                        <a-radio-button value="d">设计</a-radio-button>
+                    </a-radio-group>
+                    <a-select  style="width: 200px;margin-left:10px" v-model="dataDimensionValue" allowClear  :loading='specificLoading'>
+                        <a-select-option v-for="(item,index) in dataDimensionList" :key="index" :value='item.id'>
+                            {{item.name}}
+                        </a-select-option>
+                    </a-select>
+                </div>
+            </div>
+        </div>
+
+        <div class="echart">
+            <div class="echart-header">
+                数据趋势
+            </div>
+            <div class="echartBody">
+                <div id="echart" ref="echart" style="width:100%;height:350px">
+                    <!-- <a-empty style="position: relative; top: 50%; margin-top: -65px" /> -->
+                </div>
+            </div>
+        </div>
+
+        <div class="tableBody">
+            <YoutTable 
+                headTitle='详细数据'
+                :isNeedCustomColumn='true'
+                :isNeedExport='true'
+                :mediaType='1'
+                :columns='column'
+                :columnsFixd='columnsFixd'
+                :scrollX='2500'
+                :pagination='ipagination'
+                @exportExcel='exportExcel'
+                @change='tableChange'
+            >
+
+            </YoutTable>
+        </div>
+    </div>
+</template>
+
+<script>
+import moment from 'moment';
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
+import YoutTable from '@/components/youtTable/YoutTable'
+var echarts = require('echarts')
+
+const columnsFixd = [
+    {
+        title: '时间',
+        dataIndex: 'date',
+        scopedSlots: { customRender: 'date' },
+        align: 'center',
+        key:'date',
+        width:200,
+        fixed:'left',
+        
+    },
+    {
+        title: '账户ID',
+        dataIndex: 'accountId',
+        align: 'center',
+        width: 200,
+        fixed:'left',
+        scopedSlots: { customRender: 'accountId' }
+    },
+    {
+        title: '账户昵称',
+        dataIndex: 'authName',
+        align: 'center',
+        width: 200,
+        fixed:'left',
+    },
+    
+]
+
+const initVariableColimns=[
+    {
+          title: '消耗(元)',
+          dataIndex: 'cost',
+          width:150,
+          tip: '广告在投放期间的花费总额',
+          align: 'center',
+          scopedSlots: { customRender: 'cost' },
+          sorter: () => {}
+    },
+      // {
+      //     title: '折后消耗(元)',
+      //     dataIndex: 'discountCost',
+      //     width:150,
+      //     tip: '广告在投放期间的花费总额',
+      //     align: 'center',
+      //     scopedSlots: { customRender: 'discountCost' },
+      //     sorter: () => {}
+      // },
+    {
+        title: '封面曝光数',
+        dataIndex: 'photoShow',
+        tip: '广告在瀑布流被观看次数',
+        align: 'center',       
+        scopedSlots: { customRender: 'photoShow' },
+        sorter:() => {}
+    },
+    {
+        title: '封面点击数',
+        dataIndex: 'photoClick',
+        tip: '用户点击封面进入视频播放页的次数(数据会进行反作弊去重)',
+        align: 'center',
+    
+        scopedSlots: { customRender: 'photoClick' },
+        sorter: () => {}
+    },
+    {
+        title: '封面点击率',
+        dataIndex: 'clickRate',
+        tip: '封面点击数占封面展示数百分比',
+        align: 'center',    
+        scopedSlots: { customRender: 'clickRate' },
+        sorter:() => {}
+    },
+    {
+        title: '素材曝光数',
+        dataIndex: 'aClick',
+        tip: '用户进入视频播放页观看的次数(数据会进行反作弊去重)',
+        align: 'center',
+    
+        scopedSlots: { customRender: 'aClick' },
+        sorter:() => {}
+    },
+    {
+        title: '行为数',
+        dataIndex: 'bClick',
+        tip: '用户在视频播放页单击转化按钮的次数/展示数*100%',
+        align: 'center',
+    
+        scopedSlots: { customRender: 'bClick' },
+        sorter:() => {}
+    },
+    
+    {
+        title: '行为率',
+        dataIndex: 'bClickRate',
+        tip: '行为数占素材曝光数百分比',
+        align: 'center',    
+        scopedSlots: { customRender: 'bClickRate' },
+        sorter:() => {}
+    },
+    {
+        title: '平均千次封面曝光花费(元)',
+        dataIndex: 'cpm',
+        tip: '花费/封面曝光数*1000',
+        align: 'center',    
+        scopedSlots: { customRender: 'cpm' },
+        sorter:() => {}
+    },
+    {
+        title: '平均封面点击单价(元)',
+        dataIndex: 'cpc',
+        tip: '花费/封面点击数',
+        align: 'center',    
+        scopedSlots: { customRender: 'cpc' },
+        sorter:() => {}
+    },
+    {
+        title: '平均行为单价(元)',
+        dataIndex: 'cpb',
+        tip: '总花费/行为数',
+        align: 'center',    
+        scopedSlots: { customRender: 'cpb' },
+        sorter:() => {}
+    },
+]
+    export default {
+        components:{
+            YoutTable,
+        },
+        data() {
+            return {
+                column:[...columnsFixd,...initVariableColimns] ,//table的表头
+                columnsFixd,
+                ipagination: {
+                    current: 1,
+                    pageSize: 10,
+                    //   pageSizeOptions: ['10', '20', '30'],
+                    showTotal: (total, range) => {
+                        return range[0] + "-" + range[1] + " 共" + total + "条"
+                    },
+                    showQuickJumper: true,
+                    showSizeChanger:true,
+                    pageSizeOptions: ['10', '30', '50'],
+                    total: 0,
+                    onChange: (current, pageSize) => {
+                        // 切换分页时的回调,
+                        // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+                        this.ipagination.current = current;
+                        this.ipagination.pageSize= pageSize;
+                    }
+                },
+
+                dateRanges:{ '今天': [moment(), moment()],
+                '昨天':[moment().subtract(1,'days'), moment().subtract(1,'days')],
+                '半个月': [moment(), moment().endOf('month')], 
+                '一个月': [moment(), moment().endOf('month')], 
+                },
+                dateValue:[],
+                dataDimension:'a',
+                dataDimensionValue:'',
+                dataDimensionList:[],
+                specificLoading:false,
+            }
+        },
+        methods: {
+            //导出报表
+            exportExcel() {
+                console.log('触发导出事件')
+                let column = this.columns.map((item, index) => {
+                    
+                        return item.dataIndex      
+                        
+                })
+                let columns=column.splice(3)
+                    // console.log(columns)
+                downFilePost('/ctop/kuaishou/dailyPage/report/excel', {
+                    
+                    mediaId:this.mediaId,
+                    discount:this.discount,
+                    accountIds:this.accountId,
+                    startDate:this.dateValue[0].format('YYYY-MM-DD'),
+                    endDate:this.dateValue[1].format('YYYY-MM-DD'),
+                    hour:this.timeSelectValue,
+                    target:this.target,
+                    order:this.order,
+                    columns,
+                    
+                }).then(res => {
+                    let blob = new Blob([res], {
+                    type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+                    })
+                    let downloadElement = document.createElement('a')
+                    let href = window.URL.createObjectURL(blob) //创建下载的链接
+                    downloadElement.href = href
+                    downloadElement.download = moment().format('YYYY-MM-DD') + '账户报表.xlsx' //下载后文件名
+                    document.body.appendChild(downloadElement)
+                    downloadElement.click() //点击下载
+                    document.body.removeChild(downloadElement) //下载完成移除元素
+                    window.URL.revokeObjectURL(href) //释放掉blob对象
+                })
+            },
+            tableChange(data){
+                console.log(data)
+            },
+            //获取echart的值
+            initEchart(idName, optionName) {
+                const chart = this.$refs[idName]
+                //   console.log(chart)
+                if (chart) {
+                    const myChart = echarts.init(document.getElementById(idName))
+                    // myChart.showLoading({
+                    //     text: "图表数据正在努力加载..."
+                    // });
+                    
+                    myChart.setOption(optionName)
+                    window.addEventListener('resize', function() {
+                    myChart.resize()
+                    })
+                }
+            },
+            handlerEchartOption(data){
+                
+                var option ={
+                    // title: {
+                    //     text: '折线图堆叠'
+                    // },
+                    tooltip: {
+                        trigger: 'axis'
+                    },
+                    // legend: {
+                    //     data: ['邮件营销', '联盟广告', ]
+                    // },
+                    grid: {
+                        left: '3%',
+                        right: '4%',
+                        bottom: '3%',
+                        containLabel: true
+                    },
+                    legend: {
+                        icon: 'circle',
+                        top: '5%',
+                        right: '5%',
+                        itemWidth: 6,
+                        itemGap: 20,
+                        textStyle: {
+                            color: '#556677'
+                        }
+                    },
+                    toolbox: {
+                        // feature: {
+                        //     saveAsImage: {}
+                        // }
+                    },
+                    xAxis: {
+                        type: 'category',
+                        data: ['1','2','3','4','5','6','7'],
+                        boundaryGap: false,
+                        // 坐标轴线
+                        axisLine: {
+                            show: false,
+                            lineStyle: {
+                            color: '#999'
+                            }
+                        },
+                        // 分割线
+                        splitLine: {
+                            show: true,
+                            lineStyle: {
+                            type: 'dashed',
+                            color: '#e5e5e5'
+                            }
+                        }
+                    },
+                    yAxis: {
+                        type: 'value',
+                        axisLine: {
+                            show: false,
+                            lineStyle: {
+                                color: '#999'
+                            }
+                        },
+                        splitLine: {
+                            lineStyle: {
+                                type: 'dashed',
+                                color: '#e5e5e5'
+                            }
+                        }
+                    },
+                    series: [
+                        {
+                            name: '邮件营销',
+                            type: 'line',
+                            stack: '总量',
+                            data: [120, 132, 101, 134, 90, 230, 210],
+                            symbol: 'circle',
+                            symbolSize: 1,
+                            lineStyle: {
+                            normal: {
+                                width: 2,
+                                // color: '#0bcd74'
+                            }
+                            },
+                            itemStyle: {
+                                borderColor: '#ffffff',
+                                borderWidth: 0
+                            },
+                        },
+                        {
+                            name: '联盟广告',
+                            type: 'line',
+                            stack: '总量',
+                            data: [220, 182, 191, 234, 290, 330, 310],
+                            symbol: 'circle',
+                            symbolSize: 1,
+                            lineStyle: {
+                                normal: {
+                                    width: 2,
+                                    // color: '#0bcd74'
+                                }
+                            },
+                            itemStyle: {
+                                borderColor: '#ffffff',
+                                borderWidth: 3
+                            },
+                        },
+                        
+                    ]
+                }
+
+                return option
+            },
+            disabledDate(current) {
+                return current && current > moment().endOf('day');
+            },
+            dataDimensionChange(e){
+                console.log(`checked = ${e.target.value}`);
+            },
+            
+        },
+        mounted() {
+            this.$nextTick(()=>{
+                this.initEchart('echart',this.handlerEchartOption([]))
+            })
+        },
+    }
+</script>
+
+<style lang="scss" scoped>
+.materialReport{
+    .option{
+        background: white;
+        padding: 20px;
+        display: flex;
+        justify-content: flex-start;
+        flex-wrap :wrap;
+        .item{
+            margin-right: 15px;
+            margin-bottom: 15px;
+            height: 32px;
+            line-height: 32px;
+            flex-shrink: 0;
+            span{
+                margin-right:10px;
+            }
+        }
+        
+    }
+    .echart{
+        margin-top: 20px;
+        padding:0 20px 20px;
+        background: white;
+        .echart-header{
+            padding:20px 0;
+            font-size: 15px;
+            font-weight: 600;
+        }
+    }
+    .tableBody{
+        margin-top: 20px;
+    }
+}
+</style>
+<style>
+    .card-container {
+        
+        overflow: hidden;
+        /* padding: 24px; */
+    }
+    .card-container > .ant-tabs-card > .ant-tabs-content {
+        /* height: 120px; */
+        margin-top: -16px;
+    }
+
+    .card-container > .ant-tabs-card > .ant-tabs-content > .ant-tabs-tabpane {
+        background: #fff ;
+        /* padding: 16px; */
+    }
+
+    .card-container > .ant-tabs-card > .ant-tabs-bar {
+        border-color: #fff;
+    }
+
+    .card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab {
+        border-color: transparent;
+        background: transparent !important;
+    }
+
+    .card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
+        border-color: #fff;
+        background: #fff !important;
+    }
+</style>

+ 19 - 2
src/views/modules/Statistics/materialStatistics.vue

@@ -93,7 +93,7 @@
             size="middle"
             :customRow="rowClick"
             :loading="loading"
-            :scroll="{ x: 2300 }"
+            :scroll="{ x: 2600 }"
           >
             <div slot="url" slot-scope="url">
               <video @click.stop class="video" :src="url" controls="controls" style="height:200px;width:112.5px">
@@ -106,6 +106,7 @@
             <span slot="photoClickCost" slot-scope="photoClickCost">{{ photoClickCost | toFixtwo }}</span>
             <span slot="actionCost" slot-scope="actionCost">{{ actionCost | toFixtwo }}</span>
             <span slot="conversionPrice" slot-scope="conversionPrice">{{ conversionPrice | toFixtwo }}</span>
+            <span slot="play3sRate" slot-scope="play3sRate">{{ play3sRate | getBo }}</span>
             <span slot="operation" slot-scope="text,record">
                 <a href="javascript:;" @click.stop="showRelevantPeople(record)">查看相关人员</a>
             </span>
@@ -248,6 +249,14 @@ const columns = [
     sorter: (a, b) => a.conversionPrice - b.conversionPrice
   },
   {
+    title: '3s播放率',
+    dataIndex: 'play3sRate',
+    key: 'play3sRate',
+    scopedSlots: { customRender: 'play3sRate' },
+    align: 'center',
+    sorter: (a, b) => a.play3sRate - b.play3sRate
+  },
+  {
     title:'相关人员',
     dataIndex:'operation',
     key:'operation',
@@ -341,7 +350,15 @@ const columnsDetail = [
     key: 'conversionPrice',
     scopedSlots: { customRender: 'conversionPrice' },
     align: 'center'
-  }
+  },
+  {
+    title: '3s播放率',
+    dataIndex: 'play3sRate',
+    key: 'play3sRate',
+    scopedSlots: { customRender: 'play3sRate' },
+    align: 'center',
+    
+  },
 ]
 export default {
   name: 'data-display-statistics',

+ 233 - 29
src/views/modules/Statistics/newPlanStatic/newPlanStatic.vue

@@ -222,7 +222,19 @@
               </a-select-option>
             </a-select> 
             <a-button type='primary' style="position:absolute;right:20px" @click="search">查询</a-button>
-        </div>
+          </div>
+          <div style="margin-bottom:20px">
+              <span>数据维度:</span>
+                <a-radio-group v-model="value" @change="dataTypeChange">
+                    <a-radio :value="1">
+                        广告计划
+                    </a-radio>
+                    <a-radio :value="2" v-show="tabKey==2">
+                        广告组
+                    </a-radio>
+                    
+                </a-radio-group>
+          </div>
           <div class="time"  @click="opendate" >
             <datePick  :dateValue.sync='dateValue'   :type.sync='type'   />
             
@@ -236,7 +248,9 @@
       <div class="showNumBox">
           <a-col :sm="24" :md="10" :xl="10" :xxl="10">
             <span class="title">
-              新上{{tabKey==1?'计划数':'推广组'}}
+              
+              <template v-if="tabKey==1 || tabKey==2&&value==1 ">新上计划数</template>
+               <template v-else-if="tabKey==2&&value==2">新上推广组</template>
             </span>
             <div>
               <countTo
@@ -254,7 +268,10 @@
           </a-col>
           
           <a-col :sm="24" :md="10" :xl="10" :xxl="10">
-            <span class="title">有效{{tabKey==1?'计划数':'推广组'}}</span>
+            <span class="title">
+               <template v-if="tabKey==1 || tabKey==2&&value==1 ">有效计划数</template>
+               <template v-else-if="tabKey==2&&value==2">有效推广组</template>
+            </span>
            <div>
               <countTo
                 :startVal="0"
@@ -283,10 +300,14 @@
       <a-col :span="24">
         <div class="tableBody">
           <a-tabs v-model="tableTab" @change="tableTabChange">
-            <a-tab-pane :key="1" :tab="tabKey==1?'新上计划数':'新上推广组'">        
+            <a-tab-pane :key="1" :tab="(tabKey==1||tabKey==2&&value==1)?'新上计划数':'新上推广组'">        
             </a-tab-pane>
-            <a-tab-pane :key="2" :tab="tabKey==1?'有效计划数':'有效推广组'">       
+            <a-tab-pane :key="2" :tab="(tabKey==1||tabKey==2&&value==1)?'有效计划数':'有效推广组'">       
             </a-tab-pane>
+
+            <a-button slot="tabBarExtraContent" @click="exportExcel" :loading="exportloading" v-show="tabKey==2">
+              导出报表
+            </a-button>
           </a-tabs>
           <a-table :columns="columns" :dataSource="dataTable" :pagination="false" :loading="loading" bordered>             
           </a-table> 
@@ -308,7 +329,7 @@ import moment from 'moment'
 import countTo from 'vue-count-to'
 import lifting from '../components/lifting'
 import {  getKsAccountReport, getKsDetail, getReportList } from '@api/video.js'
-import { getAction, postAction } from '@/api/manage'
+import { getAction, postAction ,downFile, downFilePost } from '@/api/manage'
 
 import timeCheck from '../components/timeCheck'
 
@@ -514,7 +535,106 @@ let KScolumnsVaild=[
   },
 ]
 
-
+let KScolumnsPlan=[
+  // {
+  //   title: '项目名称',
+  //   dataIndex: 'projectName',
+  //   scopedSlots: { customRender: 'projectName' },
+  //   align: 'center',
+  //   key:'projectName'
+    
+  // },
+  {
+    title: '账户名称',
+    dataIndex: 'authName',
+    scopedSlots: { customRender: 'authName' },
+    align: 'center',
+    key:'authName'
+    
+  },
+  {
+    title: '账户ID',
+    dataIndex: 'accountId',
+    scopedSlots: { customRender: 'accountId' },
+    align: 'center',
+    key:'accountId'
+    
+  },
+  {
+    title: '账户所属人',
+    dataIndex: 'userName',
+    scopedSlots: { customRender: 'userName' },
+    align: 'center',
+    key:'userName'
+    
+  },
+  {
+    title: '新上计划数',
+    dataIndex: 'new',
+    scopedSlots: { customRender: 'new' },
+    align: 'center',
+    key:'new'
+    
+  },
+  {
+    title: '最近上新',
+    dataIndex: 'maxCreateTime',
+    scopedSlots: { customRender: 'maxCreateTime' },
+    align: 'center',
+    key:'maxCreateTime'
+    
+  },
+]
+let KScolumnsPlanVaild=[
+  // {
+  //   title: '项目名称',
+  //   dataIndex: 'projectName',
+  //   scopedSlots: { customRender: 'projectName' },
+  //   align: 'center',
+  //   key:'projectName'
+    
+  // },
+  {
+    title: '账户名称',
+    dataIndex: 'authName',
+    scopedSlots: { customRender: 'authName' },
+    align: 'center',
+    key:'authName'
+    
+  },
+  {
+    title: '账户ID',
+    dataIndex: 'accountId',
+    scopedSlots: { customRender: 'accountId' },
+    align: 'center',
+    key:'accountId'
+    
+  },
+  {
+    title: '账户所属人',
+    dataIndex: 'userName',
+    scopedSlots: { customRender: 'userName' },
+    align: 'center',
+    key:'userName'
+    
+  },
+  {
+    title: '有效计划数',
+    dataIndex: 'valid',
+    scopedSlots: { customRender: 'valid' },
+    align: 'center',
+    key:'valid'
+    
+  },
+  {
+    title: '最近上新',
+    dataIndex: 'maxCreateTime',
+    scopedSlots: { customRender: 'maxCreateTime' },
+    align: 'center',
+    key:'maxCreateTime'
+    
+  },
+]
 
 
 let sectionOption={
@@ -631,8 +751,10 @@ export default {
      datePick
   },
 
-  data: function() {
+  data() {
     return {
+      exportloading:false,
+      value:2,
       KSaccountList:[],
       TTaccountList:[],
 
@@ -649,7 +771,7 @@ export default {
       SHOW_PARENT,
 
       type:3,
-      dateValue:[moment().subtract(7,'days'), moment()],
+      dateValue:[moment().subtract(7, 'days'), moment().subtract(1, 'days')],
 
       operate:'',
       operateList:[],
@@ -677,6 +799,58 @@ export default {
     }
   },
   methods: {
+    //导出报表
+        exportExcel() {
+            this.exportloading=true;
+            let url='';
+            let nameType=''
+            if(this.value==2){
+              url='/ctop/kuaishou/newGroup/report/excel'
+            }else{
+              url='/ctop/kuaishou/newPlan/report/excel'
+            }
+            if(this.value==2){
+                nameType='广告组'
+            }else if(this.value==1){
+                nameType='广告计划'
+            }
+            downFilePost(url,{
+              accountIds:this.accountId,
+              userId:this.operate || '',
+              startDate:this.dateValue[0].format('YYYY-MM-DD'),
+              endDate:this.dateValue[1].format('YYYY-MM-DD'),
+              target:this.tableTab=='1'?'new':'valid',
+              order:this.order
+            }).then(res => {
+                this.exportloading=false;
+                let blob = new Blob([res], {
+                    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+                })
+                let downloadElement = document.createElement('a')
+                let href = window.URL.createObjectURL(blob) //创建下载的链接
+                downloadElement.href = href
+                downloadElement.download = moment().format('YYYY-MM-DD') + nameType+'.xlsx' //下载后文件名
+                document.body.appendChild(downloadElement)
+                downloadElement.click() //点击下载
+                document.body.removeChild(downloadElement) //下载完成移除元素
+                window.URL.revokeObjectURL(href) //释放掉blob对象
+            })
+        },
+    dataTypeChange(e){
+      console.log(e.target.value)
+        if(this.value==2){
+          this.operateList=this.KSoperateList
+          this.treeData=this.KSaccountList;
+          this.columns=this.tableTab==1?[...KScolumns]:[...KScolumnsVaild];
+          this.sectionOption.legend.data=['新上推广组','有效推广组']
+        }else{
+          this.operateList=this.KSoperateList
+          this.treeData=this.KSaccountList;
+          this.columns=this.tableTab==1?[...KScolumnsPlan]:[...KScolumnsPlanVaild];
+          this.sectionOption.legend.data=['新上计划数','有效计划数']
+        }
+        this.getNewPlan()
+    },
       //项目改变后的事件
     treeChange(val) {
       // console.log(this.treeData)
@@ -794,7 +968,8 @@ export default {
     // 快手头条的切换
     tabChange(key){
       console.log(key);
-      
+      this.treeValue=[];
+      this.operate=undefined;
       if(key==1){
         // toutiao
         this.treeData=this.TTaccountList;
@@ -803,11 +978,20 @@ export default {
         this.sectionOption.legend.data=['新上计划数','有效计划数']
       }else{
         // kuaishou
-        this.operateList=this.KSoperateList
-        this.treeData=this.KSaccountList;
-        this.columns=this.tableTab==1?[...KScolumns]:[...KScolumnsVaild]
-        this.sectionOption.legend.data=['新上推广组','有效推广组']
+        if(this.value==2){
+          this.operateList=this.KSoperateList
+          this.treeData=this.KSaccountList;
+          this.columns=this.tableTab==1?[...KScolumns]:[...KScolumnsVaild]
+          this.sectionOption.legend.data=['新上推广组','有效推广组']
+        }else{
+          this.operateList=this.KSoperateList
+          this.treeData=this.KSaccountList;
+          this.columns=this.tableTab==1?[...KScolumnsPlan]:[...KScolumnsPlanVaild]
+          this.sectionOption.legend.data=['新上计划数','有效计划数']
+        }
+        
       }
+      
       this.getNewPlan()
     },
     operateChange(value){
@@ -1038,7 +1222,12 @@ export default {
         url='/ctop/bytedance/newPlan/report/data'
       }else{
         // 快手
-        url='/ctop/kuaishou/newGroup/report/data'
+        if(this.value==2){
+          url='/ctop/kuaishou/newGroup/report/data'
+        }else{
+          url='/ctop/kuaishou/newPlan/report/data'
+        }
+        
       }
       // if(this.accountId){
       //   this.operate='';
@@ -1046,16 +1235,23 @@ export default {
       //   this.accountId=''
       // }
       this.loading=true;
-      
+      this.echartSpinning=true;
       this.sectionOption=JSON.parse(JSON.stringify(sectionOption));
       if(this.tabKey==1){
         this.sectionOption.legend.data=['新上计划数','有效计划数']
         this.sectionOption.series[0].name='新上计划数'
         this.sectionOption.series[1].name='有效计划数'
       }else{
-        this.sectionOption.legend.data=['新上推广组','有效推广组']
-        this.sectionOption.series[0].name='新上推广组'
-        this.sectionOption.series[1].name='有效推广组'
+        if(this.value==2){
+          this.sectionOption.legend.data=['新上推广组','有效推广组']
+          this.sectionOption.series[0].name='新上推广组'
+          this.sectionOption.series[1].name='有效推广组'
+        }else{
+          this.sectionOption.legend.data=['新上计划数','有效计划数']
+          this.sectionOption.series[0].name='新上计划数'
+          this.sectionOption.series[1].name='有效计划数'
+        }
+        
       }
       
       postAction(url,{
@@ -1070,18 +1266,26 @@ export default {
         this.loading=false;
         this.echartSpinning=false;
         if(res.success){
-          this.effectPlan=res.result.sumData.valid;
-          this.newPlan=res.result.sumData.new;
-          this.dataTable=res.result.listData;
-
-          // 处理echar数据
-          res.result.chartData.map(item=>{
-            this.sectionOption.xAxis.data.push(item.statDate)
-            this.sectionOption.series[0].data.push(item.new)
-            this.sectionOption.series[1].data.push(item.valid)
-          })
+          if(res.result){
+              this.effectPlan=res.result.sumData.valid;
+              this.newPlan=res.result.sumData.new;
+              this.dataTable=res.result.listData;
+              // 处理echar数据
+              res.result.chartData.map(item=>{
+                this.sectionOption.xAxis.data.push(item.statDate)
+                this.sectionOption.series[0].data.push(item.new)
+                this.sectionOption.series[1].data.push(item.valid)
+              })
          
 
+          }else{
+              this.effectPlan=0;
+              this.newPlan=0;
+              this.dataTable=[];
+          }
+          
+
+          
 
           this.getEchartData('sectionChart', this.sectionOption);
 

+ 902 - 0
src/views/modules/Statistics/popularVideo.vue

@@ -0,0 +1,902 @@
+<style lang="scss" scoped>
+.search-bar {
+  display: flex;
+  align-items: center;
+}
+.search-box p {
+  display: inline-block;
+  border: 1px solid #f2f2f2;
+  border-radius: 5px;
+  margin-right: 10px;
+  padding: 5px 10px;
+  cursor: pointer;
+}
+</style>
+<style>
+.showNumBox{
+  margin: 10px 0;
+}
+.showNumBox .ant-card-body {
+  display: flex;
+  justify-content: center;
+}
+.showNumBox p,
+.showNumBox span {
+  text-align: center;
+  line-height: 40px;
+  font-size: 30px;
+  font-weight: 600;
+  color: red;
+  margin: 0;
+}
+.search-box .ant-card-body {
+  padding: 5px 15px;
+}
+.showNumBox .ant-card-body .styleElse {
+  line-height: 60px;
+  height: 40px;
+  font-size: 16px;
+  font-weight: 400;
+  margin-left: 10px;
+}
+.ant-modal-wrap .yincang .ant-modal-content .ant-modal-footer {
+  display: none !important;
+}
+.yincang .ant-col-6 p {
+  text-align: left;
+  color: red;
+  font-size: 16px;
+  font-weight: 500;
+}
+.ant-table-thead div {
+  font-weight: 700;
+}
+.tool-tip {
+  position: absolute;
+  top: 65px;
+  right: 10px;
+}
+</style>
+<style lang='less'>
+.ant-card-head .ant-tabs-bar{
+  padding: 0;
+}
+.search-box .ant-card-body {
+  padding: 5px 15px;
+
+}
+.search-box{
+  padding: 15px 10px;
+}
+.search-box p {
+  display: inline-block;
+  border: 1px solid #f2f2f2;
+  border-radius: 5px;
+  margin-right: 10px;
+  padding: 5px 10px;
+  cursor: pointer;
+}
+.statistics .ant-col-6 .ant-card-body .styleElse {
+  line-height: 60px;
+  height: 40px;
+  font-size: 16px;
+  font-weight: 400;
+  margin-left: 10px;
+}
+.ant-modal-wrap .yincang .ant-modal-content .ant-modal-footer {
+  display: none !important;
+}
+.yincang .ant-col-6 p {
+  text-align: left;
+  color: red;
+  font-size: 16px;
+  font-weight: 500;
+}
+.ant-table-thead div {
+  font-weight: 700;
+}
+.tool-tip {
+  position: absolute;
+  top: 65px;
+  right: 10px;
+}
+.statistics{
+  .ant-card-bordered {
+     border: none; 
+  }
+  .ant-card-head .ant-tabs {
+    clear: both;
+    margin-bottom: -13px;
+    color: rgba(0, 0, 0, 0.65);
+    font-weight: normal;
+    font-size: 14px;
+}
+.duibi{
+  position: absolute;
+  right: 24px;
+  top: 15px;
+}
+  p{
+    margin-bottom: 0;
+  }
+}
+
+</style>
+
+<style lang="less">
+.newPlanStatic{
+  .divider{
+      height: 62px;
+  }
+  .showNumBox{
+    background: white;
+    overflow: hidden;
+    margin: 15px 0;
+    padding: 30px 0;
+    text-align: center;
+    .ant-card-body{
+      padding-top: 0;
+    }
+    .title{     
+
+      font-size: 14px;
+      font-family: PingFangSC-Regular, PingFang SC;
+      font-weight: 400;
+      color: #999999;
+      line-height: 22px;
+      display: inline-block;
+    }
+  }
+  .tabbody{
+    background: white;
+    padding: 0 24px;
+    margin-bottom: 15px;
+    .ant-tabs-bar {
+      margin: 0;
+    }
+  }
+  .chartBox{
+    background: white;
+    padding: 20px 0;
+  }
+  .tableBody{
+    background: white;
+    padding: 20px ;
+  }
+}
+</style>
+
+<template>
+  <div class="newPlanStatic">
+    <div class="tabbody">
+      <a-tabs v-model="tabKey" @change="tabChange">
+        <a-tab-pane :key="1" tab="头条">        
+        </a-tab-pane>
+        <a-tab-pane :key="2" tab="快手">       
+        </a-tab-pane>
+      </a-tabs>
+    </div>
+    
+    <a-row>
+      <a-col :span="24">
+        
+        <a-card :bordered="false" class="search-box">
+          <div style="margin-bottom:20px">
+            
+
+            <span style="margin-left:20px">编导:</span>
+            <a-select
+              v-model="planId"
+              show-search
+              placeholder="请输入名字"
+              option-filter-prop="children"
+              style="width: 200px"
+              :filter-option="filterOption"
+              @change="operateChange"
+              :disabled='operateDisabled'
+              allowClear
+            >
+              <a-select-option v-for="item in designList" :key="item.user_id" :value="item.id">
+                {{item.realname+'_('+item.roleName+')'}}
+              </a-select-option>
+            </a-select> 
+            <span style="margin-left:20px">剪辑:</span>
+            <a-select
+              v-model="clipId"
+              show-search
+              placeholder="请输入名字"
+              option-filter-prop="children"
+              style="width: 200px"
+              :filter-option="filterOption"
+              @change="operateChange"
+              :disabled='operateDisabled'
+              allowClear
+            >
+              <a-select-option v-for="item in designList" :key="item.user_id" :value="item.id">
+                {{item.realname+'_('+item.roleName+')'}}
+              </a-select-option>
+            </a-select> 
+            <span style="margin-left:20px">拍摄:</span>
+            <a-select
+              v-model="shotId"
+              show-search
+              placeholder="请输入名字"
+              option-filter-prop="children"
+              style="width: 200px"
+              :filter-option="filterOption"
+              @change="operateChange"
+              :disabled='operateDisabled'
+              allowClear
+            >
+              <a-select-option v-for="item in designList" :key="item.user_id" :value="item.id">
+                {{item.realname+'_('+item.roleName+')'}}
+              </a-select-option>
+            </a-select> 
+            <a-button type='primary' style="position:absolute;right:20px" @click="search">查询</a-button>
+            
+          </div>
+           <div style="margin-bottom:20px">
+                <span>日期选择:</span>
+                <a-range-picker
+                    @change="dateChange"
+                    v-model="dateRange"
+                    :disabled-date="disabledDate" 
+                    style="width:200px"                    
+                />
+                <span style="margin-left:20px">数据维度:</span>
+                <a-radio-group v-model="value" @change="dataTypeChange">
+                    <a-radio value="valid">
+                        有效视频
+                    </a-radio>
+                    <a-radio value="hot">
+                        爆款视频
+                    </a-radio>
+                    <a-radio value="onlie">
+                        上线时间
+                    </a-radio>
+                    
+                </a-radio-group>
+          </div>
+          <div class="time"   >
+              
+            
+          </div>
+
+        </a-card>
+      </a-col>
+    </a-row>
+    
+    
+    <a-row style="margin-bottom:15px;margin-top:12px">
+      <a-col :span="24">
+        <div class="tableBody">
+          <!-- <a-button  type='primary' class="export" style="margin-bottom:20px" @click="exportExcel" :loading="exportloading">导出报表</a-button> -->
+          <a-table :columns="columns" :dataSource="dataTable" :pagination="ipagination" :loading="loading" bordered @change="tableChange">  
+                <span slot="createImg" slot-scope="text,record">  
+                    <a-popover placement="right">
+                        <template slot="content">
+                            <video :src="record.url" style="width:250px" controls  ></video>
+                        </template>
+                        <template slot="title">
+                        </template>                       
+                        <img :src="record.coverUrl || noImg" alt="" style="width:80px">
+                    </a-popover>
+                </span> 
+                <span slot='companyName' slot-scope="text">{{text || '未知'}}</span>          
+                <span slot='planName' slot-scope="text">{{text || '-'}}</span>          
+                <span slot='clipName' slot-scope="text">{{text || '-'}}</span>          
+                <span slot='shotName' slot-scope="text">{{text || '-'}}</span>          
+                <span slot='totalCost' slot-scope="text">{{text |decimalsHandle}}</span>          
+                <span slot='activeNum' slot-scope="text">{{text |formatCurrency}}</span>          
+                <span slot='clickNum' slot-scope="text">{{text |formatCurrency}}</span>          
+                <span slot='convertNum' slot-scope="text">{{text |formatCurrency}}</span>          
+                <span slot='showNum' slot-scope="text">{{text |formatCurrency}}</span>          
+                <span slot='aclick' slot-scope="text">{{text |formatCurrency}}</span>          
+                <span slot='bclick' slot-scope="text">{{text |formatCurrency}}</span>          
+                <span slot='photoClick' slot-scope="text">{{text |formatCurrency}}</span>          
+                <span slot='photoShow' slot-scope="text">{{text |formatCurrency}}</span>          
+          </a-table> 
+        </div>
+               
+      </a-col>
+    </a-row>
+  </div>
+</template>
+
+<script>
+
+
+import { TreeSelect } from 'ant-design-vue';
+const SHOW_PARENT = TreeSelect.SHOW_PARENT;
+import ARow from 'ant-design-vue/es/grid/Row'
+import ACol from 'ant-design-vue/es/grid/Col'
+import moment from 'moment'
+
+import {  getKsAccountReport, getKsDetail, getReportList } from '@api/video.js'
+import {
+    getAction,
+    postAction,
+    downFile,
+    downFilePost
+  } from '@/api/manage';
+
+
+import qs from 'qs'
+
+
+
+let TTcolumns=[
+    {
+    title: '视频',
+    dataIndex: 'createImg',
+    scopedSlots: { customRender: 'createImg' },
+    align: 'center',
+    key:'userNcreateImgame'
+    
+  },
+  {
+    title: '视频ID',
+    dataIndex: 'videoCode',
+    scopedSlots: { customRender: 'videoCode' },
+    align: 'center',
+    key:'videoCode'
+    
+  },
+  {
+    title: '视频上线时间',
+    dataIndex: 'stateDate',
+    scopedSlots: { customRender: 'stateDate' },
+    align: 'center',
+    key:'stateDate'
+    
+  },
+  
+  {
+    title: '所属公司',
+    dataIndex: 'companyName',
+    scopedSlots: { customRender: 'companyName' },
+    align: 'center',
+    key:'companyName'
+    
+  },
+  {
+    title: '策划名称',
+    dataIndex: 'planName',
+    scopedSlots: { customRender: 'planName' },
+    align: 'center',
+    key:'planName'
+    
+  },
+  {
+    title: '剪辑名称',
+    dataIndex: 'clipName',
+    scopedSlots: { customRender: 'clipName' },
+    align: 'center',
+    key:'clipName'
+    
+  },
+  {
+    title: '拍摄名称',
+    dataIndex: 'shotName',
+    scopedSlots: { customRender: 'shotName' },
+    align: 'center',
+    key:'shotName'
+    
+  },
+  {
+    title: '总消耗',
+    dataIndex: 'totalCost',
+    scopedSlots: { customRender: 'totalCost' },
+    align: 'center',
+    key:'totalCost'
+    
+  },
+  {
+    title: '点击数',
+    dataIndex: 'clickNum',
+    scopedSlots: { customRender: 'clickNum' },
+    align: 'center',
+    key:'clickNum'
+    
+  },
+  {
+    title: '曝光数',
+    dataIndex: 'showNum',
+    scopedSlots: { customRender: 'showNum' },
+    align: 'center',
+    key:'showNum'
+    
+  },
+  {
+    title: '激活数',
+    dataIndex: 'activeNum',
+    scopedSlots: { customRender: 'activeNum' },
+    align: 'center',
+    key:'activeNum'
+    
+  },
+  {
+    title: '转化数',
+    dataIndex: 'convertNum',
+    scopedSlots: { customRender: 'convertNum' },
+    align: 'center',
+    key:'convertNum'
+    
+  },
+//   {
+//     title: '总消耗',
+//     dataIndex: 'totalCost',
+//     scopedSlots: { customRender: 'totalCost' },
+//     align: 'center',
+//     key:'totalCost'
+    
+//   },
+]
+
+
+
+let KScolumns=[
+  {
+    title: '视频',
+    dataIndex: 'createImg',
+    scopedSlots: { customRender: 'createImg' },
+    align: 'center',
+    key:'userNcreateImgame'
+    
+  },
+  {
+    title: '视频ID',
+    dataIndex: 'videoCode',
+    scopedSlots: { customRender: 'videoCode' },
+    align: 'center',
+    key:'videoCode'
+    
+  },
+  {
+    title: '视频上线时间',
+    dataIndex: 'stateDate',
+    scopedSlots: { customRender: 'stateDate' },
+    align: 'center',
+    key:'stateDate'
+    
+  },
+  
+  {
+    title: '所属公司',
+    dataIndex: 'companyName',
+    scopedSlots: { customRender: 'companyName' },
+    align: 'center',
+    key:'companyName'
+    
+  },
+  {
+    title: '策划名称',
+    dataIndex: 'planName',
+    scopedSlots: { customRender: 'planName' },
+    align: 'center',
+    key:'planName'
+    
+  },
+  {
+    title: '剪辑名称',
+    dataIndex: 'clipName',
+    scopedSlots: { customRender: 'clipName' },
+    align: 'center',
+    key:'clipName'
+    
+  },
+  {
+    title: '拍摄名称',
+    dataIndex: 'shotName',
+    scopedSlots: { customRender: 'shotName' },
+    align: 'center',
+    key:'shotName'
+    
+  },
+  {
+    title: '总消耗',
+    dataIndex: 'totalCost',
+    scopedSlots: { customRender: 'totalCost' },
+    align: 'center',
+    key:'totalCost'
+    
+  },
+  {
+    title: '封面曝光',
+    dataIndex: 'photoShow',
+    scopedSlots: { customRender: 'photoShow' },
+    align: 'center',
+    key:'photoShow'
+    
+  },
+  {
+    title: '封面点击',
+    dataIndex: 'photoClick',
+    scopedSlots: { customRender: 'photoClick' },
+    align: 'center',
+    key:'photoClick'
+    
+  },
+  {
+    title: '素材曝光',
+    dataIndex: 'aclick',
+    scopedSlots: { customRender: 'aclick' },
+    align: 'center',
+    key:'aclick'
+    
+  },
+  {
+    title: '行为数',
+    dataIndex: 'bclick',
+    scopedSlots: { customRender: 'bclick' },
+    align: 'center',
+    key:'bclick'
+    
+  },
+]
+
+
+
+
+
+export default {
+  
+    components: {
+        ACol,
+        ARow,
+        
+    },
+
+    data() {
+        return {
+            exportloading:false,
+            planId:'',
+            shotId:'',
+            clipId:'',
+            dateRange:[moment().subtract(1,'weeks'),moment()],
+            noImg:require('@/assets/noImg.png'),
+            ipagination: {
+                current: 1,
+                pageSize: 10,
+                //   pageSizeOptions: ['10', '20', '30'],
+                showTotal: (total, range) => {
+                    return range[0] + "-" + range[1] + " 共" + total + "条"
+                },
+                showQuickJumper: true,
+                showSizeChanger:true,
+                pageSizeOptions: ['10', '30', '50'],
+                total: 0,
+                onChange: (current, pageSize) => {
+                    // 切换分页时的回调,
+                    // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+                    this.ipagination.current = current;
+                    this.ipagination.pageSize= pageSize;
+                }
+            },
+            value:'valid',
+            KSaccountList:[],
+            TTaccountList:[],
+
+            KSdesignList:[],
+            TTdesignList:[],
+
+            
+            operateDisabled:false,
+            userId:JSON.parse(localStorage.getItem('pro__Login_Userinfo')).value.id,
+            duration: 1000,
+            //treeselect的参数
+            treeValue: [],
+            treeData: [],
+            SHOW_PARENT,
+
+            type:3,
+            dateValue:[moment().subtract(7,'days'), moment()],
+
+            operate:'',
+            designList:[],
+
+            tabKey:1,
+
+            loading: false,
+            TTcolumns,
+            KScolumns,
+            columns:[...TTcolumns],    
+            dataTable: [],
+            
+            tableTab:1,
+
+            newPlan:0,
+            effectPlan:0,
+            
+            
+
+            openOptions:false,
+
+            target:'',
+            order:'desc',
+        }
+    },
+    methods: {
+         moment,
+        disabledDate(current) {           
+            return current && current > moment()
+        }, 
+        dateChange(date, dateString) {
+            // console.log(date,dateString)               
+        },
+        //导出报表
+        exportExcel() {
+            this.exportloading=true;
+            let url='';
+            if(this.tabKey==1){
+                url='/ctop/bytedanceVideoEtlInfo/exportXls';
+            }else {
+                url='/ctop/kuaishouVideoEtlInfo/exportXls'
+            }
+            let nameType=''
+            if(this.value=='valid'){
+                nameType='有效视频'
+            }else if(this.value=='hot'){
+                nameType='爆款视频'
+            }else if(this.value=='online'){
+                nameType='视频上线时间'
+            }
+
+            downFilePost(url,qs.stringify({
+                type:this.value,
+                clipId:this.clipId,
+                shotId:this.shotId,
+                planId:this.planId,
+                startData:this.dateRange[0].format('YYYY-MM-DD'),
+                endData:this.dateRange[1].format('YYYY-MM-DD'),  
+            })).then(res => {
+                this.exportloading=false;
+                let blob = new Blob([res], {
+                    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+                })
+                let downloadElement = document.createElement('a')
+                let href = window.URL.createObjectURL(blob) //创建下载的链接
+                downloadElement.href = href
+                downloadElement.download = moment().format('YYYY-MM-DD') + nameType+'.xlsx' //下载后文件名
+                document.body.appendChild(downloadElement)
+                downloadElement.click() //点击下载
+                document.body.removeChild(downloadElement) //下载完成移除元素
+                window.URL.revokeObjectURL(href) //释放掉blob对象
+            })
+        },
+        dataTypeChange(e){
+            console.log(e.target.value)
+            
+            this.getNewPlan()
+        },
+    
+        
+        filterOption(input, option){
+            // console.log(input, option)
+            return (
+                option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+                );
+        },
+     
+    
+        // 快手头条的切换
+        tabChange(key){
+            console.log(key);
+            this.treeValue=[];
+            this.ipagination.current=1
+           this.columns=this.tabKey==1?[...TTcolumns]:[...KScolumns]
+            
+            this.getNewPlan()
+        },
+        operateChange(value){
+        console.log(value);
+        if(value){
+            this.accountDisabled=true;
+            this.accountId=''
+        }else{
+            this.accountDisabled=false
+        }
+        },
+
+        tableChange(pagination, filters, sorter, { currentDataSource }){
+            console.log(pagination)
+            this.ipagination.current=pagination.current;
+            this.ipagination.pageSize=pagination.pageSize;
+            this.getNewPlan()
+        },
+       
+        // table区域的tab切换
+        tableTabChange(key){
+            if(key==1){
+            
+                this.columns=this.tabKey==1?[...TTcolumns]:[...KScolumns]
+                this.target='new'
+            }else{
+                
+                this.columns=this.tabKey==1?[...TTcolumnsVaild]:[...KScolumnsVaild]
+                this.target='valid'
+            }
+            this.getNewPlan()
+        },
+    
+       
+
+        // 获取所有运营
+        getAllOperator(key){
+            let url='/sys/user/getAllDesigner'
+            this.designList=[]
+            
+            getAction(url,{}).then(res=>{
+                console.log(res);
+                if(res.success){
+                
+                    this.designList=res.data
+               
+                
+                }
+            })
+        },
+
+
+        // 获取展示数据
+        getNewPlan(){
+            let url=''
+            if(this.tabKey==1){
+                // 头条
+                url='/ctop/bytedanceVideoEtlInfo/list'
+            }else{
+                // 快手
+                
+                url='/ctop/kuaishouVideoEtlInfo/list'
+                
+            }
+            
+            this.loading=true;
+
+            getAction(url,{
+                type:this.value,
+                clipId:this.clipId==''?null:this.clipId,
+                shotId:this.shotId==''?null:this.shotId,
+                planId:this.planId==''?null:this.planId,
+                startDate:this.dateRange[0].format('YYYY-MM-DD'),
+                endDate:this.dateRange[1].format('YYYY-MM-DD'),
+                pageSize:this.ipagination.pageSize,
+                pageNo:this.ipagination.current
+            }).then(res=>{
+                console.log(res);
+                this.loading=false;
+            
+                if(res.success){
+                    
+                    if(res.result){
+                        this.dataTable=res.result.records
+                        this.ipagination.total=res.result.total
+                    }
+
+                }
+            })
+        
+        },
+
+        // 查询按钮
+        search(){
+            // if(this.accountId || this.operate){
+            //     this.echartSpinning=true;
+            //     this.getNewPlan()
+            // }else{
+            //     this.$message.error('请选择具体账户或者运营')
+            // }
+            this.ipagination.current=1;
+            this.getNewPlan()
+            
+        },
+    
+    },
+    watch: {
+        dateValue(newName,oldName){
+        
+            this.search()
+        },
+    },
+    computed: {
+        newDate() {
+        var myDate = new Date()
+        myDate.getYear() //获取当前年份(2位)
+        var n = myDate.getFullYear() //获取完整的年份(4位,1970-????)
+        var m = myDate.getMonth() //获取当前月份(0-11,0代表1月)
+        var d = myDate.getDate() //获取当前日(1-31)
+        var day = myDate.getHours()
+        return day
+        }
+    },
+    mounted() {
+        this.getNewPlan()
+        this.getAllOperator()
+    },
+    activated: function() {
+        
+        
+    },
+  
+    filters: {
+        toPercentage(val) {
+        if(typeof val != 'string'){
+            return (val * 100).toFixed(2) + '%'
+        }else{
+            return val
+        }
+        
+        },
+        //保留两位小数并且变成货币格式
+        decimalsHandle(val){
+            
+            if(val && typeof val !='string'){
+                if(val>=0){
+                    val=parseFloat(val).toFixed(2);
+                    let numberStr = val.toString()
+                    let str = numberStr.split('.')
+                    
+                    let str0=str[0].split('').reverse();
+                    for (let i = 0; i < str0.length; i++) {
+                        if ((i + 1) % 4 === 0) {
+                            str0.splice(i, 0, ',')
+                        }
+                    }
+                    str0.reverse()
+                    let handleResult = ''
+                    for (let j = 0; j < str0.length; j++) {
+                        handleResult += str0[j]
+                    }
+                    
+                    return handleResult+'.'+str[1]
+                }else{
+                    val=parseFloat(val).toFixed(2);
+                    let numberStr = val.toString()
+                    let str = numberStr.split('.')
+                    
+                    let str0=str[0].substr(1).split('').reverse();
+                    for (let i = 0; i < str0.length; i++) {
+                        if ((i + 1) % 4 === 0) {
+                            str0.splice(i, 0, ',')
+                        }
+                    }
+                    str0.reverse()
+                    let handleResult = ''
+                    for (let j = 0; j < str0.length; j++) {
+                        handleResult += str0[j]
+                    }
+                    
+                    return '-'+handleResult+'.'+str[1]
+                }
+                
+            }else if(typeof val =='string'){
+                return val
+            }
+            else{
+                return 0
+            }           
+        },
+        //变成货币格式
+        formatCurrency(val){
+        if(val){
+            let numberStr = val.toString()
+            let str = numberStr.split('').reverse()
+            for (let i = 0; i < str.length; i++) {
+                if ((i + 1) % 4 === 0) {
+                str.splice(i, 0, ',')
+                }
+            }
+            str.reverse()
+            let handleResult = ''
+            for (let j = 0; j < str.length; j++) {
+                handleResult += str[j]
+            }
+            return handleResult
+        }else{
+            return '-'
+        }
+            
+        }
+    }
+}
+</script>

+ 38 - 9
src/views/modules/Statistics/refuseDataCreat.vue

@@ -67,7 +67,7 @@
     </a-row>
     <a-modal :title="editTitle" :visible="visible" @ok="handleOk" :confirmLoading="confirmLoading"
       @cancel="handleCancel">
-      <a-textarea v-model="editWord" autosize />
+      <a-textarea v-model="editWord" autosize   :maxLength='30'/>
     </a-modal>
     <a-modal title="一键重提" @cancel="handleClose" :visible="visibleAgain" @ok="handleOkAgain"
       :confirmLoading="againLoading" :width="650">
@@ -193,25 +193,29 @@
       title: '账号Id',
       dataIndex: 'accountId',
       key: 'accountId',
-      align: 'center'
+      align: 'center',
+      width:120,
     },
     {
       title: '计划Id',
       dataIndex: 'campaignId',
       key: 'campaignId',
-      align: 'center'
+      align: 'center',
+       width:120,
     },
     {
-      title: '广告组id',
+      title: '广告组Id',
       dataIndex: 'unitId',
       key: 'unitId',
-      align: 'center'
+      align: 'center',
+       width:120,
     },
     {
-      title: '创意id',
+      title: '创意Id',
       dataIndex: 'creativeId',
       key: 'photoClick',
-      align: 'center'
+      align: 'center',
+       width:120,
     },
     {
       title: '创意名称',
@@ -617,6 +621,7 @@
         params.campaignId = localStorage.getItem('accountIdCreat')
         params.pageSize = this.ipagination.pageSize
         params.pageNo = this.ipagination.current
+        params.creativeName=this.keyWord
         params.putStatus = this.putStatus == "0" ? null : this.putStatus
         getAction('/MaterialRefuse/getRefuseCreative', params).then(res => {
           if (res.code == 0) {
@@ -633,8 +638,32 @@
         })
       },
       addUserKey() {
-        this.dataList = this.list.filter(item => {
-          return item.creativeName.toLowerCase().indexOf(this.keyWord.toLowerCase()) > -1
+        // this.dataList = this.list.filter(item => {
+        //   return item.creativeName.toLowerCase().indexOf(this.keyWord.toLowerCase()) > -1
+        // })
+        this.loading = true
+        var params = {}
+        this.selectedRowKeys = []
+        this.selectedRowKeysValue = []        
+        params.accountId = this.appId
+        params.accountId = localStorage.getItem('accountIdCreatNow')
+        params.campaignId = localStorage.getItem('accountIdCreat')
+        params.pageSize = this.ipagination.pageSize
+        params.pageNo = this.ipagination.current
+        params.putStatus = this.putStatus == "0" ? null : this.putStatus
+        params.creativeName=this.keyWord
+        getAction('/MaterialRefuse/getRefuseCreative', params).then(res => {
+          if (res.code == 0) {
+            this.dataList = res.result.records.map((v, index) => {
+              return {
+                ...v,
+                key: index
+              }
+            })
+            this.list = this.dataList
+            this.loading = false
+            this.ipagination.total = res.result.total
+          }
         })
       },
       reset() {

+ 39 - 11
src/views/modules/Statistics/refuseDataCreatNew.vue

@@ -16,7 +16,7 @@
           <div style="display:flex;margin:0 0 20px 0;position:relative">
             <a-input placeholder="请输出要查找的创意名称" style="width:300px;" v-model="keyWord" />
             <a-button type="primary" style="margin-left:10px" @click="addUserKey">搜索</a-button>
-            <a-button type="primary" style="margin-left:10px" @click="reset()">刷新列表</a-button>
+            <a-button type="primary" style="margin-left:10px" @click="reset">刷新列表</a-button>
             <a-button type="primary" style="margin-left:10px" @click="clickAgain" v-if="selectedRowKeys.length>0"
               :loading="loadingList">一键重提
             </a-button>
@@ -67,7 +67,7 @@
     </a-row>
     <a-modal :title="editTitle" :visible="visible" @ok="handleOk" :confirmLoading="confirmLoading"
       @cancel="handleCancel">
-      <a-textarea v-model="editWord" autosize />
+      <a-textarea v-model="editWord" autosize :maxLength='editTitle=="广告语修改"?30:200' />
     </a-modal>
     <a-modal title="一键重提" @cancel="handleClose" :visible="visibleAgain" @ok="handleOkAgain"
       :confirmLoading="againLoading" :width="650">
@@ -193,25 +193,29 @@
       title: '账号Id',
       dataIndex: 'accountId',
       key: 'accountId',
-      align: 'center'
+      align: 'center',
+       width:120,
     },
     {
       title: '计划Id',
       dataIndex: 'campaignId',
       key: 'campaignId',
-      align: 'center'
+      align: 'center',
+       width:120,
     },
     {
-      title: '广告组id',
+      title: '广告组Id',
       dataIndex: 'unitId',
       key: 'unitId',
-      align: 'center'
+      align: 'center',
+       width:120,
     },
     {
-      title: '创意id',
+      title: '创意Id',
       dataIndex: 'creativeId',
       key: 'photoClick',
-      align: 'center'
+      align: 'center',
+       width:120,
     },
     {
       title: '创意名称',
@@ -431,7 +435,7 @@
         return this.form.getFieldValue(className)
       },
       syncCreative() {
-
+        
         this.loadingSyncCreative = true
         var params = {}
         //  localStorage.setItem('accountIdCreat', record.campaignId)
@@ -615,6 +619,7 @@
         // params.campaignId = localStorage.getItem('accountIdCreat')
         params.pageSize = this.ipagination.pageSize
         params.pageNo = this.ipagination.current
+        params.creativeName=this.keyWord
         params.putStatus = this.putStatus == "0" ? null : this.putStatus
         getAction('/MaterialRefuse/getRefuseCreative', params).then(res => {
           if (res.code == 0) {
@@ -631,11 +636,34 @@
         })
       },
       addUserKey() {
-        this.dataList = this.list.filter(item => {
-          return item.creativeName.toLowerCase().indexOf(this.keyWord.toLowerCase()) > -1
+        // this.dataList = this.list.filter(item => {
+        //   return item.creativeName.toLowerCase().indexOf(this.keyWord.toLowerCase()) > -1
+        // })
+        this.loading = true
+        var params = {}
+        this.selectedRowKeys = []
+        this.selectedRowKeysValue = []        
+        params.accountId = this.appId
+        params.pageSize = this.ipagination.pageSize
+        params.pageNo = this.ipagination.current
+        params.putStatus = this.putStatus == "0" ? null : this.putStatus
+        params.creativeName=this.keyWord
+        getAction('/MaterialRefuse/getRefuseCreative', params).then(res => {
+          if (res.code == 0) {
+            this.dataList = res.result.records.map((v, index) => {
+              return {
+                ...v,
+                key: index
+              }
+            })
+            this.list = this.dataList
+            this.loading = false
+            this.ipagination.total = res.result.total
+          }
         })
       },
       reset() {
+        // this.keyWord='';
         this.addUser()
       }
     },

+ 49 - 16
src/views/modules/advertiser/AdvertiserList.vue

@@ -19,15 +19,13 @@
                 @search="getList"
               >
                 <a-select-option :value="item.id" v-for="(item, index) of list" :key="index">
-                  {{
-                  item.name
-                  }}
+                  {{ item.name }}
                 </a-select-option>
               </a-select>
             </a-form-item>
           </a-col>
           <a-col :md="8" :sm="8">
-            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+            <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
               <a-button type="primary" @click="searchQueryOne" icon="search">查询</a-button>
               <a-button type="primary" @click="searchRe" icon="reload" style="margin-left: 8px">重置</a-button>
             </span>
@@ -44,18 +42,18 @@
       <a-tab-pane key="product" tab="产品列表">
         <a-tag
           color="blue"
-          style="height:30px;line-height:30px;font-size:14px;margin-bottom:20px"
+          style="height: 30px; line-height: 30px; font-size: 14px; margin-bottom: 20px"
           v-if="queryParam.advertiserId"
         >
-          {{advertiserName}}
+          {{ advertiserName }}
           <a-icon type="close" @click="clear('advertiserId')" />
         </a-tag>
-        <a-row :gutter="24" style="margin-bottom:20px">
+        <a-row :gutter="24" style="margin-bottom: 20px">
           <a-col :md="8" :sm="8">
             <a-input placeholder="请输入产品名称" v-model="queryParam.productName"></a-input>
           </a-col>
           <a-col :md="8" :sm="8">
-            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+            <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
               <a-button type="primary" @click="searchQueryOne" icon="search">查询</a-button>
             </span>
           </a-col>
@@ -64,18 +62,18 @@
       <a-tab-pane key="project" tab="项目列表">
         <a-tag
           color="blue"
-          style="height:30px;line-height:30px;font-size:14px;margin-bottom:20px"
+          style="height: 30px; line-height: 30px; font-size: 14px; margin-bottom: 20px"
           v-if="queryParam.productId"
         >
-          {{advertiserName?advertiserName+' / '+productName:productName}}
+          {{ advertiserName ? advertiserName + ' / ' + productName : productName }}
           <a-icon type="close" @click="clear('productId')" />
         </a-tag>
-        <a-row :gutter="24" style="margin-bottom:20px">
+        <a-row :gutter="24" style="margin-bottom: 20px">
           <a-col :md="8" :sm="8">
             <a-input placeholder="请输入项目名称" v-model="queryParam.projectName"></a-input>
           </a-col>
           <a-col :md="8" :sm="8">
-            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+            <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
               <a-button type="primary" @click="searchQueryOne" icon="search">查询</a-button>
             </span>
           </a-col>
@@ -96,6 +94,25 @@
         :loading="loading"
         @change="handleTableChange"
       >
+        <span slot="ocpxActionType" slot-scope="text">
+          <div v-if="text">
+            <span v-for="(item, index) of JSON.parse(text)" :key="index"
+              >{{ item | ocpxActionType }}{{ index == JSON.parse(text).length - 1 ? '' : ',' }}</span
+            >
+          </div>
+          <div v-else>-</div>
+
+          <!-- {{ text | ocpxActionType }} -->
+        </span>
+        <span slot="bidType" slot-scope="text">
+          <div v-if="text && JSON.parse(text).length > 0">
+            <span v-for="(item, index) of JSON.parse(text)" :key="index"
+              >{{ item | bidType }}{{ index == JSON.parse(text).length - 1 ? '' : ',' }}</span
+            >
+          </div>
+          <div v-else>-</div>
+        </span>
+
         <span slot="action" slot-scope="text, record">
           <a @click="handleEdit(record)">编辑</a>
 
@@ -105,7 +122,7 @@
           </a-popconfirm>
         </span>
         <span slot="actionProduct" slot-scope="text, record">
-          <a @click="handleEditElse(record,'product')">编辑</a>
+          <a @click="handleEditElse(record, 'product')">编辑</a>
 
           <a-divider type="vertical" />
           <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
@@ -113,7 +130,7 @@
           </a-popconfirm>
         </span>
         <span slot="actionProject" slot-scope="text, record">
-          <a @click="handleEditElse(record,'project')">编辑</a>
+          <a @click="handleEditElse(record, 'project')">编辑</a>
 
           <a-divider type="vertical" />
           <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
@@ -122,8 +139,8 @@
         </span>
         <span slot="maxBid" slot-scope="text">{{ text / 1000 }}</span>
         <span slot="maxDeepCpaBid" slot-scope="text">{{ text / 1000 }}</span>
-        <a slot="name" slot-scope="text,record" @click="toProduct(record,'product')">{{text}}</a>
-        <a slot="productName" slot-scope="text,record" @click="toProduct(record,'project')">{{text}}</a>
+        <a slot="name" slot-scope="text, record" @click="toProduct(record, 'product')">{{ text }}</a>
+        <a slot="productName" slot-scope="text, record" @click="toProduct(record, 'project')">{{ text }}</a>
       </a-table>
     </div>
     <!-- table区域-begin -->
@@ -256,6 +273,22 @@ const projectColumns = [
     },
   },
   {
+    title: '优化目标',
+    align: 'center',
+    dataIndex: 'bidType',
+    scopedSlots: {
+      customRender: 'bidType',
+    },
+  },
+  {
+    title: '转化目标',
+    align: 'center',
+    dataIndex: 'ocpxActionType',
+    scopedSlots: {
+      customRender: 'ocpxActionType',
+    },
+  },
+  {
     title: '供应商',
     align: 'center',
     dataIndex: 'supplierCode_dictText',

+ 7 - 1
src/views/modules/advertiser/ProjectList.vue

@@ -133,7 +133,7 @@
           <!-- {{ text | ocpxActionType }} -->
         </span>
         <span slot="bidType" slot-scope="text">
-          <div v-if="text">
+          <div v-if="text && JSON.parse(text).length > 0">
             <span v-for="(item, index) of JSON.parse(text)" :key="index"
               >{{ item | bidType }}{{ index == JSON.parse(text).length - 1 ? '' : ',' }}</span
             >
@@ -297,6 +297,12 @@ export default {
         383: '授信',
         384: '完件',
         394: '订单提交',
+        324: '唤起应用',
+        715: '微信复制优化目标',
+        716: '多转化事件',
+        396:'注册优化目标',
+        731:'广告观看5次',
+        732:'广告观看10次',
       }
       return data[sta]
     },

+ 23 - 5
src/views/modules/advertiser/ProjectMemberList.vue

@@ -173,9 +173,10 @@
             :wrapper-col="{ xs: { span: 24 }, sm: { span: 16 } }"
             v-if="loginType == 'kuaishou'"
           >
-            <a-radio-group buttonStyle="outline" v-model="agentType">
-              <a-radio-button value="0">否</a-radio-button>
-              <a-radio-button value="1">是</a-radio-button>
+            <a-radio-group buttonStyle="outline" v-model="id">
+              <!-- <a-radio-button value="0">否</a-radio-button>
+              <a-radio-button value="1">是</a-radio-button> -->
+              <a-radio-button v-for="item in authConfigList" :key="item.id" :value='item.id'>{{item.agentName}}</a-radio-button>
             </a-radio-group>
           </a-form-item> -->
           <a-form-item
@@ -423,6 +424,7 @@ export default {
   mixins: [JeecgListMixin],
   data() {
     return {
+      authConfigList:[],
       title: '',
       titleAccount: '',
       description: '我的项目',
@@ -434,7 +436,7 @@ export default {
       accountName: '',
       password: '',
       loginType: 'kuaishou',
-      agentType: '1',
+      id: undefined,
       form: this.$form.createForm(this),
       record: '',
       systemType: '不限',
@@ -828,7 +830,7 @@ export default {
             params.authorizationType = this.loginType
             if (this.loginType == 'kuaishou') {
               params.mediaId = this.mediaId
-              params.agentType = this.agentType
+              params.id = this.id
             } else if (this.loginType == 'bytedance') {
               params.mediaId = 1
             }
@@ -848,6 +850,7 @@ export default {
     },
     searchReset() {
       this.keyWord = ''
+      this.ipagination.current = 1
       // this.dataSource = this.dataElse
       if (this.noTitleKey == 'participation') {
         this.getParticipateList()
@@ -856,6 +859,7 @@ export default {
       }
     },
     searchQuery() {
+      this.ipagination.current=1
       if (this.noTitleKey == 'participation') {
         this.getParticipateList()
       } else {
@@ -887,10 +891,24 @@ export default {
         this.getAllUserList()
       }
     },
+    getauthConfigList(){
+      getAction('/auth/oauthConfig/list',{
+        status:0,
+        mediaId:2
+      }).then(res=>{
+        console.log(res)
+        this.authConfigList=res.result;
+        if(res.result.length>0){
+          this.id=res.result[0].id
+        }
+        
+      })
+    }
   },
   mounted() {
     this.$nextTick(() => {
       this.getParticipateList()
+      this.getauthConfigList()
     })
   },
 }

+ 27 - 5
src/views/modules/advertiser/modules/AdvertiserModal.vue

@@ -88,13 +88,22 @@
             rules: [{
               required: true,
               message: '请输入联系人手机!'
-            }]
+            },{
+              validator:this.mobileChecked
+            }
+            ]
           },
           email: {
-            rules: [{
-              required: true,
-              message: '请输入联系人邮箱!'
-            }]
+            rules: [
+              {
+                type: 'email',
+                message: '邮箱格式不正确,请重新输入',
+              },
+              {
+                required: true,
+                message: '请输入联系人邮箱!',
+              },
+              ]
           },
           pid: {
             rules: [{
@@ -199,6 +208,19 @@
       filterOption(input, option) {
         return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
       },
+      mobileChecked(rule, value, callback){
+        // console.log(rule, value, callback)
+            var strRegex = /^1[0-9]{10}$/
+            var re = new RegExp(strRegex)
+            // console.log(re.test(res))
+            if (re.test(value)) {
+                callback()
+            } else if(value && !re.test(value)){
+                callback('手机号码不正确,请正确输入')
+            }else{
+              callback()
+            }
+      }
     }
   }
 </script>

+ 77 - 30
src/views/modules/advertiser/modules/ProjectModal.vue

@@ -30,7 +30,7 @@
           :labelCol="labelCol"
           :wrapperCol="wrapperCol"
           label="供应商"
-          v-if="model.mediaId=='2'||model.mediaId=='4'"
+          v-if="model.mediaId == '2' || model.mediaId == '4'"
         >
           <a-select
             optionFilterProp="children"
@@ -38,14 +38,8 @@
             :filterOption="filterOption"
             v-decorator="['supplierCode', validatorRules.supplierCode]"
           >
-            <a-select-option
-              :value="item.supplierCode"
-              v-for="(item, index) of supplierList"
-              :key="index"
-            >
-              {{
-              item.supplierName
-              }}
+            <a-select-option :value="item.supplierCode" v-for="(item, index) of supplierList" :key="index">
+              {{ item.supplierName }}
             </a-select-option>
           </a-select>
         </a-form-item>
@@ -59,9 +53,7 @@
             v-decorator="['advertiserId', validatorRules.advertiserId]"
           >
             <a-select-option :value="item.id" v-for="(item, index) of list" :key="index">
-              {{
-              item.name
-              }}
+              {{ item.name }}
             </a-select-option>
           </a-select>
         </a-form-item>
@@ -71,39 +63,65 @@
             showSearch
             :filterOption="filterOption"
             v-decorator="['productId', validatorRules.productId]"
-            :disabled="getFormFieldValue('advertiserId')==''||getFormFieldValue('advertiserId')==null"
+            :disabled="getFormFieldValue('advertiserId') == '' || getFormFieldValue('advertiserId') == null"
           >
             <a-select-option :value="item.id" v-for="(item, index) of listProduct" :key="index">
-              {{
-              item.productName
-              }}
+              {{ item.productName }}
             </a-select-option>
           </a-select>
         </a-form-item>
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="最高出价">
-          <a-input
-            placeholder="请输入最高出价"
-            v-decorator="['maxBid', validatorRules.maxBid]"
-            addonAfter="元"
-          />
+          <a-input placeholder="请输入最高出价" v-decorator="['maxBid', validatorRules.maxBid]" addonAfter="元" />
         </a-form-item>
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="最高转化出价">
           <a-input placeholder="最高转化出价" v-decorator="['maxDeepCpaBid']" addonAfter="元" />
         </a-form-item>
+        <div v-if="model.mediaId == '2' || model.mediaId == '4'">
+          <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="优化目标">
+            <a-select
+              v-decorator="['bidType', { rules: [{ required: true, message: '请输入表单名称' }], initialValue: 2 }]"
+              mode="multiple"
+            >
+              <a-select-option :value="2">点击数</a-select-option>
+              <a-select-option :value="10">OCPM</a-select-option>
+              <a-select-option :value="6">OCPC</a-select-option>
+            </a-select>
+          </a-form-item>
+          <div v-if="Array.isArray(getFormFieldValue('bidType'))">
+            <a-form-item
+              label="转化目标"
+              :labelCol="labelCol"
+              :wrapperCol="wrapperCol"
+              v-show="
+                getFormFieldValue('bidType').findIndex((item) => item == 10) > -1 ||
+                getFormFieldValue('bidType').findIndex((item) => item == 6) > -1
+              "
+            >
+              <a-select v-model="model.ocpxActionType" mode="multiple">
+                <a-select-option :value="2">行为数</a-select-option>
+                <a-select-option :value="item.ocpxActionType" v-for="(item, index) in ocpxList" :key="index">{{
+                  item.ocpxActionName
+                }}</a-select-option>
+              </a-select>
+            </a-form-item>
+          </div>
+        </div>
+
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="销售">
           <a-select
             showSearch
             optionFilterProp="children"
             style="width: 100%"
             :filterOption="filterOption"
-            v-decorator="['saleId',]"
+            v-decorator="['saleId', { rules: [{ required: true, message: '请选择销售' }] }]"
           >
           <!--  { rules: [{  required: true,message: '请选择销售' }] } -->
             <a-select-option
               v-for="appModel in optionsElse"
               :key="appModel.userId + new Date().getTime()"
               :value="appModel.userId"
-            >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option>
+              >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option
+            >
           </a-select>
         </a-form-item>
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="运营负责人">
@@ -120,7 +138,8 @@
               v-for="appModel in options"
               :key="appModel.userId + new Date().getTime()"
               :value="appModel.userId"
-            >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option>
+              >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option
+            >
           </a-select>
         </a-form-item>
         <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="设计负责人">
@@ -137,7 +156,8 @@
               v-for="appModel in options"
               :key="appModel.userId + new Date().getTime()"
               :value="appModel.userId"
-            >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option>
+              >{{ appModel.realName }}&#12288;&#12288;{{ appModel.roleName }}</a-select-option
+            >
           </a-select>
         </a-form-item>
       </a-form>
@@ -198,6 +218,7 @@ export default {
       optionsElse: [],
       supplierList: [],
       editAll: false,
+      ocpxList: [],
     }
   },
   created() {
@@ -205,7 +226,7 @@ export default {
   },
   methods: {
     validateInputCode(rule, value, callback) {
-      if (!value || value > 0) {
+      if (value > 0) {
         callback()
       } else {
         callback('请输入大于0的最高报价!')
@@ -238,7 +259,7 @@ export default {
       params.pageSize = 1000
       params.pageNo = 1
       console.log(params)
-      getAction(this.url.getList,params)
+      getAction(this.url.getList, params)
         .then((res) => {
           if (res.success) {
             console.log(res)
@@ -269,6 +290,7 @@ export default {
     edit(record) {
       this.getSupplierList()
       this.getList()
+      this.getOcpxList()
       if (record.advertiserId) {
         this.editAll = true
         getAction('/ctop/product/list', { advertiserId: record.advertiserId, pageSize: 1000 }).then((res) => {
@@ -277,7 +299,18 @@ export default {
           }
         })
       }
-      var params = { ...record }
+
+      // var params = { ...record }
+      if (record.mediaId == '2' || record.mediaId == '4') {
+        console.log(record)
+        var params = { ...record }
+        params.bidType = record.bidType == null || record.bidType == '' ? [] : JSON.parse(record.bidType)
+        params.ocpxActionType =
+          record.ocpxActionType == null || record.ocpxActionType == '' ? [] : JSON.parse(record.ocpxActionType)
+      } else {
+        var { ocpxActionType, bidType, ...params } = record
+        this.showDian = false
+      }
 
       console.log(record)
       this.form.resetFields()
@@ -304,7 +337,8 @@ export default {
               'industryCode',
               'supplierCode',
               // 'advertiserType',
-              'saleId'
+              'saleId',
+              'bidType'
             )
           )
         } else {
@@ -323,7 +357,9 @@ export default {
               'industryCode',
               'supplierCode',
               // 'advertiserType',
-              'saleId'
+              'saleId',
+              'bidType',
+              'ocpxActionType'
             )
           )
         }
@@ -375,6 +411,10 @@ export default {
           formData.responsibleId = values.responsibleId
           formData.designResponsibleId = values.designResponsibleId
           formData.userId = formData.userId ? formData.userId : that.userInfo().id
+
+          formData.ocpxActionType =
+            formData.bidType == 2 ? JSON.stringify([0]) : JSON.stringify(formData.ocpxActionType)
+          formData.bidType = JSON.stringify(formData.bidType)
           httpAction(httpurl, formData, method)
             .then((res) => {
               if (res.success) {
@@ -401,6 +441,13 @@ export default {
       console.log(valueName, key)
       this.resId = key
     },
+    getOcpxList() {
+      this.getAction('/ocpx/kuaiShouOcpxActionTypeConfig/list').then((res) => {
+        if (res.success) {
+          this.ocpxList = res.result
+        }
+      })
+    },
   },
 }
 </script>

+ 1 - 0
src/views/modules/advertiser/modules/Treeselect.vue

@@ -8,6 +8,7 @@
     <treeselect
       :multiple="multiple"
       :disable-branch-nodes="!multiple"
+      :disable-fuzzy-matching="true"
       :options="options"
       :load-options="loadOptions"
       placeholder="请选择项目"

+ 12 - 3
src/views/modules/advertiser/modules/projectListModal.vue

@@ -95,6 +95,10 @@
               "
             >
               <a-select v-model="model.ocpxActionType" mode="multiple">
+
+
+
+                
                 <a-select-option :value="2">行为数</a-select-option>
                 <a-select-option :value="180">激活</a-select-option>
                 <a-select-option :value="53">表单提交</a-select-option>
@@ -107,7 +111,12 @@
                 <a-select-option :value="191">首日ROI</a-select-option>
                 <a-select-option :value="396">注册优化目标</a-select-option>
                 <a-select-option :value="717">广告观看事件</a-select-option>
-                <a-select-option :value="700">唤起应用</a-select-option>
+                <a-select-option :value="324">唤起应用</a-select-option>
+
+                 <a-select-option :value="715">微信复制优化目标</a-select-option>
+                 <a-select-option :value="716">多转化事件</a-select-option>
+                 <a-select-option :value="731">广告观看5次</a-select-option>
+                 <a-select-option :value="732">广告观看10次</a-select-option>
               </a-select>
             </a-form-item>
           </div>
@@ -330,8 +339,8 @@ export default {
       //       }
       if (record.mediaId == '2' || record.mediaId == '4') {
         var params = { ...record }
-        params.bidType = (record.bidType == null||record.bidType == '') ? [2] : JSON.parse(record.bidType)
-        params.ocpxActionType = (record.ocpxActionType == null||record.ocpxActionType == '') ? [2] : JSON.parse(record.ocpxActionType)
+        params.bidType = (record.bidType == null||record.bidType == '') ? [] : JSON.parse(record.bidType)
+        params.ocpxActionType = (record.ocpxActionType == null||record.ocpxActionType == '') ? [] : JSON.parse(record.ocpxActionType)
         this.showDian = true
       } else {
         var { ocpxActionType, bidType, ...params } = record

+ 647 - 0
src/views/modules/autoLaunch/appIdList.vue

@@ -0,0 +1,647 @@
+<template>
+    <div class="toutiaoBatch">
+        
+        
+        <div class="toolbox-automate-rules-create-content_title">
+            <h3>账户应用信息</h3>
+            <a-button type='primary' @click="goNewConfigInfo" class="goNewConfigInfo">添加应用</a-button>
+        </div>
+        
+        <div class="topOptions">
+            <div >
+                <Treeselect :appId.sync="accountId" :multiple="false"  request="2,4"   ref="treeSelect" style="margin-bottom:8px;width:600px " />               
+            </div>
+            <span class="optionBtn">
+                <a-button type='primary' @click="search" class="searchBtn">查询</a-button>
+            </span>
+        </div>
+        <div class="tableArea">
+            <!-- <div class="tableOption" v-if="selectedRowKeys.length">
+                
+                
+               :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
+            </div> -->
+            <div class="table">
+                <a-table
+                    :columns="columns"
+                    :data-source="data"
+                    bordered
+                    :pagination="ipagination"
+                    :loading="loading"
+                    @change="sort"
+                    :scroll="{'x':scrollX}"
+                    
+                >
+
+                    
+                    <span slot="authName" slot-scope="text">
+                        <!-- <a href="javascript:;" >{{text}}</a> -->
+                        {{text || '-'}}
+                    </span>
+                    <span slot="time" slot-scope="text,record">
+                        {{record.startTime}}至{{record.endTime}}
+                    </span>
+                    <span slot="status" slot-scope="text">
+                        {{text | handlerStatus}}
+                    </span>
+                    <span slot="operator" slot-scope="text,record">
+                        <a href="javascript:;"  @click="goPlanList(record)">编辑</a>
+                        <a-divider type="vertical" />
+                        <a href="javascript:;"  @click="deleteRecord(record)">删除</a>
+                        <a-divider type="vertical" />
+                        <a-popover v-model="record.show" trigger="click" placement="topRight" @visibleChange='visibleChange'>
+                            <div slot="content">
+                                    <span style='font-weight:700;margin-right:15px;font-size:15px'>修改后重提</span>
+                                    <a-radio-group v-model="examineAgainType" >
+                                        <a-radio :value="1">修改广告语</a-radio>
+                                        <a-radio :value="0">修改封面</a-radio>
+                                    </a-radio-group>
+                                    <a-button type='default' @click="examineAgainCancel(record)" size='small' style='margin-right:10px'>取消</a-button>
+                                    <a-button type='primary' @click="examineAgainOk(record)" size='small'  class="ok">重提</a-button>
+                            </div>
+                            <a href="javascript:;"  type='primary' @click="()=>{record.show=true}">一键重提</a>
+                            
+                        </a-popover>
+                        <a-divider type="vertical" />
+                        <a-popover v-model="record.visible" trigger="click" placement="topLeft" @visibleChange='visibleChange'>
+                            <span slot="title">出价</span>
+                            <template  slot="content" style="width:300px;">
+                                <div style="margin:5px 0 0">
+                                    <span ><a-input-number :min="0" v-model="newBid" :step="0.1" placeholder="请输入出价" size="small" style='margin-right:20px;width:120px' /></span>
+                                    <p style="color:red;font-size:12px;height:16px;padding:5px 0">{{bidErrorMessage}}</p>
+                                </div>
+                                
+                                <div>
+                                    <a-button type='default' @click="bidChangeCancel(record)" size='small' style='margin-right:10px'>取消</a-button>
+                                    <a-button type='primary' @click="bidChangeOk(record)" size='small' class="ok">修改</a-button>
+                                </div>
+                                
+                            </template>
+                            <a href="javascript:;"  type='primary' @click="()=>{record.visible=true}">修改出价</a>
+                        </a-popover>
+                    </span>
+
+                </a-table>
+            </div>
+        </div>
+        
+       
+              
+    <!-- </a-spin> -->
+    </div>
+</template>
+
+<script>
+import moment from 'moment';
+import { getAction, postAction, downFile, downFilePost,deleteAction } from '@/api/manage';
+// import { JeecgListMixin } from '@/mixins/ipagination'
+// import editableCell from './editableCell'
+import Treeselect from '@/views/modules/Statistics/components/Treeselect.vue'
+import qs from 'qs'
+let typeValue='预算'
+
+
+const strategyColumns = [
+  
+//   {
+//     title: 'ID',
+//     dataIndex: 'id',
+//     key: 'id',
+//     align: 'center',
+//     scopedSlots: { customRender: 'id' },
+//     width:110,
+    
+//   },
+//    {
+//     title: '所属账户名称',
+//     dataIndex: 'authName',
+//     key: 'authName',
+//     align: 'center',
+//     scopedSlots: { customRender: 'authName' }, 
+//     width:200  
+//   },
+  {
+    title: '所属账户ID',
+    dataIndex: 'accountId',
+    key: 'accountId',
+    align: 'center',
+    scopedSlots: { customRender: 'accountId' },   
+  },
+  
+  
+    {
+        title: '应用名称',
+        dataIndex: 'appName',
+        align: 'appName',    
+        scopedSlots: { customRender: 'appName' },
+        align: 'center',
+        // sorter:() => {}
+    },
+    {
+        title: '应用标识',
+        dataIndex: 'appVersion',
+        align: 'appVersion',    
+        scopedSlots: { customRender: 'appVersion' },
+        align: 'center',
+        // sorter:() => {}
+    },
+    {
+        title: '状态',
+        dataIndex: 'status',
+        align: 'status',    
+        scopedSlots: { customRender: 'status' },
+        align: 'center',
+        // sorter:() => {}
+    },
+    {
+        title: '备注',
+        dataIndex: 'remark',
+        align: 'remark',    
+        scopedSlots: { customRender: 'remark' },
+        align: 'center',
+        // sorter:() => {}
+    },
+    {
+        title: '创建时间',
+        dataIndex: 'createTime',
+        key: 'createTime',
+        align: 'center',
+        scopedSlots: { customRender: 'createTime' },
+            
+    },
+//  {
+//     title: '操作',
+//     dataIndex: 'operator',
+//     key: 'operator',
+//     align: 'center',
+//     scopedSlots: { customRender: 'operator' },
+//     width:350,
+   
+//   },
+
+];
+
+const publicColumns = [    
+    
+]
+
+export default {
+    name:'strategy-list',
+    components: {
+        // editableCell,
+        Treeselect,
+    },
+    // mixins: [JeecgListMixin],
+    data() {
+        return {
+            selectedRecord:{},
+            bidErrorMessage:'',
+            examineAgainType:1,
+            newBid:undefined,
+            examineAgain:false,
+            accountId:[],
+            accountList:[],
+            strategyState:undefined,
+            strategyName:'',
+            strategyId:undefined,
+            accountId:[],
+            scrollX:0,
+            ipagination: {
+                current: 1,
+                pageSize: 10,
+                //   pageSizeOptions: ['10', '20', '30'],
+                showTotal: (total, range) => {
+                    return range[0] + "-" + range[1] + " 共" + total + "条"
+                },
+                showQuickJumper: true,
+                showSizeChanger:true,
+                pageSizeOptions: ['10', '30', '50'],
+                total: 0,
+                onChange: (current, pageSize) => {
+                    // 切换分页时的回调,
+                    // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+                    this.ipagination.current = current;
+                    this.ipagination.pageSize= pageSize;
+                }
+            },
+           
+            spinning:false,
+            moment,
+           
+            optionId:'',//input输入的id或关键词
+          
+           
+            selectDisable:true,
+            optValue:undefined,//操作设置的值 删除 暂停 开启
+            visible: false,//出价里的弹出框
+
+            //主页的表格
+            data:[],
+            columns:[...strategyColumns,...publicColumns],
+            selectedRowKeys:[],
+            
+            loading:false,
+            editID:0,
+
+            url: {               
+                list:'/ai/aiKuaiShouAppInfo/pageList',
+                delete:'/ctop/aiKuaishouAdvertiserStrategy/delete',
+            },
+
+
+            
+        }
+    },
+    computed: {
+        hasSelected() {
+        return this.selectedRowKeys.length > 0;
+        },
+    },
+    methods: {
+        examineAgainMethod(record){
+            console.log(record)
+            this.examineAgain=true;
+            this.selectedRecord=record
+        },
+        visibleChange(){
+            this.bidErrorMessage='';
+            this.examineAgainType=1;
+            this.newBid=undefined;
+            
+        },
+        bidChangeCancel(record){
+            record.visible=false;
+            this.newBid=undefined;
+            this.bidErrorMessage=''
+        },
+        bidChangeOk(record){
+            if(this.newBid){
+                record.visible=false;
+                postAction('/ai/batchUpdate/updateGroupBid',{
+                    accountId:record.accountId,
+                    bid:this.newBid*1000
+                }).then(res=>{
+                    console.log(res)
+                    if(res.code==0){
+                        this.$message.success(res.message)
+                        this.newBid=undefined;
+                        this.getStrategyList()
+                    }
+                    
+                })
+            }else{
+                this.bidErrorMessage='请正确填写出价'
+                // this.$message.error('请正确填写出价')
+            }
+            
+        },
+
+        examineAgainCancel(record){
+            record.show=false;
+            this.examineAgainType=1
+        },
+        examineAgainOk(record){
+            record.show=false;
+            postAction('/kuaishou/creative/again',{
+                accountId:record.accountId,
+                updateType:this.examineAgainType
+            }).then(res=>{
+                console.log(res);
+                if(res.code==0){
+                    this.$message.success('正在重提中,您可稍后查看结果')
+                }else{
+                    this.$message.success(res.message)
+                }
+                this.examineAgainType=1
+            })
+            
+        },
+        onSelectChange(selectedRowKeys) {
+            console.log('selectedRowKeys changed: ', selectedRowKeys);
+            this.selectedRowKeys = selectedRowKeys;
+        },
+        goNewConfigInfo(){
+            this.$router.push('/autoLaunch/newAppId')
+        },
+        goPlanList(record){
+            console.log(record)
+            this.$parent.currentStrategyId=record.id;
+            this.$router.push(`/autoLaunch/configLaunchInfo?id=${record.id}`)
+        },
+        deleteRecord(record){
+            this.loading=true
+            deleteAction(this.url.delete,{
+                id:record.id
+            }).then(res=>{
+                this.loading=false
+                if(res.success){
+                    this.$message.success(res.message);
+                    this.getStrategyList()
+                }else{
+                    this.$message.success(res.message);
+                }
+            })
+        },
+        filterOption(input, option) {
+            return (
+                option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+            );
+        },
+        
+        //查询按钮事件
+        search(){
+            this.ipagination.current=1;
+            this.getStrategyList()            
+        },
+        //点击分页
+        sort(pagination, filters, sorter, { currentDataSource }){
+            console.log(pagination)
+            this.ipagination.current=pagination.current;
+
+            this.ipagination.pageSize=pagination.pageSize;
+            this.getStrategyList()
+        },
+
+        getStrategyList(){
+            this.loading = true
+            console.log(this.accountId)
+            getAction(this.url.list,{
+                strategyId:this.strategyId==undefined?null:this.strategyId,
+                accountId:this.accountId,
+                pageNo:this.ipagination.current,
+                pageSize:this.ipagination.pageSize
+            }).then((res)=>{
+                this.data=[]
+                console.log(res)
+                this.loading = false
+                if(res.success){
+
+                    this.ipagination.total = res.result.total
+                    
+                    res.result.records.forEach((item)=>{
+                        item.key=item.id;
+                        item.show=false;
+                        item.visible=false;
+                    })
+
+                    this.data = res.result.records;
+                    this.selectedRowKeys=[];
+                }
+            })
+        },
+      
+    },
+    mounted() {
+       
+        this.getStrategyList()
+    },
+    
+    activated() {
+        this.getStrategyList()
+    },
+    beforeDestroy() {
+
+    },
+    filters: {
+        toPercentage(val) {
+            if(val){
+                if(typeof val != 'string'){
+                    return (val * 100).toFixed(2) + '%'
+                }else{
+                    return val
+                }
+            }else if(typeof val =='string'){
+                    return val
+                }
+            else{
+                return 0
+            }
+        },
+        //保留两位小数并且变成货币格式
+        decimalsHandle(val){
+
+            if(val && typeof val !='string'){
+                if(val>=0){
+                    val=parseFloat(val).toFixed(2);
+                    let numberStr = val.toString()
+                    let str = numberStr.split('.')
+
+                    let str0=str[0].split('').reverse();
+                    for (let i = 0; i < str0.length; i++) {
+                        if ((i + 1) % 4 === 0) {
+                            str0.splice(i, 0, ',')
+                        }
+                    }
+                    str0.reverse()
+                    let handleResult = ''
+                    for (let j = 0; j < str0.length; j++) {
+                        handleResult += str0[j]
+                    }
+
+                    return handleResult+'.'+str[1]
+                }else{
+                    val=parseFloat(val).toFixed(2);
+                    let numberStr = val.toString()
+                    let str = numberStr.split('.')
+
+                    let str0=str[0].substr(1).split('').reverse();
+                    for (let i = 0; i < str0.length; i++) {
+                        if ((i + 1) % 4 === 0) {
+                            str0.splice(i, 0, ',')
+                        }
+                    }
+                    str0.reverse()
+                    let handleResult = ''
+                    for (let j = 0; j < str0.length; j++) {
+                        handleResult += str0[j]
+                    }
+
+                    return '-'+handleResult+'.'+str[1]
+                }
+
+            }else if(typeof val =='string'){
+                return val
+            }
+            else{
+                return 0
+            }
+        },
+        //变成货币格式
+        formatCurrency(val){
+            if((val||val==0)&& typeof val !='string'){
+                let numberStr = val.toString()
+                let str = numberStr.split('').reverse()
+                for (let i = 0; i < str.length; i++) {
+                    if ((i + 1) % 4 === 0) {
+                    str.splice(i, 0, ',')
+                    }
+                }
+                str.reverse()
+                let handleResult = ''
+                for (let j = 0; j < str.length; j++) {
+                    handleResult += str[j]
+                }
+                return handleResult
+            }else if(typeof val =='string'){
+                    return val
+            }
+            else{
+                return '-'
+            }
+
+        },
+        
+        handlerStatus(val){
+            let string='';
+            switch (val) {
+                case 0:
+                    string='待创建'
+                    break;
+                case 1:
+                    string='创建中'
+                    break;
+                case 2:
+                    string='创建成功'
+                    break;
+                case 3:
+                    string='创建失败'
+                    break;
+            
+                default:
+                    break;
+            }
+            return string
+        }
+    }
+}
+</script>
+<style lang="scss">
+    #closeIcon{
+         color: #0E74D2;
+    }
+    .toutiaoBatch{
+        .ant-tag .anticon-close {      
+            color: #1890ff;        
+        }
+        .ant-tag .anticon-close:hover{      
+            color: rgba(0, 0, 0, 0.85);    
+        }
+
+    }
+    
+    .ant-tooltip-inner,.ant-tooltip,.ant-tooltip-arrow::before{
+        background-color: #fff;
+        color: #333;
+    }
+    #batchModal{
+        .rules,.totalPrice{
+            font-weight: 600;
+        }
+
+        .selectePlan{
+            font-size: 14px;
+            font-weight: 700;
+            color: #333;
+            padding: 20px 0;
+        }
+        .totalPrice{
+            margin-left: 20px;
+        }
+        .modifyTable{
+            margin-top: 20px;
+            width: 100%;
+            height: 400px;
+            overflow: auto;
+            font-weight: 600;
+        }
+    }
+    #copyModal{
+        .ant-modal-header{
+            text-align: center;
+        }
+        .copyTip{
+            font-size: 12px;
+            color: #999;
+        }
+        .copyName{
+            width: 118px;
+            display: inline-block;
+            text-align: right;
+            .copyKeyStart{
+                color: red;
+            }
+        }
+        // font-weight: 600;
+    }
+</style>
+<style lang="scss" scoped>
+.toutiaoBatch{
+    .breadcrumb{
+            height: 22px;
+            font-size: 12px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #000000;
+            line-height: 22px;
+        }
+    background-color: #fff;
+    padding: 10px 20px;
+    position: relative;
+    width: 100%;
+    .OptinItem{
+        display: inline-block;
+        margin-right: 15px;
+        margin-top: 15px;
+        .ok{
+            margin-right: 15px;
+        }
+    }
+    .OptinItem:first-child{
+        margin-right: 10px;
+    }
+    .topOptions{
+        padding: 15px 0;
+        display: flex;
+        justify-content: space-between;
+        .topOpt{
+            width: 100%;
+            margin-bottom: 10px;
+        }
+    }
+    .optionBtn{
+        // display: inline-block;
+        float: right;
+        // .searchBtn{
+            // margin-right: 10px;
+        // }
+    }
+    .tableArea{
+        .tableOption{
+            padding: 20px 0;
+        }
+    }
+    .toolbox-automate-rules-create-content_title {
+        background-color: #fff;
+        display: flex;
+        flex-flow: row nowrap;
+        justify-content: flex-start;
+        align-items: center;
+        margin-bottom: 28px;
+        position: relative;
+        h3 {
+            font-size: 22px;
+            margin: 0;
+            font-weight: 400;
+            height: 30px;
+            line-height: 30px;
+        }
+        .goNewConfigInfo{
+            position: absolute;
+            right: 0;
+            top: 4px;
+        }
+    }
+
+}
+
+</style>

+ 47 - 0
src/views/modules/autoLaunch/autoLaunchList.vue

@@ -0,0 +1,47 @@
+<template>
+
+        <component v-bind:is="currentTabComponent">
+
+        </component>
+    
+    
+</template>
+
+<script>
+import moment from 'moment';
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
+export default {
+    name:'index',
+    data() {
+        return {
+            currentTabComponent:'strategyList',
+            currentStrategyId:'',
+            currentPlanId:'',
+            currentGroupId:'',
+            userId:'',
+            currentStrateg:{},
+        }
+    },
+    components:{   
+        strategyList: () => import('./strategyList'), 
+        planList: () => import('./planList'), 
+        groupList: () => import('./groupList'), 
+        previewStrategy: () => import('./previewStrategy'), 
+        
+    },
+
+    mounted(){
+       this.currentTabComponent='strategyList' 
+        let userInfo=localStorage.getItem('pro__Login_Userinfo');
+        let userId=''
+        if(userInfo){
+            this.userId=JSON.parse(userInfo).value.id
+        }
+    },
+    beforeDestroy() {
+        this.currentTabComponent='strategyList' 
+    },
+   
+}
+
+</script>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2155 - 0
src/views/modules/autoLaunch/autoLaunchReport.vue


+ 124 - 0
src/views/modules/autoLaunch/autoReportIndex.vue

@@ -0,0 +1,124 @@
+<template>
+<div class="autoLaunch">
+    <div class="card-container">
+        <a-tabs type="card" v-model="analaysisDirection" @change="analaysisDirectionChange" :animated='true'>
+            <a-tab-pane key="1" tab="素材+出价"></a-tab-pane>
+            <a-tab-pane key="2" tab="素材+定向"></a-tab-pane>
+            <a-tab-pane key="3" tab="时间+出价"></a-tab-pane>
+            <!-- <a-tab-pane key="3" tab="">
+            </a-tab-pane> -->
+        </a-tabs>
+        <component v-bind:is="currentTabComponent">
+        </component>
+     </div>
+</div>
+
+    
+        
+    
+    
+</template>
+
+<script>
+import moment from 'moment';
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
+export default {
+    name:'index',
+    data() {
+        return {
+            currentTabComponent:'materialAndOrient',
+            analaysisDirection:'1',
+            currentStrategy:{}
+        }
+    },
+    components:{   
+        materialAndOrient: () => import('./autoLaunchReport'), 
+        materialAndBid: () => import('./materialAndBid'), 
+        
+    },
+    methods: {
+        analaysisDirectionChange(key){
+            // console.log(key)
+            // if(key=='1'){
+            //     this.currentTabComponent='materialAndOrient' 
+            // }else if(key=='2'){
+            //     this.currentTabComponent='materialAndBid' 
+            // }
+        }
+    },
+    watch:{
+        analaysisDirection(key,oldkey){
+            console.log(key)
+            if(key=='1'){
+                this.currentTabComponent='materialAndOrient' 
+            }else if(key=='2'){
+                this.currentTabComponent='materialAndBid' 
+            }
+        }
+    },
+    mounted(){
+       this.currentTabComponent='materialAndOrient' ;
+       let currentStrategy=localStorage.getItem('currentStrategy');
+        if(currentStrategy){
+            this.currentStrategy=JSON.parse(currentStrategy);
+            this.analaysisDirection=this.currentStrategy.scenes;
+            // this.analaysisDirectionChange(this.currentStrategy.scenes)
+        }
+    },
+    beforeDestroy() {
+        this.currentTabComponent='materialAndOrient' ;
+        localStorage.setItem('currentStrategy','');
+    },
+   
+}
+
+</script>
+
+<style lang="less">
+.autoLaunch{
+    
+    .card-container {
+        background: #f5f5f5;
+        // overflow: hidden;
+        // padding: 24px;
+        .ant-tabs-nav .ant-tabs-tab {
+            position: relative;
+            display: inline-block;
+            -webkit-box-sizing: border-box;
+            box-sizing: border-box;
+            height: 100%;
+            margin: 0 ;
+            padding: 0px 16px 8px;
+            text-decoration: none;
+            cursor: pointer;
+            -webkit-transition: color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+            transition: color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+            font-size: 16px;
+        }
+    }
+    .card-container > .ant-tabs-card > .ant-tabs-content {
+        // height: 120px;
+        margin-top: -16px;
+    }
+
+    .card-container > .ant-tabs-card > .ant-tabs-content > .ant-tabs-tabpane {
+        background: #fff;
+        // padding: 16px;
+    }
+
+    .card-container > .ant-tabs-card > .ant-tabs-bar {
+        border-color: #fff;
+    }
+
+    .card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab {
+        border-color: transparent;
+        background: transparent !important;
+    }
+
+    .card-container > .ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
+        border-color: #fff;
+        background: #fff !important;
+    }
+}
+
+</style>

+ 3 - 5
src/views/modules/autoLaunch/components/MultiCheckBox.vue

@@ -116,7 +116,7 @@ import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
               currentList:this.curLayerNum>1? this.listArr : []
             })
           },
-            deep: true
+          deep: true
       },
 
       parentChecked: {
@@ -204,7 +204,7 @@ import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
             value:'all',
             checked:e.target.checked,
             indeterminates:false,
-            parentCode:this.listArr[0].parentCode
+            parent:this.listArr[0].parent
         })
       },
       
@@ -224,13 +224,11 @@ import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
     },
     mounted() {
       this.currentLayerNum = this.curLayerNum
-
       this.listArr.forEach(element => {
         this.plainOptions.push(element.value)
         // console.log(this.plainOptions)
       })
- 
-    
+
        console.log('zhixingle yici')
       if (this.$refs.checkList) {
         let refsCheckListArr = Array.from(this.$refs.checkList)

+ 249 - 0
src/views/modules/autoLaunch/components/Treeselect.vue

@@ -0,0 +1,249 @@
+<style lang="scss" scoped>
+.select-project {
+  width: 50%;
+}
+</style>
+<template>
+  <div class="select-project">
+    <treeselect
+      :multiple="multiple"
+      :disable-branch-nodes="!multiple"
+      :disable-fuzzy-matching="true"
+      :options="options"
+      :load-options="loadOptions"
+      placeholder="请选择项目以及账户"
+      v-model="value"
+      :value-consists-of="valueConsistsOf"
+      :auto-load-root-options="false"
+      @select="update"
+      @input="emitValue"
+      :limit="2"
+      :default-options="true"
+      :limitText="
+        count => {
+          return '隐藏' + count + '条'
+        }
+      "
+      noChildrenText="该项目下暂无账号"
+      :noOptionsText="showLoading"
+    />
+  </div>
+</template>
+
+<script>
+//   @open="getParticipateList"
+// import the component
+import Treeselect from '@riophae/vue-treeselect'
+// import the styles
+import '@riophae/vue-treeselect/dist/vue-treeselect.css'
+import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
+
+import { getAction, postAction } from '@/api/manage'
+import { mapGetters } from 'vuex'
+// We just use `setTimeout()` here to simulate an async operation
+// instead of requesting a real API server for demo purpose.
+let called = false
+export default {
+  data: () => ({
+    value: null,
+    valueConsistsOf: 'LEAF_PRIORITY',
+    options: [],
+    showLoading: 'loading...',
+  }),
+  props: {
+    //是否多选
+    multiple: {
+      type: Boolean,
+      default() {
+        return true
+      },
+    },
+    appId: {
+      
+      default() {
+        return ''
+      },
+    },
+    //判断媒体类型
+    request: {
+      type: String,
+      default() {
+        return '2,4'
+      },
+    },
+    //一级请求接口
+    reqUrl: {
+      type: String,
+      default() {
+        return '/ctop/projectMember/participateListByMediaId'
+      },
+    },
+  },
+  components: {
+    Treeselect,
+  },
+  watch: {
+    $route(n, o) {},
+      appId: {
+        handler(n, o) {
+          console.log(n)
+          if (n.length == 0) {
+            if (this.multiple) {
+              this.value = []
+            } else {
+              this.value = undefined
+            }
+          }else{
+            this.value=this.appId
+          }
+        },
+        deep: true
+      }
+  },
+  methods: {
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    update(node, id) {
+      // console.log(node)
+      // getAction('/ctop/userAllocation/getAccountListByProjectId', {
+      //   projectId: node.id,
+      // }).then((res) => {
+      //   // console.log(res)
+      //   if (res.code == 0) {
+      //     if (res.result.length > 0) {
+      //       node.children = res.result.map((item) => {
+      //         return {
+      //           id: item.accountId,
+      //           label: item.userName + '         ' + item.authName,
+      //         }
+      //       })
+      //     } else {
+      //     }
+      //   } else {
+      //     new Error('Failed to load options: network error.')
+      //   }
+      // })
+    },
+    emitValue() {
+      this.$emit('update:appId', this.value)
+    },
+    loadOptions({ action, parentNode, callback }) {
+      // Typically, do the AJAX stuff here.
+      // Once the server has responded,
+      // assign children options to the parent node & call the callback.
+      if (action === LOAD_CHILDREN_OPTIONS) {
+        // getAction('/ctop/userAllocation/getAccountListByProjectId', {
+        //   projectId: parentNode.id,
+        // }).then((res) => {
+        //   if (res.code == 0) {
+        //     if (res.result.length > 0) {
+        //       parentNode.children = res.result.map((item) => {
+        //         return {
+        //           id: item.accountId,
+        //           label: item.userName + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' + item.authName,
+        //         }
+        //       })
+        //       callback()
+        //     } else {
+        //       parentNode.children = []
+        //       callback()
+        //     }
+        //   } else {
+        //     callback(new Error('Failed to load options: network error.'))
+        //   }
+        // })
+      }
+    },
+    getParticipateList() {
+      //我参与的
+      //   toutiaoParticipateList
+      var params = {}
+      params.userId = this.userInfo().id
+
+      if (this.request == '1,3') {
+        params.type = 'bytedance'
+      } else if (this.request == '2,4') {
+        params.type = 'kuaishou'
+      }
+
+      if (this.reqUrl == '/ctop/projectMember/participateListByMediaId') {
+        postAction(this.reqUrl, params).then((res) => {
+          if (res.success) {
+            this.options = res.result.map((item) => {
+              return {
+                id: item.projectId + 'projectId',
+                label: item.projectName + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' + item.advertiserName,
+                children: item.accountList
+                  ? item.accountList.map((i) => {
+                      return {
+                        id: i.accountId,
+                        label:
+                          (i.userName.length==2?i.userName+'\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0':i.userName.length==3?i.userName+'\xa0\xa0\xa0\xa0':i.userName) +
+                          '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' +
+                          i.accountId +
+                          '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' +
+                          i.authName,
+                      }
+                    })
+                  : [],
+              }
+            })
+          }
+        })
+      } else if(this.reqUrl == '/ctop/userAllocation/getAccountIdsByUserId'){
+          getAction(this.reqUrl, {
+            userId: this.userInfo().id,
+          }).then((res) => {
+            if (res.success) {
+              if (res.result.length > 0) {
+                res.result.forEach((element,index) => {
+                  if(element){                  
+                      this.options.push({});                    
+                    
+                        this.options.label=element.auth_name+'_('+element.project_name+')'
+                        this.options.id=element.account_id;
+                        this.options.key=element.account_id;                  
+                  }      
+                });
+              } else {
+                this.showLoading = '暂无数据'
+              }
+            }
+          })
+      }else {
+        getAction(this.reqUrl, {
+          userId: this.userInfo().id,
+        }).then((res) => {
+          if (res.code == 0) {
+            if (res.result.length > 0) {
+              var arr = this.request.split(',')
+              var dataTwo = []
+              var data = res.result.filter((item) => {
+                return item.mediaId == arr[0]
+              })
+              if (arr.length > 1) {
+                dataTwo = res.result.filter((item) => {
+                  return item.mediaId == arr[1]
+                })
+              }
+              var allData = data.concat(dataTwo)
+              this.options = allData.map((item) => {
+                return {
+                  id: item.projectId,
+                  label: item.projectName + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' + item.advertiserName,
+                  children: null,
+                }
+              })
+            } else {
+              this.showLoading = '暂无数据'
+            }
+          }
+        })
+      }
+    },
+  },
+
+  mounted() {
+    this.getParticipateList()
+  },
+}
+</script>

+ 107 - 66
src/views/modules/autoLaunch/components/linkMultiSelect.vue

@@ -73,27 +73,28 @@
           
           let childrensArr = Array.from(this.$refs.mycheckBox.children)
           setTimeout(() => {
-            // console.log(val, index)
+            console.log(val, index)
             // console.log(val.data.checked)
             if (index == 1 || this.clickKey == 1) {
                 this.$refs.mycheckBox.style.width = '100%'
-                if(val.data.hasChild){
+                if(val.data.code&&this.maxLayers>index){
                     getAction(this.listUrl,{
-                        parentCode:val.data.code,
-                        level:this.maxLayers
+                        parent:val.data.code,
+                        // level:2
                     }).then((res)=>{
                         // console.log(res);
                         if(res.success){
-                            if(res.data.length>0){
-                                res.data.forEach((item,index)=>{
+                            if(res.result.length>0){
+                                res.result.forEach((item,index)=>{
                                     
-                                    item.value=item.code
+                                    item.value=item.regionId
+                                    item.code=item.regionId
                                     item.checked=val.data.checked;
                                     item.indeterminates=false;
                                 })
                                 // console.log(this.checkedShowList)
                                 this.checkedShowList.forEach((ele)=>{
-                                  res.data.forEach((item)=>{
+                                  res.result.forEach((item)=>{
                                       if(ele.code==item.code){
                                             item.checked=true;
                                             return
@@ -110,40 +111,50 @@
                                 this.parentChecked1 = val.data.checked
                                 this.parentChecked2 = val.data.checked
                                 this.parentChecked3 = val.data.checked
-                                this.listArr2=res.data
+                                this.listArr2=res.result
                                 this.title2 = val.data.name
-                            }                    
+                            }else{
+                                this.listArr3 = []
+                                this.title3 = ''
+                                this.listArr4 = []
+                                this.title4 = ''
+                                this.listArr2 = []
+                                this.title2 = ''
+                                this.resetStyle(childrensArr, index)
+                            }                      
                         };
                         
                     })  
-                }else{
-                    this.listArr3 = []
-                    this.title3 = ''
-                    this.listArr4 = []
-                    this.title4 = ''
-                    this.listArr2 = []
-                    this.title2 = ''
-                    this.resetStyle(childrensArr, index)
-                }  
                 
+                }
+                if(val.data.value=='all'){
+                  this.listArr3 = []
+                  this.title3 = ''
+                  this.listArr4 = []
+                  this.title4 = ''
+                  this.listArr2 = []
+                  this.title2 = ''
+                  this.resetStyle(childrensArr, index)
+                }
                 //  this.checkedShowList=val.checkList     
             } else if (index == 2 || this.clickKey == 2) {
-                if(val.data.hasChild){
+                if(val.data.code&&this.maxLayers>index){
                     getAction(this.listUrl,{
-                        parentCode:val.data.code,
-                        level:this.maxLayers
+                        parent:val.data.code,
+                      //  level:3
                     }).then((res)=>{
                         // console.log(res);
                         if(res.success){
-                            if(res.data.length>0){
-                                res.data.forEach((item,index)=>{
-                                    item.value=item.code
+                            if(res.result.length>0){
+                                res.result.forEach((item,index)=>{
+                                    item.value=item.regionId
+                                    item.code=item.regionId
                                     item.checked=val.data.checked;
                                     item.indeterminates=false;
                                 
                                 })
                                 this.checkedShowList.forEach((ele)=>{
-                                  res.data.forEach((item)=>{
+                                  res.result.forEach((item)=>{
                                       if(ele.code==item.code){
                                             item.checked=true;
                                         }
@@ -157,25 +168,33 @@
                                 this.styleHandle(childrensArr, index)
                                 this.parentChecked2 = val.data.checked
                                 this.parentChecked3 = val.data.checked
-                                this.listArr3=res.data
+                                this.listArr3=res.result
                                 this.title3 = val.data.name
+                            }else{
+                              this.listArr4 = []
+                              this.title4 = ''
+                              this.listArr3 = []
+                              this.title3 = ''
+                              this.$refs.mycheckBox.style.width = '100%'
+                              this.resetStyle(childrensArr, index)
                             }                    
                         };
                         
                     })
-                }else{
+                }
+                if(val.data.value=='all'){
                     this.listArr4 = []
                     this.title4 = ''
                     this.listArr3 = []
                     this.title3 = ''
                     this.$refs.mycheckBox.style.width = '100%'
                     this.resetStyle(childrensArr, index)
-                }  
-                 
+                }
+               
               
                 let ind=-1
                 this.listArr1.forEach((ele,i)=>{                       
-                    if(ele.code==val.data.parentCode){
+                    if(ele.code==val.data.parent){
                         ind=i
                         // console.log(ind)
                     }                        
@@ -187,48 +206,53 @@
                 
             } else if (index == 3 || this.clickKey == 3) {
 
-                if(val.data.hasChild){
+                if(val.data.code&&this.maxLayers>index){
                     getAction(this.listUrl,{
-                        parentCode:val.data.code,
-                        level:this.maxLayers
+                        parent:val.data.code,
+                        // level:4
                     }).then((res)=>{
                         // console.log(res);
                         if(res.success){
-                            if(res.data.length>0){
-                                res.data.forEach((item,index)=>{
-                                    item.value=item.code
+                            if(res.result.length>0){
+                                res.result.forEach((item,index)=>{
+                                    item.value=item.regionId
+                                    item.code=item.regionId
                                     item.checked=val.data.checked;
                                     item.indeterminates=false;
                                 
                                 })
                                 this.checkedShowList.forEach((ele)=>{
-                                  res.data.forEach((item)=>{
+                                  res.result.forEach((item)=>{
                                       if(ele.code==item.code){
                                             item.checked=true;
                                         }
                                   })
                                         
                                 })
-                                this.listArr4 = res.data
+                                this.listArr4 = res.result
                                 this.title4 = val.data.name
                                 this.$refs.mycheckBox.style.width = '200%'
                                 this.styleHandle(childrensArr, index)
                                 this.parentChecked3 = val.data.checked
                                 
+                            }else{
+                              this.$refs.mycheckBox.style.width = '150%'
+                              this.resetStyle(childrensArr, index)
                             }                    
                         };
                         
                     })
-                }else{
+                 }
+                 if(val.data.value=='all'){
                     this.$refs.mycheckBox.style.width = '150%'
                     this.resetStyle(childrensArr, index)
-                }  
-
+                }
+               
                 let ind=-1;
                 if(this.listArr2){
                     // console.log(this.listArr2)                                      
                     this.listArr2.forEach((ele,i)=>{                       
-                      if(ele.code==val.data.parentCode){
+                      if(ele.code==val.data.parent){
                           ind=i
                           // console.log(ind)
                       }                                           
@@ -240,7 +264,7 @@
                 }
                      let z=-1          
                     this.listArr1.forEach((element,num)=>{                        
-                      if(element.code==this.listArr2[ind].parentCode){
+                      if(element.code==this.listArr2[ind].parent){
                           z=num
                           // console.log(ind)
                       }
@@ -260,7 +284,7 @@
                     let ind=-1
                     this.listArr3.forEach((ele,i)=>{
                         
-                        if(item.code==val.data.parentCode){
+                        if(item.code==val.data.parent){
                             ind=i
                             // console.log(ind)
                         }
@@ -277,14 +301,14 @@
                     let ind=-1
                     this.listArr3.forEach((ele,i)=>{
                         
-                        if(item.code==val.data.parentCode){
+                        if(item.code==val.data.parent){
                             ind=i
                             // console.log(ind)
                         }
                                             
                     })   
                     this.listArr2.forEach((element,num)=>{
-                        if(item.code==this.listArr3[ind].parentCode){
+                        if(item.code==this.listArr3[ind].parent){
                             ind=num
                             // console.log(ind)
                         }                        
@@ -301,7 +325,7 @@
                         let z=-1;
                         this.listArr1.forEach((element,num)=>{
                             
-                            if(item.code==this.listArr2[ind].parentCode){
+                            if(item.code==this.listArr2[ind].parent){
                                 z=num
                                 // console.log(z)
                             }
@@ -320,7 +344,7 @@
              
             }
           }, 100)
-          this.$emit('getSelectedArr',val.checkList)
+          // this.$emit('getSelectedArr',val.checkList)
 
         })
       },
@@ -367,13 +391,13 @@
           if(item.level==2){
               // console.log('------------------------------------');
               let childList=this.checkedShowList.filter((element,index) => {
-                  return element.parentCode==item.parentCode;
+                  return element.parent==item.parent;
               });
               let data=[]
               let checkList=[];
               let plainOptions=[]
               this.listArr1.forEach((ele)=>{
-                  if(ele.code==item.parentCode){
+                  if(ele.code==item.parent){
                       data=ele;
                   }
                   if(ele.checked){
@@ -473,12 +497,12 @@
           
         }else if(val.curLayerNum==2){
           this.checkedShowList=this.checkedShowList.filter((item)=>{
-              return item.code!=val.currentList[0].parentCode
+              return item.code!=val.currentList[0].parent
           })
           
           if(val.checkList.length>0&&val.checkList.length<val.currentList.length){
             this.checkedShowList=this.checkedShowList.filter((item)=>{
-              return item.parentCode!=val.currentList[0].parentCode
+              return item.parent!=val.currentList[0].parent
             })
             // console.log(this.checkedShowList)
             val.checkList.forEach((ele)=>{
@@ -499,27 +523,27 @@
             // console.log(this.checkedShowList)
           }else if(val.checkList.length==0){
             this.checkedShowList=this.checkedShowList.filter((item)=>{
-              return item.parentCode!=val.currentList[0].parentCode
+              return item.parent!=val.currentList[0].parent
 
             })
           }else if(val.checkList.length==val.currentList.length){
             this.checkedShowList=this.checkedShowList.filter((item)=>{
-              return item.parentCode!=val.currentList[0].parentCode
+              return item.parent!=val.currentList[0].parent
             })
             this.listArr1.forEach((item)=>{
-                if(item.code==val.currentList[0].parentCode){
+                if(item.code==val.currentList[0].parent){
                     this.checkedShowList.push(item)
                 }
             })
           }
         }else if(val.curLayerNum==3){
           this.checkedShowList=this.checkedShowList.filter((item)=>{
-              return item.code!=val.currentList[0].parentCode
+              return item.code!=val.currentList[0].parent
           })
           
           if(val.checkList.length>0&&val.checkList.length<val.currentList.length){
             this.checkedShowList=this.checkedShowList.filter((item)=>{
-              return item.parentCode!=val.currentList[0].parentCode
+              return item.parent!=val.currentList[0].parent
             })
             // console.log(this.checkedShowList)
             val.checkList.forEach((ele)=>{
@@ -540,15 +564,15 @@
             // console.log(this.checkedShowList)
           }else if(val.checkList.length==0){
             this.checkedShowList=this.checkedShowList.filter((item)=>{
-              return item.parentCode!=val.currentList[0].parentCode
+              return item.parent!=val.currentList[0].parent
               
             })
           }else if(val.checkList.length==val.currentList.length){
             this.checkedShowList=this.checkedShowList.filter((item)=>{
-              return item.parentCode!=val.currentList[0].parentCode
+              return item.parent!=val.currentList[0].parent
             })
             this.listArr2.forEach((item)=>{
-                if(item.code==val.currentList[0].parentCode){
+                if(item.code==val.currentList[0].parent){
                     this.checkedShowList.push(item)
                 }
             })
@@ -556,6 +580,14 @@
         }else if(val.curLayerNum==4){
 
         }
+
+
+        let dataArr=[];
+        this.checkedShowList.forEach(item=>{
+          dataArr.push(item.code)
+        })
+        this.$emit('getSelectedArr',dataArr)
+
       },
 
 
@@ -564,21 +596,30 @@
         // this.listArr1=this.listArr;
         this.title1=this.title;
         // console.log(this.listUrl)
+        console.log(this.listArr,'----------------')
         if(this.listUrl){
             getAction(this.listUrl,{
-                parentCode:0,
-                level:this.maxLayers
+                parent:0,
+                level:1
             }).then((res)=>{
                 console.log(res);
                 if(res.success){
-                    res.data.forEach((item,index)=>{
-                        item.value=item.code
+                    res.result.forEach((item,index)=>{
+                        item.value=item.regionId
+                        item.code=item.regionId
                         item.checked=false;
                         item.indeterminates=false;
                         
                     })
                 };
-                this.listArr1=res.data
+                this.listArr1=res.result;
+                this.listArr.forEach(item=>{
+                  this.listArr1.forEach(ele=>{
+                    if(ele.value==item){
+                      ele.checked=true
+                    } 
+                  })
+                })
             })
         }
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1045 - 0
src/views/modules/autoLaunch/components/materialList.vue


+ 712 - 0
src/views/modules/autoLaunch/components/platForm.vue

@@ -0,0 +1,712 @@
+<template>
+    <div class="workBench">
+        <div class="topBody">
+            <p class="breadcrumb">工作台</p>
+            <div class="bottom">
+                <div class="touxiang">
+                    <img src="@/assets/touxiang.png"  alt="">
+                </div>  
+                <div class='tip'>
+                    <p class="greet">{{getTimeState()}},{{roleInfo.realname}},祝你开心每一天!</p>
+                    <p class="descPosition">
+                        <span>{{roleInfo.roleName}}</span>
+                        <a-divider type="vertical" />
+                        <span>{{roleInfo.area}}地区-{{roleInfo.departName}}</span>
+                    </p>
+                </div>
+                <a-button type='primary' class="mybtn" @click="sendOrder">
+                    <a-icon type="plus" />
+                    发起订单
+                </a-button>
+            </div>
+        </div>
+        <div class="section">
+            <div class="sectionBody">
+                <div class="sectionLeftBox">
+                    <div class="leftTop">
+                        <div class="sectionHead">
+                            我的工作内容
+                        </div>
+                        <div class="zhanshiBox">
+                           
+                            <div class="item" @click="goOrderList(1)">                               
+                                <div class="title">
+                                    <img src="@/assets/work.png" alt="" class="iconImg">
+                                    <span>我发起的订单</span>
+                                </div>
+                                <div class="itemBody">
+                                    <p class="count">{{countInfo.newOrder || 0}} <span>个</span></p>
+                                </div>
+                            </div>
+                            <div class="item" @click="goMaterialList(1)">                                
+                                <div class="title">
+                                    <img src="@/assets/work.png" alt="" class="iconImg">
+                                    <span>待审核的物料</span>
+                                </div>
+                                <div class="itemBody">
+                                    <p class="count">{{countInfo.toAuditMaterial || 0}}<span>个</span></p>
+                                </div>                              
+                            </div>
+                           
+                            <div class="item" @click="goOrderList(2)">                               
+                                <div class="title">                                   
+                                    <img src="@/assets/work.png" alt="" class="iconImg">
+                                    <span>已完成的订单</span>
+                                </div>
+                                <div class="itemBody">
+                                    <p class="count">{{countInfo.finishOrder ||0}}<span>个</span></p>
+                                </div>
+                            </div>
+                            <div class="item" @click="goOrderList(3)">                                
+                                <div class="title">                                   
+                                    <img src="@/assets/work.png" alt="" class="iconImg">
+                                    <span>被驳回的订单</span>
+                                </div>
+                                <div class="itemBody">
+                                    <p class="count">{{countInfo.rejectOrder || 0}} <span>个</span></p>
+                                </div>
+                            </div>
+                            <!-- <div class="item" @click="goOrderList(4)">                                
+                                <div class="title">
+                                    <img src="@/assets/work.png" alt="" class="iconImg">
+                                    <span>全部订单</span>
+                                </div>
+                                <div class="itemBody">
+                                    <p class="count">{{countInfo.allOrder}}<span>个</span></p>
+                                </div>                                
+                            </div> -->
+                        </div>  
+                    </div>
+                    <div class="leftBottom">
+                        <div class="sectionHead">
+                            订单进度
+                             <!-- <a-button type="link" class="allOrder" @click="goOrderList(1)">全部订单</a-button> -->
+                        </div>
+                        <a-spin :spinning="orderProgressSpinning">
+                        <div class="orderProgress">
+                            
+                            <ul class="orderProgress-list" v-if="orderProgressList.length>0">
+                                <li v-for="(item,index) in orderProgressList" :key="index"  >
+                                    <!-- <span  style="display:block;width:100%"> -->
+                                    <div style="display:flex;align-items: center;" class="orderProgress-list-item" @click="orderDetail(item)">
+                                        <div style="display:flex;width:80%; align-items: center;" >
+                                            <span class="item-icon"></span>
+                                            <div class="content">
+                                                <p class="name">{{item.orderTitle}}</p>
+                                                <p class="desc">{{item.orderRemark}}</p>
+                                            </div>
+                                        </div>
+                                        
+                                        <div class="progress" v-if="item.orderStatus==1||item.orderStatus==3">
+                                            <a-progress type="circle" :percent="(item.materialFinishAmount/item.materialAmount)*100" :width='30' :showInfo='false'  :strokeWidth='10' />
+                                            <span style="margin-left:15px">{{(item.materialFinishAmount/item.materialAmount)*100}}%</span>
+                                        </div>
+                                        <div class="progress" v-else>
+                                            {{item.orderStatus|handleOrderStatus}}
+                                        </div>
+                                    </div>
+                                    <!-- </span> -->
+                                </li>
+                            </ul>
+                            <div   v-else style="width:100%;height:585px;line-height:585px;text-align:center">
+                               
+                                <img src="@/assets/nodata.png" alt="" style="width:300px;text-align:center">
+                            </div>
+                            <!-- hideOnSinglePage -->
+                            <a-pagination size="small" :total="totalPage" :current='currentPage' :pageSize='8' class="fenye" @change='pageChange'  show-quick-jumper  />
+                            
+                        </div>
+                        </a-spin>
+                    </div>
+                </div>
+                <div class="sectionRightBox">
+                    <div class="rightTop">
+                        <div class="sectionHead">
+                            操作记录
+                        </div>
+                        <a-spin :spinning="spinning">
+                        <div class="optionRecordList">
+                            
+                            <a-timeline >
+                                <a-timeline-item color='#F0F2F5' style="height:46px" v-for="(item,index) in operateRecordList" :key="index">
+                                <p style="margin-bottom:0px">
+                                    <span class="content-item">{{item.userName}}{{item.operate}}{{item.materialName||item.orderTitle}}</span> 
+                                    <span class="time">{{item.time}}</span>
+                                </p>
+                                </a-timeline-item>
+                                
+                            </a-timeline>
+
+                           
+                            
+                        </div>
+                        </a-spin>
+                    </div>
+                    <!-- <div class="rightBottom">
+                        <div class="sectionHead">
+                            本周项目燃尽图
+                        </div>
+                        <div class="burnDown">
+                             <a-progress type="circle" :percent="75"  :width='150' :strokeWidth='6' />
+                             <div class="tip">
+                                <p class="done">
+                                    <span class="item-icon"></span>
+                                    <span>已完成订单:{{}}个</span>
+                                </p>
+                                <p class="all">
+                                    <span class="item-icon"></span>
+                                    <span>未完成订单:{{}}个</span>
+                                </p>
+                             </div>
+                        </div>
+                    </div> -->
+
+                </div>
+                
+            </div>
+        </div>
+    </div>
+</template>
+
+<script>
+import moment from 'moment';
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
+
+export default {
+    name:'operator-platform',
+    data() {
+        return {
+            moment,
+            roleInfo:{},
+            todayGreet:moment(),
+            orderProgressSpinning:false,
+            countInfo:{},
+
+            spinning:false,
+            touxiang:'@/assets/touxiang.png',
+            // 订单进度
+            orderProgressList:[
+                
+            ],
+
+            // 操作记录
+            optionRecord:[],
+
+            // 本周项目燃尽图
+            burnDownChart:[],
+
+            // 分页参数
+            totalPage:0,
+            currentPage:1,
+
+            userInfo:{},
+            roleCode:'',
+
+            operateRecordList:[],
+
+            TimerObj:null,
+        }
+    },
+    methods: {
+        goOrderList(val){
+            console.log(val);
+            // console.log(this.$parent)
+            this.$parent.currentTabComponent='orderList';
+            this.$parent.orderStatus=val
+            
+        },
+        goMaterialList(val){
+            this.$parent.currentTabComponent='materialList';
+            this.$parent.materialStatus=val
+        },
+        orderDetail(item){
+            console.log(item)
+            this.$parent.currentTabComponent='orderDetail';
+            this.$parent.orderId=item.id
+        },
+        // 分页页码改变
+        pageChange(page, pageSize){
+            this.currentPage=page;
+            // console.log(page,pageSize)
+            this.getOrderList()
+        },
+        
+        // 发起订单
+        sendOrder(){
+            this.$parent.currentTabComponent='placeOrder';
+            
+        },
+        // 获取订单列表
+        getOrderList(){
+          
+            let params={
+                createBy:this.userInfo.id,
+                pageNo:this.currentPage,
+                pageSize:8,
+            }
+            this.orderProgressSpinning=true;
+            getAction('/platform/order/listByCreatorOrDesignLeader',params).then(res=>{
+                console.log(res);
+                this.loading=false;
+                this.orderProgressSpinning=false;
+                if(res.success){
+
+                    this.orderProgressList=res.result.list;
+                    this.totalPage=res.result.total;
+
+                }
+            })
+        },
+
+        // 操作记录
+        getOperationRecord(){
+            this.spinning=true;
+            getAction('/platform/operateRecord/createDesc').then(res=>{
+                console.log(res)
+                this.spinning=false;
+                if(res.success){
+                    this.operateRecordList=res.result.list.map((item,index)=>{
+                       
+                            let time='';
+                            let startTime=moment(item.createTime)
+                            console.log(startTime) 
+                            if(moment().diff(startTime,'hours')>24){
+                                time=item.createTime.split(/[ ]+/)[0]
+                                return {
+                                    ...item,
+                                    time,
+                                }
+                            }
+                            else if(moment().diff(startTime,'minutes')>60){
+                                time=item.createTime.split(/[ ]+/)[1]
+                                return {
+                                    ...item,
+                                    time,
+                                }
+                            }else if(moment().diff(startTime,'minutes')>=1){
+                                time=moment().diff(startTime,'minutes')+'分钟前'
+                                return {
+                                    ...item,
+                                    time,
+                                }
+                            }else if(moment().diff(startTime,'minutes')==0){
+                                time=moment().diff(startTime,'seconds')+'秒前'
+                                return {
+                                    ...item,
+                                    time,
+                                }
+                            }
+                        
+                        
+                        
+                    });
+
+                    
+                }
+            })
+        },
+        
+        scrollRecord(){
+            console.log(this.$refs.scrollRecord);
+            this.TimerObj=setInterval(()=>{
+                this.getOperationRecord()
+
+            },60000)            
+        },
+
+
+        // 获取工作台内容
+        getPlantformInfo(){
+            getAction('/platform/query/jobContent').then(res=>{
+                console.log(res)
+                if(res.success){
+                    if(this.$parent.role=='operator'){
+                        this.countInfo=res.result.operatorJobContent
+                    }else if(this.$parent.role=='design'){
+                        this.countInfo=res.result.designJobContent
+                    }else if(this.$parent.role=='designLeader'){
+                        this.countInfo=res.result.designLeaderJobContent
+                    }
+                }
+            })
+        },
+
+
+        getTimeState () {
+            // 获取当前时间
+            let timeNow = new Date();
+            // 获取当前小时
+            let hours = timeNow.getHours();
+            // 设置默认文字
+            let text = ``;
+            // 判断当前时间段
+            if (hours >= 0 && hours <= 5) {
+                text = `凌晨好`;
+            }else if(hours >= 6 && hours <= 9){
+                text = `早上好`;
+            } else if(hours > 9 && hours <= 12){
+                text = `上午好`;
+            }else if (hours > 12 && hours <= 14) {
+                text = `中午好`;
+            } else if (hours > 14 && hours <= 18) {
+                text = `下午好`;
+            } else if (hours > 18 && hours <= 24) {
+                text = `晚上好`;
+            }
+            // 返回当前时间段对应的状态
+            return text
+        },
+
+        getidentity(){
+            getAction('/platform/query/identity',{}).then(res=>{
+                console.log(res);
+                if(res.success){
+                    this.roleInfo=res.result
+                }
+            })
+        }
+
+    },
+    mounted(){
+        let userInfo=localStorage.getItem('pro__Login_Userinfo');
+        if(userInfo){
+            this.userInfo=JSON.parse(userInfo).value
+        }
+        this.roleCode=localStorage.getItem('roleCode')
+        this.getOrderList()
+        this.getOperationRecord()
+        this.scrollRecord()
+        this.getPlantformInfo()
+        this.getidentity()
+        
+    },
+    activated(){
+        let userInfo=localStorage.getItem('pro__Login_Userinfo');
+        if(userInfo){
+            this.userInfo=JSON.parse(userInfo).value
+        }
+        this.roleCode=localStorage.getItem('roleCode')
+        this.getOrderList()
+        this.getOperationRecord()
+        
+        this.getPlantformInfo()
+        this.getidentity()
+    },
+    beforeDestroy(){
+        clearInterval(this.TimerObj)
+    },
+    filters:{
+        handleOrderStatus(val){
+            let text
+            switch (val) {
+                case 0:
+                    text='待接单'
+                    break;
+                case 1:
+                    text='制作中'
+                    break;
+                case 2:
+                    text='已驳回'
+                    break;
+                case 3:
+                    text='已完成'
+                    break;
+                case -1:
+                    text='已撤回'
+                    break;
+            
+                default:
+                    text='出错'
+                    break;
+            }
+            return text
+        }
+    },
+    
+}
+
+</script>
+
+<style lang="scss" scoped>
+.workBench{
+    ul,li{
+        margin: 0;
+        padding: 0;
+    }
+    width: 100%;
+    .topBody{
+        width: 100%;
+        height: 146px;
+        background: #FFFFFF;
+        margin-bottom: 12px;
+        padding: 20px;
+        box-sizing: border-box;
+        .breadcrumb{
+            width: 42px;
+            height: 22px;
+            font-size: 12px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #000000;
+            line-height: 22px;
+        }
+        .bottom{
+            display: flex;
+            position: relative;
+            // padding: 20px;
+            .touxiang{
+                width: 72px;
+                height: 72px;
+                margin-right: 20px;
+                border-radius: 50%;
+                overflow: hidden;
+                img{
+                    width: 100%;
+                    height: 100%;
+                    border-radius: 50%;
+                }
+            }
+            .tip{
+                .greet{
+                    height: 28px;
+                    font-size: 20px;
+                    font-family: PingFangSC-Medium, PingFang SC;
+                    font-weight: 500;
+                    color: rgba(0, 0, 0, 0.85);
+                    line-height: 28px;
+                }
+                .descPosition{
+                    height: 22px;
+                    font-size: 14px;
+                    font-family: PingFangSC-Regular, PingFang SC;
+                    font-weight: 400;
+                    color: rgba(0, 0, 0, 0.45);
+                    line-height: 22px;
+                }
+
+            }
+            .mybtn{
+                position: absolute;
+                // top: 50%;
+                // margin-left: -18px;
+                right: 0;
+            }
+        }
+
+    }
+    .section{
+        .sectionBody{
+            display: flex;
+            .sectionHead{
+                padding: 15px 20px;
+                // height: 24px;
+                font-size: 16px;
+                font-family: PingFangSC-Medium, PingFang SC;
+                font-weight: 500;
+                color: rgba(0, 0, 0, 0.85);
+                line-height: 24px;
+                border-bottom: 1px solid  #E9E9E9;;
+                position: relative;
+                .allOrder{
+                    position: absolute;
+                    right: 5px;
+                }
+            }
+            .sectionLeftBox{
+                width: 70%;
+               
+                .leftTop{
+                    overflow: hidden;
+                    background: white;
+                }
+                .zhanshiBox{
+                    display: flex;
+                    flex-wrap: wrap;
+                    .item{
+                        width: 33.33%;
+                        // background: brown;
+                        padding: 20px ;
+                        border-right: 1px solid #E9E9E9;
+                        border-bottom: 1px solid #E9E9E9;
+                        .title{
+                            padding-bottom: 34px;
+                            color: #000000;
+                            .iconImg{
+                                width: 24px;
+                                margin-right: 8px;
+                            }
+                        }
+                        .itemBody{
+                            text-align: center;
+                            .count{
+                                
+                                font-size: 24px;
+                                font-family: PingFangSC-Medium, PingFang SC;
+                                font-weight: 500;
+                                color: #000000;
+                                line-height: 32px;
+                                cursor: pointer;
+                                span{
+                                    font-size: 16px;
+                                    cursor: pointer;
+                                }
+                            }
+                            .count:hover{                                
+                                color: #1890FF;
+                            }
+                        }
+                    }
+                    .item:nth-child(3n){
+                        border-right: 0;
+                    }
+                }
+                .leftBottom{
+                    margin-top: 12px;
+                    background: white;
+                    .orderProgress{
+                        padding: 0 20px;
+                        height: 585px;
+                        position: relative;
+                        .orderProgress-list-item{
+                            padding: 10px 0;
+                            display: flex;
+                            align-items: center;
+                            border-bottom: 1px solid  #E9E9E9;;
+                            justify-content:space-between;
+                            cursor: pointer;
+                            .item-icon{
+                                width: 8px;
+                                height: 8px;
+                                background: #3BA0FF;
+                                margin-right: 15px;
+                                display: inline-block;
+                                border-radius: 50%;
+                            }
+                            .content{
+                                width: 70%;
+                                overflow: hidden;
+                                font-size: 14px;
+                                font-family: PingFangSC-Regular, PingFang SC;
+                                font-weight: 400;
+                                .name{
+                                    height: 22px;                                    
+                                    color: rgba(0, 0, 0, 0.65);
+                                    line-height: 22px;
+                                    text-overflow: ellipsis;
+                                    white-space: nowrap;
+                                    overflow: hidden;
+                                    margin-bottom: 0px;
+                                }
+                                .desc{
+                                    height: 22px;
+                                    color: rgba(0, 0, 0, 0.25);
+                                    line-height: 22px;
+                                    text-overflow: ellipsis;
+                                    white-space: nowrap;
+                                    overflow: hidden;
+                                     margin-bottom: 0px;
+                                }
+                            }
+                            .progress{
+                                float: right;
+                            }
+                        }
+                        .fenye{
+                            padding: 20px 0;
+                            text-align: right;
+                            position: absolute;
+                            right: 20px;
+                            bottom: 0px;
+                        }
+                    }
+                }
+            }
+            .sectionRightBox{
+                width: 29.5%;
+                background: white;
+                margin-left: 12px;
+                height: 1023px;
+                .rightTop{
+                  
+                     .optionRecordList{
+                         margin: 20px;
+                         padding: 10px 0;
+                         box-sizing: border-box;
+                          height: 928px;
+                        //  overflow: auto;
+                        overflow: hidden;
+                        position: relative;
+                         p{
+                             width: 100%;
+                         }
+                        .content-item{
+                            width: 70%;
+                            display: inline-block;
+                            overflow: hidden;
+                            text-overflow: ellipsis;
+                            white-space: nowrap;
+                        }
+                        .time{
+                            width: 30%;
+                            display: inline-block;
+                            overflow: hidden;
+                            text-overflow: ellipsis;
+                            white-space: nowrap;
+                            text-align: right;
+                        }
+                     }
+                }
+                .rightBottom{
+                    margin-top: 12px;
+                     background: white;
+                    .burnDown{
+                         padding: 30px 20px;
+                         text-align: center;
+                         .tip{
+                            margin-top: 40px;
+                            display: flex;
+                            justify-content: space-around;
+                             
+                            height: 22px;
+                            font-size: 14px;
+                            font-family: PingFangSC-Regular, PingFang SC;
+                            font-weight: 400;
+                            color: rgba(0, 0, 0, 0.65);
+                            line-height: 22px;
+                             .done{
+                                .item-icon{
+                                     width: 8px;
+                                    height: 8px;
+                                    background: #3BA0FF;
+                                    margin-right: 15px;
+                                    display: inline-block;
+                                    border-radius: 50%;
+                                }
+                             }
+                             .all{
+                                .item-icon{
+                                    width: 8px;
+                                    height: 8px;
+                                    background: #F0F2F5;
+                                    margin-right: 15px;
+                                    display: inline-block;
+                                    border-radius: 50%;
+                                } 
+                             }
+                         }
+                    }
+
+                }
+            }
+        }
+    }
+}
+</style>
+
+<style lang="less">
+    .workBench{
+        .ant-timeline-item-head{
+            background: rgb(240,242,245);
+        }
+    }
+</style>

+ 5 - 5
src/views/modules/autoLaunch/radioCheck.vue

@@ -65,7 +65,7 @@ export default {
     methods: {
         //单选多选的事件
         radioCheckChange(e,item){
-            console.log(e.target,item,!item.disabled);
+            // console.log(e.target,item,!item.disabled);
             
             this.currentSelect=e.target.value;
             if(!item.disabled){
@@ -78,11 +78,11 @@ export default {
                         this.selectValue.splice(0,1)
                     }
                     
-                    if(this.selectValue.indexOf(e.target.value)==-1){
-                        this.selectValue.push(e.target.value)
-                    }else if(this.selectValue.indexOf(e.target.value)>-1){
+                    if(this.selectValue.indexOf(item.value)==-1){
+                        this.selectValue.push(item.value)
+                    }else if(this.selectValue.indexOf(item.value)>-1){
                         this.selectValue=this.selectValue.filter((item)=>{
-                            return item!=e.target.value
+                            return item!=item.value
                         })  
                     }
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2642 - 0
src/views/modules/autoLaunch/configLaunchInfo.vue


+ 673 - 0
src/views/modules/autoLaunch/configLaunchList.vue

@@ -0,0 +1,673 @@
+<template>
+    <div class="toutiaoBatch">
+        
+        
+        <div class="toolbox-automate-rules-create-content_title">
+            <h3>账户配置信息</h3>
+            <a-button type='primary' @click="goNewConfigInfo" class="goNewConfigInfo">新建配置信息</a-button>
+        </div>
+        
+        <div class="topOptions">
+            <div >
+                <Treeselect :appId.sync="accountId" :multiple="false"  request="2,4"   ref="treeSelect" style="margin-bottom:8px;width:600px " />               
+            </div>
+            <span class="optionBtn">
+                <a-button type='primary' @click="search" class="searchBtn">查询</a-button>
+            </span>
+        </div>
+        <div class="tableArea">
+            <!-- <div class="tableOption" v-if="selectedRowKeys.length">
+                
+                
+               :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
+            </div> -->
+            <div class="table">
+                <a-table
+                    :columns="columns"
+                    :data-source="data"
+                    bordered
+                    :pagination="ipagination"
+                    :loading="loading"
+                    @change="sort"
+                    :scroll="{'x':scrollX}"
+                    
+                >
+                    <span slot="status" slot-scope="text,record">
+                        <a-spin :spinning="record.spin" size="small" >
+                            <div class="spin-content">
+                                <a-switch size="default" :checked='text==1'  @change="switchChange(text,record)"/>
+                            </div>
+                        </a-spin>    
+                        
+                    </span>
+                    <span slot="openProgramCreate" slot-scope="text,record">
+                        <a-spin :spinning="record.openProgramCreateSpin" size="small" >
+                            <div class="spin-content">
+                                <a-switch size="default" :checked='text==1'  @change="openProgramCreateSwitchChange(text,record)"/>
+                            </div>
+                        </a-spin>    
+                        
+                    </span>
+                    <span slot="cpaBid" slot-scope="text">
+                        {{text/1000}}
+                    </span>
+                    <span slot="authName" slot-scope="text">
+                        <!-- <a href="javascript:;" >{{text}}</a> -->
+                        {{text || '-'}}
+                    </span>
+                    <span slot="time" slot-scope="text,record">
+                        {{record.startTime}}至{{record.endTime}}
+                    </span>
+                    <span slot="operator" slot-scope="text,record">
+                        <a href="javascript:;"  @click="goPlanList(record)">编辑</a>
+                        <a-divider type="vertical" />
+                        <a href="javascript:;"  @click="deleteRecord(record)">删除</a>
+                        <a-divider type="vertical" />
+                        <a-popover v-model="record.show" trigger="click" placement="topRight" @visibleChange='visibleChange'>
+                            <div slot="content">
+                                    <span style='font-weight:700;margin-right:15px;font-size:15px'>修改后重提</span>
+                                    <a-radio-group v-model="examineAgainType" >
+                                        <a-radio :value="1">修改广告语</a-radio>
+                                        <a-radio :value="0">修改封面</a-radio>
+                                    </a-radio-group>
+                                    <a-button type='default' @click="examineAgainCancel(record)" size='small' style='margin-right:10px'>取消</a-button>
+                                    <a-button type='primary' @click="examineAgainOk(record)" size='small'  class="ok">重提</a-button>
+                            </div>
+                            <a href="javascript:;"  type='primary' @click="()=>{record.show=true}">一键重提</a>
+                            
+                        </a-popover>
+                        <a-divider type="vertical" />
+                        <a-popover v-model="record.visible" trigger="click" placement="topLeft" @visibleChange='visibleChange'>
+                            <span slot="title">出价</span>
+                            <template  slot="content" style="width:300px;">
+                                <div style="margin:5px 0 0">
+                                    <span ><a-input-number :min="0" v-model="newBid" :step="0.1" placeholder="请输入出价" size="small" style='margin-right:20px;width:120px' /></span>
+                                    <p style="color:red;font-size:12px;height:16px;padding:5px 0">{{bidErrorMessage}}</p>
+                                </div>
+                                
+                                <div>
+                                    <a-button type='default' @click="bidChangeCancel(record)" size='small' style='margin-right:10px'>取消</a-button>
+                                    <a-button type='primary' @click="bidChangeOk(record)" size='small' class="ok">修改</a-button>
+                                </div>
+                                
+                            </template>
+                            <a href="javascript:;"  type='primary' @click="()=>{record.visible=true}">修改出价</a>
+                        </a-popover>
+                    </span>
+
+                </a-table>
+            </div>
+        </div>
+        
+       
+              
+    <!-- </a-spin> -->
+    </div>
+</template>
+
+<script>
+import moment from 'moment';
+import { getAction, postAction, downFile, downFilePost,deleteAction } from '@/api/manage';
+// import { JeecgListMixin } from '@/mixins/ipagination'
+// import editableCell from './editableCell'
+import Treeselect from '@/views/modules/Statistics/components/Treeselect.vue'
+import qs from 'qs'
+let typeValue='预算'
+
+
+const strategyColumns = [
+  
+  {
+    title: '开关',
+    dataIndex: 'status',
+    key: 'status',
+    align: 'center',
+    scopedSlots: { customRender: 'status' },
+    width:110,
+    
+  },
+   {
+    title: '所属账户名称',
+    dataIndex: 'authName',
+    key: 'authName',
+    align: 'center',
+    scopedSlots: { customRender: 'authName' }, 
+    width:300  
+  },
+  {
+    title: '所属账户ID',
+    dataIndex: 'accountId',
+    key: 'accountId',
+    align: 'center',
+    scopedSlots: { customRender: 'accountId' },   
+  },
+  
+  {
+    title: '创建时间',
+    dataIndex: 'createTime',
+    key: 'createTime',
+    align: 'center',
+    scopedSlots: { customRender: 'createTime' },
+        
+  },
+  {
+        title: '出价',
+        dataIndex: 'cpaBid',
+        align: 'center',    
+        scopedSlots: { customRender: 'cpaBid' },
+        // sorter:() => {}
+    },
+//   {
+//         title: '是否开启程序化创建',
+//         dataIndex: 'openProgramCreate',
+//         align: 'center',    
+//         scopedSlots: { customRender: 'openProgramCreate' },
+//         sorter:() => {},
+//         width:180,
+//     },
+ {
+    title: '操作',
+    dataIndex: 'operator',
+    key: 'operator',
+    align: 'center',
+    scopedSlots: { customRender: 'operator' },
+    width:350,
+   
+  },
+
+];
+
+const publicColumns = [    
+    
+]
+
+export default {
+    name:'strategy-list',
+    components: {
+        // editableCell,
+        Treeselect,
+    },
+    // mixins: [JeecgListMixin],
+    data() {
+        return {
+            selectedRecord:{},
+            bidErrorMessage:'',
+            examineAgainType:1,
+            newBid:undefined,
+            examineAgain:false,
+            accountId:[],
+            accountList:[],
+            strategyState:undefined,
+            strategyName:'',
+            strategyId:undefined,
+            accountId:[],
+            scrollX:0,
+            ipagination: {
+                current: 1,
+                pageSize: 10,
+                //   pageSizeOptions: ['10', '20', '30'],
+                showTotal: (total, range) => {
+                    return range[0] + "-" + range[1] + " 共" + total + "条"
+                },
+                showQuickJumper: true,
+                showSizeChanger:true,
+                pageSizeOptions: ['10', '30', '50'],
+                total: 0,
+                onChange: (current, pageSize) => {
+                    // 切换分页时的回调,
+                    // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+                    this.ipagination.current = current;
+                    this.ipagination.pageSize= pageSize;
+                }
+            },
+           
+            spinning:false,
+            moment,
+           
+            optionId:'',//input输入的id或关键词
+          
+           
+            selectDisable:true,
+            optValue:undefined,//操作设置的值 删除 暂停 开启
+            visible: false,//出价里的弹出框
+
+            //主页的表格
+            data:[],
+            columns:[...strategyColumns,...publicColumns],
+            selectedRowKeys:[],
+            
+            loading:false,
+            editID:0,
+
+            url: {               
+                list:'/ctop/aiKuaishouAdvertiserStrategy/list',
+                delete:'/ctop/aiKuaishouAdvertiserStrategy/delete',
+            },
+
+
+            xiugaiData:[],//存分别修改时候的数组
+        }
+    },
+    computed: {
+        hasSelected() {
+        return this.selectedRowKeys.length > 0;
+        },
+    },
+    methods: {
+        //状态改变
+        switchChange(text,record){
+            // this.spinning=true;
+            console.log(text,record)
+            record.spin=true;
+            
+            
+            let status=text==1?0:1;
+            getAction(`/ctop/aiKuaishouAdvertiserStrategy/oprateStatus`,{
+                id:record.id,
+                status
+            }).then((res)=>{
+                
+                    record.spin=false;
+                if(res.success){
+                    this.getStrategyList()
+                    this.$message.success(res.message)
+                }else{
+                    this.$message.error(res.message)
+                }
+            })
+           
+
+        },
+        //是否开启程序化创意状态改变
+        openProgramCreateSwitchChange(text,record){
+            // this.spinning=true;
+            console.log(text,record)
+            record.openProgramCreateSpin=true;
+            
+            
+            let status=text==1?0:1;
+            getAction(`/ctop/aiKuaishouAdvertiserStrategy/oprateCreativeStatus`,{
+                id:record.id,
+                status
+            }).then((res)=>{
+                
+                    record.openProgramCreateSpin=false;
+                if(res.success){
+                    this.getStrategyList()
+                    this.$message.success(res.message)
+                }else{
+                    this.$message.error(res.message)
+                }
+            })
+           
+
+        },
+        examineAgainMethod(record){
+            console.log(record)
+            this.examineAgain=true;
+            this.selectedRecord=record
+        },
+        visibleChange(){
+            this.bidErrorMessage='';
+            this.examineAgainType=1;
+            this.newBid=undefined;
+            
+        },
+        bidChangeCancel(record){
+            record.visible=false;
+            this.newBid=undefined;
+            this.bidErrorMessage=''
+        },
+        bidChangeOk(record){
+            if(this.newBid){
+                record.visible=false;
+                postAction('/ai/batchUpdate/updateGroupBid',{
+                    accountId:record.accountId,
+                    bid:this.newBid*1000
+                }).then(res=>{
+                    console.log(res)
+                    if(res.code==0){
+                        this.$message.success(res.message)
+                        this.newBid=undefined;
+                        this.getStrategyList()
+                    }
+                    
+                })
+            }else{
+                this.bidErrorMessage='请正确填写出价'
+                // this.$message.error('请正确填写出价')
+            }
+            
+        },
+
+        examineAgainCancel(record){
+            record.show=false;
+            this.examineAgainType=1
+        },
+        examineAgainOk(record){
+            record.show=false;
+            postAction('/kuaishou/creative/again',{
+                accountId:record.accountId,
+                updateType:this.examineAgainType
+            }).then(res=>{
+                console.log(res);
+                if(res.code==0){
+                    this.$message.success('正在重提中,您可稍后查看结果')
+                }else{
+                    this.$message.success(res.message)
+                }
+                this.examineAgainType=1
+            })
+            
+        },
+        onSelectChange(selectedRowKeys) {
+            console.log('selectedRowKeys changed: ', selectedRowKeys);
+            this.selectedRowKeys = selectedRowKeys;
+        },
+        goNewConfigInfo(){
+            this.$router.push('/autoLaunch/configLaunchInfo')
+        },
+        goPlanList(record){
+            console.log(record)
+            this.$parent.currentStrategyId=record.id;
+            this.$router.push(`/autoLaunch/configLaunchInfo?id=${record.id}`)
+        },
+        deleteRecord(record){
+            this.loading=true
+            deleteAction(this.url.delete,{
+                id:record.id
+            }).then(res=>{
+                this.loading=false
+                if(res.success){
+                    this.$message.success(res.message);
+                    this.getStrategyList()
+                }else{
+                    this.$message.success(res.message);
+                }
+            })
+        },
+        filterOption(input, option) {
+            return (
+                option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+            );
+        },
+        
+        //查询按钮事件
+        search(){
+            this.ipagination.current=1;
+            this.getStrategyList()            
+        },
+        //点击分页
+        sort(pagination, filters, sorter, { currentDataSource }){
+            console.log(pagination)
+            this.ipagination.current=pagination.current;
+
+            this.ipagination.pageSize=pagination.pageSize;
+            this.getStrategyList()
+        },
+
+        getStrategyList(){
+            this.loading = true
+            console.log(this.accountId)
+            getAction(this.url.list,{
+                strategyId:this.strategyId==undefined?null:this.strategyId,
+                accountId:this.accountId,
+                pageNo:this.ipagination.current,
+                pageSize:this.ipagination.pageSize
+            }).then((res)=>{
+                this.data=[]
+                console.log(res)
+                this.loading = false
+                if(res.success){
+
+                    this.ipagination.total = res.result.total
+                    
+                    res.result.records.forEach((item)=>{
+                        item.key=item.id;
+                        item.show=false;
+                        item.visible=false;
+                        item.spin=false;
+                        item.openProgramCreateSpin=false;
+                    })
+
+                    this.data = res.result.records;
+                    this.selectedRowKeys=[];
+                }
+            })
+        },
+      
+    },
+    mounted() {
+       
+        this.getStrategyList()
+    },
+    
+    activated() {
+        this.getStrategyList()
+    },
+    beforeDestroy() {
+
+    },
+    filters: {
+        toPercentage(val) {
+            if(val){
+                if(typeof val != 'string'){
+                    return (val * 100).toFixed(2) + '%'
+                }else{
+                    return val
+                }
+            }else if(typeof val =='string'){
+                    return val
+                }
+            else{
+                return 0
+            }
+        },
+        //保留两位小数并且变成货币格式
+        decimalsHandle(val){
+
+            if(val && typeof val !='string'){
+                if(val>=0){
+                    val=parseFloat(val).toFixed(2);
+                    let numberStr = val.toString()
+                    let str = numberStr.split('.')
+
+                    let str0=str[0].split('').reverse();
+                    for (let i = 0; i < str0.length; i++) {
+                        if ((i + 1) % 4 === 0) {
+                            str0.splice(i, 0, ',')
+                        }
+                    }
+                    str0.reverse()
+                    let handleResult = ''
+                    for (let j = 0; j < str0.length; j++) {
+                        handleResult += str0[j]
+                    }
+
+                    return handleResult+'.'+str[1]
+                }else{
+                    val=parseFloat(val).toFixed(2);
+                    let numberStr = val.toString()
+                    let str = numberStr.split('.')
+
+                    let str0=str[0].substr(1).split('').reverse();
+                    for (let i = 0; i < str0.length; i++) {
+                        if ((i + 1) % 4 === 0) {
+                            str0.splice(i, 0, ',')
+                        }
+                    }
+                    str0.reverse()
+                    let handleResult = ''
+                    for (let j = 0; j < str0.length; j++) {
+                        handleResult += str0[j]
+                    }
+
+                    return '-'+handleResult+'.'+str[1]
+                }
+
+            }else if(typeof val =='string'){
+                return val
+            }
+            else{
+                return 0
+            }
+        },
+        //变成货币格式
+        formatCurrency(val){
+            if((val||val==0)&& typeof val !='string'){
+                let numberStr = val.toString()
+                let str = numberStr.split('').reverse()
+                for (let i = 0; i < str.length; i++) {
+                    if ((i + 1) % 4 === 0) {
+                    str.splice(i, 0, ',')
+                    }
+                }
+                str.reverse()
+                let handleResult = ''
+                for (let j = 0; j < str.length; j++) {
+                    handleResult += str[j]
+                }
+                return handleResult
+            }else if(typeof val =='string'){
+                    return val
+            }
+            else{
+                return '-'
+            }
+
+        },
+        
+        
+    }
+}
+</script>
+<style lang="scss">
+    #closeIcon{
+         color: #0E74D2;
+    }
+    .toutiaoBatch{
+        .ant-tag .anticon-close {      
+            color: #1890ff;        
+        }
+        .ant-tag .anticon-close:hover{      
+            color: rgba(0, 0, 0, 0.85);    
+        }
+
+    }
+    
+    .ant-tooltip-inner,.ant-tooltip,.ant-tooltip-arrow::before{
+        background-color: #fff;
+        color: #333;
+    }
+    #batchModal{
+        .rules,.totalPrice{
+            font-weight: 600;
+        }
+
+        .selectePlan{
+            font-size: 14px;
+            font-weight: 700;
+            color: #333;
+            padding: 20px 0;
+        }
+        .totalPrice{
+            margin-left: 20px;
+        }
+        .modifyTable{
+            margin-top: 20px;
+            width: 100%;
+            height: 400px;
+            overflow: auto;
+            font-weight: 600;
+        }
+    }
+    #copyModal{
+        .ant-modal-header{
+            text-align: center;
+        }
+        .copyTip{
+            font-size: 12px;
+            color: #999;
+        }
+        .copyName{
+            width: 118px;
+            display: inline-block;
+            text-align: right;
+            .copyKeyStart{
+                color: red;
+            }
+        }
+        // font-weight: 600;
+    }
+</style>
+<style lang="scss" scoped>
+.toutiaoBatch{
+    .breadcrumb{
+            height: 22px;
+            font-size: 12px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #000000;
+            line-height: 22px;
+        }
+    background-color: #fff;
+    padding: 10px 20px;
+    position: relative;
+    width: 100%;
+    .OptinItem{
+        display: inline-block;
+        margin-right: 15px;
+        margin-top: 15px;
+        .ok{
+            margin-right: 15px;
+        }
+    }
+    .OptinItem:first-child{
+        margin-right: 10px;
+    }
+    .topOptions{
+        padding: 15px 0;
+        display: flex;
+        justify-content: space-between;
+        .topOpt{
+            width: 100%;
+            margin-bottom: 10px;
+        }
+    }
+    .optionBtn{
+        // display: inline-block;
+        float: right;
+        // .searchBtn{
+            // margin-right: 10px;
+        // }
+    }
+    .tableArea{
+        .tableOption{
+            padding: 20px 0;
+        }
+    }
+    .toolbox-automate-rules-create-content_title {
+        background-color: #fff;
+        display: flex;
+        flex-flow: row nowrap;
+        justify-content: flex-start;
+        align-items: center;
+        margin-bottom: 28px;
+        position: relative;
+        h3 {
+            font-size: 22px;
+            margin: 0;
+            font-weight: 400;
+            height: 30px;
+            line-height: 30px;
+        }
+        .goNewConfigInfo{
+            position: absolute;
+            right: 0;
+            top: 4px;
+        }
+    }
+
+}
+
+</style>

+ 18 - 2
src/views/modules/autoLaunch/createStrategy.vue

@@ -194,7 +194,9 @@ export default {
         //推广目的改变
         marketingGoalChange(e){
             console.log(e.target)
-            this.marketingGoalHandle(e.target.value)
+            let strategyNamepart=this.marketingGoalHandle(e.target.value);
+            this.strategyName ='[策略]_'+ strategyNamepart+'_' + moment().format('MM_DD_hh:mm') ;
+
         },
     
         // 验证网址
@@ -317,7 +319,7 @@ export default {
                     str='推广品牌'
                     break;
                 case '5':
-                    str='营销线'
+                    str='营销线'
                     break;
                 case '7':
                     str='应用活跃'
@@ -340,6 +342,19 @@ export default {
     this.strategyName ='[策略]_'+ strategyNamepart+'_' + moment().format('MM_DD_hh:mm') ;
 
     
+    this.$nextTick(()=>{
+      if(this.$parent.strategyInfo.accountId){
+          this.form.setFieldsValue(
+            {
+              ...this.$parent.strategyInfo
+            }
+          )
+          this.accountId=this.$parent.strategyInfo.accountId
+          this.strategyName=this.$parent.strategyInfo.strategyName
+      }
+    })
+
+    
   },
 }
 </script>
@@ -399,6 +414,7 @@ export default {
   li {
     margin: 0;
     padding: 0;
+    
   }
   .moduler {
     background: #fff;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1086 - 0
src/views/modules/autoLaunch/groupList.vue


+ 3 - 2
src/views/modules/autoLaunch/index.vue

@@ -18,12 +18,13 @@ export default {
             isEdit:false,
             strategyInfo:{},
             accountInfo:{},
+            previewStrategyInfo:{},
         }
     },
     components:{   
         createStrategy: () => import('./createStrategy'), 
-        setDirectional: () => import('./setDirectional'), 
-        setCreate: () => import('./setCreate'), 
+        setDirectional: () => import('./setDirectional'),  
+        previewStrategy: () => import('./previewStrategy'), 
         
     },
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2153 - 0
src/views/modules/autoLaunch/materialAndBid.vue


+ 495 - 0
src/views/modules/autoLaunch/newAppId.vue

@@ -0,0 +1,495 @@
+<template>
+  <div class="newAppId">
+    
+        <div class="moduler">
+            <div class="moduler-title">选择账户</div>
+            <div>
+            <div class="row-item">
+                <div class="hint-item"></div>
+                <div class="label-item">
+                <div class="text-item">账户</div>
+                <div class="required-item"></div>
+                </div>
+                <div class="input-item">                    
+                    <!-- <Treeselect :appId.sync="accountId" :multiple="false" request="2" reqUrl='/ctop/projectMember/getProjectAccountByUserId'  ref="treeSelect" style="margin-bottom:8px;width:580px " /> -->
+                   
+                    <Treeselect :appId.sync="accountId" :multiple="false"  request="2,4"   ref="treeSelect" style="margin-bottom:8px;width:600px " />               
+              
+                </div>
+            </div>
+            </div>
+        </div>
+     
+        
+    
+        <!-- 基础信息 -->
+        <div class="moduler">
+            <div class="moduler-title">应用信息</div>
+            <div class="row-item">
+                <div class="hint-item"></div>
+                    <div class="label-item">
+                    <div class="text-item">操作系统</div>
+                    <div class="required-item"></div>
+                </div>
+                <div class="input-item">
+                    <a-form-item>
+                          <a-radio-group  v-model="platform" >
+                            <a-radio-button :value="1">Android应用刚下载</a-radio-button>
+                            <a-radio-button :value="3">IOS应用下载</a-radio-button>
+                        </a-radio-group>
+                    </a-form-item>
+                </div>
+            </div>
+
+            <div class="row-item">
+            <div class="hint-item"> </div>
+            <div class="label-item">
+              <div class="text-item">上传应用图标</div>
+              <div class="required-item"></div>
+            </div>
+            <div class="input-item">
+                
+              <uploadFile
+                  :value.sync="urlListImage.url"
+                  :checkFile="fileWater"
+                  @overUpload="overUploadImage"
+                  @removeUpload="deleteImage"
+                  :fileCount="1"
+                  uploadType="image"
+                  :disabled="!accountId"
+              />
+                
+            </div>
+            </div>
+            <div class="row-item">
+            <div class="hint-item"> </div>
+            <div class="label-item">
+              <div class="text-item">上传应用文件</div>
+              <div class="required-item"></div>
+            </div>
+            <div class="input-item">
+                
+                    <a :href="attachmentUrl" style="margin-right:20px;display:block" v-if="attachmentUrl">{{attachmentName}}</a>
+                    <a-upload
+                        name="file"
+                        :multiple="false"
+                        :action="uploadAction"
+                        :headers="tokenHeader"
+                        :file-list="fileList"
+                        :showUploadList="false"
+                        :beforeUpload="beforeUpload"
+                        @change="handleChange"
+                        style="margin-right:20px"
+                        
+                        >
+                            <a-button :disabled="!accountId&&!urlListImage.url || loadDisabled">
+                            <a-icon type="upload" />
+                                {{loadDisabled?'上传中,请稍后':'文件上传'}}
+                            </a-button>
+                    </a-upload>
+
+            </div>
+          </div>  
+            
+        </div>
+    
+      <div class="moduler">
+        <div class="opt">
+          <a-button type="default" style="margin-right:15px" @click="goBack">返回列表</a-button>
+         
+          <!-- <a-button type="primary" @click="goNext"  :loading="goNextloading">确定</a-button> -->
+        </div>
+      </div>
+
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import {ACCESS_TOKEN} from "@/store/mutation-types";
+import moment from 'moment'
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage'
+import Treeselect from '@/views/modules/Statistics/components/Treeselect.vue'
+import { TreeSelect } from 'ant-design-vue';
+import qs from 'qs'
+const SHOW_PARENT = TreeSelect.SHOW_PARENT;
+// import selectCheckAll from './toutiaoTime'
+import BMF from 'browser-md5-file'
+import uploadFile from '@/components/uploadFile.vue'
+
+var str = ""
+for (let i = 0; i < 7*48; i++) {
+ str+='0'
+  
+}
+const fileSuffix = [
+  'xlsx',
+  'xls',
+  'zip'
+]
+export default {
+    components: {
+       
+        Treeselect,
+        uploadFile,
+    },
+    data() {
+        return {
+          platform:1,
+            urlListImage: {
+                url: '', 
+                md5:'',
+                signature:'',
+              imageToken:'',
+            },
+            attachmentName:'',
+            attachmentUrl:'',
+            treeData:[],
+            accountId:undefined,
+           
+            goNextloading:false,
+            goPlanShowloading:false,
+            
+            fileList:[],
+            isEidt:false,
+            loadDisabled:false,
+            tokenHeader: {'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)},
+            uploadAction:'',
+            imageinfo:{
+              signature:'',
+              imageToken:'',
+            }
+
+        }
+    },
+    watch: {
+        accountId(n,o){
+          this.urlListImage={
+                url: '',
+                signature:'',
+                imageToken:'',
+          }
+          this.fileList=[];
+          this. attachmentName='';
+            this.attachmentUrl='';
+        }
+    },
+    methods: {
+    
+        fileWater(file) {
+            console.log(file)
+            var bmf = new BMF()
+            var that = this
+            
+            this.urlListImage = {
+                url: '',
+                md5: '',
+                
+            }
+            
+            return new Promise( (resolve, reject)=> {
+                bmf.md5(file, (err, md5) => {
+                  that.urlListImage.name=file.name
+                  that.urlListImage.md5=md5
+                  that.urlListImage.size=file.size
+                })
+                resolve()
+            })
+        },
+        deleteImage(urls) {
+            console.log(urls, this.urlListImage.url)
+            this.urlListImage.url='';
+            
+        },
+        overUploadImage(urlAll) {
+            console.log(urlAll)
+            var that = this
+            that.material = []
+            that.imageArrList = []
+            var img
+            if (urlAll.length > 0) {
+                urlAll.forEach((ele,index)=>{
+
+                    this.urlListImage.url=ele.url
+                    postAction('/ai/aiKuaiShouAppInfo/uploadAppIconImage',{
+                      accountId:this.accountId,
+                      url:'http:'+this.urlListImage.url
+                    }).then(res=>{
+                      this.urlListImage.signature=res.signature
+                      this.urlListImage.imageToken=res.imageToken
+                    })
+                })
+                
+            } else {}
+        },
+        addImage(item) {
+            this.addImageVisible = true
+            this.addImageData = item
+        },
+        
+        //获取表单的某一个属性值
+        getFormData(className) {
+        return this.form.getFieldValue(className)
+        },
+       
+        goBack() {
+            this.$router.replace('/autoLaunch/appIdList')
+            this.$bus.$emit('remove', '/autoLaunch/newAppId')
+        },
+    
+       
+        //请求项目和账户内容
+        accountHttp(){
+            this.treeData=[];
+            this.accountIds=[];
+            getAction('/ctop/projectMember/getProjectAccountByUserId?mediaType=2', {}).then(res => {
+            if(res.success){
+                    // console.log(res);
+                    if(res.result){
+                        res.result.forEach((element,index) => {
+                        if(element){                  
+                            this.treeData.push({});                    
+                            this.treeData[index].title=element.project.projectName +'_('+ element.project.advertiserName +')';
+                            this.treeData[index].value='project'+element.project.projectId;
+                            this.treeData[index].key=element.project.projectId;
+                            this.treeData[index].mediaId=element.project.mediaId;
+                            this.treeData[index].children=[];
+                                                
+                            if(element.account.length){
+                            element.account.forEach((ele,i)=>{
+                                this.treeData[index].children.push({});
+                                this.treeData[index].children[i].title=ele.userName+'_'+ele.authName+'_'+element.project.projectName;
+                                this.treeData[index].children[i].value=ele.accountId;
+                                this.treeData[index].children[i].key=ele.accountId;
+                            })
+                                
+                            }                           
+                        }      
+                        });
+                        // console.log(this.treeData)
+                        
+                    }
+            }
+            })
+        },
+
+        
+        beforeUpload(file) {
+            // ${this.form.project}
+            if (process.env.NODE_ENV == 'development') { 
+                this.uploadAction= `/jeecg-boot/ai/aiKuaiShouAppInfo/importAppExcel?accountId=${this.accountId}&platform=${this.platform}&imageToken=${this.urlListImage.imageToken}`
+            } 
+            else if (process.env.NODE_ENV == 'debug') { 
+            } 
+            else if (process.env.NODE_ENV == 'production') { 
+
+              this.uploadAction= `${this.axios.defaults.baseURL}/ai/aiKuaiShouAppInfo/importAppExcel?accountId=${this.accountId}&platform=${this.platform}&imageToken=${this.urlListImage.imageToken}`
+            }
+
+            this.loadDisabled = true
+            const size = (Number(file.size) / (1024 * 1024)).toFixed(2)
+            const fileName = file.name
+            const fileStrArr = fileName.split('.')
+            const suffix = fileStrArr[fileStrArr.length - 1]
+
+            let result = fileSuffix.some((item) => {
+                return item === suffix
+            })
+
+            if (!result) {
+                this.$message.error('不支持该文件类型')
+                this.loadDisabled = false
+                return false
+            }
+
+            // if (size > 10) {
+            //     this.$message.error('文件不能大于10MB')
+            //     this.loadDisabled = false
+            //     return false
+            // }
+            
+        },
+        handleChange(info) {
+            console.log(info)
+            let fileList = [...info.fileList];
+
+            // 1. Limit the number of uploaded files
+            //    Only to show two recent uploaded files, and old ones will be replaced by the new
+            fileList = fileList.slice(-2);
+
+            // 2. read from response and show file link
+            fileList = fileList.map(file => {
+                if (file.response) {
+                    // Component will show file.url as link
+                    file.url = file.response.url;
+                }
+                return file;
+            });
+            if(fileList.length>0){
+                this.fileList = [
+                    {
+                        ...fileList[fileList.length-1]
+                    }
+                ]
+            }else{
+                this.fileList=[]
+            }
+            // this.loadDisabled = false 
+            // this.$message.success('文件导入成功,异步创建中,请稍后查看...')
+            if (info.file.status !== 'uploading') {
+                console.log(info.file, info.fileList)
+            }
+            if (info.file.status === 'done') {
+                
+                this.loadDisabled = false 
+                if(info.file.response.code==0){
+                  this.$message.success(info.file.response.message)
+                  this.$router.replace('/autoLaunch/appIdList')
+                  this.$bus.$emit('remove', '/autoLaunch/newAppId')
+                }else{
+                  this.$message.error(info.file.response.message)
+                }
+                
+            } else if (info.file.status === 'error') {
+                this.$message.error(`${info.file.name}上传失败`)
+                this.loadDisabled = false
+            }
+
+            // console.log(this.form)
+        },
+        
+    },
+    
+  mounted() {
+    this.accountHttp()
+   
+  },
+}
+</script>
+<style lang="scss">
+.newAppId{
+  .ant-btn-danger {
+    background-color: #ff4d4f !important; 
+  }
+}
+
+
+.ant-tooltip-inner,
+.ant-tooltip,
+.ant-tooltip-arrow::before {
+  background-color: #fff;
+  color: #333;
+}
+.ant-tooltip-inner {
+  span {
+    display: block;
+  }
+}
+.ant-tooltip {
+  max-width: 450px;
+}
+.newPlan {
+  .ant-radio-button-wrapper {
+    min-width: 80px;
+    text-align: center;
+  }
+  .ant-form-item {
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    margin: 0;
+    padding: 0;
+    color: rgba(0, 0, 0, 0.65);
+    font-size: 14px;
+    font-variant: tabular-nums;
+    line-height: 1.5;
+    list-style: none;
+    -webkit-font-feature-settings: 'tnum';
+    font-feature-settings: 'tnum';
+    vertical-align: top;
+  }
+  .directedBody {
+    .ant-form-item {
+      margin-bottom: 20px;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.newAppId {
+  font-family: PingFangSC-Regular, tahoma, arial, 'Hiragino Sans GB', 'Microsoft yahei', sans-serif;
+  color: #333;
+  ul,
+  li {
+    margin: 0;
+    padding: 0;
+    
+  }
+  .moduler {
+    background: #fff;
+    margin-bottom: 16px;
+    position: relative;
+    padding: 32px 24px 48px 32px;
+    border-radius: 4px;
+    box-shadow: 0px 1px 6px 0px rgba(0, 0, 0, 0.05);
+    .moduler-title {
+      display: flex;
+      align-items: center;
+      font-size: 22px;
+      margin-bottom: 20px;
+    }
+    .row-item {
+      display: flex;
+      justify-content: flex-start;
+      align-items: center;
+      margin-bottom: 32px;
+    }
+    .row-item:last-of-type {
+      margin-bottom: 0;
+    }
+    .row-item .hint-item {
+      width: 24px;
+      min-width: 24px;
+      align-self: flex-start;
+      line-height: 20px;
+      height: 20px;
+      margin-top: 9px;
+    }
+    .row-item .label-item {
+      position: relative;
+      align-items: flex-start;
+      align-self: flex-start;
+      line-height: 20px;
+      height: 20px;
+      margin-top: 10px;
+      width: 80px;
+      min-width: 80px;
+      .text-item {
+        font-size: 14px;
+        width: 60px;
+      }
+    }
+    .row-item .required-item {
+      width: 4px;
+      height: 4px;
+      border-radius: 2px;
+      background: #f45858;
+      position: absolute;
+      right: 10px;
+      top: 50%;
+      transform: translateY(-50%);
+    }
+    .row-item .input-item {
+      min-width: 480px;
+      position: relative;
+      // height: 35px;
+      .tip {
+        font-size: 12px;
+        color: tomato;
+      }
+    }
+  }
+  .opt {
+    text-align: right;
+  }
+}
+</style>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1098 - 0
src/views/modules/autoLaunch/planList.vue


+ 861 - 0
src/views/modules/autoLaunch/previewStrategy.vue

@@ -0,0 +1,861 @@
+
+<style lang="scss" scoped>
+.previewStrategy{
+    .moduler {
+         .opt {
+            text-align: right;
+        }
+        width: 100%;
+        background: #fff;
+        margin-bottom: 16px;
+        position: relative;
+        padding: 32px 24px 48px 32px;
+        // border-radius: 4px;
+        // box-shadow: 0px 1px 6px 0px rgba(0, 0, 0, 0.05);
+        .moduler-title {
+        display: flex;
+        align-items: center;
+        font-size: 22px;
+        margin-bottom: 20px;
+        }
+        .extraClass{
+            .row-item {
+                margin-bottom: 20px;
+            }
+            
+        }
+        .row-item {
+        display: flex;
+        justify-content: flex-start;
+        align-items: center;
+        margin-bottom: 25px;
+        }
+        .row-item:last-of-type {
+        margin-bottom: 0;
+        }
+        .row-item .hint-item {
+        width: 24px;
+        min-width: 24px;
+        align-self: flex-start;
+        line-height: 20px;
+        height: 20px;
+        margin-top: 9px;
+        }
+        .row-item .label-item {
+        position: relative;
+        align-items: flex-start;
+        align-self: flex-start;
+        line-height: 20px;
+        height: 20px;
+        margin-top: 10px;
+        width: 80px;
+        min-width: 80px;
+        .text-item {
+            font-size: 14px;
+            width: 60px;
+        }
+        }
+        .row-item .required-item {
+        width: 4px;
+        height: 4px;
+        border-radius: 2px;
+        background: #f45858;
+        position: absolute;
+        right: 10px;
+        top: 50%;
+        transform: translateY(-50%);
+        }
+        .row-item .input-item {
+        min-width: 480px;
+        position: relative;
+        // height: 35px;
+        .tip {
+            font-size: 12px;
+            color: tomato;
+        }
+        }
+        .adName{
+        display: flex;
+        .nameList{
+            width: 90%;
+        }
+        .item{
+            display: inline-block;
+            width: 30%;
+            margin-left: 15px;
+            margin-bottom: 10px;
+        }
+        }
+    }
+     .toolbox-automate-rules-create-body {
+        margin: 16px 0 16px ;
+        padding: 32px 32px 16px;
+        background-color: #fff;
+        border-radius: 4px;
+    }
+    .toolbox-automate-rules-create-content_title {
+        background-color: #fff;
+        display: flex;
+        flex-flow: row nowrap;
+        justify-content: flex-start;
+        align-items: center;
+        margin-bottom: 28px;
+        h3 {
+            font-size: 22px;
+            margin: 0;
+            font-weight: 400;
+            height: 30px;
+            line-height: 30px;
+        }
+    }
+    .toolbox-automate-rules-create-content {
+        padding-left: 28px;
+    }
+    ul,li{
+        margin: 0;
+        padding: 0;
+    }
+   
+    width: 100%;
+    .topBody{
+        width: 100%;
+        background: #FFFFFF;
+        margin-bottom: 12px;
+        padding: 20px;
+        box-sizing: border-box;
+        .breadcrumb{
+            height: 22px;
+            font-size: 12px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #000000;
+            line-height: 22px;
+        }
+        .bottom{
+            display: flex;
+            position: relative;
+            justify-content: space-between;
+            // padding: 20px;
+            .orderIcon{
+                width: 28px;
+                height: 28px;
+                margin-right: 15px;
+                img{
+                    width: 100%;
+                }
+            }
+            .tip{
+                .greet{
+                    width: 300px;
+                    height: 28px;
+                    font-size: 20px;
+                    font-family: PingFangSC-Medium, PingFang SC;
+                    font-weight: 500;
+                    color: rgba(0, 0, 0, 0.85);
+                    line-height: 28px;
+                    margin-bottom: 5px;
+                }
+                .descPosition{
+                    
+                    font-size: 14px;
+                    font-family: PingFangSC-Regular, PingFang SC;
+                    font-weight: 400;
+                    color: rgba(0, 0, 0, 0.45);
+                    overflow: hidden;
+                    margin-bottom: 0;
+                    li{
+                        height: 22px;
+                        line-height: 22px;
+                        margin-top:3px ;
+                    }
+                    span{
+                        width: 250px;
+                        display: inline-block;
+                    }
+                }
+
+            }
+            .optBody{
+                width: 200px;
+                flex-shrink:0;
+                // justify-content: flex-end;
+                text-align: right;
+                .btnBody{
+                    margin-bottom: 10px;
+                }
+                .orderInfo{
+                    display: flex;
+                    justify-content: space-between;
+                    text-align: right;
+                    p{
+                        margin-bottom: 0;
+                    }
+                    
+                    .markName{                        
+                        height: 22px;
+                        font-size: 14px;
+                        font-family: PingFangSC-Regular, PingFang SC;
+                        font-weight: 400;
+                        color: rgba(0, 0, 0, 0.45);
+                        line-height: 22px;
+                    }
+                    .big{                                               
+                        height: 28px;
+                        font-size: 20px;
+                        font-family: PingFangSC-Regular, PingFang SC;
+                        font-weight: 400;
+                        color: rgba(0, 0, 0, 0.85);
+                        line-height: 28px;
+                    }
+                }
+
+            }
+        }
+
+    }
+    .section{
+        background: white;
+        padding:20px ;
+        .breadcrumb{
+            height: 22px;
+            font-size: 12px;
+            font-family: PingFangSC-Regular, PingFang SC;
+            font-weight: 400;
+            color: #000000;
+            line-height: 22px;
+        }
+        .sectionBody{
+            
+            p{
+                margin-bottom: 0;
+            }
+            .section-item{
+                background: white;
+                margin-bottom: 20px;
+            }
+            .tabBox{
+                padding: 15px 20px 0;
+                display: flex;
+                flex-wrap: wrap;
+                position: relative;
+                .search-item{
+                    margin-bottom: 12px;
+                    width: 30%;
+                }
+                .opt-item{
+                    position: absolute;
+                    right: 20px;
+                    top: 16px;
+                }
+            }
+            .sectionHead{
+                padding: 15px 20px;
+                // height: 24px;
+                font-size: 16px;
+                font-family: PingFangSC-Medium, PingFang SC;
+                font-weight: 500;
+                color: rgba(0, 0, 0, 0.85);
+                line-height: 24px;
+                border-bottom: 1px solid  #E9E9E9;;
+                .allOrder{
+                    float: right;
+                }
+            }
+            .section-box{
+                margin-top: 30px;
+                padding: 20px 20px;
+                border: 1px solid #E9E9E9;
+                .description{
+                    margin-top: 10px;
+                    .time{
+                        height: 32px;
+                        line-height: 32px;
+                    }
+                }
+                ul{
+                    display: flex;
+                    flex-wrap: wrap;
+                    // justify-content: space-around;
+                }
+                li{
+                    
+                    width: 30%;
+                    height: 22px;
+                    font-size: 14px;
+                    font-family: PingFangSC-Regular, PingFang SC;
+                    font-weight: 400;
+                    color: rgba(0, 0, 0, 0.85);
+                    line-height: 22px;
+                    text-align: left;
+                    margin-bottom: 15px;
+                }
+                .top{
+                    margin-bottom: 25px;
+                }
+                .bottom{
+                    h4{
+                        
+                        font-size: 15px;
+                        font-family: PingFangSC-Medium, PingFang SC;
+                        font-weight: 600;
+                        color: rgba(0, 0, 0, 0.85);
+                        margin-bottom: 25px;
+                    }
+                }
+                .shenhe{
+                    width: 6px;
+                    height: 6px;
+                    display: inline-block;
+                    background: #52C41A;
+                    border-radius: 50%;
+                    position: relative;
+                    top: -2px;
+
+                }
+                .wancheng{
+                    width: 6px;
+                    height: 6px;
+                     display: inline-block;
+                    background: #1890FF;
+                    border-radius: 50%;
+                    // margin-right: 3px;
+                    position: relative;
+                    top: -2px;
+                }
+                .bohui{
+                    width: 6px;
+                    height: 6px;
+                    display: inline-block;
+                    background: #F5222D;
+                    border-radius: 50%;
+                    position: relative;
+                    top: -2px;
+                }
+            }
+            
+        }
+    }
+}
+.videoBox{
+   
+    height: 240px;
+}
+.imgBox{
+    width: 90%;
+}
+.videomarterialInfo{
+    position: relative;
+    height: 800px;
+}
+.marterialInfo{
+    overflow: auto;   
+    height: 800px;
+    position: relative;
+    p{margin-bottom: 0;}
+    ul,li{
+        margin: 0;
+        padding: 0;
+    }
+    .info-item{
+        margin-bottom: 20px;
+        display: flex;
+        // justify-content: center;
+        align-items: flex-start;
+        span{
+            display: inline-block;
+            width: 70px;
+            text-align: left;
+            flex-shrink: 0;
+        }
+        .ant-tag{
+            width: auto;
+            min-width: 50px;
+            text-align: center;
+        }
+    }
+    .info{
+        ul{
+            width: 100%;
+            display: flex;
+            justify-content: space-between;
+            flex-wrap: wrap;
+        }
+        li{
+            width: 33.3%;
+            margin-bottom: 20px;
+        }
+        margin-bottom: 0;
+    }
+    // .btnBody{
+    //     width: 100%;
+    //     height: 80px;
+    //     position: relative;
+    // }
+    .bottom-btn{
+        width: 100%; 
+        text-align: center;
+        position: absolute;
+        bottom: 0px;
+        left: 0;
+        // margin-top: 20px;
+
+    }
+    .scriptbottom-btn{
+        width: 100%; 
+        // height: 60px;  
+        line-height: 60px;   
+        text-align: center;
+        position: absolute;
+        bottom: 0px;
+        left: 0;
+       
+    }
+}
+</style>
+
+<style lang="less">
+    .previewStrategy{
+        .ant-timeline-item-head{
+            background: rgb(240,242,245);
+        }
+        .muen{
+            cursor: pointer;
+        }
+        .muen:hover{
+            color: #1890ff;
+        }
+    }
+    
+    
+</style>
+<template>
+    <div class="previewStrategy ">   
+        <a-spin :spinning="spinning">
+        <div class="toolbox-automate-rules-create-body">
+            <div class="toolbox-automate-rules-create-content_title"><h3>策略预览</h3></div>
+            <div class="toolbox-automate-rules-create-content">
+                
+                    <a-table
+                        size="middle"
+                        :columns="columns"
+                        :dataSource="data"
+                        id="outTable"
+                        :pagination="ipagination"
+                        :loading="loading"
+                        @change="sort"
+                        style="word-break: break-all;"
+                        :bordered='true'
+                        >
+                        <div slot="materialStatus" slot-scope="text" >
+                            <span class="wancheng" v-if="text==7"> </span>
+                            <span class="bohui" v-else-if="text==6||text==3"> </span>
+                            <span class="shenhe" v-else> </span>
+                            {{text | handlerMaterialStatus}}
+                        </div>
+                        <div slot="scriptStatus" slot-scope="text,record">
+                            <span v-if="record.materialStatus==0&&role=='design'">-</span>
+                            <a href="javascript:;" v-if="record.materialStatus==0&&role=='designLeader'"  @click="scriptAssign(record)">指派</a>
+                            <span v-else>
+                                    <a href="javascript:;" @click="scriptViewDetails(record)">{{record.planName}}</a>
+                            </span>
+                        </div>
+                        <div slot="videoStatus" slot-scope="text,record">
+                            <span v-if="record.materialStatus==0&&role=='design'">-</span>
+                            <a href="javascript:;" v-if="record.materialStatus==0&&role=='designLeader'"  @click="videoAssign(record)">指派</a>
+                            <span v-else>
+                                    <a href="javascript:;" @click="viewDetails(record)">{{record.clipName}}</a>
+                            </span>
+                        </div>
+                        <div slot="operator" slot-scope="text,record">                            
+                            <a href="javascript:;" @click="goDetail(record)">查看详情</a>
+                        </div>
+
+                    </a-table>
+
+                    <a-drawer
+                    title="视频详情"
+                    width="800"
+                    :placement="placement"
+                    :closable="false"
+                    :visible="visible"
+                    @close="onClose"
+                    >
+                        <a-tabs
+                        default-active-key="1"
+                        tab-position="top"
+                        :style="{ height: '200px' }"
+                        @prevClick="callback"
+                        @nextClick="callback"
+                        >
+                            <a-tab-pane v-for="i in 30" :key="i" :tab="`Tab-${i}`">  </a-tab-pane>
+                        </a-tabs>
+                        <a-spin :spinning="visibleLoading">                            
+                        <div class="marterialInfo videomarterialInfo">
+                            <div class="info-item">
+                                <span>素材类型:</span>
+                                <p>{{ currentVideo.videoStatus | handlerVideoStatus }}</p>
+                            </div> 
+                            <div class="info-item">
+                                <span>视频预览:</span>
+                               <div class="videoBox">
+                                    <video style="height:100%" :src="currentVideo.url" controls v-if="currentVideo.url"></video>
+                                    <img :src="defaultPic" alt="" style="width:100px;margin:0 10px 8px 0" v-else>
+                                </div> 
+                            </div>
+                            <div class="info-item">
+                                <span>封面预览:</span>
+                                <div class="imgBox">
+                                    <div >
+                                        <template v-if="currentVideo.imgList&&currentVideo.imgList.length">
+                                            <img  alt="" style="width:100px;margin:0 10px 8px 0" v-for="(item,index) in currentVideo.imgList"  :key='index' :src="item"> 
+                                        </template>
+                                        <span v-else>暂无封面</span>
+                                    </div>
+
+                                </div>
+                            </div>
+                            
+                            <div class="info-item" >
+                                <span>创意标题:</span>
+                                <p>
+                                   
+                                </p>
+                            </div>
+                            <div class="info-item" >
+                                <span>广告语:</span>
+                                <p>
+                                   
+                                </p>
+                            </div>
+                            <div class="info-item" >
+                                <span>行动号召:</span>
+                                <p>
+                                   
+                                </p>
+                            </div>
+                            <div class="info-item" >
+                                <span>监测链接</span>
+                                <p>
+                                   
+                                </p>
+                            </div>
+                           
+                           
+                            <div class="bottom-btn">
+                                <a-button type='default' @click="onClose">关闭</a-button>
+                            </div>
+                         
+                            
+                        </div>
+                        </a-spin>
+                    </a-drawer>
+            </div>
+        </div>
+        <div class="moduler">
+                    <!-- <div class="moduler-title">计划名称</div> -->
+            <div class="opt">
+                <a-button type="default" style="margin-right:15px" @click="goBack">取消创建</a-button>
+                <a-button type="primary"  style="margin-right:15px" @click="saveHandler" :loading="saveLoading">确认创建</a-button>
+            </div>
+        </div>  
+    </a-spin>     
+        
+    </div>
+</template>
+
+<script>
+import moment from 'moment';
+import qs from 'qs'
+import { getAction, postAction, downFile, downFilePost } from '@/api/manage';
+import Vue from 'vue'
+import {ACCESS_TOKEN} from "@/store/mutation-types"
+import BMF from 'browser-md5-file'
+import { fileCheck, fileCheckImage, fileEdit, fileEditAll,orderFileInsert} from '@/api/actor'
+import uploadFile from '@/components/uploadFile.vue'
+import { closeAllVideoFun, stopOtherVideo } from '@/utils/videoControl'
+import UploadToAli from '@femessage/upload-to-ali'
+import { mapGetters } from 'vuex'
+import TrendVue from '../../../components/Trend/Trend.vue';
+
+let listColumns=[
+    {
+        title: '广告组',
+        dataIndex: 'materialName',
+        align: 'center',        
+        key: 'materialName',
+        scopedSlots: { customRender: 'materialName' }
+    },
+    {
+        title: '所属计划',
+        dataIndex: 'materialId',
+        align: 'center',        
+        key: 'tag',
+        scopedSlots: { customRender: 'materialId' }
+    },
+    {
+        title: '优化目标',
+        dataIndex: 'materialStatus',
+        align: 'center',        
+        key: 'materialStatus',
+        scopedSlots: { customRender: 'materialStatus' }
+    },
+    {
+        title: '出价',
+        dataIndex: 'scriptStatus',
+        align: 'center',        
+        key: 'scriptStatus',
+        scopedSlots: { customRender: 'scriptStatus' }
+    },
+     {
+        title: '深度优化目标',
+        dataIndex: 'videoStatus',
+        align: 'center',        
+        key: 'videoStatus',
+        width:250,
+        scopedSlots: { customRender: 'videoStatus' }
+    },
+    {
+        title: '深度优化出价',
+        dataIndex: 'orderTitle',
+        align: 'center',        
+        key: 'orderTitle',
+        scopedSlots: { customRender: 'orderTitle' }
+    },
+    {
+        title: '广告位置',
+        dataIndex: 'position',
+        align: 'center',        
+        key: 'position',
+        scopedSlots: { customRender: 'position' }
+    },
+    {
+        title: '创意',
+        dataIndex: 'operator',
+        align: 'center',        
+        key: 'operator',
+        scopedSlots: { customRender: 'operator' }
+    },
+   
+]
+
+
+export default {
+    name:'preview-strategy',
+    
+    data() {
+        
+        return {
+            spinning:false,
+            currentVideo:{},
+            visible: false,
+            visibleLoading:false,
+            placement: 'right',
+            loading:false,
+            data:[],
+            columns:[...listColumns],
+            url:{
+                assgin:'/platform/designer/assign',
+                scriptDetail:'/platform/material/scriptDetail',
+                videoDetail:'/platform/material/videoDetail',
+                scriptAccept:'/platform/material/script/accept',
+                scriptReject:'/platform/material/script/reject',
+                videoAccept:'/platform/material/video/accept',
+                videoReject:'/platform/material/video/reject',
+            },     
+            ipagination: {
+                current: 1,
+                pageSize: 10,
+                //   pageSizeOptions: ['10', '20', '30'],
+                showTotal: (total, range) => {
+                    return range[0] + "-" + range[1] + " 共" + total + "条"
+                },
+                showQuickJumper: true,
+                showSizeChanger:true,
+                pageSizeOptions: ['10', '30', '50'],
+                total: 0,
+                onChange: (current, pageSize) => {
+                    // 切换分页时的回调,
+                    // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+                    this.ipagination.current = current;
+                    this.ipagination.pageSize= pageSize;
+                }
+            }, 
+        }
+    },
+    methods: {
+        goDetail(record){
+            consoel.log(record);
+            this.visible=true;
+        },
+        callback(val) {
+            console.log(val);
+        },
+        onClose() {
+            this.visible = false;
+        },
+
+        sort(pagination, filters, sorter, { currentDataSource }){
+        
+            this.ipagination.current=pagination.current;
+
+            this.ipagination.pageSize=pagination.pageSize;
+            this.materialHttp(this.activeKey)
+        },
+        // 请求列表
+        getListHttp(type){
+            this.loading=true;           
+            this.data=[];
+            let  params=this.handlerParams(type)
+            params={
+                ...params,
+                pageNo:this.ipagination.current,
+                pageSize:this.ipagination.pageSize
+            }
+            getAction('/platform/material/listByRole',params).then(res=>{
+                console.log(res);
+                if(res.success){
+                    this.loading=false;   
+                    this.data=res.result.list;
+                    this.ipagination.total=res.result.total;
+
+                }
+            })
+        },
+
+        
+
+        saveHandler(){
+             this.$refs.ruleForm.validate(valid=> {
+                if (valid) {
+                    // this.form.rulesList=this.rulesList;
+                    console.log(valid,this.form);
+                    
+                    this.saveLoading=true;
+
+                        if(this.currentRuleId){
+                            let ruleList=this.form.ruleList.filter(item=>{
+                                return !item.groupId
+                            })
+                            console.log(ruleList)
+                            if(ruleList.length>0){
+                                postAction(this.url.createRuleGroup,{
+                                    templateId:this.currentRuleId,
+                                    ruleList
+                                }).then(res=>{
+                                    console.log(res);
+                                    this.saveLoading=false;
+                                    if(res.success){
+                                        
+                                        this.$router.push('/earlyWarningRules/index')
+                                        this.$bus.$emit('remove', `/earlyWarningRules/configRules?id=${this.currentRuleId}`)
+                                    }else{
+                                        this.$message.error(res.message)
+                                    }
+                                    
+                                })
+                            }else{
+                                this.$router.push('/earlyWarningRules/index')
+                                this.$bus.$emit('remove', `/earlyWarningRules/configRules?id=${this.currentRuleId}`)
+                            }
+                            
+                        }else{
+                            postAction(this.url.creativeTemplate,this.form).then(res=>{
+                                console.log(res);
+                                this.saveLoading=false;
+                                if(res.success){
+                                    this.$router.push('/earlyWarningRules/index')
+                                    this.$bus.$emit('remove', '/earlyWarningRules/configRules')
+                                }else{
+                                    this.$message.error(res.message)
+                                }
+                                    
+                            
+                            })
+                        }
+                    
+                    
+                    
+                } else {
+                    console.log('error submit!!');
+                    this.$message.error('请按提示填写必填项目!')
+                    return false;
+                }
+            });
+        },
+
+        goBack() {
+             this.$router.push('/earlyWarningRules/index')
+            this.$bus.$emit('remove', '/earlyWarningRules/configRules')
+           
+        },
+
+
+    },
+    mounted(){
+        
+    },
+    activated() {
+        
+    },
+    filters:{
+        handlerMaterialStatus(val){
+            let str='';
+            switch(val){
+                
+                case 0:
+                    str= '待指派'
+                    break;
+                case 1:
+                    str= '脚本待上传'
+                    break;
+                case 2:
+                    str= '脚本待审核'
+                    break;
+                case 3:
+                    str= '脚本被驳回'
+                    break;
+                case 4:
+                    str= '视频待上传'
+                    break;
+                case 5:
+                    str= '视频待审核'
+                    break;
+                case 6:
+                    str= '视频被驳回'
+                    break;
+                case 7:
+                    str= '物料已完结'
+                    break;
+                default:
+                    str='出错了'
+                    break;
+            }
+            return str
+        },
+        handlerVideoStatus(val){
+            let str='';
+            switch(val){
+                
+                case 0:
+                    str= '待上传'
+                    break;
+                case 1:
+                    str= '待审核'
+                    break;
+                case 2:
+                    str= '被驳回'
+                    break;
+                case 3:
+                    str= '已审核'
+                    break;
+                default:
+                    str='出错了'
+                    break;
+            }
+            return str
+        },
+        
+    },
+
+}
+</script>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 599 - 88
src/views/modules/autoLaunch/setDirectional.vue


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1090 - 0
src/views/modules/autoLaunch/strategyList.vue


+ 1 - 1
src/views/modules/autoRules/newBlankRule.vue

@@ -915,7 +915,7 @@ export default {
         },
 
         goBack() {
-            this.$router.replace('/autoRules')
+            this.$router.push('/autoRules')
             this.$bus.$emit('remove', '/newBlankRule')
            
         },

+ 8 - 0
src/views/modules/columnConst/accountConst.js

@@ -1218,6 +1218,14 @@ export const KScustomFields= [
           scopedSlots: { customRender: 'eventCreditGrantAppRate' },
           sorter:() => {}
         },
+        {
+          title: '3s播放率',
+          dataIndex: 'play3sRate',
+          tip: '3s播放数/素材曝光数',
+          align: 'center',    
+          scopedSlots: { customRender: 'play3sRate' },
+          sorter:() => {}
+        },
       ]
     },
     {

+ 117 - 47
src/views/modules/earlyWarningRules/configRules.vue

@@ -61,8 +61,10 @@
                             <div class="required-item"></div>
                         </div>
                         <div class="input-item  extraClass" style="min-width:80%" > 
-                            <a-collapse accordion >
-                                <a-collapse-panel v-for="(item,index) in form.ruleList" :key="index" :header="item.groupName" :style="customStyle">
+                            <!-- v-model="activeKey" defaultActiveKey='0'-->
+                            <a-collapse accordion  v-model="activeKey" @change="collapseChange" ref="collapse">
+                                <template  v-for="(item,index) in form.ruleList"   >
+                                <a-collapse-panel   :header="item.groupName" :style="customStyle" >
                                     <span slot="extra">
                                          <a-popconfirm
                                             :title="`确定删除吗?`"
@@ -179,7 +181,9 @@
                                                 
                                                     <div class="rules-list-item">
                                                         <div class="rules-list-item-subject" style="width:180px">
-                                                            <a-form-model-item ref="baseIndex"  prop="baseIndex">
+                                                            <a-form-model-item ref="baseIndex"   :prop="'ruleList.'+index+'.ruleDetail.'+ind+'.baseIndex'"  :rules="[
+                                                                { required: true, message: '请选择指标', trigger: 'blur' },
+                                                            ]">
                                                                 <a-cascader
                                                                     v-model="ele.baseIndex"
                                                                     :options="rulesFieldList"
@@ -195,7 +199,9 @@
                                                         <template >
                                                         
                                                         <div class="rules-list-item-subject" >
-                                                            <a-form-model-item ref="ruleCondition"  prop="ruleCondition">
+                                                            <a-form-model-item ref="ruleCondition" :prop="'ruleList.'+index+'.ruleDetail.'+ind+'.ruleCondition'"  :rules="[
+                                                                { required: true, message: '请选择运算符', trigger: 'blur' },
+                                                            ]">
                                                                 <a-select   v-model="ele.ruleCondition" placeholder="运算符" :disabled="!!ele.ruleId">
                                                                     <a-select-option  v-for="item in ele.conditionList" :key="item.id" :value='item.ruleCondition'>{{item.conditionName}}</a-select-option>
                                                                 </a-select>
@@ -221,10 +227,10 @@
                                                         </div>
 
 
-                                                        <div class="rules-list-item-subject" v-if="ele.dataType=='number'">
+                                                        <!-- <div class="rules-list-item-subject" v-if="ele.dataType=='number'">
                                                             <a-input-number :min="0" style="width:100%" :max="9999999.99" :step="1" v-model="ele.threshold" placeholder="请输入" :disabled="!!ele.ruleId" />
                                                             <span style="margin-left:8px;line-height:32px">{{ele.dataUnit }}</span>
-                                                        </div>
+                                                        </div> -->
                                                         <div class="rules-list-item-subject" >
                                                             <a-form-model-item ref="isUnlimited"  prop="isUnlimited">
                                                                 <a-select   v-model="ele.isUnlimited" placeholder="是否必填" :disabled="!!ele.ruleId">
@@ -277,6 +283,8 @@
                                         </div>
                                     </div>
                                 </a-collapse-panel>
+                                </template>
+                               
                                 
                             </a-collapse>
                             <div class="add-rule" @click="addRule"> 添加规则</div>
@@ -312,7 +320,8 @@ export default {
     },
     data() {
         return {
-            tabActiveKey:[0],
+            activeKey:'0',
+            // tabActiveKey:[0],
             customStyle:'background: #f9f9fa;border-radius: 4px;margin-bottom:15px;overflow: hidden;border: 1px solid #d9d9d9;',
             conditionList:[],
             url:{
@@ -365,6 +374,7 @@ export default {
                         operate:'SEND',//预警方式
                         sendType:'Wechat',//通知方式
                     },
+                   
                 ],
             },
             rules: {
@@ -437,7 +447,7 @@ export default {
             
         },
         blurGroupName(item){
-            if(this.currentRuleId){
+            if(this.currentRuleId&&item.groupId){
                 if(item.groupName!=''&&item.remark!=''){
                     putAction('/ruleGroup/edit',{id:item.groupId,groupName:item.groupName,remark:item.remark}).then(res=>{
                         if(res.success){
@@ -552,6 +562,9 @@ export default {
             }
             
         },
+        collapseChange(key){
+            console.log(key)
+        },
         addRule(){
             this.form.ruleList.push(
                 {
@@ -582,7 +595,10 @@ export default {
                     ]
                 },
             )
-
+            console.log(this.$refs.collapse)
+            
+            this.activeKey=(this.form.ruleList.length-1)+'';
+           
             
         },
         deleteRulesListItem(index,ind){
@@ -590,6 +606,7 @@ export default {
             this.form.ruleList[index].ruleDetail=this.form.ruleList[index].ruleDetail.filter((ele,i)=>{
                 return i!=ind
             })
+            
         },
         deleteIcon(event){
             event.stopPropagation();
@@ -607,6 +624,7 @@ export default {
                         this.form.ruleList=this.form.ruleList.filter((ele,ind)=>{
                             return ind!=index
                         })
+                        this.activeKey=(this.form.ruleList.length-1)+'';
                     }else{
                         this.$message.error(res.message)
                     }
@@ -615,6 +633,7 @@ export default {
                 this.form.ruleList=this.form.ruleList.filter((ele,ind)=>{
                     return ind!=index
                 })
+                this.activeKey=(this.form.ruleList.length-1)+'';
             }
             
         },
@@ -647,31 +666,37 @@ export default {
                     this.saveLoading=true;
 
                         if(this.currentRuleId){
-                            let ruleList=this.form.ruleList.filter(item=>{
-                                return !item.groupId
-                            })
-                            console.log(ruleList)
-                            if(ruleList.length>0){
-                                postAction(this.url.createRuleGroup,{
-                                    templateId:this.currentRuleId,
-                                    ruleList
-                                }).then(res=>{
-                                    console.log(res);
-                                    this.saveLoading=false;
-                                    if(res.success){
-                                        
-                                        this.$router.push('/earlyWarningRules/index')
-                                        this.$bus.$emit('remove', `/earlyWarningRules/configRules?id=${this.currentRuleId}`)
-                                    }else{
-                                        this.$message.error(res.message)
-                                    }
-                                    
+                            if(this.form.ruleList.length){
+                                let ruleList=this.form.ruleList.filter(item=>{
+                                    return !item.groupId
                                 })
+                                console.log(ruleList)
+                                if(ruleList.length>0){
+                                    postAction(this.url.createRuleGroup,{
+                                        templateId:this.currentRuleId,
+                                        ruleList
+                                    }).then(res=>{
+                                        console.log(res);
+                                        this.saveLoading=false;
+                                        if(res.success){
+                                            
+                                            this.$router.push('/earlyWarningRules/index')
+                                            this.$bus.$emit('remove', `/earlyWarningRules/configRules?id=${this.currentRuleId}`)
+                                        }else{
+                                            this.$message.error(res.message)
+                                        }
+                                        
+                                    })
+                                }else{
+                                    this.$router.push('/earlyWarningRules/index')
+                                    this.$bus.$emit('remove', `/earlyWarningRules/configRules?id=${this.currentRuleId}`)
+                                }
                             }else{
-                                this.$router.push('/earlyWarningRules/index')
-                                this.$bus.$emit('remove', `/earlyWarningRules/configRules?id=${this.currentRuleId}`)
+                                this.saveLoading=false;
+                                this.$message.error('模板内具体规则不能为空')
                             }
                             
+                            
                         }else{
                             postAction(this.url.creativeTemplate,this.form).then(res=>{
                                 console.log(res);
@@ -718,8 +743,9 @@ export default {
                     id:this.$route.query.id
                 }).then(res=>{
                     console.log(res);
+                    // this.spinning=false;
                     if(res.success){
-                        this.spinning=false;
+                        // this.spinning=false;
                         new Promise((resolve,reject)=>{
                              getAction(this.url.fieldList,{   
                                 mediaType:res.result.mediaType,
@@ -739,28 +765,44 @@ export default {
                                 }            
                             })
                         }).then(data=>{
-                             res.result.ruleList.map((item,index)=>{
-                                item.ruleDetail.forEach((ele,ind)=>{
+                            if(res.result.ruleList){
+                                res.result.ruleList.map((item,index)=>{
+                                    item.ruleDetail.forEach((ele,ind)=>{
 
-                                    ele.baseIndex=[ele.ruleDimension,ele.indicatorCode];
-                                    getAction(this.url.ruleCondition,{
-                                        dataType:ele.dataType
-                                    }).then(result=>{
-                                        console.log(result)
-                                        if(result.success){
-                                            ele.conditionList=result.result
-                                            console.log(this.form);
-                                            this.form={};
-                                            this.form=res.result
-                                        }
+                                        ele.baseIndex=[ele.ruleDimension,ele.indicatorCode];
+                                        getAction(this.url.ruleCondition,{
+                                            dataType:ele.dataType
+                                        }).then(result=>{
+                                            console.log(result)
+                                            if(result.success){
+                                                ele.conditionList=result.result
+                                                console.log(this.form);
+                                                this.form={};
+                                                this.form=res.result
+                                            }
+                                        })
                                     })
                                 })
-                            })
 
+                                this.form=res.result;
+                                this.spinning=false
+                            }else{
+                                
+                                this.form={
+                                    ...res.result,
+                                    ruleList:[]
+                                }
+                                // this.form.ruleList=[]
+                                this.spinning=false
+                            }
+                             
+                            // this.form=res.result;
                             
-                            this.form=res.result;
                         })
                        
+                    }else{
+                        this.$message.error(res.message);
+                        this.spinning=false;
                     }
                 })
             }else{
@@ -1072,7 +1114,7 @@ export default {
             .rules-list-item {
                 box-sizing: border-box;
                 width: 100%;
-                padding: 15px;
+                padding: 20px;
                 background: #f8f9fa;
                 border-radius: 4px;
                 margin-bottom: 16px;
@@ -1262,6 +1304,34 @@ export default {
        border: 1px solid #fff; 
        background-color: #fff;
     }
+    // .rules-list-item{
+    .ant-form-explain{
+        clear: both;
+        min-height: 22px;
+        margin-top: -2px;
+        color: rgba(0, 0, 0, 0.45);
+        font-size: 14px;
+        line-height: 1.5;
+        -webkit-transition: color 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);
+        transition: color 0.3s cubic-bezier(0.215, 0.61, 0.355, 1);
+        position: absolute;
+    }
+    // }
+    
+    .has-error .ant-form-explain, .has-error .ant-form-split {
+        color: #f5222d;
+    }
 
+    .has-error .ant-form-explain, .has-error .ant-form-split {
+        color: #f5222d;
+    }
+
+    .has-error .ant-form-explain, .has-error .ant-form-split {
+        color: #f5222d;
+    }
+
+    .has-error .ant-form-explain, .has-error .ant-form-split {
+        color: #f5222d;
+    }
 }
 </style>

+ 249 - 0
src/views/modules/earlyWarningRules/historyWarning.vue

@@ -0,0 +1,249 @@
+<template>
+  <a-card :bordered="false" title="预警管理">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline">
+        <a-row :gutter="24">
+          <a-col :md="6" :sm="8">
+            <a-form-item label="媒体">
+              <a-radio-group v-model="mediaType">
+                <a-radio-button value=""> 全部 </a-radio-button>
+                <a-radio-button value="快手"> 快手 </a-radio-button>
+                <a-radio-button value="头条"> 头条 </a-radio-button>
+              </a-radio-group>
+            </a-form-item>
+          </a-col>
+          <a-col :md="6" :sm="8">
+            <a-form-item label="运营名称">
+              <a-input placeholder="请输入运营名称" v-model="userId"></a-input>
+            </a-form-item>
+          </a-col>
+          <template>
+            <a-col :md="6" :sm="8">
+              <a-form-item label="账户ID">
+                <Treeselect :appId.sync="accountId" :multiple="false" ref="treeSelect" style="width: 100%" />
+              </a-form-item>
+            </a-col>
+          </template>
+          <a-col :md="6" :sm="8">
+            <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+
+    <!-- 操作按钮区域 -->
+    <!-- <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+    </div>-->
+
+    <!-- table区域-begin -->
+    <!-- 供应商 -->
+    <div>
+      <a-table
+        ref="table"
+        size="middle"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        style="word-break: break-all"
+      >
+        <span slot="userId" slot-scope="text">{{ text.split('_')[0] }}</span>
+        <div slot="alarmDetail" slot-scope="text" style="text-align: left; width: 100%; padding: 0 10px">
+          {{ text }}
+        </div>
+      </a-table>
+    </div>
+  </a-card>
+</template>
+
+<script>
+import JTreeSelect from '@/components/jeecg/JTreeSelect'
+import { httpAction, getAction } from '@/api/manage'
+import Treeselect from './pushTreeSelect.vue'
+export default {
+  name: 'ProjectList',
+  components: {
+    JTreeSelect,
+    Treeselect,
+  },
+  data() {
+    return {
+      dataSource: [],
+      mediaType: '',
+      userId: '',
+      accountId: '',
+      description: '项目管理页面',
+      // 表头
+      columns: [
+        {
+          title: '媒体',
+          align: 'center',
+          dataIndex: 'mediaType',
+          width: 100,
+        },
+        {
+          title: '账户ID',
+          align: 'center',
+          dataIndex: 'accountId',
+          width: 200,
+        },
+        {
+          title: '运营',
+          align: 'center',
+          dataIndex: 'userId',
+          scopedSlots: {
+            customRender: 'userId',
+          },
+          width: 100,
+        },
+        {
+          title: '预警字段',
+          align: 'center',
+          dataIndex: 'groupName',
+          scopedSlots: {
+            customRender: 'groupName',
+          },
+          width: 100,
+        },
+        {
+          title: '预警时间',
+          align: 'center',
+          dataIndex: 'createTime',
+          scopedSlots: {
+            customRender: 'createTime',
+          },
+          width: 200,
+        },
+        {
+          title: '预警信息',
+          align: 'center',
+          dataIndex: 'alarmDetail',
+          scopedSlots: {
+            customRender: 'alarmDetail',
+          },
+        },
+      ],
+      list: [],
+      options: [],
+      loading: false,
+      ipagination: {
+        current: 1,
+        pageSize: 10,
+        //   pageSizeOptions: ['10', '20', '30'],
+        showTotal: (total, range) => {
+          return range[0] + '-' + range[1] + ' 共' + total + '条'
+        },
+        showQuickJumper: true,
+        //   showSizeChanger: true,
+        total: 0,
+        onChange: (current) => {
+          // 切换分页时的回调,
+          // 当在页面定义change事件时,切记要把此处的事件清除,因为这两个事件重叠了,可能到时候会导致一些莫名的bug
+          this.ipagination.current = current
+        },
+      },
+    }
+  },
+  computed: {
+    importExcelUrl: function () {
+      return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`
+    },
+  },
+  watch: {
+    'ipagination.current': function (n, o) {
+      if (n != o) {
+        this.getHistoryList()
+      }
+    },
+  },
+  methods: {
+    searchQuery() {
+      this.ipagination.current = 1
+      this.getHistoryList()
+    },
+    searchReset() {
+      this.mediaType = ''
+      this.userId = ''
+      this.accountId = ''
+      this.ipagination.current = 1
+      this.getHistoryList()
+    },
+    getHistoryList() {
+      this.loading = true
+      var params = {}
+      params.mediaType = this.mediaType
+      params.userId = this.userId
+      params.accountId = this.accountId
+      params.pageNo = this.ipagination.current
+      params.pageSize = this.ipagination.pageSize
+
+      getAction('/alarm/alarmEventSend/pageList', params).then((res) => {
+        this.loading = false
+        if (res.success) {
+          this.dataSource = res.result.list.map((item, index) => {
+            return { ...item, key: index }
+          })
+          this.ipagination.total = res.result.total
+        } else {
+          this.$message.error(res.message)
+        }
+      })
+    },
+    getList() {
+      var params = {}
+      // params.userId = this.userInfo().id
+      params.pageSize = 1000
+      params.pageNo = 1
+      getAction('/ctop/advertiser/list', params)
+        .then((res) => {
+          if (res.success) {
+            this.list = res.result.records
+          } else {
+            this.$message.warning(res.message)
+          }
+        })
+        .finally(() => {})
+    },
+    filterOption(input, option) {
+      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
+    },
+    getAllUserList(value) {
+      this.options = []
+      getAction('/sys/user/getAllUserList', { pageSize: 50, pageNo: 1, userName: value }).then((res) => {
+        if (res.success) {
+          this.options = res.result.list
+        }
+      })
+    },
+    search(value) {
+      this.options = []
+      if (value != '') {
+        // this.options = this.list.filter(item => {
+        //   var data = item.realName + ' ' + item.roleName
+        //   return data.toLowerCase().indexOf(value.toLowerCase()) > -1
+        // })
+        // this.options = [...this.options]
+        this.getAllUserList(value)
+      } else {
+        this.getAllUserList()
+      }
+    },
+  },
+  created() {},
+  mounted() {
+    this.getHistoryList()
+    // this.getAllUserList()
+    // this.getList()
+  },
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>

+ 2 - 2
src/views/modules/earlyWarningRules/index.vue

@@ -9,8 +9,8 @@
                 <a-input v-model="templateName" placeholder="模板名字" style="width:250px;margin-right:40px"/>
             </div>
             <div>
-                <span>模板id:</span>
-                <a-input v-model="templateId" placeholder="模板id" style="width:250px"/>
+                <span>模板ID:</span>
+                <a-input v-model="templateId" placeholder="模板ID" style="width:250px"/>
             </div>
             
 

+ 21 - 0
src/views/modules/earlyWarningRules/pushTreeSelect.vue

@@ -8,6 +8,7 @@
     <treeselect
       :multiple="multiple"
       :disable-branch-nodes="!multiple"
+      :disable-fuzzy-matching="true"
       :options="options"
       :load-options="loadOptions"
       placeholder="请选择项目以及账户"
@@ -51,12 +52,32 @@ export default {
         return true
       },
     },
+    appId: {
+      default() {
+        return ''
+      },
+    },
   },
   components: { Treeselect },
   watch: {
     $route(n, o) {
       console.log(n, o)
     },
+    appId: {
+      handler(n, o) {
+        console.log(n)
+        if (n.length == 0) {
+          if (this.multiple) {
+            this.value = []
+          } else {
+            this.value = undefined
+          }
+        } else {
+          this.value = this.appId
+        }
+      },
+      deep: true,
+    },
   },
   methods: {
     ...mapGetters(['nickname', 'avatar', 'userInfo']),

+ 91 - 116
src/views/modules/earlyWarningRules/ruleModule.vue

@@ -3,6 +3,12 @@
 .display-none-selset {
   display: none !important;
 }
+.ruleModule .ant-form-item-label > label::after {
+  content: '';
+  position: relative;
+  top: -0.5px;
+  margin: 0 8px 0 2px;
+}
 </style>
 <template>
   <div class="ruleModule">
@@ -32,7 +38,7 @@
       </div>
       <a-spin :spinning="spinLoading">
         <div class="toolbox-automate-rules-create-content">
-          <a-form-model ref="ruleForm" :model="form" layout="horizontal">
+          <a-form-model ref="ruleForm" :model="form" layout="horizontal" :hideRequiredMark="true">
             <div class="moduler">
               <template v-for="(item, index) of form.ruleList">
                 <div class="row-item" v-if="item.ruleType == 'base' && item.isCopy == 0" :key="index">
@@ -60,6 +66,12 @@
                         trigger: value.dataType == 'array' ? 'change' : 'blur',
                       }"
                     >
+                      <span
+                        style="color: red; font-size: 16px; font-weight: 500"
+                        v-if="value.modelType == 'numberText'"
+                      >
+                        {{ value.ruleCondition | conditionName }}
+                      </span>
                       <a-input-number
                         :disabled="!editShow"
                         v-model="value.threshold"
@@ -72,12 +84,14 @@
                         v-model="value.threshold"
                         style="width: 300px; margin-right: 5px"
                         v-else-if="value.modelType == 'text'"
+                        @change="inputChange(value)"
                       />
                       <selectGroup
                         :disabled="!editShow"
                         v-model="value.threshold"
                         style="width: 300px; margin-right: 5px"
                         :code="value.dictId"
+                        :requestUrl="value.requestUrl"
                         :multiple="
                           value.dataType == 'string' ||
                           value.dataType == 'number' ||
@@ -123,6 +137,7 @@
                       </a-select>
 
                       <!-- <p v-else-if="value.modelType == 'timeRange'">{{value.threshold}}</p> -->
+
                       <scheduleTime
                         style="width: 100%"
                         :scheduleTime.sync="value.threshold"
@@ -186,6 +201,10 @@
                                     }"
                                     v-if="value.modelType == 'numberText'"
                                   >
+                                    <span style="color: red; font-size: 16px; font-weight: 500">
+                                      {{ value.ruleCondition | conditionName }}
+                                    </span>
+
                                     <a-input-number
                                       :disabled="!editShow"
                                       style="width: 100px; margin-right: 5px"
@@ -221,10 +240,12 @@
                                     }"
                                     v-else-if="value.modelType == 'select' || value.modelType == 'checkBox'"
                                   >
+                                    <!--  -->
                                     <selectGroup
                                       :disabled="!editShow"
                                       v-model="value.threshold"
                                       :code="value.dictId"
+                                      :requestUrl="value.requestUrl"
                                       :multiple="
                                         value.dataType == 'string' ||
                                         value.dataType == 'number' ||
@@ -326,6 +347,9 @@
                                     }"
                                     v-if="value.modelType == 'numberText'"
                                   >
+                                    <span style="color: red; font-size: 16px; font-weight: 500">
+                                      {{ value.ruleCondition | conditionName }}
+                                    </span>
                                     <a-input-number
                                       :disabled="!editShow"
                                       style="width: 100px; margin-right: 5px"
@@ -354,7 +378,12 @@
                                     }"
                                     v-else-if="value.modelType == 'text'"
                                   >
-                                    <a-input :disabled="!editShow" v-model="value.threshold" style="width: 95%" />
+                                    <a-input
+                                      :disabled="!editShow"
+                                      v-model="value.threshold"
+                                      style="width: 95%"
+                                      @change="inputChange"
+                                    />
                                   </a-form-model-item>
                                   <a-form-model-item
                                     :label-col="{ span: 6 }"
@@ -381,6 +410,7 @@
                                       :disabled="!editShow"
                                       v-model="value.threshold"
                                       :code="value.dictId"
+                                      :requestUrl="value.requestUrl"
                                       :multiple="
                                         value.dataType == 'string' ||
                                         value.dataType == 'number' ||
@@ -778,6 +808,10 @@ export default {
     },
   },
   methods: {
+    inputChange(value) {
+      value.threshold = value.threshold.trim()
+      console.log(value)
+    },
     addData(valueElse, value, index) {
       // alert(1)
       if (index == 0) {
@@ -796,17 +830,7 @@ export default {
     disabledDate(current) {
       return current && current < moment().subtract(1, 'days')
     },
-    // 应用方式改变
-    applyRangeChange(e) {
-      this.checkedList = []
-      this.checkAll = false
-      this.indeterminate = false
-      if (e.target.value == 'ACCORDINGTO_STATUS') {
-        this.form.appStatus = '1'
-      } else {
-        this.form.appStatus = null
-      }
-    },
+
     // 获取计划列表
     getCampaignList() {
       getAction('/kuaishou/batch/getCampaignList', {
@@ -868,27 +892,6 @@ export default {
       }
     },
 
-    handleChange(value) {
-      let rulesList = {}
-      rulesList = this.rulesFieldList.filter((item) => {
-        return item.metricValueCode == value
-      })[0]
-      this.rulesList = []
-      rulesList.childs.forEach((ele, index) => {
-        this.rulesList.push({
-          metricValueName: ele.metricValueName,
-          metricValueCode: ele.metricValueCode,
-          dataRange: 'CURRENT_DAY_DATA',
-          judgeMethod: 'GT_EQ',
-          judgeType: 'MONEY',
-          threshold: undefined,
-          minThreshold: undefined,
-          campaignStatus: undefined,
-          unitStatus: undefined,
-        })
-      })
-    },
-
     filterOption(input, option) {
       return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
     },
@@ -907,78 +910,19 @@ export default {
     resetForm() {
       this.$refs.ruleForm.resetFields()
     },
-    addRule() {
-      this.rulesList.push({
-        metricValueName: ['0', 'COST'],
-        dataRange: 'CURRENT_DAY_DATA',
-        judgeMethod: 'GT_EQ',
-        judgeType: 'MONEY',
-        budgetMultiple: 0.5,
-        budgetMultipleMin: 0.5,
-        budgetMultipleMax: 0.8,
-        campaignStatus: undefined,
-        unitStatus: undefined,
-        threshold: 0,
-        maxNumber: 0,
-      })
-    },
-    deleteRulesListItem(item, index) {
-      console.log(item, index)
-      this.rulesList = this.rulesList.filter((ele, ind) => {
-        return ind != index
-      })
-    },
+
     displayRender({ labels }) {
       return labels[labels.length - 1]
     },
-    conditionChange(item) {
-      console.log(item)
-      if (item.metricValueName[1] == 'COST') {
-        item.judgeType = 'MONEY'
-      } else {
-        item.judgeType = undefined
-      }
-      item.specificMoney = undefined
-      item.specificMoneyMin = undefined
-      item.specificMoneyMax = undefined
-      item.threshold = undefined
-      item.maxNumber = undefined
-      item.campaignStatus = undefined
-      item.unitStatus = undefined
-    },
-
-    applyObjChange(e) {
-      // console.log(e.target.value)
-      this.plainOptions = []
-      this.checkedList = []
-      this.checkAll = false
-      this.indeterminate = false
-      if (e.target.value == 'ACCOUNT') {
-        this.form.processMethod = 'SEND'
-        this.rulesFieldList = this.accountFieldList
-      } else if (e.target.value == 'CAMPAIGN') {
-        this.rulesFieldList = this.campaignFieldList
-      } else if (e.target.value == 'UNIT') {
-        this.rulesFieldList = this.unitFieldList
-      }
-
-      if (this.form.applyAccount) {
-        if (e.target.value == 'CAMPAIGN') {
-          this.spinning = true
-          this.getCampaignList()
-        } else if (e.target.value == 'UNIT') {
-          this.spinning = true
-          this.getCampaignList()
-          this.getUnitList()
-        }
-      }
-    },
 
     saveHandler() {
       this.$refs.ruleForm.validate((valid) => {
         if (valid) {
           // this.form.rulesList=this.rulesList;
-
+          var str = ''
+          for (let i = 0; i < 7 * 24; i++) {
+            str += '0'
+          }
           var datas = []
           datas = this.form.ruleList.map((item) => {
             return {
@@ -988,7 +932,11 @@ export default {
                   var data = end.map((c) => {
                     return {
                       ...c,
-                      threshold: isArray(c.threshold) ? JSON.stringify(c.threshold) : c.threshold,
+                      threshold: isArray(c.threshold)
+                        ? c.dataType != 'array'
+                          ? c.threshold[0]
+                          : JSON.stringify(c.threshold)
+                        : c.threshold,
                     }
                   })
                   return data
@@ -996,13 +944,19 @@ export default {
                   return {
                     ...end,
                     threshold: isArray(end.threshold)
-                      ? end.modelType == 'region'
-                        ? JSON.stringify(
-                            end.threshold.map((c) => {
-                              return c.value
-                            })
-                          )
-                        : JSON.stringify(end.threshold)
+                      ? end.dataType == 'array'
+                        ? end.modelType == 'region'
+                          ? JSON.stringify(
+                              end.threshold.map((c) => {
+                                return c.value
+                              })
+                            )
+                          : JSON.stringify(end.threshold)
+                        : end.threshold[0]
+                      : end.modelType == 'scheduleTime'
+                      ? end.threshold == str
+                        ? ''
+                        : end.threshold
                       : end.threshold,
                   }
                 }
@@ -1146,7 +1100,15 @@ export default {
                     return {
                       ...c,
                       threshold:
-                        c.modelType == 'tagBox' ? (c.threshold == null ? undefined : c.threshold) : c.threshold,
+                        c.modelType == 'tagBox'
+                          ? c.threshold == null
+                            ? undefined
+                            : c.threshold
+                          : c.modelType == 'checkBox'
+                          ? c.dataType == 'array'
+                            ? c.threshold
+                            : [c.threshold]
+                          : c.threshold,
                     }
                   })
                   return [...data]
@@ -1154,7 +1116,15 @@ export default {
                   return {
                     ...end,
                     threshold:
-                      end.modelType == 'tagBox' ? (end.threshold == null ? undefined : end.threshold) : end.threshold,
+                      end.modelType == 'tagBox'
+                        ? end.threshold == null
+                          ? undefined
+                          : end.threshold
+                        : end.modelType == 'checkBox'
+                        ? end.dataType == 'array'
+                          ? end.threshold
+                          : [end.threshold]
+                        : end.threshold,
                   }
                 }
               }),
@@ -1286,15 +1256,20 @@ export default {
         width: 120px;
       }
     }
-    .row-item .required-item {
-      width: 4px;
-      height: 4px;
-      border-radius: 2px;
-      background: #f45858;
+    .row-item .required-item::after {
+      content: '*';
+      // width: 4px;
+      // height: 4px;
+      // border-radius: 2px;
+      // background: #f45858;
+      color: #f5222d;
+      font-size: 14px;
       position: absolute;
-      right: 10px;
-      top: 50%;
-      transform: translateY(-50%);
+      left: -40px;
+      top: -1px;
+      font-family: SimSun, sans-serif;
+
+      // transform: translateY(-50%);
     }
     .row-item .input-item {
       min-width: 480px;

+ 13 - 8
src/views/modules/earlyWarningRules/switchConfig.vue

@@ -305,15 +305,20 @@ export default {
         width: 100px;
       }
     }
-    .row-item .required-item {
-      width: 4px;
-      height: 4px;
-      border-radius: 2px;
-      background: #f45858;
+    .row-item .required-item::after {
+      content: '*';
+      // width: 4px;
+      // height: 4px;
+      // border-radius: 2px;
+      // background: #f45858;
+      color: #f5222d;
+      font-size: 14px;
       position: absolute;
-      right: 10px;
-      top: 50%;
-      transform: translateY(-50%);
+      left: -40px;
+      top: -1px;
+      font-family: SimSun, sans-serif;
+
+      // transform: translateY(-50%);
     }
     .row-item .input-item {
       min-width: 480px;

+ 122 - 42
src/views/modules/earlyWarningRules/useRuleList.vue

@@ -8,7 +8,8 @@
     <div class="tabBody">
       <a-tabs v-model="tabKey" @change="tabChange">
         <a-tab-pane key="1" tab="模板列表"></a-tab-pane>
-        <a-tab-pane key="2" tab="我的模板"></a-tab-pane>
+        <a-tab-pane key="2" tab="我的模板"> </a-tab-pane>
+        <a-button slot="tabBarExtraContent" type="link" @click="toHistory"> 预警历史 </a-button>
       </a-tabs>
     </div>
     <div class="tableBody">
@@ -25,6 +26,29 @@
           @search="onSearch"
         />
       </div> -->
+      <div class="table-page-search-wrapper" v-if="tabKey == '2'">
+        <a-form layout="inline">
+          <a-row :gutter="24">
+            <a-col :md="6" :sm="8">
+              <a-form-item label="账户名称">
+                <Treeselect :appId.sync="projectId" :multiple="false" ref="treeSelect" style="width: 100%" />
+              </a-form-item>
+            </a-col>
+            <a-col :md="6" :sm="8">
+              <a-form-item label="绑定人">
+                <a-input placeholder="请输入绑定的运营" v-model="userName"></a-input>
+              </a-form-item>
+            </a-col>
+
+            <a-col :md="6" :sm="8">
+              <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
+                <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+                <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              </span>
+            </a-col>
+          </a-row>
+        </a-form>
+      </div>
       <div class="table">
         <a-table
           size="middle"
@@ -49,9 +73,9 @@
             {{ text | handleMediaType }}
           </span>
           <span slot="accountStatus" slot-scope="text">
-              <span class="bohui" v-if="text==1"></span>
-              <span class="shenhe" v-if="text==0"></span>
-              {{text?'暂停':'投放中'}}
+            <span class="bohui" v-if="text == 1"></span>
+            <span class="shenhe" v-if="text == 0"></span>
+            {{ text ? '暂停' : '投放中' }}
           </span>
           <span slot="processMethod" slot-scope="text">
             {{ text == 'SEND' ? '仅发送通知' : '发送并关停组' }}
@@ -72,7 +96,14 @@
       </div>
     </div>
     <!-- pushRuleVisible -->
-    <a-modal v-model="pushRuleVisible" title="推送账户选择" @ok="handleOk" :confirmLoading="confirmLoading" width="60%">
+    <a-modal
+      v-model="pushRuleVisible"
+      title="推送账户选择"
+      @ok="handleOk"
+      @cancel="cancelPush"
+      :confirmLoading="confirmLoading"
+      width="60%"
+    >
       <a-form layout="inline" class="rule-tree-select">
         <a-form-item
           label="请选择账户"
@@ -89,7 +120,7 @@
 <script>
 import moment from 'moment'
 import Treeselect from './pushTreeSelect.vue'
-import { getAction, postAction, downFile, downFilePost, deleteAction , putAction } from '@/api/manage'
+import { getAction, postAction, downFile, downFilePost, deleteAction, putAction } from '@/api/manage'
 let existColumns = [
   // {
   //     title: '运行/暂停',
@@ -134,14 +165,13 @@ let existColumns = [
 ]
 
 let recordsColumns = [
-
-    {
-      title: '运行/暂停',
-      dataIndex: 'status',
-      align: 'center',
-      width:100,
-      key: 'status',
-      scopedSlots: { customRender: 'status' }
+  {
+    title: '运行/暂停',
+    dataIndex: 'status',
+    align: 'center',
+    width: 100,
+    key: 'status',
+    scopedSlots: { customRender: 'status' },
   },
   {
     title: '模板名称',
@@ -201,6 +231,8 @@ export default {
   name: 'useRuleList',
   data() {
     return {
+      projectId: '',
+      userName: '',
       relationCount: 2,
       pushRuleVisible: false,
       confirmLoading: false,
@@ -251,12 +283,44 @@ export default {
     Treeselect,
   },
   methods: {
+    toHistory() {
+      this.$router.replace({ path: '/earlyWarningRules/historyWarning' })
+    },
+
+    searchQuery() {
+      this.ipagination.current = 1
+      let url = ''
+      if (this.tabKey == '1') {
+        this.columns = [...existColumns]
+        url = '/ruleTemplate/list'
+      } else {
+        this.columns = [...recordsColumns]
+        url = '/ruleAccountTemplate/getTemplateApplied'
+      }
+      this.getTableListHttp(url)
+    },
+    searchReset() {
+      this.ipagination.current = 1
+      this.projectId = ''
+      this.userName = ''
+      let url = ''
+      if (this.tabKey == '1') {
+        this.columns = [...existColumns]
+        url = '/ruleTemplate/list'
+      } else {
+        this.columns = [...recordsColumns]
+        url = '/ruleAccountTemplate/getTemplateApplied'
+      }
+      this.getTableListHttp(url)
+    },
     moment,
     onSearch(value) {
       console.log(value)
     },
     tabChange(key) {
       console.log(key)
+      this.projectId = ''
+      this.userName = ''
       this.ipagination.current = 1
       let url = ''
       if (key == '1') {
@@ -298,31 +362,43 @@ export default {
     },
 
     handleOk() {
-      this.confirmLoading = true
-      getAction('/ruleAccountTemplate/checkAccountTemplate', { accountId: this.accountId }).then((res) => {
-        console.log(res)
-        if (res.success) {
-          if (!res.result.isApplication) {
-            postAction('/ruleAccountTemplate/pushTemplateToAccount', {
-              templateId: this.templateId,
-              accountId: this.accountId,
-            }).then((r) => {
-              var data = { id: this.templateId, edit: true, accountId: this.accountId }
-              localStorage.setItem('getRuleDetail', JSON.stringify(data))
-              this.$router.push('/earlyWarningRules/ruleModule')
+      if (this.accountId) {
+        this.confirmLoading = true
+        getAction('/ruleAccountTemplate/checkAccountTemplate', { accountId: this.accountId }).then((res) => {
+          console.log(res)
+          if (res.success) {
+            if (!res.result.isApplication) {
+              postAction('/ruleAccountTemplate/pushTemplateToAccount', {
+                templateId: this.templateId,
+                accountId: this.accountId,
+              }).then((r) => {
+                if (r.success) {
+                  var data = { id: this.templateId, edit: true, accountId: this.accountId }
+                  localStorage.setItem('getRuleDetail', JSON.stringify(data))
+                  this.$router.push('/earlyWarningRules/ruleModule')
+                  this.confirmLoading = false
+                  this.accountId = undefined
+                } else {
+                  this.$message.error(r.message)
+                }
+              })
+            } else {
+              // this.accountId = ''
+              this.$message.error(`此账户下已绑定模板${res.result.templateName},请重新选择账户`)
               this.confirmLoading = false
-            })
+            }
           } else {
-            this.accountId = ''
-            this.$message.error(`此账户下已绑定模板${res.result.templateName},请重新选择账户`)
+            // this.accountId = ''
+            this.$message.error(res.message)
             this.confirmLoading = false
           }
-        } else {
-          this.accountId = ''
-          this.$message.error(res.message)
-          this.confirmLoading = false
-        }
-      })
+        })
+      } else {
+        this.$message.error('请选择需要推送的账户')
+      }
+    },
+    cancelPush() {
+      this.accountId = ''
     },
     // recordsRule(record){
     //     console.log(record);
@@ -371,7 +447,7 @@ export default {
     },
     switchChange(text, record) {
       console.log(text, record)
-      if(record.accountStatus==0 || record.accountStatus==1&&text){
+      if (record.accountStatus == 0 || (record.accountStatus == 1 && text)) {
         record.spin = true
         let templateStatus = 0
         if (text) {
@@ -402,19 +478,24 @@ export default {
             // this.getTableListHttp()
           }
         })
-      }else{        
-          this.$message.error('当前账户已关停,预警规则不支持开启!')
+      } else {
+        this.$message.error('当前账户已关停,预警规则不支持开启!')
       }
-      
     },
 
     getTableListHttp(url) {
       this.data = []
       this.loading = true
       // let url='/alarm/alarmEventRule/list'
+      var params = {}
+      if (this.tabKey == '2') {
+        params.accountId = this.projectId
+        params.userName = this.userName
+      }
       getAction(url, {
         pageNo: this.ipagination.current,
         pageSize: this.ipagination.pageSize,
+        ...params,
       }).then((res) => {
         console.log(res)
         this.loading = false
@@ -502,7 +583,7 @@ export default {
       margin-bottom: 15px;
     }
 
-    .shenhe{
+    .shenhe {
       width: 6px;
       height: 6px;
       display: inline-block;
@@ -511,7 +592,7 @@ export default {
       position: relative;
       top: -2px;
     }
-    .bohui{
+    .bohui {
       width: 6px;
       height: 6px;
       display: inline-block;
@@ -521,6 +602,5 @@ export default {
       top: -2px;
     }
   }
-
 }
 </style>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 922 - 804
src/views/modules/kuaishouapp/account/accountIndex.vue


+ 22 - 8
src/views/modules/kuaishouapp/account/advertisingGroup.vue

@@ -1176,18 +1176,32 @@ let realTimeColumn=[
               ...res.result.appInfo,
               ...res.result.target
             }
-
+          if(this.campaignType=='2'||this.campaignType==2){
+            getAction('/kuaishou/batch/getIsActivate', {
+              accountId: localStorage.getItem('accountId'),
+              appId:this.copyData.appId,
+              campaignType:2
+            }).then(res => {
+              if (res.success) {
+                this.allForm.groupTypeData = res.result
+              }
+            })
+          }else{
+            getAction('/kuaishou/batch/getIsActivate', {
+              accountId: localStorage.getItem('accountId'),
+              campaignType:this.campaignType
+            }).then(res => {
+              if (res.success) {
+                this.allForm.groupTypeData = res.result
+              }
+            })
+          }
             this.copyLoading = false
           }
 
         })
-        getAction('/kuaishou/batch/getIsActivate', {
-          accountId: localStorage.getItem('accountId')
-        }).then(res => {
-          if (res.success) {
-            this.allForm.groupTypeData = res.result
-          }
-        })
+        
+       
       },
       toDetail(record) {
         // 点击改行时要做的事情

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1223 - 0
src/views/modules/kuaishouapp/account/copyAllUnit.vue


+ 14 - 1
src/views/modules/kuaishouapp/account/newMould.vue

@@ -47,7 +47,7 @@
         </span>
       </a-table>
     </a-row>
-    <a-modal v-model="visible" title="广告组创建信息" :width="900" v-if="visible" :maskClosable="false">
+    <a-modal v-model="visible" title="模板创建" :width="900" v-if="visible" :maskClosable="false" @cancel='newTemplateCancel'>
       <a-form-item label="模板名称" :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }">
         <a-input placeholder="请输入模板名称" v-model="name" style="width:100%;position:relative;" />
@@ -147,6 +147,8 @@
       handleSubmit(e) {
         //   this.$refs.population.handleSubmit()
         e.preventDefault()
+        if(this.name){
+
         this.$refs.population.handleSubmit()
         var data = this.populationData
         console.log(JSON.stringify(data))
@@ -182,6 +184,10 @@
             }
           })
         }
+        
+        }else{
+          this.$message.error('请输入模板名字')
+        }
       },
       getData(className) {
         return this.form.getFieldValue(className)
@@ -195,6 +201,13 @@
         console.log(item.templateContent)
         this.visible = true
       },
+      newTemplateCancel(){
+        this.active = ''
+        this.editId = undefined
+        this.name = ''
+        this.populationData = {}
+        this.visible = false
+      },
       handleDelete(id) {
         deleteAction('/kuaishou/batch/deleteDirectionalTemplate', {
           id: id

+ 1 - 1
src/views/modules/kuaishouapp/account/stepForm/Step1.vue

@@ -46,7 +46,7 @@
         <a-input
           v-decorator="[
             'dayBudget',
-            { rules: [{ required: true, message: 'error:' }, { validator: handleConfirmValue }] }
+            { rules: [{ required: true, message: ' ' }, { validator: handleConfirmValue }] }
           ]"
           placeholder="不小于500,不超过100000000,仅支持输入自然数"
           type="number"

+ 63 - 25
src/views/modules/kuaishouapp/account/stepForm/Step2.vue

@@ -45,7 +45,7 @@
         <creat-application ref="application" />
       </a-form-item>
       <a-form-item label="转化类型" :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
-        :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }" v-if="campaignType == '3'">
+        :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }" v-if="campaignType == 3">
         <a-radio-group buttonStyle="solid"
           v-decorator="['urlType', { rules: [{ required: true, message: '请选择目标应用' }], initialValue: '1' }]">
           <a-radio-button value="1">淘宝商品</a-radio-button>
@@ -87,7 +87,7 @@
         <a-form-item label="选择转化" :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
           :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }">
           <a-select allowClear labelInValue style="width:100%" v-model="convertId" @focus="getConvertList">
-            <a-select-option :value="item.convert_id" v-for="(item,index) in convertList" :key="item.convert_id">
+            <a-select-option :value="item.convert_id" v-for="(item) in convertList" :key="item.convert_id">
               {{item.convert_name}}</a-select-option>
           </a-select>
         </a-form-item>
@@ -108,7 +108,7 @@
         </a-checkbox>
       </a-form-item>
       <a-form-item label=" " :labelCol="{ lg: { span: 7}, sm: { span: 7 } }"
-        :wrapperCol="{ lg: { span: 10 }, sm: { span: 16 } }" class="else-label" v-if="getData('useAppMarket')">
+        :wrapperCol="{ lg: { span: 10 }, sm: { span: 16 } }" class="else-label" v-if="getData('useAppMarket')&&campaignType == '2'&&(getPlatForm(getData('appId'))=='1'||getPlatForm(getData('appId'))=='2')">
         请勾选投放应用已上架的应用商店(默认全选)
         <a-checkbox-group v-model="allForm.appStore">
           <a-checkbox value="huawei">华为</a-checkbox>
@@ -167,7 +167,7 @@
       </a-form-item>
       <a-form-item label=" " :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }" class="else-label" v-if="allForm.dayBudget == '1'">
-        <a-input placeholder="不小于100,不超过100000000,仅支持输入自然数" v-decorator="[
+        <a-input-number placeholder="不小于100,不超过100000000,仅支持输入自然数" style="width:100%" v-decorator="[
             'dayBudget',
             {
               rules: [{ required: true, message: '请填写预算' }, { validator: budgetValue }]
@@ -591,7 +591,7 @@
           scheduleTime: '1',
           scheduleTimeData: '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
           group: [],
-          groupTypeData: null,
+          groupTypeData: {},
           fail: [],
           success: [],
           sceneId: [7],
@@ -672,18 +672,38 @@
         this.checkedTrue = e.target.checked
       },
       addGroup() {
-        this.allForm.group.push({
-          bidType:  10,
-          bid: '',
-          cpaBid: '',
-          showTipCheck: false,
-          deepConversionBidCheck: false,
-          unitName: '',
-          unitNameCheck: false,
-          deepConversionType: '',
-          deepConversionBid: '',
-          ocpxActionType:this.campaignType == '2' && this.allForm.groupTypeData.isActivate == '1' ? 180 : 2,
-        })
+        if(this.campaignType=='2'||this.campaignType==2){
+          if(this.getData('appId')){
+            this.allForm.group.push({
+              bidType:  10,
+              bid: '',
+              cpaBid: '',
+              showTipCheck: false,
+              deepConversionBidCheck: false,
+              unitName: '',
+              unitNameCheck: false,
+              deepConversionType: '',
+              deepConversionBid: '',
+              ocpxActionType:this.campaignType == '2' && this.allForm.groupTypeData.isActivate == '1' ? 180 : 2,
+            })
+          }else{
+            this.$message.error('请选择目标应用之后添加广告组')
+          }
+        }else{
+           this.allForm.group.push({
+              bidType:  10,
+              bid: '',
+              cpaBid: '',
+              showTipCheck: false,
+              deepConversionBidCheck: false,
+              unitName: '',
+              unitNameCheck: false,
+              deepConversionType: '',
+              deepConversionBid: '',
+              ocpxActionType:this.campaignType == '2' && this.allForm.groupTypeData.isActivate == '1' ? 180 : 2,
+            })
+        }
+
       },
       resData(index) {
         this.allForm.group[index].bid = ''
@@ -959,6 +979,7 @@
                   var dataJson = JSON.stringify(dataElse)
                   localStorage.setItem('pans', dataJson)
                   localStorage.setItem('appId', this.getData('appId'))
+                  
                 }
               } else {
                 this.loading = false
@@ -973,6 +994,16 @@
       },
       handleChange(value) {
         //   this.$refs.population.getAppList(value)
+        this.allForm.group = []
+        getAction('/kuaishou/batch/getIsActivate', {
+          accountId: localStorage.getItem('accountId'),
+          appId:this.getData('appId'),
+          campaignType:2
+        }).then(res => {
+          if (res.success) {
+            this.allForm.groupTypeData = res.result
+          }
+        })
       },
       handleChangeMould(value) {
         if (value) {
@@ -1043,7 +1074,19 @@
         getAction('/kuaishou/batch/getCampaignList', params).then(res => {
           if (res.success) {
             this.campaignType = res.result.records[0].campaignType
-            console.log(this.campaignType)
+
+
+            if(this.campaignType!=2){
+              getAction('/kuaishou/batch/getIsActivate', {
+                accountId: localStorage.getItem('accountId'),
+                campaignType:this.campaignType
+              }).then(res => {
+                if (res.success) {
+                  this.allForm.groupTypeData = res.result
+                }
+              })
+            }
+            // console.log(this.campaignType)
           }
         })
       },
@@ -1061,13 +1104,8 @@
       this.getAppList()
       this.getCampaignList()
       this.getMould()
-      getAction('/kuaishou/batch/getIsActivate', {
-        accountId: localStorage.getItem('accountId')
-      }).then(res => {
-        if (res.success) {
-          this.allForm.groupTypeData = res.result
-        }
-      })
+
+
 
       getAction('/kuaishou/batch/getWhiteList',{
         accountId:localStorage.getItem('accountId')

+ 59 - 35
src/views/modules/kuaishouapp/account/stepForm/Step3.vue

@@ -432,21 +432,21 @@ li.chouzhen.first:before {
             </a-layout>
           </a-form-item>
 
-          <a-form-item label="创意分类" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-form-item label="创意分类" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="creativeCategorySwitch">
             <a-cascader
               :options="createOptions"
-              v-decorator="['creativeCategory']"
+              v-decorator="['creativeCategory',{ rules: [{ required: true, message: '创意分类必选' }] }]"
               :fieldNames="fieldNames"
               placeholder="请选择创意分类"
             />
           </a-form-item>
 
-          <a-form-item label="创意标签" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-form-item label="创意标签" :labelCol="labelCol" :wrapperCol="wrapperCol"  v-if="creativeCategorySwitch">
             <a-select
               mode="tags"
               style="width: 100%"
               placeholder="按回车生成标签"
-              v-decorator="['creativeTag', { validator: creativeTagValid }]"
+              v-decorator="['creativeTag',{ rules: [{ required: true, message: '创意标签必填' }] }]"
               dropdownClassName="display-none-selset"
               :token-separators="[',', ' ', ',']"
             >
@@ -541,7 +541,7 @@ li.chouzhen.first:before {
               >监测链接列表</a
             >
           </a-form-item>
-          <a-form-item label="第三方ActionBar点击监控链接" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-form-item label="第三方ActionBar点击监控链接" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="actionbarClickUrlSwitch">
             <a-input
               v-decorator="[
                 'actionbarClickUrl',
@@ -868,35 +868,35 @@ li.chouzhen.first:before {
       <span style="color: red" v-if="!showTrackUrlNameElse">名称重复</span>
     </a-modal>
     <a-modal title="监测链接列表" v-model="clickTrackUrlList" :width="1000" :footer="null">
-       <a-spin :spinning="spinning">
-      <a-row :gutter="10" class="onlny-click-track">
-        <a-col :sm="24" style="margin-bottom: 20px; z-index: 10">
-          <a-card class="search-box" style="over-flow: auto">
-            <!-- <a-input v-model="trackName"></a-input> -->
-            <a-input-search
-              placeholder="请输入监测链接名称"
-              enter-button="Search"
-              size="large"
-              @search="onSearch"
-              style="width: 40%; margin-bottom: 20px"
-              v-model="trackName"
-            />
-            <a-list size="large" bordered :dataSource="trackUrlList">
-              <a-list-item slot="renderItem" slot-scope="item" :title="item.trackUrl" style="line-height: 50px">
-                <div slot="actions">
-                  <a @click="okClickTrackUrl(item)">选择</a>
-                  <a-divider type="vertical" />
-                  <a @click="removeClickTrackUrl(item)">删除</a>
-                </div>
+      <a-spin :spinning="spinning">
+        <a-row :gutter="10" class="onlny-click-track">
+          <a-col :sm="24" style="margin-bottom: 20px; z-index: 10">
+            <a-card class="search-box" style="over-flow: auto">
+              <!-- <a-input v-model="trackName"></a-input> -->
+              <a-input-search
+                placeholder="请输入监测链接名称"
+                enter-button="Search"
+                size="large"
+                @search="onSearch"
+                style="width: 40%; margin-bottom: 20px"
+                v-model="trackName"
+              />
+              <a-list size="large" bordered :dataSource="trackUrlList">
+                <a-list-item slot="renderItem" slot-scope="item" :title="item.trackUrl" style="line-height: 50px">
+                  <div slot="actions">
+                    <a @click="okClickTrackUrl(item)">选择</a>
+                    <a-divider type="vertical" />
+                    <a @click="removeClickTrackUrl(item)">删除</a>
+                  </div>
 
-                {{ item.trackName }}
-                <a-input v-model="item.trackUrl" readOnly style="margin: 10px; width: 70%"></a-input>
-              </a-list-item>
-            </a-list>
-          </a-card>
-        </a-col>
-      </a-row>
-       </a-spin>
+                  {{ item.trackName }}
+                  <a-input v-model="item.trackUrl" readOnly style="margin: 10px; width: 70%"></a-input>
+                </a-list-item>
+              </a-list>
+            </a-card>
+          </a-col>
+        </a-row>
+      </a-spin>
     </a-modal>
   </a-card>
 </template>
@@ -945,7 +945,7 @@ export default {
       clickTrackUrlShow: false,
       clickTrackUrlShowType: '1',
       clickTrackUrlList: false,
-      spinning:false,
+      spinning: false,
       trackUrlList: [],
       trackUrlName: '',
       showSite: true,
@@ -1083,6 +1083,8 @@ export default {
       },
       tagName: '',
       optionsTag: [],
+      creativeCategorySwitch:false,
+      actionbarClickUrlSwitch:false,
     }
   },
   methods: {
@@ -2276,7 +2278,7 @@ export default {
   },
   mounted: function () {
     this.$nextTick(() => {
-      Splitting()
+      
       if (localStorage.getItem('pans')) {
         this.pans = JSON.parse(localStorage.getItem('pans')).map((item) => {
           return {
@@ -2374,6 +2376,28 @@ export default {
           this.stickerStyles = []
         }
       })
+
+      getAction('/kuaishou/batch/getWhiteList', {
+        accountId: localStorage.getItem('accountId'),
+      }).then((res) => {
+        if (res.success) {
+          // console.log(res)
+          if (res.result) {
+            this.creativeCategorySwitch = res.result.creative_category_switch == 1 ? true : false
+            this.actionbarClickUrlSwitch = res.result.actionbar_click_url_switch == 1 ? true : false
+
+            // if (res.result.alliance_account == 1) {
+            //   this.allianceAccount = true
+            // } else {
+            //   this.allianceAccount = false
+            // }
+          } else {
+            this.creativeCategorySwitch = false
+            this.actionbarClickUrlSwitch = false
+          }
+        }
+      })
+      Splitting()
     })
   },
 }

+ 59 - 9
src/views/modules/kuaishouapp/account/stepForm/Step4.vue

@@ -63,6 +63,9 @@
 .display-none-selset {
   display: none !important;
 }
+.only-step4 .ant-form-item-label {
+  text-align: left;
+}
 </style>
 <style scoped lang="scss">
 .actor-photo-list {
@@ -142,7 +145,7 @@ li.chouzhen.first:before {
 }
 </style>
 <template>
-  <a-card :body-style="{ padding: '24px 32px' }" :bordered="false" class="only-step3">
+  <a-card :body-style="{ padding: '24px 32px' }" :bordered="false" class="only-step4">
     <a-tabs style="width: 50%; margin: 0 auto" type="editable-card" hideAdd @edit="remove">
       <a-tab-pane
         v-for="(pane, bestIndex) in pans"
@@ -259,8 +262,8 @@ li.chouzhen.first:before {
                             >推荐封面</a
                           >
                           <br />
-                          <span v-for="(item, deleteIndex) of item.imageList" style="position: relative">
-                            <img :src="item.url" style="width: 18%; margin: 1%" :key="item.url" />
+                          <span v-for="(itemImg, deleteIndex) of item.imageList" style="position: relative">
+                            <img :src="itemImg.url" style="width: 18%; margin: 1%" :key="itemImg.url" />
                             <a-icon
                               type="close-circle"
                               @click="deleteData(index, bestIndex, deleteIndex)"
@@ -380,21 +383,21 @@ li.chouzhen.first:before {
             </div>
           </a-form-item>
 
-          <a-form-item label="创意分类" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-form-item label="创意分类" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="creativeCategorySwitch">
             <a-cascader
               :options="createOptions"
-              v-decorator="['creativeCategory']"
+              v-decorator="['creativeCategory',{ rules: [{ required: true, message: '创意分类必选' }] }]"
               :fieldNames="fieldNames"
               placeholder="请选择创意分类"
             />
           </a-form-item>
 
-          <a-form-item label="创意标签" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-form-item label="创意标签" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="creativeCategorySwitch">
             <a-select
               mode="tags"
               style="width: 100%"
               placeholder="按回车生成标签"
-              v-decorator="['creativeTag', { validator: creativeTagValid }]"
+              v-decorator="['creativeTag',{ rules: [{ required: true, message: '创意标签必填' }] }]"
               dropdownClassName="display-none-selset"
               :token-separators="[',',' ',',']"
             >
@@ -477,7 +480,7 @@ li.chouzhen.first:before {
           </a-form-item>
           
           <!-- , { validator: handleConfirmValue } -->
-          <a-form-item label="第三方ActionBar点击监控链接" :labelCol="labelCol" :wrapperCol="wrapperCol">
+          <a-form-item label="第三方ActionBar点击监控链接" :labelCol="labelCol" :wrapperCol="wrapperCol" v-if="actionbarClickUrlSwitch">
             <a-input
               v-decorator="[
                 'actionbarClickUrl',
@@ -878,6 +881,8 @@ export default {
   },
   data() {
     return {
+      creativeCategorySwitch: false,
+      actionbarClickUrlSwitch: false,
       optionsTag: [],
       defaultProps: {
         children: 'children',
@@ -1723,7 +1728,31 @@ export default {
       if (this.pans.length == 0) {
         this.$bus.$emit('remove', '/account/stepForm')
       } else {
-        this.addCreative(0)
+         this.horizontalPhoto = [
+          {
+            videoList: [],
+            imageList: [],
+            creativeMaterialType: '2',
+            imageUrlList: [],
+            checkArrImage: [],
+            chouzhenShow: false,
+          },
+        ]
+        this.verticalPhoto = [
+          {
+            videoList: [],
+            imageList: [],
+            creativeMaterialType: '1',
+            imageUrlList: [],
+            checkArrImage: [],
+            chouzhenShow: false,
+          },
+        ]
+        this.captionsList = [{ captions: '' }]
+        this.stickerStylesValue = []
+        this.coverSlogansList = [{ coverSlogans: '' }]
+        this.addCreative(0)
+        this.addAdList(0)
         getAction('/kuaishou/batch/checkCreativeCount', {
           unitId: this.pansKey,
           accountId: localStorage.getItem('accountId'),
@@ -2443,6 +2472,27 @@ export default {
           this.stickerStyles = []
         }
       })
+
+      getAction('/kuaishou/batch/getWhiteList', {
+        accountId: localStorage.getItem('accountId'),
+      }).then((res) => {
+        if (res.success) {
+          // console.log(res)
+          if (res.result) {
+            this.creativeCategorySwitch = res.result.creative_category_switch == 1 ? true : false
+            this.actionbarClickUrlSwitch = res.result.actionbar_click_url_switch == 1 ? true : false
+
+            // if (res.result.alliance_account == 1) {
+            //   this.allianceAccount = true
+            // } else {
+            //   this.allianceAccount = false
+            // }
+          } else {
+            this.creativeCategorySwitch = false
+            this.actionbarClickUrlSwitch = false
+          }
+        }
+      })
     })
   },
 }

+ 54 - 31
src/views/modules/kuaishouapp/account/stepForm/stepModule/targetedPopulation.vue

@@ -164,14 +164,14 @@ li:hover {
     <a-form-item
       label="年龄"
       :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
-      :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+      :wrapperCol="{ lg: { span: 17 }, sm: { span: 17 } }"
     >
       <a-radio-group v-model="allForm.ageType" buttonStyle="solid">
         <a-radio-button value="noLimit">不限</a-radio-button>
         <a-radio-button value="ageLimit">限定年龄段</a-radio-button>
         <a-radio-button value="ageCustom">自定义年龄段</a-radio-button>
       </a-radio-group>
-      <div v-if="allForm.ageType == 'ageLimit'">
+      <div v-if="allForm.ageType == 'ageLimit'" style="margin-top: 5px">
         <a-checkbox-group v-decorator="['agesRange', { rules: [{ required: true, message: '请选择年龄段' }] }]">
           <!-- <a-checkbox :value="0">0-11岁</a-checkbox>
           <a-checkbox :value="12">12-17岁</a-checkbox> -->
@@ -201,7 +201,7 @@ li:hover {
     <a-form-item
       label="性别"
       :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
-      :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+      :wrapperCol="{ lg: { span: 17 }, sm: { span: 17 } }"
     >
       <a-radio-group
         buttonStyle="solid"
@@ -234,6 +234,7 @@ li:hover {
       :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
       v-if="allForm.platform_os == 1"
       class="else-label"
+      style="margin-top: -16px"
     >
       <a-radio-group
         v-decorator="[
@@ -256,6 +257,7 @@ li:hover {
       :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
       v-if="allForm.platform_os == 2"
       class="else-label"
+      style="margin-top: -16px"
     >
       <a-radio-group
         v-decorator="[
@@ -282,22 +284,22 @@ li:hover {
         <a-radio-button value="0">不限</a-radio-button>
         <a-radio-button value="1">选择品牌</a-radio-button>
       </a-radio-group>
-      <div v-if="allForm.device == '1'" style="width: 120%">
+      <div v-if="allForm.device == '1'" style="width: 120%; margin-top: 15px">
         <a-checkbox-group
           v-decorator="['deviceBrand', { rules: [{ required: true, message: '请选择设备品牌' }] }]"
           style="width: 120%"
         >
-          <a-checkbox :value="1">OPPO</a-checkbox>
-          <a-checkbox :value="2">VIVO</a-checkbox>
-          <a-checkbox :value="3">华为</a-checkbox>
-          <a-checkbox :value="4">小米</a-checkbox>
-          <a-checkbox :value="5">荣耀</a-checkbox>
-          <a-checkbox :value="6">三星</a-checkbox>
-          <a-checkbox :value="7">金立</a-checkbox>
-          <a-checkbox :value="8">魅族</a-checkbox>
-          <a-checkbox :value="9">乐视</a-checkbox>
-          <a-checkbox :value="10">其他</a-checkbox>
-          <a-checkbox :value="11" v-if="allForm.platform_os == 0">苹果</a-checkbox>
+          <a-checkbox :value="1" style="margin-bottom: 8px">OPPO</a-checkbox>
+          <a-checkbox :value="2" style="margin-bottom: 8px">VIVO</a-checkbox>
+          <a-checkbox :value="3" style="margin-bottom: 8px">华为</a-checkbox>
+          <a-checkbox :value="4" style="margin-bottom: 8px">小米</a-checkbox>
+          <a-checkbox :value="5" style="margin-bottom: 8px">荣耀</a-checkbox>
+          <a-checkbox :value="6" style="margin-bottom: 8px">三星</a-checkbox>
+          <a-checkbox :value="7" style="margin-bottom: 8px">金立</a-checkbox>
+          <a-checkbox :value="8" style="margin: 0 0 8px 0">魅族</a-checkbox>
+          <a-checkbox :value="9" style="margin-bottom: 8px">乐视</a-checkbox>
+          <a-checkbox :value="10" style="margin-bottom: 8px">其他</a-checkbox>
+          <a-checkbox :value="11" v-if="allForm.platform_os == 0" style="margin-bottom: 8px">苹果</a-checkbox>
         </a-checkbox-group>
       </div>
     </a-form-item>
@@ -310,21 +312,21 @@ li:hover {
         <a-radio-button value="0">不限</a-radio-button>
         <a-radio-button value="1">选择价格</a-radio-button>
       </a-radio-group>
-      <div v-if="allForm.price == '1'" style="width: 120%">
+      <div v-if="allForm.price == '1'" style="width: 120%; margin-top: 10px">
         <a-checkbox-group
           v-decorator="['devicePrice', { rules: [{ required: true, message: '请选择设备价格' }] }]"
           style="width: 120%"
         >
-          <a-checkbox :value="1">1500以下</a-checkbox>
-          <a-checkbox :value="2">1501~2000</a-checkbox>
-          <a-checkbox :value="3">2001~2500</a-checkbox>
-          <a-checkbox :value="4">2501~3000</a-checkbox>
-          <a-checkbox :value="5">3001~3500</a-checkbox>
-          <a-checkbox :value="6">3501~4000</a-checkbox>
-          <a-checkbox :value="7">4001~4500</a-checkbox>
-          <a-checkbox :value="8">4501~5000</a-checkbox>
-          <a-checkbox :value="9">5001~5500</a-checkbox>
-          <a-checkbox :value="10">5500以上</a-checkbox>
+          <a-checkbox :value="1" style="margin-bottom: 8px">1500以下</a-checkbox>
+          <a-checkbox :value="2" style="margin-bottom: 8px">1501~2000</a-checkbox>
+          <a-checkbox :value="3" style="margin-bottom: 8px">2001~2500</a-checkbox>
+          <a-checkbox :value="4" style="margin-bottom: 8px">2501~3000</a-checkbox>
+          <a-checkbox :value="5" style="margin-left: 0; margin-bottom: 8px">3001~3500</a-checkbox>
+          <a-checkbox :value="6" style="margin-bottom: 8px">3501~4000</a-checkbox>
+          <a-checkbox :value="7" style="margin-bottom: 8px">4001~4500</a-checkbox>
+          <a-checkbox :value="8" style="margin-bottom: 8px">4501~5000</a-checkbox>
+          <a-checkbox :value="9" style="margin-left: 0; margin-bottom: 8px">5001~5500</a-checkbox>
+          <a-checkbox :value="10" style="margin-bottom: 8px">5500以上</a-checkbox>
         </a-checkbox-group>
       </div>
     </a-form-item>
@@ -536,7 +538,7 @@ li:hover {
     <a-form-item
       label="过滤已转化用户"
       :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
-      :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+      :wrapperCol="{ lg: { span: 15 }, sm: { span: 15 } }"
     >
       <!-- v-decorator="[
           'isOpen',
@@ -959,8 +961,14 @@ export default {
   computed: {},
   methods: {
     getPeople() {
+      var data = ''
+      if (this.$route.path == '/creat/creatUnit') {
+        data = localStorage.getItem('campaignAccountId')
+      } else {
+        data = localStorage.getItem('accountId')
+      }
       return new Promise((resolve, reject) => {
-        getAction('/kuaishou/batch/getPopulationList', { accountId: localStorage.getItem('accountId') }).then((res) => {
+        getAction('/kuaishou/batch/getPopulationList', { accountId: data }).then((res) => {
           if (res.success) {
             if (res.result) {
               this.dataList = res.result.map((item, index) => {
@@ -1138,6 +1146,10 @@ export default {
       this.formAll.validateFields((err, values) => {
         if (!err) {
           //   this.checkArr
+          if(values.age){
+              values.min=values.age[0];
+              values.max=values.age[1];
+          }
           var json = {}
           if (this.allForm.appType == '2') {
             json.appIds = this.optionsAll
@@ -1212,10 +1224,15 @@ export default {
     getAppAllElse(e) {
       this.checkArr = this.optionsAll
       // this.getAppAll()
-
+      var data = ''
+      if (this.$route.path == '/creat/creatUnit') {
+        data = localStorage.getItem('campaignAccountId')
+      } else {
+        data = localStorage.getItem('accountId')
+      }
       if (this.appListValue != '') {
         getAction('/kuaishou/batch/getAppSearch', {
-          accountId: localStorage.getItem('accountId'),
+          accountId: data,
           appName: e.target.value,
         }).then((res) => {
           if (res.result) {
@@ -1233,9 +1250,15 @@ export default {
       }
     },
     getAppAll(e) {
+      var data = ''
+      if (this.$route.path == '/creat/creatUnit') {
+        data = localStorage.getItem('campaignAccountId')
+      } else {
+        data = localStorage.getItem('accountId')
+      }
       if (e.target.value !== '') {
         getAction('/kuaishou/batch/getAppSearch', {
-          accountId: localStorage.getItem('accountId'),
+          accountId: data,
           appName: e.target.value,
         }).then((res) => {
           if (res.result) {

+ 44 - 38
src/views/modules/kuaishouapp/account/stepForm/stepModule/test.vue

@@ -3,10 +3,10 @@
     <table class="time_table table" v-on:mouseleave="mouseleave">
       <thead>
         <tr>
-          <th rowspan="2" style="width:120px">日期/时间</th>
+          <th rowspan="2" style="width: 120px">日期/时间</th>
         </tr>
         <tr>
-          <th class="unselectable" v-for="(num, index) in numData" :key="index" style="width:30px">{{ num }}</th>
+          <th class="unselectable" v-for="(num, index) in numData" :key="index" style="width: 30px">{{ num }}</th>
         </tr>
       </thead>
       <tbody>
@@ -41,8 +41,8 @@ export default {
       type: String,
       default() {
         return '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
-      }
-    }
+      },
+    },
   },
   data() {
     return {
@@ -52,39 +52,39 @@ export default {
       timeData: [
         {
           date: '周一',
-          time: []
+          time: [],
         },
         {
           date: '周二',
-          time: []
+          time: [],
         },
         {
           date: '周三',
-          time: []
+          time: [],
         },
         {
           date: '周四',
-          time: []
+          time: [],
         },
         {
           date: '周五',
-          time: []
+          time: [],
         },
         {
           date: '周六',
-          time: []
+          time: [],
         },
         {
           date: '周日',
-          time: []
-        }
+          time: [],
+        },
       ],
       selectFlag: false,
       max: {
         x: 0,
-        y: 0
+        y: 0,
       },
-      dataString: ''
+      dataString: '',
     }
   },
   methods: {
@@ -102,7 +102,7 @@ export default {
     showOne(index, key) {
       //   this.timeData[index].time[key].isSelected = !this.timeData[index].time[key].isSelected
     },
-    mousedown: function(index, key) {
+    mousedown: function (index, key) {
       this.selectStart = []
       this.selectFlag = true
       if (this.timeData[index].time[key].value == false) {
@@ -114,10 +114,10 @@ export default {
       }
       this.selectStart.push({
         index: index,
-        key: key
+        key: key,
       })
     },
-    mouseover: function(index, key) {
+    mouseover: function (index, key) {
       // x 垂直方向  y 水平方向
       if (this.selectFlag) {
         if (index >= this.max.x) {
@@ -128,11 +128,11 @@ export default {
         }
         var start = {
           x: this.selectStart[0].index,
-          y: this.selectStart[0].key
+          y: this.selectStart[0].key,
         }
         var end = {
           x: index,
-          y: key
+          y: key,
         }
         for (var i = end.x; i <= this.max.x; i++) {
           for (var j = end.y; j <= this.max.y; j++) {
@@ -153,14 +153,14 @@ export default {
         }
       }
     },
-    mouseup: function(index, key) {
+    mouseup: function (index, key) {
       var start = {
         x: this.selectStart[0].index,
-        y: this.selectStart[0].key
+        y: this.selectStart[0].key,
       }
       var end = {
         x: index,
-        y: key
+        y: key,
       }
       /* 渲染选中的区域 */
       var data = []
@@ -179,7 +179,7 @@ export default {
         this.timeData[5].time,
         this.timeData[6].time
       )
-      this.dataString = arr.map(item => {
+      this.dataString = arr.map((item) => {
         if (item.isSelected) {
           return 1
         } else {
@@ -191,10 +191,10 @@ export default {
       this.selectFlag = false
       this.max = {
         x: 0,
-        y: 0
+        y: 0,
       }
     },
-    mouseleave: function() {
+    mouseleave: function () {
       this.selectFlag = false
     },
     setItemDate(sum) {
@@ -216,37 +216,43 @@ export default {
       }
     },
     init() {
-      var str = this.scheduleTime
+      var str = ''
+      if (this.scheduleTime) {
+        str = this.scheduleTime
+      } else {
+        str =
+          '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
+      }
       var arr = str.split('')
       this.timeData = [
         {
           date: '周一',
-          time: []
+          time: [],
         },
         {
           date: '周二',
-          time: []
+          time: [],
         },
         {
           date: '周三',
-          time: []
+          time: [],
         },
         {
           date: '周四',
-          time: []
+          time: [],
         },
         {
           date: '周五',
-          time: []
+          time: [],
         },
         {
           date: '周六',
-          time: []
+          time: [],
         },
         {
           date: '周日',
-          time: []
-        }
+          time: [],
+        },
       ]
       for (let i = 0; i < arr.length; i++) {
         if (i < 24) {
@@ -265,16 +271,16 @@ export default {
           this.timeData[6].time.push({ isSelected: arr[i] == 1 ? true : false, move: false, value: false })
         }
       }
-    }
+    },
   },
   watch: {
     scheduleTime: {
       immediate: true, // immediate选项可以开启首次赋值监听
       handler(newVal, oldVal) {
         this.init()
-      }
-    }
-  }
+      },
+    },
+  },
 }
 </script>
 

+ 102 - 55
src/views/modules/kuaishouapp/batchCreation/campaignList.vue

@@ -15,6 +15,7 @@
       <a-col :span="24" style="display: flex">
         <Treeselect :appId.sync="appId" :multiple="false" request="2,4" ref="treeSelect" style="margin: 8px 20px" />
         <a-button type="primary" style="margin: 10px" @click="addUser">搜索</a-button>
+        <!-- <a-button type="primary" style="margin: 10px; float: right" @click="newCreat">批量创建</a-button> -->
       </a-col>
     </a-row>
     <a-form layout="inline">
@@ -49,6 +50,8 @@
     </a-row>
     <a-row style="margin-top: 15px">
       <a-card>
+        <!-- :btn="btn"  -->
+
         <a-button @click="dianji" style="margin-bottom: 15px">新增广告计划</a-button>
         <div v-show="selectedRowKeys.length > 0">
           请输入修改金额:
@@ -106,6 +109,18 @@
           :pagination="ipagination"
           @change="sort"
         >
+          <span slot="actionTwo" slot-scope="text, record">
+            <a-popconfirm @confirm="getInfo(record, 'allUnit')">
+              <div slot="title">
+                <div>
+                  计划名称:
+                  <a-input placeholder="请输入" v-model="refuseReason" style="display: inline-block; width: 500px" />
+                </div>
+              </div>
+              <!-- <a-button slot="okText" type="primary" :disabled="refuseReason == ''">确定</a-button> -->
+              <a @click="setData(record)">复制此计划下所有组</a>
+            </a-popconfirm>
+          </span>
           <template slot="campaignName" slot-scope="text, record">
             <div style="display: flex; justify-content: center">
               <a @click="toDetail(record)" class="count" v-show="!record.editName">{{ text }}</a>
@@ -193,51 +208,22 @@
       </template>
     </a-modal>
 
-    <!-- 实时数据 -->
-    <a-modal v-model="realTimeVisiable" title="广告计划实时数据" @afterClose="clear" width="80%" :maskClosable="false">
-      <div class="optBody">
-        <a-range-picker
-          :disabled-date="disabledDate"
-          format="YYYY-MM-DD"
-          style="width: 250px"
-          @change="dateValueChange"
-          v-model="dateValue"
-        />
-      </div>
-      <div class="tableBox" style="margin-top: 20px; min-height: 400px">
-        <a-table
-          size="middle"
-          :columns="realTimeColumn"
-          :dataSource="realTimeData"
-          bordered
-          :pagination="false"
-          :scroll="{ x: scrollX }"
-          :loading="realTimeLoading"
-          ref="accountTable"
-          style="word-break: break-all"
-        >
-          <span slot="ctr" slot-scope="text">{{ text | toPercentage }}</span>
-          <span slot="action_ratio" slot-scope="text">{{ text | toPercentage }}</span>
-          <span slot="photo_click_ratio" slot-scope="text">{{ text | toPercentage }}</span>
-
-          <span slot="charge" slot-scope="text">{{ text | decimalsHandle }}</span>
-          <span slot="activationCost" slot-scope="text, records">{{
-            (records.activation / records.charge) | decimalsHandle
-          }}</span>
-          <span slot="event_register_cost" slot-scope="text">{{ text | decimalsHandle }}</span>
-          <span slot="form_cost" slot-scope="text">{{ text | decimalsHandle }}</span>
-          <span slot="event_order_paid_cost" slot-scope="text">{{ text | decimalsHandle }}</span>
+    <a-modal v-model="allUnitCopy" title="复制计划下所有组" width="80%" :maskClosable="false">
+      <a-form-item
+        label="是否修改定向与出价"
+        :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
+        :wrapperCol="{ lg: { span: 17 }, sm: { span: 17 } }"
+      >
+        <a-radio-group buttonStyle="solid" v-model="editUnit" @change="editUnitType">
+          <a-radio-button value="1">是</a-radio-button>
+          <a-radio-button value="2">否</a-radio-button>
+        </a-radio-group>
+      </a-form-item>
 
-          <span slot="show" slot-scope="text">{{ text | formatCurrency }}</span>
-          <span slot="photo_click" slot-scope="text">{{ text | formatCurrency }}</span>
-          <span slot="aclick" slot-scope="text">{{ text | formatCurrency }}</span>
-          <span slot="bclick" slot-scope="text">{{ text | formatCurrency }}</span>
-          <span slot="activation" slot-scope="text">{{ text | formatCurrency }}</span>
-          <span slot="event_register" slot-scope="text">{{ text | formatCurrency }}</span>
-          <span slot="form_count" slot-scope="text">{{ text | formatCurrency }}</span>
-          <span slot="event_order_paid" slot-scope="text">{{ text | formatCurrency }}</span>
-        </a-table>
-      </div>
+      <copyAllUnit ref="copyAllUnit" v-if="editUnit == '1'" @getUnitData="getUnitData" />
+      <template slot="footer">
+        <a-button key="submit" type="primary" @click="handleEditAllUnit"> 确定 </a-button>
+      </template>
     </a-modal>
   </div>
 </template>
@@ -252,7 +238,7 @@ import { deleteAction, getAction, postAction } from '@/api/manage'
 
 import Treeselect from '@/views/modules/Statistics/components/Treeselect.vue'
 
-//   import copyGroup from './copyGroup'
+import copyAllUnit from '../account/copyAllUnit'
 
 var columns = [
   {
@@ -265,6 +251,16 @@ var columns = [
       customRender: 'campaignName',
     },
   },
+  // {
+  //   title: '操作',
+  //   align: 'center',
+  //   dataIndex: 'actionTwo',
+  //   fixed: 'left',
+  //   width: 200,
+  //   scopedSlots: {
+  //     customRender: 'actionTwo',
+  //   },
+  // },
   {
     title: '计划单日预算金额',
     align: 'center',
@@ -461,6 +457,7 @@ export default {
     ARow,
     countTo,
     Treeselect,
+    copyAllUnit,
     //   copyGroup
   },
   data: function () {
@@ -550,6 +547,12 @@ export default {
       campaignBudget: 'UNLIMITED',
       unitId: '',
       campaignId: '',
+      editUnit: '2',
+      allUnitCopy: false,
+      oldCampaignId: '',
+      oldCampaignName: '',
+      newCampaignId: '',
+      campaignType: '',
     }
   },
   filters: {
@@ -669,6 +672,50 @@ export default {
     },
   },
   methods: {
+    newCreat() {
+      if (this.appId) {
+        window.open('/user/new-batch?accountId=' + this.appId, '_blank')
+      } else {
+        window.open('/user/new-batch', '_blank')
+      }
+    },
+    getUnitData() {
+      this.addUser()
+      this.allUnitCopy = false
+      this.editUnit = '2'
+    },
+    handleEditAllUnit(e) {
+      if (this.editUnit == '1') {
+        this.$refs.copyAllUnit.handleSubmit(e)
+      } else {
+        postAction('/kuaishouCampaignCopyData/add', {
+          accountId: this.appId,
+          oldCampaignId: this.oldCampaignId,
+          oldCampaignName: this.oldCampaignName,
+          newCampaignId: this.newCampaignId,
+        }).then((res) => {
+          if (res.success) {
+            this.addUser()
+            this.allUnitCopy = false
+          }
+        })
+      }
+    },
+    editUnitType() {
+      if (this.editUnit == '2') {
+      } else {
+        var params = {
+          accountId: this.appId,
+          oldCampaignId: this.oldCampaignId,
+          oldCampaignName: this.oldCampaignName,
+          newCampaignId: this.newCampaignId,
+          campaignType: this.campaignType,
+        }
+        this.$nextTick(() => {
+          this.$refs.copyAllUnit.handleOk(params)
+        })
+      }
+    },
     disabledDate(current) {
       // console.log(current)
       return (current && current > moment()) || (current && current < moment().subtract(7, 'days'))
@@ -777,7 +824,8 @@ export default {
       d = d < 10 ? '0' + d : d
       this.refuseReason = item.campaignName + '-' + y + '/' + MM + '/' + d
     },
-    getInfo(item) {
+    getInfo(item, type) {
+      this.editUnit == '2'
       if (this.refuseReason == '') {
         this.$message.error('请输入计划名称')
         return
@@ -790,15 +838,13 @@ export default {
         params.accountId = this.appId + ''
         postAction('/kuaishou/batch/campaignCreate', params).then((res) => {
           if (res.success) {
-            this.jihua = true
-            this.loadingGroup = false
-            this.refuseReason = ''
-            this.unitId = ''
-            // 7156834
-            this.planId = res.result
-            this.campaignId = item.campaignId
-            this.getDataList(item.campaignId)
-            this.addUser()
+            if (type) {
+              this.allUnitCopy = true
+              this.oldCampaignId = item.campaignId
+              this.oldCampaignName = item.campaignName
+              this.newCampaignId = res.result
+              this.campaignType = item.campaignType
+            }
           } else {
             this.$message.error(res.message)
           }
@@ -844,6 +890,7 @@ export default {
       if (this.appId) {
         this.getSpend(params)
         this.getCampaignList(params)
+        localStorage.setItem('campaignAccountId', this.appId)
       } else {
         this.$message.error('请选择账户')
       }

+ 3 - 3
src/views/modules/kuaishouapp/batchCreation/creat/creatCampaign.vue

@@ -46,7 +46,7 @@
         <a-input
           v-decorator="[
             'dayBudget',
-            { rules: [{ required: true, message: 'error:' }, { validator: handleConfirmValue }] },
+            { rules: [{ required: true, message: ' ' }, { validator: handleConfirmValue }] },
           ]"
           placeholder="不小于500,不超过100000000,仅支持输入自然数"
           type="number"
@@ -135,10 +135,10 @@ export default {
               localStorage.setItem('campaignList', res.result)
               localStorage.setItem('campaignType', this.type)
               this.loading = false
-              this.$router.replace({
+              this.$bus.$emit('remove', '/creat/creatCampaign')
+              this.$router.push({
                 path: '/creat/creatUnit',
               })
-              this.$bus.$emit('remove', '/creat/creatCampaign')
             } else {
               this.$message.error(res.message)
               this.loading = false

+ 247 - 83
src/views/modules/kuaishouapp/batchCreation/creat/creatUnit.vue

@@ -87,7 +87,7 @@
         :label="campaignType == 3 ? ' ' : '链接'"
         :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
-        v-if="campaignType != 2"
+        v-if="campaignType == 3||campaignType == 4||campaignType == 5||campaignType == 6||campaignType == 7"
         :class="{ 'else-label': campaignType == 3 }"
       >
         <a-input
@@ -166,7 +166,7 @@
         :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 16 } }"
         class="else-label"
-        v-if="getData('useAppMarket')"
+        v-if="getData('useAppMarket')&&campaignType == '2' && (getPlatForm(getData('appId')) == '1' || getPlatForm(getData('appId')) == '2')"
       >
         请勾选投放应用已上架的应用商店(默认全选)
         <a-checkbox-group v-model="allForm.appStore">
@@ -441,16 +441,22 @@
           :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
           v-if="item.bidType == 1"
         >
+                    <!-- v-model="item.bid" -->
           <a-input-number
-            v-model="item.bid"
-            @change="showTip(index)"
+
+            v-decorator="[
+            'bid',
+            {
+              rules: [{ required: true, message: '出价必填' }, {validator: bidCheck}],
+            },
+          ]"
             :style="{ borderColor: item.showTipCheck ? 'red' : '#d9d9d9' }"
             style="width: 100%"
           >
           </a-input-number>
-          <span style="color: red" v-if="item.showTipCheck && item.ocpxActionType == 180"
+          <!-- <span style="color: red" v-if="item.showTipCheck && item.ocpxActionType == 180"
             >不得低于0.2元,不得高于项目最高出价{{ maxBid }}元</span
-          >
+          > -->
         </a-form-item>
         <a-form-item
           label="目标成本"
@@ -458,21 +464,26 @@
           :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
           v-else
         >
+                    <!-- v-model="item.cpaBid" -->
           <a-input-number
-            v-model="item.cpaBid"
-            @change="showTip(index)"
-            :style="{ borderColor: item.showTipCheck ? 'red' : '#d9d9d9' }"
+
+            v-decorator="[
+            'cpaBid',
+            {
+              rules: [{ required: true, message: '目标成本必填' }, {validator: cpaBidCheck}],
+            },]"
+          
             style="width: 100%"
           >
           </a-input-number>
-          <span style="color: red" v-if="item.showTipCheck">{{
+          <!-- <span style="color: red" v-if="item.showTipCheck">{{
             item.bidType == 1
               ? '不得低于1元,不得高于项目最高出价' + maxBid + '元'
               : '不得低于1元,不得高于项目最高出价' + maxBid + '元'
-          }}</span>
+          }}</span> -->
           <span
             style="color: red; font-weight: 700"
-            v-else-if="item.ocpxActionType == 2 && item.cpaBid && item.cpaBid > 1"
+            v-if="item.ocpxActionType == 2 && getData('cpaBid') && getData('cpaBid') > 1"
           >
             行为出价大于1元,请注意!!!
           </span>
@@ -492,7 +503,7 @@
             @change="deep_conversion_bidTip(index)"
             :style="{ borderColor: item.deepConversionBidCheck ? 'red' : '#d9d9d9' }"
             style="width: 100%"
-            :disabled="item.cpaBid == ''"
+            :disabled="getData('cpaBid')==null||getData('cpaBid') == ''"
           ></a-input-number>
           <span style="color: red" v-if="item.deepConversionBidCheck"
             >深度转化目标成本必须高于优化目标成本,且不得高于3000元</span
@@ -503,7 +514,12 @@
           :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
           :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
         >
-          <a-input v-model="item.unitName" @change="checkGroup($event, index)"></a-input>
+        <!-- v-model="item.unitName"  -->
+          <a-input  v-decorator="[
+            'unitName',
+            {
+              rules: [{ required: true, message: '广告组必填' }, {validator: handleConfirmValue}],
+            },]" @change="checkGroup($event, index)"></a-input>
           <span style="color: red" v-if="item.unitNameCheck">广告组名称重复</span>
         </a-form-item>
       </div>
@@ -517,7 +533,7 @@
         <a-radio-group
           buttonStyle="solid"
           v-decorator="['creativeMaterialType', { initialValue: '1' }]"
-          @change="changeType(item)"
+          @change="changeType()"
         >
           <a-radio-button value="1">竖版视频</a-radio-button>
           <a-radio-button value="2">横版视频</a-radio-button>
@@ -540,11 +556,25 @@
         ></a-input>
       </a-form-item>
       <a-form-item
+        label="创建类型"
+        :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
+        :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+      >
+         <a-radio-group
+          buttonStyle="solid"
+          v-decorator="['createType', { rules: [{ required: true, message: '请选择目标应用' }], initialValue: '0' }]"
+          @change="getPageSize"
+        >
+          <a-radio-button value="0">单品</a-radio-button>
+          <a-radio-button value="1">混搭</a-radio-button>
+        </a-radio-group>
+      </a-form-item>
+      <a-form-item
         label="选择视频"
         :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
       >
-        <a @click="getVideoList()">选择视频</a> {{ videoList.length + '/' + getData('createCount') }}
+        <a @click="getVideoList()">选择视频</a> {{ videoList.length + '/' + (getData('createType')=='0'?getData('createCount'):getData('createCount')*15) }}
         <br />
         <div v-if="videoList.length > 0 && showVideo" style="display:flex;flex-wrap:wrap">
           <span v-for="(item, index) of videoList" :key="index" style="position: relative" class="width-video">
@@ -558,12 +588,20 @@
         :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
       >
+      <!-- v-model.trim="allForm.description" -->
+      <!-- @keyup="getData('description')?getData('description')=this.value.replace(/^ +| +$/g,'')" -->
         <a @click="showTitle()">推荐广告语</a>
         <div class="step4-else" style="display: inline-block; position: relative; border-radius: 4px; width: 100%; border: 1px solid #d9d9d9;">
           <a-textarea
             class="rending"
             placeholder="请输入广告语"
-            v-model.trim="allForm.description"
+             v-decorator="['description',{ rules: [{ required: true, message: '广告语必填' }] }]"
+             @keyup="getData('description')?form.setFieldsValue({
+                description: getData('description').replace(/\s/g,'')
+              }):null"
+            @change="getData('description')?form.setFieldsValue({
+                description: getData('description').replace(/\s/g,'')
+              }):null"
             :autosize="{ minRows: 2, maxRows: 6 }"
             :max-length="30"
           ></a-textarea>
@@ -581,7 +619,7 @@
               margin-bottom: 0;
             "
           >
-            {{ allForm.description.length + '/30' }}
+            {{ (getData('description')?getData('description').length:0) + '/30' }}
           </p>
         </div>
         <br />
@@ -597,10 +635,11 @@
         label="创意分类"
         :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+        v-if="creativeCategorySwitch"
       >
         <a-cascader
           :options="createOptions"
-          v-decorator="['creativeCategory']"
+          v-decorator="['creativeCategory',{ rules: [{ required: true, message: '创意分类必选' }] }]"
           :fieldNames="fieldNames"
           placeholder="请选择创意分类"
         />
@@ -609,19 +648,19 @@
         label="创意标签"
         :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+        v-if="creativeCategorySwitch"
       >
         <a-select
           mode="tags"
           style="width: 100%"
           placeholder="按回车生成标签"
-          v-decorator="['creativeTag']"
+          v-decorator="['creativeTag',{ rules: [{ required: true, message: '创意标签必填' }] }]"
           dropdownClassName="display-none-selset"
           :token-separators="[',', ' ', ',']"
         >
         </a-select>
         <span v-if="getData('creativeTag') && getData('creativeTag').length > 10" style="color: red"
-          >创意标签最多填写10个,请删减</span
-        >
+        >创意标签最多填写10个,请删减</span>
         <br />
         <a-popconfirm @confirm="getInfo()">
           <div slot="title">
@@ -700,6 +739,7 @@
         label="第三方ActionBar点击监控链接"
         :labelCol="{ lg: { span: 7 }, sm: { span: 7 } }"
         :wrapperCol="{ lg: { span: 10 }, sm: { span: 17 } }"
+        v-if="actionbarClickUrlSwitch"
       >
         <a-input v-decorator="['actionbarClickUrl']" placeholder="请输入第三方点击监控链接"> </a-input>
         <span style="color: red; position: relative; top: -10px">仅加白使用</span>
@@ -750,9 +790,14 @@
       :width="1000"
     >
       <a-tabs type="card" @change="callback" v-model="active" class="check-video">
-        <div slot="tabBarExtraContent">
-          当前选择数量{{ sumContent  + '/' + getData('createCount') }}
+        <div slot="tabBarExtraContent"> 
+          当前选择数量
+          {{ sumContent + '/' + (getData('createType')=='0'?getData('createCount'):getData('createCount')*15) }}
+          <a-button  type="primary" @click="tongbu()" :loading="tongbuLoading" style="margin-left:10px">
+          刷新素材</a-button
+        >
         </div>
+         
         <a-tab-pane :tab="item.label" v-for="item of tab" :key="item.value">
           <a-row :gutter="24">
             <a-col :span="12">
@@ -1152,12 +1197,17 @@ export default {
       checkVideo: [],
       checkVideoAll: [],
       checkVideoWai: [],
+      checkVideoWhole:[],
       dataSource: [],
       active: 0,
       time: [],
       channelType: 0,
       creativeMaterialType: '',
       tab: [
+        // {
+        //   value: 2,
+        //   label: '全部',
+        // },
         {
           value: 0,
           label: '内部',
@@ -1169,6 +1219,8 @@ export default {
       ],
       templateList: [],
       allianceAccount: false,
+      creativeCategorySwitch: false,
+      actionbarClickUrlSwitch: false,
       tongbuLoading: false,
       convert: false,
       convertId: '',
@@ -1204,7 +1256,7 @@ export default {
       appId: '',
       loading: false,
       campaignTemplateId: '',
-      campaignType: '2',
+      campaignType: null,
       maxBid: 0,
       allForm: {
         dayBudget: '0',
@@ -1237,6 +1289,7 @@ export default {
       cunTitleVisible: false,
       cunTitleList: [],
       createCount: 0,
+      tongbuLoading: false,
     }
   },
   computed: {
@@ -1265,6 +1318,35 @@ export default {
     },
   },
   methods: {
+    tongbu() {
+      this.tongbuLoading = true
+      getAction('/kuaishou/batch/syncVideo', {
+        accountId: localStorage.getItem('campaignAccountId'),
+      }).then((res) => {
+        if (res.success) {
+          this.$message.success(res.message)
+          this.tongbuLoading = false
+          var params = {}
+          params.accountId = localStorage.getItem('campaignAccountId')
+          params.materialType = this.creativeMaterialType
+          params.pageSize = this.ipagination.pageSize
+          params.pageNo = 1
+          params.status = 0
+          params.channelType = this.channelType
+          params.orderBy = this.orderBy
+          if (this.time.length > 0) {
+            // params.startDate = moment(this.time[0]).format('YYYY-MM-DD')
+            // params.endDate = moment(this.time[1]).format('YYYY-MM-DD')
+            params.startDate = moment(this.time[0]).format('YYYY-MM-DD') + ' 00:00:00'
+            params.endDate = moment(this.time[1]).format('YYYY-MM-DD') + ' 23:59:59'
+          }
+          this.showVideoList('/kuaishou/kuaiShouVideoGet/getVideoList', params)
+        } else {
+          this.$message.error(res.message)
+          this.tongbuLoading = false
+        }
+      })
+    },
     removeTitleCun(item) {
       deleteAction('/kuaishou/kuaiShouTitleCollection/delete', {
         id: item.id,
@@ -1276,17 +1358,20 @@ export default {
     },
     okTitleCun(item) {
       this.allForm.description = item.title
+      this.form.setFieldsValue({
+        description: item.title,
+      })
       this.cunTitleVisible = false
       this.cunTitleList = []
     },
     cunTitle() {
-      if (this.allForm.description == '') {
+      if (this.getData('description') && this.getData('description') == '') {
         this.$message.error('请填写广告语后再进行收藏')
       } else {
         var params = {}
         params.accountId = localStorage.getItem('campaignAccountId')
         params.userId = this.userInfo().id
-        params.title = this.allForm.description
+        params.title = this.getData('description')
         postAction('/kuaishou/kuaiShouTitleCollection/add', params).then((res) => {
           if (res.success) {
             this.$message.success('收藏成功')
@@ -1314,6 +1399,12 @@ export default {
     },
     okTitle(item) {
       this.allForm.description = item
+      this.$nextTick(() => {
+        this.form.setFieldsValue({
+          description: item,
+        })
+      })
+
       this.titleVisible = false
       this.dataOne = []
       this.value = ''
@@ -1616,14 +1707,29 @@ export default {
         sum += this.checkVideoWai[i].length
       }
       this.sumContent = sum
-      if (sum > this.getData('createCount')) {
-        this.$message.error('最多选择' + this.getData('createCount') + '个素材')
-        this.checkVideo = []
-        this.sumContent = this.sumContent - 5
-        if (this.active == 0) {
-          this.checkVideoAll[this.ipagination.current - 1] = this.checkVideo
-        } else if (this.active == 1) {
-          this.checkVideoWai[this.ipagination.current - 1] = this.checkVideo
+      if (this.getData('createType') == '0') {
+        if (sum > this.getData('createCount')) {
+          this.$message.error('最多选择' + this.getData('createCount') + '个素材')
+          this.checkVideo = []
+          this.sumContent = this.sumContent - 5
+
+          if (this.active == 0) {
+            this.checkVideoAll[this.ipagination.current - 1] = this.checkVideo
+          } else if (this.active == 1) {
+            this.checkVideoWai[this.ipagination.current - 1] = this.checkVideo
+          }
+        }
+      } else {
+        if (sum > this.getData('createCount') * 15) {
+          this.$message.error('最多选择' + this.getData('createCount') * 15 + '个素材')
+          this.checkVideo = []
+          this.sumContent = this.sumContent - 15
+
+          if (this.active == 0) {
+            this.checkVideoAll[this.ipagination.current - 1] = this.checkVideo
+          } else if (this.active == 1) {
+            this.checkVideoWai[this.ipagination.current - 1] = this.checkVideo
+          }
         }
       }
     },
@@ -1648,14 +1754,28 @@ export default {
         sum += this.checkVideoWai[i].length
       }
       this.sumContent = sum
-      if (sum > this.getData('createCount')) {
-        this.$message.error('最多选择' + this.getData('createCount') + '个素材')
-        this.checkVideo.pop()
-        this.sumContent--
-        if (this.active == 0) {
-          this.checkVideoAll[this.ipagination.current - 1] = this.checkVideo
-        } else if (this.active == 1) {
-          this.checkVideoWai[this.ipagination.current - 1] = this.checkVideo
+
+      if (this.getData('createType') == '0') {
+        if (sum > this.getData('createCount')) {
+          this.$message.error('最多选择' + this.getData('createCount') + '个素材')
+          this.checkVideo.pop()
+          this.sumContent--
+          if (this.active == 0) {
+            this.checkVideoAll[this.ipagination.current - 1] = this.checkVideo
+          } else if (this.active == 1) {
+            this.checkVideoWai[this.ipagination.current - 1] = this.checkVideo
+          }
+        }
+      } else {
+        if (sum > this.getData('createCount') * 15) {
+          this.$message.error('最多选择' + this.getData('createCount') * 15 + '个素材')
+          this.checkVideo.pop()
+          this.sumContent--
+          if (this.active == 0) {
+            this.checkVideoAll[this.ipagination.current - 1] = this.checkVideo
+          } else if (this.active == 1) {
+            this.checkVideoWai[this.ipagination.current - 1] = this.checkVideo
+          }
         }
       }
     },
@@ -1723,7 +1843,7 @@ export default {
         this.checkVideo = this.checkVideoWai[this.ipagination.current - 1]
       }
     },
-    changeType(item) {
+    changeType() {
       this.$nextTick(() => {
         if (this.getData('creativeMaterialType') == '1') {
           this.form.setFieldsValue({
@@ -1762,11 +1882,9 @@ export default {
       this.templateList = []
       getAction('/batch/kuaishouTemplate/list', {
         accountId: accountId,
-        pageSize: 1000,
-        pageNo: 1,
       }).then((res) => {
         if (res.success) {
-          this.templateList = res.result.records.map((item, index) => {
+          this.templateList = res.result.map((item, index) => {
             return {
               ...item,
               key: index,
@@ -1821,11 +1939,11 @@ export default {
     addGroup() {
       this.allForm.group.push({
         bidType: 10,
-        bid: '',
-        cpaBid: '',
+        // bid: '',
+        // cpaBid: '',
         showTipCheck: false,
         deepConversionBidCheck: false,
-        unitName: '',
+        // unitName: '',
         unitNameCheck: false,
         deepConversionType: '',
         deepConversionBid: '',
@@ -1833,19 +1951,25 @@ export default {
       })
     },
     resData(index) {
-      this.allForm.group[index].bid = ''
-      this.allForm.group[index].cpaBid = ''
+      // this.allForm.group[index].bid = ''
+      // this.allForm.group[index].cpaBid = ''
       this.allForm.group[index].showTipCheck = false
       this.allForm.group[index].deepConversionBidCheck = false
       this.allForm.group[index].deepConversionType = ''
       this.allForm.group[index].deepConversionBid = ''
+      this.form.setFieldsValue({
+        bid: undefined,
+      })
+      this.form.setFieldsValue({
+        cpaBid: undefined,
+      })
     },
     removeGroup(index) {
       this.allForm.group.splice(index, 1)
     },
     deep_conversion_bidTip(index) {
       if (
-        this.allForm.group[index].deepConversionBid < this.allForm.group[index].cpaBid ||
+        this.allForm.group[index].deepConversionBid < this.getData('cpaBid') ||
         this.allForm.group[index].deepConversionBid > 3000
       ) {
         this.allForm.group[index].deepConversionBidCheck = true
@@ -1869,13 +1993,13 @@ export default {
     },
     showTip(index) {
       if (this.allForm.group[index].bidType == 1) {
-        if (this.allForm.group[index].bid < 0.2 || this.allForm.group[index].bid > this.maxBid) {
+        if (this.getData('bid') < 0.2 || this.getData('bid') > this.maxBid) {
           this.allForm.group[index].showTipCheck = true
         } else {
           this.allForm.group[index].showTipCheck = false
         }
       } else {
-        if (this.allForm.group[index].cpaBid < 1 || this.allForm.group[index].cpaBid > this.maxBid) {
+        if (this.getData('cpaBid') < 1 || this.getData('cpaBid') > this.maxBid) {
           this.allForm.group[index].showTipCheck = true
         } else {
           this.allForm.group[index].showTipCheck = false
@@ -1902,23 +2026,38 @@ export default {
     getData(className) {
       return this.form.getFieldValue(className)
     },
+    bidCheck(rule, value, callback) {
+      if (value < 0.2 || value > this.maxBid) {
+        callback('不得低于0.2元,不得高于项目最高出价' + this.maxBid + '元')
+      } else {
+        callback()
+      }
+    },
+    cpaBidCheck(rule, value, callback) {
+      if (value < 1 || value > this.maxBid) {
+        callback('不得低于1元,不得高于项目最高出价' + this.maxBid + '元')
+      } else {
+        callback()
+      }
+    },
     handleConfirmValue(rule, value, callback) {
-      if (this.campaignType == 3) {
-        if (value == '') {
-          callback('请填写链接')
-        }
-      } else if (this.campaignType == 4) {
-        if (/(http|https):\/\/([\w.]+\/?)\S*/.test(value) && value != '' && value.length < 10000) {
-          callback()
-        } else {
-          callback('链接不能为空且开头为http://或https://,并且长度小于10000')
-        }
-      } else if (this.campaignType == 5) {
-        if (/(http|https):\/\/([\w.]+\/?)\S*/.test(value) && value != '' && value.length < 10000) {
-          callback()
-        } else {
-          callback('链接不能为空且开头为http://或https://,并且长度小于10000')
-        }
+      if (value != '' && value != undefined) {
+        getAction('/kuaishou/batch/checkUnitName', {
+          campaignId: localStorage.getItem('campaignList'),
+          unitName: value + '_0',
+        }).then((res) => {
+          if (res.success) {
+            if (!res.result) {
+              callback('广告组名称重复')
+            } else {
+              callback()
+            }
+          } else {
+            callback()
+          }
+        })
+      } else {
+        callback()
       }
     },
     budgetValue(rule, value, callback) {
@@ -2027,17 +2166,22 @@ export default {
     },
     handleSubmit(e) {
       e.preventDefault()
-      if (this.checkVideo.length < this.getData('createCount')) {
-        this.$message.error('选择的素材不能小于创建条数')
+      if (
+        this.checkVideo.length <
+        (this.getData('createType') == '0' ? this.getData('createCount') : this.getData('createCount') * 15)
+      ) {
+        // this.$message.error('选择的素材不能小于创建条数')
+        this.getData('createType') == '0'
+          ? this.$message.error('选择的素材不能小于创建条数')
+          : this.$message.error('选择的素材不能小于创建条数*15')
       } else {
-        this.form.validateFields((err, values) => {
+        this.form.validateFieldsAndScroll((err, values) => {
           if (!err) {
             this.loading = true
             var groupArr = this.allForm.group.map((item) => {
               return {
                 ...item,
-                cpaBid: item.cpaBid != '' ? item.cpaBid * 1000 : '',
-                bid: item.bid != '' ? item.bid * 1000 : '',
+
                 deepConversionBid: item.deepConversionBid != '' ? item.deepConversionBid * 1000 : '',
                 ocpxActionType: item.ocpxActionType,
                 bidType: item.bidType == 1 ? 2 : 10,
@@ -2045,6 +2189,8 @@ export default {
             })
             var json = {
               ...values,
+              cpaBid: values.cpaBid && values.cpaBid != '' ? values.cpaBid * 1000 : null,
+              bid: values.bid && values.bid != '' ? values.bid * 1000 : null,
               convertId: this.convertId ? this.convertId.key : null,
               dayBudget: values.dayBudget * 1000,
               photoArr: this.checkVideo,
@@ -2061,7 +2207,6 @@ export default {
               campaignId: localStorage.getItem('campaignList'),
               beginTime: moment(this.timeRange[0]).format('YYYY-MM-DD'),
               endTime: this.allForm.time == '2' ? moment(this.timeRange[1]).format('YYYY-MM-DD') : '',
-              description: this.allForm.description,
               appStore: values.useAppMarket == true ? this.allForm.appStore : null,
               useAppMarket: values.useAppMarket ? 1 : 0,
               sceneId: this.allForm.allianceAccount == '1' ? this.allForm.sceneId : [5],
@@ -2116,6 +2261,19 @@ export default {
     handleFocus() {
       // console.log('focus')
     },
+    getPageSize(data) {
+      if (data.target.value == '0') {
+        this.ipagination.pageSize = 5
+      } else if (data.target.value == '1') {
+        this.ipagination.pageSize = 15
+      }
+      this.videoList = []
+      this.checkVideo = []
+      this.checkVideoAll = []
+      this.checkVideoWai = []
+
+      this.sumContent = 0
+    },
     filterOption(input, option) {
       return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
     },
@@ -2188,7 +2346,7 @@ export default {
         viewComp: 7,
       }).then((res) => {
         if (res.success) {
-          this.siteList = res.result
+          this.siteLiRst = res.result
           if (this.siteList.length > 0) {
             this.showSite = true
           }
@@ -2257,13 +2415,19 @@ export default {
       if (res.success) {
         // console.log(res)
         if (res.result) {
-          if (res.result.alliance_account == 1) {
-            this.allianceAccount = true
-          } else {
-            this.allianceAccount = false
-          }
+          this.creativeCategorySwitch = res.result.creative_category_switch == 1 ? true : false
+          this.allianceAccount = res.result.alliance_account == 1 ? true : false
+          this.actionbarClickUrlSwitch = res.result.actionbar_click_url_switch == 1 ? true : false
+
+          // if (res.result.alliance_account == 1) {
+          //   this.allianceAccount = true
+          // } else {
+          //   this.allianceAccount = false
+          // }
         } else {
           this.allianceAccount = false
+          this.creativeCategorySwitch = false
+          this.actionbarClickUrlSwitch = false
         }
       }
     })

+ 1 - 3
src/views/modules/kuaishouapp/crossAccount/createUnit.vue

@@ -1418,11 +1418,9 @@ export default {
       this.templateList = []
       getAction('/batch/kuaishouTemplate/list', {
         accountId: accountId,
-        pageSize: 1000,
-        pageNo: 1,
       }).then((res) => {
         if (res.success) {
-          this.templateList = res.result.records.map((item, index) => {
+          this.templateList = res.result.map((item, index) => {
             return {
               ...item,
               key: index,

+ 31 - 7
src/views/modules/kuaishouapp/crossAccount/templateModal.vue

@@ -42,7 +42,9 @@
       </a-form>
     </a-spin>
     <template slot="footer">
-      <a-button type="primary" @click="handleSubmit" :loading="loading"> 确定 </a-button>
+      <!-- <a-button type="primary" @click="handleSubmit" :loading="loading"> 确定 </a-button> -->
+      <a-button type="default" @click="()=>{this.visible=false}" > 取消 </a-button>
+      <a-button type="primary" @click="handleSubmit" :loading="loading"> {{this.type=='add'?'确定':'修改'}} </a-button>
     </template>
   </a-modal>
 </template>
@@ -68,6 +70,7 @@ export default {
 
       populationData: {},
       accountId: '',
+      templateId:undefined,
       type: 'add',
       loading: false,
     }
@@ -87,6 +90,8 @@ export default {
       this.type = type
       var params = {}
       params.templateId = templateId
+      this.templateId=templateId;
+      this.accountId = accountId
       getAction('/batch/kuaishouTemplateTarget/getDetailByTemplateId', params).then((res) => {
         if (res.success) {
           var dataJson = {
@@ -109,7 +114,7 @@ export default {
           this.populationData.interestVideo = dataJson.interestVideo ? JSON.parse(dataJson.interestVideo) : null
           this.populationData.deviceBrand = dataJson.deviceBrand ? JSON.parse(dataJson.deviceBrand) : null
 
-          this.populationData.age = dataJson.ageMin ? [dataJson.ageMin, dataJson.ageMax] : []
+          this.populationData.age = dataJson.min ? [dataJson.min, dataJson.max] : []
           this.populationData.agesRange = dataJson.agesRange ? JSON.parse(dataJson.agesRange) : []
           this.populationData.devicePrice = dataJson.devicePrice ? dataJson.devicePrice : null
           this.populationData.allForm = {}
@@ -127,7 +132,7 @@ export default {
           // })
 
           this.populationData.allForm.ageType =
-            dataJson.agesRange.length > 0 ? 'ageLimit' : dataJson.ageMin ? 'ageCustom' : 'noLimit'
+            dataJson.agesRange.length > 0 ? 'ageLimit' : dataJson.min ? 'ageCustom' : 'noLimit'
           this.populationData.allForm.device = dataJson.deviceBrand ? '1' : '0'
           this.populationData.allForm.price = dataJson.devicePrice ? '1' : '0'
           this.populationData.allForm.appType = dataJson.appInterest ? '1' : dataJson.appIds ? '2' : '0'
@@ -141,7 +146,7 @@ export default {
           this.populationData.allForm.noAreaBreak = dataJson.noAreaBreak + ''
           this.populationData.allForm.checkArr =
             this.populationData.allForm.appType == '2' ? JSON.parse(dataJson.appIds) : []
-          this.$nextTick(() => {
+          this.$nextTick(() => { 
             console.log(dataJson)
             this.form.setFieldsValue(pick(dataJson, ['templateName']))
             this.spinning = false
@@ -159,14 +164,15 @@ export default {
       this.$refs.population.handleSubmit()
       this.form.validateFieldsAndScroll((err, values) => {
         if (!err) {
-          this.loading = true
+          // this.loading = true
 
           var params = {
             ...this.populationData,
             templateName: values.templateName,
             accountId: this.accountId,
+            
           }
-
+          console.log(params)
           if (this.type == 'add') {
             postAction('/batch/kuaishouTemplate/createTemplate', params).then((res) => {
               if (res.success) {
@@ -186,7 +192,25 @@ export default {
               }
             })
           } else if (this.type == 'look') {
-            this.visible = false
+            params.templateId=this.templateId
+         
+            postAction('/batch/kuaishouTemplate/updateTemplate', params).then((res) => {
+              this.visible = false
+              if (res.success) {
+                this.loading = false
+
+                getAction('/batch/kuaishouTemplate/getTemplateByAccountId', {
+                  accountId: this.accountId,
+                }).then((res) => {
+                  if (res.success) {
+                    this.$emit('getData', this.accountId)
+                  }
+                })
+              } else {
+                this.loading = false
+                this.$message.error(res.result.message)
+              }
+            })
           }
         }
       })

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 4786 - 0
src/views/modules/kuaishouapp/newBatch/index.vue


+ 0 - 0
src/views/modules/kuaishouapp/newBatch/lookPreview.vue


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác