소스 검색

Merge branch 'master' of http://git.tjyourong.com.cn/ctop/adsp-vue

jiayufei 4 년 전
부모
커밋
8c2b79aa73

+ 54 - 37
src/views/modules/autoLaunch/application/directional-service.js

@@ -11,44 +11,56 @@
         return [
             {
                 title: '账户名称',
-                dataIndex: 'accountName',
-                width: '30%'
+                dataIndex: 'authName',
+                width: '50%',
+                align: 'center'
             },
+           
             {
-                title: '所属项目',
-                dataIndex: 'projectName',
-                width: '30%'
+                title: '应用数量',
+                dataIndex: 'appCount',
+                width: '50%',
+                align: 'center'
             },
-            {
-                title: '人群包数量',
-                dataIndex: 'count',
-                width: '20%'
-            },
-            {
-                title: '状态',
-                dataIndex: 'statusStr',
-                width: '20%'
-            }
         ]
+            
     }
 
     // 原因的table列表
     setCauseColumns() {
         return [
             {
-                title: '项目名称',
-                dataIndex: 'projectName',
-                width: '30%'
+                title: '账户名称',
+                dataIndex: 'authName',
+                width: '25%',
+                align: 'center'
             },
             {
-                title: '账户名称',
-                dataIndex: 'accountName',
-                width: '30%'
+                title: '推送结果',
+                dataIndex: 'result',
+                width: '25%',
+                align: 'center'
             },
             {
-                title: '原因',
+                title: '失败原因',
                 dataIndex: 'message',
-                width: '40%'
+                width: '25%',
+                align: 'center',
+                customRender(t) {
+                    if(t === 'OK') {
+                        return '-';
+                    }
+                    else {
+                        return t;
+                    }
+                }
+            },
+            {
+                title: '操作',
+                dataIndex: 'action',
+                scopedSlots: {customRender: 'action'},
+                width: '25%',
+                align: 'center'
             }
         ]
     }
@@ -57,19 +69,16 @@
     setDepColumns() {
         return [
             {
-                title: '项目名称',
-                dataIndex: 'projectName',
-                width: '40%'
+                title: '广告组名称',
+                dataIndex: 'unitName',
+                width: '50%',
+                align: 'center'
             },
             {
-                title: '账户数量',
-                dataIndex: 'accountCount',
-                width: '20%'
-            },
-            {
-                title: '人群包数量',
-                dataIndex: 'count',
-                width: '20%'
+                title: '所属账户',
+                dataIndex: 'authName',
+                width: '50%',
+                align: 'center'
             }
         ]
     }
@@ -78,16 +87,24 @@
     setPlatform() {
         return [
             {
-                label: 0,
+                label: '',
                 value: '不限'
             },
             {
                 label: 1,
-                value: 'Android'
+                value: 'Android 应用下载'
             },
             {
                 label: 2,
-                value: 'IOS'
+                value: 'Android 网页游戏'
+            },
+            {
+                label: 3,
+                value: 'iOS 应用下载'
+            },
+            {
+                label: 4,
+                value: 'iOS 网页游戏'
             }
         ]
     }

+ 8 - 3
src/views/modules/autoLaunch/application/directional.less

@@ -1,8 +1,11 @@
 .directional-content {
     background: #fff;
-    height: calc(100vh - 137px);
+    // height: calc(100vh - 137px);
     padding: 20px;
     overflow-y: auto;
+    .middle-button {
+        margin: 0 8px;
+    }
     .control-con-header {
         margin-bottom: 20px;
         position: relative;
@@ -92,8 +95,10 @@
         height: 40px;
         line-height: 40px;
         .acount-title-left {
-            margin-right: 20px;
-            width: 100px;
+            width: 80px;
+        }
+        .acount-title-left::after {
+            content: " : ";
         }
     }
     .push-plate {

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 814 - 374
src/views/modules/autoLaunch/application/application.vue


+ 652 - 0
src/views/modules/autoLaunch/application/components/creatApplication.vue

@@ -0,0 +1,652 @@
+<style lang="less" scoped>
+.require-class {
+  /deep/ .ant-form-item-label {
+    label::before {
+      display: inline-block;
+      margin-right: 4px;
+      color: #f5222d;
+      font-size: 14px;
+      font-family: SimSun, sans-serif;
+      line-height: 1;
+      content: '*';
+    }
+  }
+}
+</style>
+<template>
+  <div>
+    <a-modal
+      title="添加应用"
+      :visible="application"
+      @ok="handleOk"
+      :confirmLoading="confirmLoading"
+      @cancel="handleCancel"
+      width="800px"
+    >
+      <a-card :body-style="{ padding: '24px 32px' }" :bordered="false">
+        <a-form :form="form">
+          <selectTable :projectId.sync="projectId" ref="selectTable" :requireCheck="true"></selectTable>
+          <a-form-item
+            label="设备类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="appType" @change="changePlatform">
+              <a-radio-button value="android">安卓</a-radio-button>
+              <a-radio-button value="ios">IOS</a-radio-button>
+            </a-radio-group>
+          </a-form-item>
+          <!-- <a-form-item v-if="appType == 'android'"> -->
+          <a-form-item
+            label="推广类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="platform" @change="changeShowUploadType">
+              <a-radio value="1">应用下载</a-radio>
+              <a-radio value="2">网页游戏</a-radio>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item
+            label="上传应用"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="uploadType" @change="changeShowUpload">
+              <a-radio-button value="1">本地上传</a-radio-button>
+              <a-radio-button value="2">填写链接</a-radio-button>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item
+            v-if="uploadType == '2'"
+            label="下载链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              placeholder="请填写应用下载链接"
+              v-decorator="[
+                'url',
+                {
+                  rules: [{ required: true, validator: handleConfirmValue }],
+                },
+              ]"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用包名"
+            v-if="uploadType == '2' && appType == 'android'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'packageName',
+                {
+                  rules: [{ required: true, message: '请填写正确的应用包名称' }],
+                },
+              ]"
+              placeholder="请填写包名称,如com.smile.gifmaker"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用名称"
+            v-if="uploadType == '2'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'appName',
+                {
+                  rules: [{ required: true, message: '请填写应用名称' }],
+                },
+              ]"
+              placeholder="请填写应用名称"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="上传图标"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 19 } }"
+            v-if="application"
+            class="require-class"
+          >
+            <uploadFile
+              v-if="application"
+              :value.sync="fileUrl"
+              :multiple="false"
+              :fileCount="1"
+              uploadType="image"
+              @overUpload="overUpload"
+              :size="100"
+            ></uploadFile>
+            <p class="upload-txt-rules">文件格式:支持上传png/jpg/jpeg图片,尺寸450*450,小于100kb</p>
+          </a-form-item>
+          <a-form-item
+            label="上传文件"
+            v-if="uploadType == '1'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            class="require-class fileUpload"
+            id="fileUpload"
+          >
+            <!-- <a-upload name="file" :file-list="fileList" :before-upload="beforeUpload" @change="handleChange">
+              <a-button><a-icon type="upload" />文件上传</a-button>
+            </a-upload> -->
+            <!-- :action="uploadAction" -->
+            <a-upload
+              name="file"
+              :multiple="false"
+              :headers="tokenHeader"
+              :file-list="fileList"
+              :showUploadList="false"
+              :beforeUpload="beforeUpload"
+              @change="handleChange"
+              style="margin-right: 20px"
+            >
+              <a-button :disabled="fileUrl == '' && !projectId">
+                <a-icon type="upload" />
+                {{ loadDisabled ? '上传中,请稍后' : '文件上传' }}
+              </a-button>
+            </a-upload>
+            <a @click="downLoadFile">文件格式下载</a>
+          </a-form-item>
+          <a-form-item
+            label="应用标记"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2'"
+          >
+            <a-input
+              v-decorator="[
+                'appVersion',
+                {
+                  rules: [{ required: true, message: ' ' }, { validator: checkAppVersion }],
+                },
+              ]"
+              placeholder="请填写应用标记,必填且不可重复,如快手-5.6.1.66"
+            />
+          </a-form-item>
+          <!-- <a-form-item>
+            <a-form-item :wrapperCol="{ span: 24 }" style="text-align: center">
+              <a-button htmlType="submit" type="primary">提交</a-button>
+              <a-button style="margin-left: 8px">保存</a-button>
+            </a-form-item>
+          </a-form-item> -->
+          <a-form-item
+            label=""
+            :labelCol="{ span: 5 }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 }, offset: 5 }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <!-- <a-radio-group
+              v-decorator="[
+                'useSdk',
+                {
+                  rules: [{ required: true }],
+                  initialValue: '0',
+                },
+              ]"
+            >
+              <a-radio value="0">未接入</a-radio>
+              <a-radio value="1">已接入</a-radio>
+            </a-radio-group> -->
+            <a-checkbox-group
+              v-decorator="[
+                'useSdk',
+                {
+                  rules: [{ message: '安卓应用已接入快手广告监测SDK必选' }],
+                },
+              ]"
+            >
+              <a-checkbox :value="0"> 该应用已接入快手广告监测SDK </a-checkbox>
+            </a-checkbox-group>
+          </a-form-item>
+          <a-form-item
+            label="隐私政策链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-input
+              v-decorator="[
+                'appPrivacyUrl',
+                {
+                  rules: [{ required: true, message: '请填写隐私政策链接' }, { validator: handleConfirmValue }],
+                },
+              ]"
+              placeholder="请填写隐私政策链接"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="监测链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-input v-decorator="['trackUrl']" placeholder="请填写监测链接" />
+          </a-form-item>
+        </a-form>
+      </a-card>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import { ACCESS_TOKEN } from '@/store/mutation-types'
+import { deleteAction, postAction, getAction, downFilePost, downFile } from '@/api/manage'
+import uploadFile from './uploadFile.vue'
+import { mapActions, mapGetters } from 'vuex'
+import BMF from 'browser-md5-file'
+import selectTable from '@/views/modules/Statistics/components/selectPagination.vue'
+import $ from 'jquery'
+const fileSuffix = ['xlsx', 'xls', 'zip']
+export default {
+  name: 'BaseForm',
+  components: {
+    uploadFile,
+    selectTable,
+  },
+  data() {
+    return {
+      useSdk: [],
+      loadDisabled: false,
+      projectId: '',
+      accountId: '',
+      fileList: [],
+      fileUrl: '',
+      accountList: {},
+      appType: 'android', //设备类型
+      platform: '1', //应用类型   : 1 Android 应用下载,2: Android 网页游戏,3: iOS 应用下载, 4:iOS 网页游戏
+      uploadType: '1', //上传类型 1 本地上传 2 填写链接
+      appVersion: '', //应用标记
+      appName: '', // 应用名称
+      packageName: '', //应用包名
+      file: '', // 上传文件
+      imageUrl: '', // 上传图标链接链接
+      downloadUrl: '', //下载链接
+      showUploadFile: true,
+      showDownLoad: false,
+      showUpload: true,
+      showAndroid: true,
+      showIOS: false,
+      customDomain: '',
+      acceptVideo: '/*.apk,/*.png,/*.jpg,/*.jpeg,/*.mp4',
+      accessKeyId: 'LTAIbNbqWzSOklQV',
+      accessKeySecret: '1rkPz7JNoXk8sJevPaeYHWqfkQXBGh',
+      region: 'oss-cn-beijing',
+      bucket: 'ctop-media',
+      form: this.$form.createForm(this),
+      url: {
+        insertTemplateUrl: '/kuaishouAppPackage/fillInLink',
+        userAllocationList: '/ctop/userAllocation/list',
+      },
+      application: false,
+      confirmLoading: false,
+      imageToken: '',
+      // uploadAction: '/kuaishouAppPackage/importAppExcel',
+      tokenHeader: { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) },
+      okCreated: false,
+      dataFile: null,
+    }
+  },
+  methods: {
+    checkAppVersion(rule, value, callback) {
+      if (value != '') {
+        if (this.projectId) {
+          let params = {}
+          params.projectId = this.projectId
+          params.appVersion = value
+          getAction('/kuaishouAppPackage/checkAppVersion', params).then((res) => {
+            if (res.success) {
+              callback()
+            } else {
+              callback(res.message)
+            }
+          })
+        }
+      } else {
+        callback('应用标记必填')
+      }
+    },
+    overUpload(file) {},
+    downLoadFile() {
+      downFile('/kuaishouAppPackage/exportAppTemplate').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 = '应用模板' //下载后文件名
+        document.body.appendChild(downloadElement)
+        downloadElement.click() //点击下载
+        document.body.removeChild(downloadElement) //下载完成移除元素
+        window.URL.revokeObjectURL(href) //释放掉blob对象
+      })
+    },
+    handleChange(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 == 200) {
+      //     // this.application = true
+      //     // this.$emit('getDataList')
+      //     this.okCreated = true
+      //     this.$message.success(info.file.response.message)
+      //   } else {
+      //     this.okCreated = false
+      //     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)
+    },
+    beforeUpload(file) {
+      // this.cosUpload(file)
+      // if (process.env.NODE_ENV == 'development') {
+      //   this.uploadAction = `/jeecg-boot/kuaishouAppPackage/importAppExcel?projectId=${this.projectId}&platform=${
+      //     this.appType == 'ios' ? +this.platform + 2 : +this.platform
+      //   }&imageUrl=${this.fileUrl}`
+      // } else if (process.env.NODE_ENV == 'debug') {
+      // } else if (process.env.NODE_ENV == 'production') {
+      //   this.uploadAction = `${this.axios.defaults.baseURL}/kuaishouAppPackage/importAppExcel?projectId=${
+      //     this.projectId
+      //   }&platform=${this.appType == 'ios' ? +this.platform + 2 : +this.platform}&imageUrl=${this.fileUrl}`
+      // }
+      // this.dataFile = file
+      this.dataFile = $('.fileUpload').eq(0).find('input')[0].files[0]
+      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
+      }
+    },
+    cosUpload(file) {
+      let 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
+      let timeElse = new Date().getTime()
+      let arr = file.name.split('.')
+      let 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] + '.'
+          }
+        }
+      }
+      cos.putObject(
+        {
+          Bucket: 'media-1301855440',
+          Region: 'ap-chongqing',
+          // 存储桶所在地域,必须字段
+          Key: that.appType + '/' + y + '-' + MM + '-' + d + '/' + str + '-' + timeElse + '.' + arr[arr.length - 1],
+          StorageClass: 'STANDARD',
+          Body: file, // 上传文件对象
+        },
+        function (err, data) {
+          if (err) {
+            that.$message.error('上传失败!!!' + err)
+            return
+          }
+          that.loadingElse = false
+          that.fileList.push({
+            uid: file.name,
+            name: file.name,
+            status: 'done',
+            url: '//' + data.Location,
+          })
+          if (that.fileList.length > 1) {
+            that.fileList = that.fileList.slice(-1)
+          }
+          const isZip = file.type.includes('zip') || file.type.includes('text')
+          const fileOvesize = file.size > 1024 * 1024 * 1024
+          if (!isZip) {
+            that.$message.error('只能上传zip格式的文件或者txt文件')
+            return
+          }
+          if (fileOvesize) {
+            that.$message.error('文件大小不能超过1G')
+            return
+          }
+          that.handleMd5(file)
+        }
+      )
+    },
+    handleMd5(file) {
+      let bmf = new BMF()
+      let that = this
+      return new Promise(function (resolve, reject) {
+        bmf.md5(file, (err, md5) => {
+          // getAction('kuaishouPopulationPackage/checkPopulationPackage', { signature: md5 })
+          //   .then((result) => {
+          //     if (result.code === 200) {
+          that.personNameDisabled = false
+          that.personResourceDisabled = false
+          resolve()
+          //   } else if (result.code === 201) {
+          //     that.$message.error(result.message)
+          //     that.personForm.name = result.result.orientationName
+          //     that.personForm.resource = result.result.type
+          //     that.personNameDisabled = true
+          //     that.personResourceDisabled = true
+          //     reject()
+          //   }
+          // })
+          // .catch((error) => {
+          //   console.log(error, 'eeee')
+          //   reject()
+          // })
+        })
+      })
+    },
+    handleOk() {
+      this.handleSubmit()
+    },
+    handleCancel() {
+      this.dataFile = null
+      this.appType = 'android'
+      this.okCreated = false
+      this.form.resetFields()
+      this.fileUrl = ''
+      this.projectId = undefined
+      this.$refs.selectTable.keyValue = ''
+      this.$refs.selectTable.getData()
+      this.file = ''
+      this.platform = '1'
+      this.application = false
+      this.uploadType = '1'
+    },
+    showApplication() {
+      this.application = true
+    },
+    handleConfirmValue(rule, value, callback) {
+      if (/(http|https):\/\/([\w.]+\/?)\S*/.test(value) && value != '') {
+        callback()
+      } else {
+        callback('链接不能为空且开头为http://或https://')
+      }
+    },
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    changePlatform() {
+      this.form.resetFields()
+      if (this.appType == 'android') {
+        this.showAndroid = true
+        this.showIOS = false
+        this.platform = '1'
+      } else {
+        this.showAndroid = false
+        this.showIOS = true
+        this.showDownLoad = true
+        this.platform = '1'
+      }
+    },
+    changeShowUpload() {
+      this.form.resetFields()
+      this.fileUrl = ''
+    },
+    changeShowUploadType() {
+      this.form.resetFields()
+      if (this.platform == '2') {
+        this.showUpload = false
+        this.showUploadFile = false
+        this.showDownLoad = true
+        this.uploadType = '1'
+      } else {
+        this.showUpload = true
+        this.showUploadFile = true
+        this.showDownLoad = false
+      }
+    },
+
+    handleSubmit() {
+      //   console.log('设备类型:' + this.appType)
+      //   console.log('应用类型:' + this.platform)
+      //   console.log('上传类型:' + this.uploadType)
+      //   console.log('应用标记:' + this.appVersion)
+      //   console.log('应用名称:' + this.appName)
+      //   console.log('包名称:' + this.packageName)
+      //   console.log('文件地址:' + this.file)
+      //   console.log('图片地址:' + this.imageUrl)
+      //   e.preventDefault()
+
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          if (this.fileUrl && this.projectId) {
+            this.confirmLoading = true
+            let params = {}
+            params.projectId = this.projectId
+            if (this.uploadType == '1') {
+              // var file = document.getElementById('fileId').files[0] //获取文件流
+              this.url.insertTemplateUrl = '/kuaishouAppPackage/importAppExcel'
+              params.platform = this.appType == 'ios' ? +this.platform + 2 : +this.platform
+              params.imageUrl = this.fileUrl
+              if (this.dataFile) {
+                let formData = new FormData()
+                formData.append('file', this.dataFile)
+                formData.append('projectId', this.projectId)
+                formData.append('platform', this.appType == 'ios' ? +this.platform + 2 : +this.platform)
+                formData.append('imageUrl', this.fileUrl)
+                // if (process.env.NODE_ENV == 'development') {
+                //   this.uploadAction = `/jeecg-boot/kuaishouAppPackage/importAppExcel?projectId=${
+                //     this.projectId
+                //   }&platform=${this.appType == 'ios' ? +this.platform + 2 : +this.platform}&imageUrl=${this.fileUrl}`
+                // } else if (process.env.NODE_ENV == 'debug') {
+                // } else if (process.env.NODE_ENV == 'production') {
+                //   this.uploadAction = `${this.axios.defaults.baseURL}/kuaishouAppPackage/importAppExcel?projectId=${
+                //     this.projectId
+                //   }&platform=${this.appType == 'ios' ? +this.platform + 2 : +this.platform}&imageUrl=${this.fileUrl}`
+                // }
+
+                postAction('/kuaishouAppPackage/importAppExcel', formData).then((res) => {
+                  this.confirmLoading = false
+                  if (res.code === 200) {
+                    this.$message.success('创建成功')
+                    this.handleCancel()
+                    this.$emit('getDataList')
+                  } else {
+                    this.$message.error(res.message)
+                  }
+                })
+              } else {
+                this.$message.error('请上传文件')
+              }
+
+              return
+            } else {
+              this.url.insertTemplateUrl = '/kuaishouAppPackage/fillInLink'
+              params = { ...values }
+              params.useSdk = params.useSdk ? (params.useSdk.length > 0 ? 1 : 0) : null
+              params.projectId = this.projectId
+              params.appIconUrl = this.fileUrl
+              params.platform = this.appType == 'ios' ? +this.platform + 2 : +this.platform
+            }
+
+            postAction(this.url.insertTemplateUrl, params).then((res) => {
+              this.confirmLoading = false
+              if (res.success) {
+                this.$message.success('创建成功')
+                this.handleCancel()
+                this.$emit('getDataList')
+              } else {
+                this.$message.error(res.message)
+              }
+            })
+          } else {
+            this.$message.error('请填写必填项')
+          }
+        }
+      })
+    },
+
+    onChange(value) {},
+  },
+  created: function () {
+    let params = {}
+    params.pageSize = '1000'
+    params.mediaId = '2'
+    params.userId = this.userInfo().id
+    getAction(this.url.userAllocationList, params).then((res) => {
+      if (res.success) {
+        this.accountList = res.result.records
+      }
+    })
+  },
+}
+</script>

+ 602 - 0
src/views/modules/autoLaunch/application/components/editApplication.vue

@@ -0,0 +1,602 @@
+<template>
+  <div>
+    <a-modal
+      title="编辑应用"
+      :visible="application"
+      @ok="handleOk"
+      :confirmLoading="confirmLoading"
+      @cancel="handleCancel"
+      width="800px"
+    >
+      <a-card :body-style="{ padding: '24px 32px' }" :bordered="false">
+        <a-form :form="form">
+          <!-- <selectTable :projectId.sync="projectId" ref="selectTable" :requireCheck="true"></selectTable> -->
+          <a-form-item
+            label="项目名称"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              disabled
+              v-decorator="[
+                'projectName',
+                {
+                  rules: [{ required: true }],
+                },
+              ]"
+            />
+          </a-form-item>
+          <a-form-item
+            label="设备类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="appType" @change="changePlatform" disabled>
+              <a-radio-button value="android">安卓</a-radio-button>
+              <a-radio-button value="ios">IOS</a-radio-button>
+            </a-radio-group>
+          </a-form-item>
+          <!-- <a-form-item v-if="appType == 'android'"> -->
+          <a-form-item
+            label="推广类型"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="platform" disabled>
+              <a-radio value="1">应用下载</a-radio>
+              <a-radio value="2">网页游戏</a-radio>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item
+            label="上传应用"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-radio-group v-model="uploadType">
+              <a-radio-button value="1" disabled>本地上传</a-radio-button>
+              <a-radio-button value="2">填写链接</a-radio-button>
+            </a-radio-group>
+          </a-form-item>
+
+          <a-form-item
+            label="上传文件"
+            v-if="uploadType == '1'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <!-- <a-upload name="file" :file-list="fileList" :before-upload="beforeUpload" @change="handleChange">
+              <a-button><a-icon type="upload" />文件上传</a-button>
+            </a-upload> -->
+            <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="(!projectId && !fileUrl) || loadDisabled">
+                <a-icon type="upload" />
+                {{ loadDisabled ? '上传中,请稍后' : '文件上传' }}
+              </a-button>
+            </a-upload>
+            <a @click="downLoadFile">文件格式下载</a>
+          </a-form-item>
+
+          <a-form-item
+            v-if="uploadType == '2'"
+            label="下载链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              placeholder="请填写应用下载链接"
+              v-decorator="[
+                'url',
+                {
+                  rules: [{ required: true, validator: handleConfirmValue }],
+                },
+              ]"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用包名"
+            v-if="uploadType == '2' && appType == 'android'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'packageName',
+                {
+                  rules: [{ required: true, message: '请填写正确的应用包名称' }],
+                },
+              ]"
+              placeholder="请填写包名称,如com.smile.gifmaker"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="应用名称"
+            v-if="uploadType == '2'"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+          >
+            <a-input
+              v-decorator="[
+                'appName',
+                {
+                  rules: [{ required: true, message: '请填写应用名称' }],
+                },
+              ]"
+              placeholder="请填写应用名称"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="上传图标"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 19 } }"
+            v-if="application"
+          >
+            <uploadFile
+              v-if="application"
+              :value.sync="fileUrl"
+              :multiple="false"
+              :fileCount="1"
+              uploadType="image"
+              @overUpload="overUpload"
+              :size="100"
+            ></uploadFile>
+            <p class="upload-txt-rules">文件格式:支持上传png/jpg/jpeg图片,尺寸450*450,小于100kb</p>
+          </a-form-item>
+
+          <a-form-item
+            label="应用标记"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2'"
+          >
+            <a-input
+              v-decorator="[
+                'appVersion',
+                {
+                  rules: [{ required: true, message: ' ' }, { validator: checkAppVersion }],
+                },
+              ]"
+              placeholder="请填写应用标记,必填且不可重复,如快手-5.6.1.66"
+            />
+          </a-form-item>
+          <!-- <a-form-item>
+            <a-form-item :wrapperCol="{ span: 24 }" style="text-align: center">
+              <a-button htmlType="submit" type="primary">提交</a-button>
+              <a-button style="margin-left: 8px">保存</a-button>
+            </a-form-item>
+          </a-form-item> -->
+          <a-form-item
+            label=""
+            :labelCol="{ span: 5 }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 }, offset: 5 }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-checkbox-group v-decorator="['useSdk']">
+              <a-checkbox :value="0"> 该应用已接入快手广告监测SDK </a-checkbox>
+            </a-checkbox-group>
+          </a-form-item>
+          <a-form-item
+            label="隐私政策链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-input
+              v-decorator="[
+                'appPrivacyUrl',
+                {
+                  rules: [{ required: true, message: '请填写隐私政策链接' }, { validator: handleConfirmValue }],
+                },
+              ]"
+              placeholder="请填写隐私政策链接"
+            />
+          </a-form-item>
+
+          <a-form-item
+            label="监测链接"
+            :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
+            :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
+            v-if="uploadType == '2' && appType == 'android'"
+          >
+            <a-input v-decorator="['trackUrl']" placeholder="请填写监测链接" />
+          </a-form-item>
+        </a-form>
+      </a-card>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import Vue from 'vue'
+import { ACCESS_TOKEN } from '@/store/mutation-types'
+import { deleteAction, postAction, getAction, downFilePost, downFile } from '@/api/manage'
+import uploadFile from './uploadFile.vue'
+import { mapActions, mapGetters } from 'vuex'
+import BMF from 'browser-md5-file'
+import selectTable from '@/views/modules/Statistics/components/selectPagination.vue'
+import pick from 'lodash.pick'
+const fileSuffix = ['xlsx', 'xls', 'zip']
+export default {
+  name: 'BaseForm',
+  components: {
+    uploadFile,
+    selectTable,
+  },
+  data() {
+    return {
+      loadDisabled: false,
+      projectId: '',
+      accountId: '',
+      fileList: [],
+      fileUrl: '',
+      accountList: {},
+      appType: 'android', //设备类型
+      platform: '1', //应用类型   : 1 Android 应用下载,2: Android 网页游戏,3: iOS 应用下载, 4:iOS 网页游戏
+      uploadType: '2', //上传类型 1 本地上传 2 填写链接
+      appVersion: '', //应用标记
+      appName: '', // 应用名称
+      packageName: '', //应用包名
+      file: '', // 上传文件
+      imageUrl: '', // 上传图标链接链接
+      downloadUrl: '', //下载链接
+      showUploadFile: true,
+      showDownLoad: false,
+      showUpload: true,
+      showAndroid: true,
+      showIOS: false,
+      customDomain: '',
+      acceptVideo: '/*.apk,/*.png,/*.jpg,/*.jpeg,/*.mp4',
+      accessKeyId: 'LTAIbNbqWzSOklQV',
+      accessKeySecret: '1rkPz7JNoXk8sJevPaeYHWqfkQXBGh',
+      region: 'oss-cn-beijing',
+      bucket: 'ctop-media',
+      form: this.$form.createForm(this),
+      url: {
+        insertTemplateUrl: '/kuaishouAppPackage/fillInLink',
+        userAllocationList: '/ctop/userAllocation/list',
+      },
+      application: false,
+      confirmLoading: false,
+      imageToken: '',
+      uploadAction: '/kuaishouAppPackage/importAppExcel',
+      tokenHeader: { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) },
+      appId: null,
+    }
+  },
+  methods: {
+    checkAppVersion(rule, value, callback) {
+      if (value != '') {
+        if (this.projectId) {
+          let params = {}
+          params.projectId = this.projectId
+          params.appVersion = value
+          getAction('/kuaishouAppPackage/checkAppVersion', params).then((res) => {
+            if (res.success) {
+              callback()
+            } else {
+              callback(res.message)
+            }
+          })
+        }
+      } else {
+        callback('应用标记必填')
+      }
+    },
+    overUpload(file) {
+      console.log(file)
+    },
+    downLoadFile() {
+      downFile('/kuaishouAppPackage/exportAppTemplate').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 = '应用模板' //下载后文件名
+        document.body.appendChild(downloadElement)
+        downloadElement.click() //点击下载
+        document.body.removeChild(downloadElement) //下载完成移除元素
+        window.URL.revokeObjectURL(href) //释放掉blob对象
+      })
+    },
+    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 == 200) {
+          this.application = true
+          this.$emit('getDataList')
+          this.$message.success(info.file.response.message)
+        } 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)
+    },
+    beforeUpload(file) {
+      // this.cosUpload(file)
+      if (process.env.NODE_ENV == 'development') {
+        this.uploadAction = `/jeecg-boot/kuaishouAppPackage/importAppExcel?projectId=${this.projectId}&platform=${
+          this.appType == 'ios' ? +this.platform + 2 : +this.platform
+        }&imageUrl=${this.fileUrl}`
+      } else if (process.env.NODE_ENV == 'debug') {
+      } else if (process.env.NODE_ENV == 'production') {
+        this.uploadAction = `${this.axios.defaults.baseURL}/kuaishouAppPackage/importAppExcel?projectId=${
+          this.projectId
+        }&platform=${this.appType == 'ios' ? +this.platform + 2 : +this.platform}&imageUrl=${this.fileUrl}`
+      }
+      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
+      }
+    },
+    cosUpload(file) {
+      let 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
+      let timeElse = new Date().getTime()
+      let arr = file.name.split('.')
+      let 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] + '.'
+          }
+        }
+      }
+      cos.putObject(
+        {
+          Bucket: 'media-1301855440',
+          Region: 'ap-chongqing',
+          // 存储桶所在地域,必须字段
+          Key: that.appType + '/' + y + '-' + MM + '-' + d + '/' + str + '-' + timeElse + '.' + arr[arr.length - 1],
+          StorageClass: 'STANDARD',
+          Body: file, // 上传文件对象
+        },
+        function (err, data) {
+          if (err) {
+            that.$message.error('上传失败!!!' + err)
+            return
+          }
+          that.loadingElse = false
+          that.fileList.push({
+            uid: file.name,
+            name: file.name,
+            status: 'done',
+            url: '//' + data.Location,
+          })
+          if (that.fileList.length > 1) {
+            that.fileList = that.fileList.slice(-1)
+          }
+          const isZip = file.type.includes('zip') || file.type.includes('text')
+          const fileOvesize = file.size > 1024 * 1024 * 1024
+          if (!isZip) {
+            that.$message.error('只能上传zip格式的文件或者txt文件')
+            return
+          }
+          if (fileOvesize) {
+            that.$message.error('文件大小不能超过1G')
+            return
+          }
+          that.handleMd5(file)
+        }
+      )
+    },
+    handleMd5(file) {
+      let bmf = new BMF()
+      let that = this
+      return new Promise(function (resolve, reject) {
+        bmf.md5(file, (err, md5) => {
+          // getAction('kuaishouPopulationPackage/checkPopulationPackage', { signature: md5 })
+          //   .then((result) => {
+          //     if (result.code === 200) {
+          that.personNameDisabled = false
+          that.personResourceDisabled = false
+          resolve()
+          //   } else if (result.code === 201) {
+          //     that.$message.error(result.message)
+          //     that.personForm.name = result.result.orientationName
+          //     that.personForm.resource = result.result.type
+          //     that.personNameDisabled = true
+          //     that.personResourceDisabled = true
+          //     reject()
+          //   }
+          // })
+          // .catch((error) => {
+          //   console.log(error, 'eeee')
+          //   reject()
+          // })
+        })
+      })
+    },
+    handleOk() {
+      this.handleSubmit()
+    },
+    handleCancel() {
+      this.form.resetFields()
+      this.imageUrl = ''
+      this.fileUrl = ''
+      this.platform = '1'
+      this.application = false
+      this.uploadType = '2'
+    },
+    showApplication(val) {
+      this.application = true
+      this.appId = val.id
+      getAction('/kuaishouAppPackage/queryById', { id: val.id }).then((res) => {
+        //   'appIconUrl',
+        if (res.success) {
+          this.fileUrl = res.result.appIconUrl
+          this.appType = res.result.platform > 2 ? 'ios' : 'android'
+          this.platform = res.result.platform > 2 ? res.result.platform - 2 + '' : res.result.platform + ''
+          res.result.useSdk = res.result.useSdk ? (res.result.useSdk == 0 ? [] : [0]) : null
+          this.projectId = res.result.projectId
+          if (this.appType == 'android') {
+            this.$nextTick(() => {
+              this.form.setFieldsValue(
+                pick(res.result, 'url', 'packageName', 'appPrivacyUrl', 'useSdk', 'trackUrl', 'appName', 'projectName')
+              )
+              setTimeout(() => {
+                this.form.setFieldsValue(pick(res.result, 'appVersion'))
+              }, 150)
+            })
+          } else {
+            setTimeout(() => {
+              this.form.setFieldsValue(pick(res.result, 'url', 'appVersion', 'projectName'))
+            }, 100)
+            setTimeout(() => {
+              this.form.setFieldsValue(pick(res.result, 'appName'))
+            }, 150)
+          }
+        }
+      })
+    },
+    handleConfirmValue(rule, value, callback) {
+      if (/(http|https):\/\/([\w.]+\/?)\S*/.test(value) && value != '') {
+        callback()
+      } else {
+        callback('链接不能为空且开头为http://或https://')
+      }
+    },
+    ...mapGetters(['nickname', 'avatar', 'userInfo']),
+    changePlatform() {
+      // this.form.resetFields()
+      // if (this.appType == 'android') {
+      //   this.showAndroid = true
+      //   this.showIOS = false
+      //   this.platform = '1'
+      // } else {
+      //   this.showAndroid = false
+      //   this.showIOS = true
+      //   this.showDownLoad = true
+      //   this.platform = '1'
+      // }
+    },
+
+    handleSubmit() {
+      //   console.log('设备类型:' + this.appType)
+      //   console.log('应用类型:' + this.platform)
+      //   console.log('上传类型:' + this.uploadType)
+      //   console.log('应用标记:' + this.appVersion)
+      //   console.log('应用名称:' + this.appName)
+      //   console.log('包名称:' + this.packageName)
+      //   console.log('文件地址:' + this.file)
+      //   console.log('图片地址:' + this.imageUrl)
+      //   e.preventDefault()
+      this.form.validateFields((err, values) => {
+        if (!err) {
+          if (this.fileUrl && this.projectId) {
+            this.confirmLoading = true
+            let params = {}
+            params.projectId = this.projectId
+            if (this.uploadType == '1') {
+              this.url.insertTemplateUrl = '/kuaishouAppPackage/importAppExcel'
+              params.platform = this.appType == 'ios' ? +this.platform + 2 : +this.platform
+              params.imageUrl = this.fileUrl
+            } else {
+              this.url.insertTemplateUrl = '/kuaishouAppPackage/fillInLink'
+              params = { ...values }
+              params.useSdk = params.useSdk ? (params.useSdk.length > 0 ? 1 : 0) : null
+              params.id = this.appId
+              params.projectId = this.projectId
+              params.appIconUrl = this.fileUrl
+              params.platform = this.appType == 'ios' ? +this.platform + 2 : +this.platform
+            }
+            postAction(this.url.insertTemplateUrl, params).then((res) => {
+              this.confirmLoading = false
+              if (res.success) {
+                this.$message.success('修改成功')
+                this.handleCancel()
+                this.$emit('getDataList')
+              } else {
+                this.$message.error(res.message)
+              }
+            })
+          } else {
+            this.$message.error('请填写必填项')
+          }
+        }
+      })
+    },
+
+    onChange(value) {
+      console.log(value)
+    },
+  },
+  created: function () {
+    let params = {}
+    params.pageSize = '1000'
+    params.mediaId = '2'
+    params.userId = this.userInfo().id
+    getAction(this.url.userAllocationList, params).then((res) => {
+      if (res.success) {
+        this.accountList = res.result.records
+      }
+    })
+  },
+}
+</script>

+ 6 - 0
src/views/modules/autoLaunch/application/components/tree-select.less

@@ -21,6 +21,12 @@
             .class-left-content {
                 overflow-y: auto;
                 height: 340px;
+                position: relative;
+                .pagin-table-class {
+                    position: absolute;
+                    bottom: 0;
+                    right: 0;
+                }
             }
             .example {
                 text-align: center;

+ 56 - 25
src/views/modules/autoLaunch/application/components/tree-select.vue

@@ -16,6 +16,14 @@
                             @check="onCheck"
                             @expand="onExpand"
                         />
+                        <!-- <a-pagination
+                            class="pagin-table-class"
+                            :total="totalAll"
+                            :show-total="total => `共 ${totalAll} 条`"
+                            size="small"
+                            @change="onShowSizeChange"
+                            @showSizeChange="onShowSizeChange"
+                        /> -->
                     </template>
                     <div class="example">
                         <a-spin :spinning="spinning"/>
@@ -54,12 +62,33 @@
 </template>
 <script>
 import {mapGetters} from 'vuex';
-import {postAction} from '@/api/manage';
+import {postAction,getAction} from '@/api/manage';
 
 export default {
     name: 'tree-select',
+    props: {
+        projectId: {
+            type: [String,Number],
+            default() {
+                return null
+            },
+        },
+        templateId: {
+            type: [String,Number],
+            default() {
+                return null
+            },
+        },
+        httpSrc: {
+            type: String,
+            default() {
+                return '/kuaishouDirectionalPackage/getAccountByProjectId'
+            }
+        }
+    },
     data() {
         return {
+            totalAll: 20,
             expandedKeys: [],
             autoExpandParent: true,
             checkedKeys: [],
@@ -69,7 +98,11 @@ export default {
             applyTypeOption: [],
             selectRightData: new Set(),
             spinning: true,
-            leftTreeNoData: false
+            leftTreeNoData: false,
+            tablePag: {
+                page: 1,
+                size: 100
+            },
         };
     },
     mounted() {
@@ -77,36 +110,32 @@ export default {
     },
     methods: {
         ...mapGetters(['userInfo']),
+        onShowSizeChange(current, pageSize) {
+            this.tablePag = {
+                page: current,
+                size: pageSize
+            };
+            this.getAccountId();
+        },
         getAccountId() {
-            postAction('/ctop/projectMember/participateListByMediaId', {
-                userId: this.userInfo().id,
-                type: 'kuaishou'
+            getAction(this.httpSrc, {
+                projectId: this.projectId,
+                id: this.templateId,
+                pageNo: this.tablePag.page,
+                pageSize: this.tablePag.size
             }).then(result => {
-                if (result.result.length) {
+                if (result.result.list.length) {
                     this.spinning = false;
-                    this.treeData = result.result.map(item => {
+                    this.treeData = result.result.list.map(item => {
                         return {
-                            key: item.projectId + 'projectId',
-                            title: item.projectName + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0' + item.advertiserName,
-                            children: item.accountList
-                            ? item.accountList.map(i => {
-                                return {
-                                    key: i.accountId,
-                                    title:
-                                    (i.userName.length === 2
-                                        ? i.userName + '\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'
-                                        + i.accountId
-                                        + '\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0\xa0'
-                                        + i.authName
-                                };
-                            }) : []
+                            key: item.accountId,
+                            title: item.authName,
+                            disabled: item.state === 1,
+                            children: null
                         };
                     });
                     this.updateTreeData = [...this.treeData];
+                    this.totalAll = result.result.total || 0;
                 }
                 else {
                     this.spinning = false;
@@ -142,6 +171,7 @@ export default {
             }
             defaultCheckKey.splice(value, 1);
             this.checkedKeys = defaultCheckKey;
+            this.$emit('applyType', this.applyTypeOption);
         },
         onChange(e) {
             const value = e.target.value;
@@ -231,6 +261,7 @@ export default {
         },
         onCheck(checkedKeys) {
             // this.checkedKeys = checkedKeys;
+            console.log(checkedKeys)
             this.nodes(this.treeData, checkedKeys);
             const filterCheckKey = this.checkedKeys.filter(item=>typeof item ==='number');
             let filterCheckKeySet = new Set(filterCheckKey);

+ 365 - 0
src/views/modules/autoLaunch/application/components/uploadFile.vue

@@ -0,0 +1,365 @@
+<style>
+</style>
+<style lang="scss" scoped>
+</style>
+<template>
+  <div class="upload-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/*' : '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 class="ant-upload-text">点击上传</div>
+      </div>
+    </a-upload>
+    <!-- <div style="color: red" v-if="sizeCheck">
+      {{ 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'" />
+      <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: '',
+    }
+  },
+  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 = []
+                var data = {
+                  uid: 1,
+                  name: '回显',
+                  status: 'done',
+                  url: n,
+                }
+                this.fileList.push(data)
+              }
+            }
+          } 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(file)
+      var image = new Image()
+      var reader = new FileReader()
+      var height = 0
+      var width = 0
+      reader.readAsDataURL(file)
+      //文件读取结束时间
+      reader.onload = function (e) {
+        image.src = reader.result
+      }
+      var that = this
+      //图片读取事件
+      image.onload = function () {
+        height = image.naturalHeight
+        width = image.naturalWidth
+      }
+      if (image.complete) {
+        height = image.naturalHeight
+        width = image.naturalWidth
+      }
+
+      setTimeout(() => {
+        if (height != 450 || width != 450) {
+          that.$message.error('请上传450*450大小的图片')
+          this.loadingElse = false
+          return
+        }
+        // console.log(fileOvesize)
+        if (fileOvesize && this.sizeCheck) {
+          this.onOversize()
+          this.loadingElse = false
+          return
+        } else {
+          if (file.type.includes('jpg') || file.type.includes('png') || file.type.includes('jpeg')) {
+            this.checkFile(file)
+              .then((res) => {
+                this.cosUpload(file)
+              })
+              .catch(() => {
+                this.loadingElse = false
+              })
+          } else {
+            this.$message.error('请上传正确格式')
+            this.loadingElse = false
+          }
+
+          return new Promise(function (resolve, reject) {
+            reject()
+          })
+        }
+      }, 200)
+    },
+    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 item.url
+                })[0]
+              )
+            }
+          } else {
+            that.$message.error('上传已达上限' + that.fileCount + '张')
+          }
+        }
+      )
+    },
+  },
+}
+</script>
+<style scoped>
+@import '~@assets/less/common.less';
+</style>

+ 1 - 0
src/views/modules/autoLaunch/directional/components/tree-select.vue

@@ -171,6 +171,7 @@ export default {
             }
             defaultCheckKey.splice(value, 1);
             this.checkedKeys = defaultCheckKey;
+            this.$emit('applyType', this.applyTypeOption);
         },
         onChange(e) {
             const value = e.target.value;

+ 1 - 0
src/views/modules/autoLaunch/directional/directional.vue

@@ -502,6 +502,7 @@ export default {
                     title: '操作',
                     dataIndex: 'action',
                     align: 'center',
+                    width: 150,
                     scopedSlots: {customRender: 'action'}
                 },
                 {

+ 4 - 4
src/views/modules/autoLaunch/material-pool/material.vue

@@ -37,10 +37,10 @@ export default {
                     key: 'url',
                     tab: '落地页管理',
                 },
-                // {
-                //     key: 'application',
-                //     tab: '应用包管理',
-                // },
+                {
+                    key: 'application',
+                    tab: '应用包管理',
+                },
             ], 
         }
     },

+ 1 - 0
src/views/modules/autoLaunch/url/components/tree-select.vue

@@ -142,6 +142,7 @@ export default {
             }
             defaultCheckKey.splice(value, 1);
             this.checkedKeys = defaultCheckKey;
+            this.$emit('applyType', this.applyTypeOption);
         },
         onChange(e) {
             const value = e.target.value;

+ 1 - 0
src/views/modules/crowd-control/components/tree-select/tree-select.vue

@@ -143,6 +143,7 @@ export default {
             }
             defaultCheckKey.splice(value, 1);
             this.checkedKeys = defaultCheckKey;
+            this.$emit('applyType', this.applyTypeOption);
         },
         onChange(e) {
             const value = e.target.value;

+ 33 - 3
src/views/modules/crowd-control/crowd-control.vue

@@ -25,9 +25,12 @@
                         <span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
                             <a-button type="primary" icon="search" @click="handleQueryList">查询</a-button>
                             <a-button type="primary" @click="handleResetForm" icon="reload" class="middle-button">重置</a-button>
-                             <a-button type="primary" @click="handleUploadPerson">
+                             <a-button type="primary" @click="handleUploadPerson" class="middle-button">
                                 上传人群包
                             </a-button>
+                             <!-- <a-button type="primary" @click="handleUpdatePerson" v-if="realShow" :loading="realLoading">
+                                更新人群
+                            </a-button> -->
                            
                         </span>
                         
@@ -243,7 +246,7 @@ import AcountSearch from '@/views/modules/Statistics/components/Treeselect.vue';
 import selectTable from '@/views/modules/Statistics/components/selectPagination.vue';
 import AppMarketService from './crowd-control-service';
 import BMF from 'browser-md5-file';
-
+import { mapGetters } from 'vuex';
 let COS = require('cos-js-sdk-v5');
 let cos = new COS({
     SecretId: 'AKIDE6IpMi8fJQRCg1iuWzFajjRs43kbbets',
@@ -394,6 +397,8 @@ export default {
                     this.handleAcountRelax(this.relaxStatus  ,this.acountRelaxDetail)
                 }
             },
+            realShow: false,
+            realLoading: false
         };
     },
     watch: {
@@ -407,9 +412,18 @@ export default {
         this.form = this.$form.createForm(this);
     },
     mounted() {
+        // this.realShow = this.userInfo().realname === '管理员' ? true : false
+        // if(!this.realShow) {
+        //     getAction('/kuaishou/batch/syncUserPopulationList',{ userId:this.userInfo().id, type:1}).then(res => {
+        //         if(res.success) {
+
+        //         }
+        //     })
+        // }
         this.handleGetTableList({});
     },
     methods: {
+        ...mapGetters(['nickname', 'avatar', 'userInfo']),
         handleAgian(val) {
             let params = {};
             params.id = val.id;
@@ -497,7 +511,7 @@ export default {
             let that = this;
             this.$confirm({
                 title: '删除提示',
-                content: '确定要删除这一条吗?',
+                content: '是否删除该人群包?',
                 onOk() {
                     getAction('/kuaishouPopulationPackage/delete', {id: data.id}).then(result => {
                         if (result.code === 200) {
@@ -726,6 +740,22 @@ export default {
         handleUploadPerson() {
             this.personVisible = true;
         },
+        handleUpdatePerson() {
+            if(this.realShow) {
+                this.realLoading = true;
+                getAction('/kuaishou/batch/syncUserPopulationList',{ userId:this.userInfo().id, type:0}).then(res => {
+                    if(res.success) {
+                        this.realLoading = false;
+                        this.$message.success('更新成功');
+                        this.handleResetForm();
+                    }
+                    else {
+                        this.realLoading = false;
+                        this.$message.error('更新失败');
+                    }
+                })
+            }
+        },
         handleOk() {
             this.$refs.ruleForm.validate(valid => {
                 if (valid) {

+ 1 - 1
src/views/modules/material/videoMaterial.vue

@@ -418,7 +418,7 @@ a {
       <a-button
         @click="onCheckAllChange"
         v-if="
-          queryParam.projectId &&
+          queryParam.productId &&
           active == '1' &&
           (role.roleCode == 'operator' ||
             role.roleCode == 'kuaishouOperationManager' ||

+ 1 - 1
vue.config.js

@@ -77,7 +77,7 @@ module.exports = {
         // target: 'http://192.168.1.43:8088', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.1.43:8806', //请求本地 需要jeecg-boot后台项目  毕洁泉
         // target: 'http://192.168.0.252:8098', //请求本地 需要jeecg-boot后台项目  毕洁泉
-        // target: 'http://192.168.1.219:8081', //请求本地 需要jeecg-boot后台项目  赵西安
+        target: 'http://192.168.1.219:8081', //请求本地 需要jeecg-boot后台项目  赵西安
         // target: 'http://192.168.1.193:8080', //请求本地 需要jeecg-boot后台项目  李煜一
         // target: 'http://192.168.1.193:31012', //请求本地 需要jeecg-boot后台项目  李煜一
         //  target: 'http://api.tjyourong.com.cn', //请求本地 需要jeecg-boot后台项目