creatApplication.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. <style lang="less" scoped>
  2. .require-class {
  3. /deep/ .ant-form-item-label {
  4. label::before {
  5. display: inline-block;
  6. margin-right: 4px;
  7. color: #f5222d;
  8. font-size: 14px;
  9. font-family: SimSun, sans-serif;
  10. line-height: 1;
  11. content: '*';
  12. }
  13. }
  14. }
  15. </style>
  16. <template>
  17. <div>
  18. <a-modal
  19. title="添加应用"
  20. :visible="application"
  21. @ok="handleSubmit"
  22. :confirmLoading="confirmLoading"
  23. @cancel="handleCancel"
  24. width="800px"
  25. >
  26. <a-card :body-style="{ padding: '24px 32px' }" :bordered="false">
  27. <a-form :form="form">
  28. <a-form-item
  29. label="下载链接"
  30. :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
  31. :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
  32. >
  33. <a-input
  34. placeholder="请填写应用下载链接"
  35. v-decorator="[
  36. 'url',
  37. {
  38. rules: [{ required: true, validator: handleConfirmValue }]
  39. }
  40. ]"
  41. id="url"
  42. />
  43. <a-tag
  44. color="#2db7f5"
  45. @click="getChangeAll('渠道号', 'form', 'url')"
  46. v-if="createTypeData && createTypeData.createType == '1'"
  47. >+渠道号</a-tag
  48. >
  49. </a-form-item>
  50. <a-form-item
  51. label="应用包名"
  52. v-if="uploadType == '2' && appType == 'android'"
  53. :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
  54. :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
  55. >
  56. <a-input
  57. v-decorator="[
  58. 'packageName',
  59. {
  60. rules: [{ required: true, message: '请填写正确的应用包名称' }]
  61. }
  62. ]"
  63. placeholder="请填写包名称,如com.smile.gifmaker"
  64. />
  65. </a-form-item>
  66. <a-form-item
  67. label="应用名称"
  68. :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
  69. :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
  70. >
  71. <a-input
  72. v-decorator="[
  73. 'appName',
  74. {
  75. rules: [{ required: true, message: '请填写应用名称' }]
  76. }
  77. ]"
  78. placeholder="请填写应用名称"
  79. />
  80. </a-form-item>
  81. <a-form-item
  82. label="上传图标"
  83. :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
  84. :wrapperCol="{ xs: { span: 24 }, sm: { span: 19 } }"
  85. v-if="application"
  86. class="require-class"
  87. >
  88. <uploadFile
  89. v-if="application"
  90. :value.sync="fileUrl"
  91. :multiple="false"
  92. :fileCount="1"
  93. uploadType="image"
  94. @overUpload="overUpload"
  95. :size="100"
  96. ></uploadFile>
  97. <p class="upload-txt-rules">文件格式:支持上传png/jpg/jpeg图片,尺寸450*450,小于100kb</p>
  98. </a-form-item>
  99. <a-form-item
  100. label="应用标记"
  101. :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
  102. :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
  103. >
  104. <a-input
  105. v-decorator="[
  106. 'appVersion',
  107. {
  108. rules: [{ required: true, message: '应用标记必填' }]
  109. }
  110. ]"
  111. placeholder="请填写应用标记,必填且不可重复,如快手-5.6.1.66"
  112. id="appVersion"
  113. />
  114. <a-tag
  115. color="#2db7f5"
  116. @click="getChangeAll('渠道号', 'form', 'appVersion')"
  117. v-if="createTypeData && createTypeData.createType == '1'"
  118. >+渠道号</a-tag
  119. >
  120. </a-form-item>
  121. <a-form-item
  122. label="隐私政策链接"
  123. :labelCol="{ xs: { span: 24 }, sm: { span: 5 } }"
  124. :wrapperCol="{ xs: { span: 24 }, sm: { span: 16 } }"
  125. >
  126. <a-input
  127. v-decorator="[
  128. 'appPrivacyUrl',
  129. {
  130. rules: [
  131. { required: true, message: '请填写隐私政策链接' },
  132. { validator: handleConfirmValue }
  133. ]
  134. }
  135. ]"
  136. placeholder="请填写隐私政策链接"
  137. />
  138. </a-form-item>
  139. </a-form>
  140. </a-card>
  141. </a-modal>
  142. </div>
  143. </template>
  144. <script>
  145. import Vue from 'vue'
  146. import { ACCESS_TOKEN } from '@/store/mutation-types'
  147. import { deleteAction, postAction, getAction, downFilePost, downFile } from '@/api/manage'
  148. import uploadFile from './uploadFile.vue'
  149. import { mapActions, mapGetters } from 'vuex'
  150. import BMF from 'browser-md5-file'
  151. import selectTable from '@/views/modules/Statistics/components/selectPagination.vue'
  152. import $ from 'jquery'
  153. const fileSuffix = ['xlsx', 'xls', 'zip']
  154. export default {
  155. name: 'BaseForm',
  156. components: {
  157. uploadFile,
  158. selectTable
  159. },
  160. data() {
  161. return {
  162. useSdk: [],
  163. loadDisabled: false,
  164. projectId: '',
  165. accountId: '',
  166. fileList: [],
  167. fileUrl: '',
  168. accountList: {},
  169. appType: 'android', //设备类型
  170. platform: '1', //应用类型 : 1 Android 应用下载,2: Android 网页游戏,3: iOS 应用下载, 4:iOS 网页游戏
  171. uploadType: '2', //上传类型 1 本地上传 2 填写链接
  172. appVersion: '', //应用标记
  173. appName: '', // 应用名称
  174. packageName: '', //应用包名
  175. file: '', // 上传文件
  176. imageUrl: '', // 上传图标链接链接
  177. downloadUrl: '', //下载链接
  178. showUploadFile: true,
  179. showDownLoad: false,
  180. showUpload: true,
  181. showAndroid: true,
  182. showIOS: false,
  183. customDomain: '',
  184. acceptVideo: '/*.apk,/*.png,/*.jpg,/*.jpeg,/*.mp4',
  185. accessKeyId: 'LTAIbNbqWzSOklQV',
  186. accessKeySecret: '1rkPz7JNoXk8sJevPaeYHWqfkQXBGh',
  187. region: 'oss-cn-beijing',
  188. bucket: 'ctop-media',
  189. form: this.$form.createForm(this),
  190. url: {
  191. insertTemplateUrl: '/kuaishouAppPackage/fillInLink',
  192. userAllocationList: '/ctop/userAllocation/list'
  193. },
  194. application: false,
  195. confirmLoading: false,
  196. imageToken: '',
  197. // uploadAction: '/kuaishouAppPackage/importAppExcel',
  198. tokenHeader: { 'X-Access-Token': Vue.ls.get(ACCESS_TOKEN) },
  199. okCreated: false,
  200. dataFile: null,
  201. createTypeData: null
  202. }
  203. },
  204. methods: {
  205. getChangeAll(type, form, field) {
  206. var node = document.getElementById(field)
  207. var v = '-{{' + type + '}}-'
  208. if (document.selection) {
  209. //IE
  210. node.focus()
  211. var sel = document.selection.createRange()
  212. sel.text = v
  213. sel.select()
  214. if (field == 'channelName') {
  215. this[form].setFieldsValue({ channelName: sel.text })
  216. } else if (field == 'channelCode') {
  217. this[form].setFieldsValue({ channelCode: sel.text })
  218. } else if (field == 'url') {
  219. this[form].setFieldsValue({ url: sel.text })
  220. } else if (field == 'clickTrackUrl') {
  221. this[form].setFieldsValue({ clickTrackUrl: sel.text })
  222. } else if (field == 'actionbarClickUrl') {
  223. this[form].setFieldsValue({ actionbarClickUrl: sel.text })
  224. } else if (field == 'appVersion') {
  225. this[form].setFieldsValue({ appVersion: sel.text })
  226. }
  227. } else if (node.selectionStart || node.selectionStart == '0') {
  228. //MOZILLA/GOOGLE
  229. var startPos = node.selectionStart
  230. var endPos = node.selectionEnd
  231. var restoreTop = node.scrollTop
  232. node.value = node.value.substring(0, startPos) + v + node.value.substring(endPos, node.value.length)
  233. if (restoreTop > 0) {
  234. node.scrollTop = restoreTop
  235. }
  236. if (field == 'channelName') {
  237. this[form].setFieldsValue({ channelName: node.value })
  238. } else if (field == 'channelCode') {
  239. this[form].setFieldsValue({ channelCode: node.value })
  240. } else if (field == 'url') {
  241. this[form].setFieldsValue({ url: node.value })
  242. } else if (field == 'clickTrackUrl') {
  243. this[form].setFieldsValue({ clickTrackUrl: node.value })
  244. } else if (field == 'actionbarClickUrl') {
  245. this[form].setFieldsValue({ actionbarClickUrl: node.value })
  246. } else if (field == 'appVersion') {
  247. this[form].setFieldsValue({ appVersion: node.value })
  248. }
  249. node.focus()
  250. node.selectionStart = startPos + v.length
  251. node.selectionEnd = startPos + v.length
  252. // this.channelName = node.value
  253. } else {
  254. //OTHER
  255. node.value += v
  256. // console.log(node.value)
  257. if (field == 'channelName') {
  258. this[form].setFieldsValue({ channelName: node.value })
  259. } else if (field == 'channelCode') {
  260. this[form].setFieldsValue({ channelCode: node.value })
  261. } else if (field == 'url') {
  262. this[form].setFieldsValue({ url: node.value })
  263. } else if (field == 'clickTrackUrl') {
  264. this[form].setFieldsValue({ clickTrackUrl: node.value })
  265. } else if (field == 'actionbarClickUrl') {
  266. this[form].setFieldsValue({ actionbarClickUrl: node.value })
  267. } else if (field == 'appVersion') {
  268. this[form].setFieldsValue({ appVersion: node.value })
  269. }
  270. node.focus()
  271. // this.channelName = node.value
  272. }
  273. },
  274. overUpload(file) {},
  275. downLoadFile() {
  276. downFile('/kuaishouAppPackage/exportAppTemplate').then(res => {
  277. let blob = new Blob([res], {
  278. type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  279. })
  280. let downloadElement = document.createElement('a')
  281. let href = window.URL.createObjectURL(blob) //创建下载的链接
  282. downloadElement.href = href
  283. downloadElement.download = '应用模板' //下载后文件名
  284. document.body.appendChild(downloadElement)
  285. downloadElement.click() //点击下载
  286. document.body.removeChild(downloadElement) //下载完成移除元素
  287. window.URL.revokeObjectURL(href) //释放掉blob对象
  288. })
  289. },
  290. handleChange(info) {
  291. this.loadDisabled = false
  292. this.$message.success('文件导入成功')
  293. },
  294. beforeUpload(file) {
  295. this.dataFile = $('.fileUpload')
  296. .eq(0)
  297. .find('input')[0].files[0]
  298. this.loadDisabled = true
  299. const size = (Number(file.size) / (1024 * 1024)).toFixed(2)
  300. const fileName = file.name
  301. const fileStrArr = fileName.split('.')
  302. const suffix = fileStrArr[fileStrArr.length - 1]
  303. let result = fileSuffix.some(item => {
  304. return item === suffix
  305. })
  306. if (!result) {
  307. this.$message.error('不支持该文件类型')
  308. this.loadDisabled = false
  309. return false
  310. }
  311. },
  312. cosUpload(file) {
  313. let that = this
  314. let date = new Date()
  315. let y = date.getFullYear()
  316. let MM = date.getMonth() + 1
  317. MM = MM < 10 ? '0' + MM : MM
  318. let d = date.getDate()
  319. d = d < 10 ? '0' + d : d
  320. let timeElse = new Date().getTime()
  321. let arr = file.name.split('.')
  322. let str = ''
  323. for (let i = 0; i < arr.length; i++) {
  324. if (i === arr.length - 1) {
  325. } else {
  326. if (i === arr.length - 2) {
  327. str += arr[i]
  328. } else {
  329. str += arr[i] + '.'
  330. }
  331. }
  332. }
  333. cos.putObject(
  334. {
  335. Bucket: 'media-1301855440',
  336. Region: 'ap-chongqing',
  337. // 存储桶所在地域,必须字段
  338. Key:
  339. that.appType +
  340. '/' +
  341. y +
  342. '-' +
  343. MM +
  344. '-' +
  345. d +
  346. '/' +
  347. str +
  348. '-' +
  349. timeElse +
  350. '.' +
  351. arr[arr.length - 1],
  352. StorageClass: 'STANDARD',
  353. Body: file // 上传文件对象
  354. },
  355. function(err, data) {
  356. if (err) {
  357. that.$message.error('上传失败!!!' + err)
  358. return
  359. }
  360. that.loadingElse = false
  361. that.fileList.push({
  362. uid: file.name,
  363. name: file.name,
  364. status: 'done',
  365. url: '//' + data.Location
  366. })
  367. if (that.fileList.length > 1) {
  368. that.fileList = that.fileList.slice(-1)
  369. }
  370. const isZip = file.type.includes('zip') || file.type.includes('text')
  371. const fileOvesize = file.size > 1024 * 1024 * 1024
  372. if (!isZip) {
  373. that.$message.error('只能上传zip格式的文件或者txt文件')
  374. return
  375. }
  376. if (fileOvesize) {
  377. that.$message.error('文件大小不能超过1G')
  378. return
  379. }
  380. that.handleMd5(file)
  381. }
  382. )
  383. },
  384. handleMd5(file) {
  385. let bmf = new BMF()
  386. let that = this
  387. return new Promise(function(resolve, reject) {
  388. bmf.md5(file, (err, md5) => {
  389. // getAction('kuaishouPopulationPackage/checkPopulationPackage', { signature: md5 })
  390. // .then((result) => {
  391. // if (result.code === 200) {
  392. that.personNameDisabled = false
  393. that.personResourceDisabled = false
  394. resolve()
  395. })
  396. })
  397. },
  398. handleOk() {
  399. this.handleSubmit()
  400. },
  401. handleCancel() {
  402. this.dataFile = null
  403. this.appType = 'android'
  404. this.okCreated = false
  405. this.form.resetFields()
  406. this.fileUrl = ''
  407. this.file = ''
  408. this.platform = '1'
  409. this.application = false
  410. },
  411. showApplication() {
  412. this.application = true
  413. },
  414. handleConfirmValue(rule, value, callback) {
  415. if (/(http|https):\/\/([\w.]+\/?)\S*/.test(value) && value != '') {
  416. callback()
  417. } else {
  418. callback('链接不能为空且开头为http://或https://')
  419. }
  420. },
  421. ...mapGetters(['nickname', 'avatar', 'userInfo']),
  422. changePlatform() {
  423. this.form.resetFields()
  424. if (this.appType == 'android') {
  425. this.showAndroid = true
  426. this.showIOS = false
  427. this.platform = '1'
  428. } else {
  429. this.showAndroid = false
  430. this.showIOS = true
  431. this.showDownLoad = true
  432. this.platform = '1'
  433. }
  434. },
  435. changeShowUpload() {
  436. this.form.resetFields()
  437. this.fileUrl = ''
  438. },
  439. changeShowUploadType() {
  440. this.form.resetFields()
  441. if (this.platform == '2') {
  442. this.showUpload = false
  443. this.showUploadFile = false
  444. this.showDownLoad = true
  445. this.uploadType = '1'
  446. } else {
  447. this.showUpload = true
  448. this.showUploadFile = true
  449. this.showDownLoad = false
  450. }
  451. },
  452. handleSubmit() {
  453. // console.log('设备类型:' + this.appType)
  454. // console.log('应用类型:' + this.platform)
  455. // console.log('上传类型:' + this.uploadType)
  456. // console.log('应用标记:' + this.appVersion)
  457. // console.log('应用名称:' + this.appName)
  458. // console.log('包名称:' + this.packageName)
  459. // console.log('文件地址:' + this.file)
  460. // console.log('图片地址:' + this.imageUrl)
  461. // e.preventDefault()
  462. this.form.validateFields((err, values) => {
  463. if (!err) {
  464. if (this.fileUrl) {
  465. this.confirmLoading = true
  466. let params = {}
  467. this.url.insertTemplateUrl = '/kuaishouAppPackage/fillInLink'
  468. params = { ...values }
  469. params.appIconUrl = this.fileUrl
  470. this.confirmLoading = false
  471. this.$emit('getDataList', params)
  472. this.handleCancel()
  473. // postAction(this.url.insertTemplateUrl, params).then(res => {
  474. // this.confirmLoading = false
  475. // if (res.success) {
  476. // this.$message.success('创建成功')
  477. // this.handleCancel()
  478. // this.$emit('getDataList')
  479. // } else {
  480. // this.$message.error(res.message)
  481. // }
  482. // })
  483. } else {
  484. this.confirmLoading = false
  485. this.$message.error('请填写必填项')
  486. }
  487. }
  488. })
  489. },
  490. onChange(value) {}
  491. },
  492. created: function() {
  493. this.createTypeData = JSON.parse(localStorage.getItem('createTypeData'))
  494. let params = {}
  495. params.pageSize = '1000'
  496. params.mediaId = '2'
  497. params.userId = this.userInfo().id
  498. getAction(this.url.userAllocationList, params).then(res => {
  499. if (res.success) {
  500. this.accountList = res.result.records
  501. }
  502. })
  503. }
  504. }
  505. </script>