apply.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <template>
  2. <view :style="vuex_skin">
  3. <!-- #ifdef MP-WEIXIN -->
  4. <u-navbar title-color="#000000" :is-back="true" title="我要报名"></u-navbar>
  5. <!-- #endif -->
  6. <view class="add-media" @click="handleUploadWork">
  7. <view class="flex-direction flex justify-center" style="align-items: center;" v-show="!showUrl">
  8. <u-icon name="plus-circle-fill" :color="vuex_theme.bgColor" size="90"></u-icon>
  9. <text v-text="activeType == 'VIDEO_TEXT'?'上传视频作品':'上传图片作品'"
  10. style="margin-top: 26rpx; color: #010101; font-size: 24rpx; font-weight: bold;">上传作品(图片或视频)</text>
  11. </view>
  12. <video v-if="activeType == 'VIDEO_TEXT' && showUrl" :src="showUrl"></video>
  13. <image v-if="activeType == 'IMAGE_TEXT' && showUrl" :src="showUrl" mode="aspectFill"></image>
  14. </view>
  15. <view class="fill-info">
  16. <text class="info-title" style="font-weight: bold; color: #010101; font-size: 34rpx;">填写信息</text>
  17. <view v-if="activeType == 'VIDEO_TEXT'" style="margin-bottom: 64rpx;">
  18. <text style="color: #010101; font-size: 28rpx; font-weight: bold;"><text style="color: #f00;">*</text> 作品封面</text>
  19. <view style="padding: 5rpx 0 20rpx; border-bottom: 1rpx solid #E3E3E3;">
  20. <upload-img ref="uploadImg" :count="1" col="4" @click="uploadCover"></upload-img>
  21. </view>
  22. </view>
  23. <view style="margin-bottom: 64rpx;">
  24. <text style="color: #010101; font-size: 28rpx; font-weight: bold;"><text style="color: #f00;">*</text> 标题</text>
  25. <view style="padding: 32rpx 0 0; border-bottom: 1rpx solid #E3E3E3;">
  26. <u-input placeholder="请输入标题内容" v-model="applyInfo.title"></u-input>
  27. </view>
  28. </view>
  29. <view style="margin-bottom: 64rpx;">
  30. <text style="color: #010101; font-size: 28rpx; font-weight: bold;"><text style="color: #f00;">*</text> 参赛者</text>
  31. <view style="padding: 32rpx 0 0; border-bottom: 1rpx solid #E3E3E3;">
  32. <u-input placeholder="请输入参赛者名称" v-model="applyInfo.player"></u-input>
  33. </view>
  34. </view>
  35. <view style="margin-bottom: 64rpx;">
  36. <text style="color: #010101; font-size: 28rpx; font-weight: bold;"><text style="color: #f00;">*</text> 详细介绍</text>
  37. <view style="padding: 32rpx 0 0; border-bottom: 1rpx solid #E3E3E3;">
  38. <u-input placeholder="请输入详细介绍" v-model="applyInfo.content"></u-input>
  39. <!-- <u-input placeholder="请输入详细介绍" v-model="applyInfo.content" type="textarea" height="60" auto-height></u-input> -->
  40. </view>
  41. </view>
  42. <view style="margin-bottom: 64rpx;">
  43. <text style="color: #010101; font-size: 28rpx; font-weight: bold;"><text style="color: #f00;">*</text> 联系方式</text>
  44. <view style="padding: 32rpx 0 0; border-bottom: 1rpx solid #E3E3E3;">
  45. <u-input placeholder="请输入手机号码" v-model="applyInfo.phone"></u-input>
  46. </view>
  47. </view>
  48. <u-button shape="circle" :custom-style="customStyle" @click="submit">确定提交</u-button>
  49. </view>
  50. <compress ref="compress"></compress>
  51. <toast ref="toast"></toast>
  52. <uploadAlert ref="uploadAlert" :updateProgress="updateProgress" @cancelUpload="cancelUpload"></uploadAlert>
  53. </view>
  54. </template>
  55. <script>
  56. import compress from "@/components/compress.vue"
  57. import uploadImg from "@/components/uploadImg/uploadImg.vue"
  58. import uploadAlert from "@/components/alert/uploadAlert.vue"
  59. import config from "@/assets/http/config.js"
  60. let uploadTask
  61. export default {
  62. name: '',
  63. components: {
  64. compress,
  65. uploadImg,
  66. uploadAlert
  67. },
  68. data() {
  69. return {
  70. //压缩参数
  71. compressParams: {
  72. src: '',
  73. maxSize: 2048,
  74. fileType: 'jpg',
  75. quality: 1,
  76. minSize: 800 //最小压缩尺寸,图片尺寸小于该时值不压缩,非H5平台有效。若需要忽略该设置,可设置为一个极小的值,比如负数。
  77. },
  78. customStyle: {
  79. color: 'white',
  80. background: "#E72226",
  81. fontSize: '32rpx',
  82. width: '340rpx',
  83. margin: '25rpx auto 0'
  84. },
  85. //显示的url,有可能是图文,也有可能是视频
  86. showUrl: '',
  87. applyInfo: {},
  88. activeType: '', //活动类型: VIDEO_TEXT视频图文 IMAGE_TEXT图片文本
  89. updateProgress: '', //上传进度
  90. };
  91. },
  92. onLoad(options) {
  93. if (this.$isEmpty(this.vuex_userId) ||
  94. this.$isEmpty(options.activeType) ||
  95. this.$isEmpty(options.activeId)) {
  96. uni.switchTab({
  97. url: "/pages/index/home"
  98. })
  99. return
  100. }
  101. this.initData(options)
  102. },
  103. methods: {
  104. /**
  105. * 初始化数据
  106. */
  107. initData(options) {
  108. this.customStyle.background = this.vuex_theme.bgColor
  109. this.activeType = options.activeType;
  110. // this.activeType = 'IMAGE_TEXT';
  111. this.applyInfo = {
  112. userId: this.vuex_userId,
  113. phone: this.vuex_phone,
  114. activeId: options.activeId,
  115. title: "",
  116. imgUrl: "",
  117. videoUrl: "",
  118. content: "",
  119. player: "",
  120. }
  121. },
  122. /**
  123. * 上传封面
  124. */
  125. uploadCover(e) {
  126. this.applyInfo.imgUrl = e[0]
  127. },
  128. /**
  129. * 上传文件
  130. * 图文存进imgUrl
  131. */
  132. async uploadFile(params) {
  133. let res = await this.$api.uploadFile(params)
  134. if (this.activeType == 'VIDEO_TEXT') {
  135. this.applyInfo.videoUrl = res.data.data.link;
  136. } else {
  137. this.applyInfo.imgUrl = res.data.data.link
  138. }
  139. },
  140. /**
  141. * 上传作品
  142. */
  143. handleUploadWork() {
  144. if (this.activeType == 'VIDEO_TEXT') {
  145. //上传视频作品
  146. this.uploadVideoWork()
  147. } else {
  148. //上传图片作品
  149. this.uploadImageWork()
  150. }
  151. },
  152. /**
  153. * 上传图文作品
  154. */
  155. async uploadImageWork() {
  156. let res = await this.$mpi.chooseImage()
  157. this.compressParams.src = res[0]
  158. this.$dialog.showLoading('作品上传中..')
  159. let src= await this.$refs.compress.compress(this.compressParams)
  160. let resp = await this.$api.uploadFile(src)
  161. this.applyInfo.imgUrl = resp.data.data.link
  162. //显示的是图文链接
  163. this.showUrl = this.applyInfo.imgUrl
  164. uni.hideLoading()
  165. },
  166. /**
  167. * 上传视频作品
  168. */
  169. async uploadVideoWork() {
  170. let resp = await this.chooseVideo()
  171. // this.$dialog.showLoading('正在上传中..')
  172. this.$refs.uploadAlert.show = true;
  173. //上传视频链接
  174. let videoRes = await this.uploadVideo(resp.tempFilePath)
  175. this.applyInfo.videoUrl = videoRes.data.link;
  176. //上传视频封面链接
  177. // let coverRes = await this.$api.uploadFile(resp.thumbTempFilePath)
  178. // this.applyInfo.imgUrl = coverRes.data.data.link
  179. // this.$refs.uploadImg.imgList = [this.applyInfo.imgUrl]
  180. //显示的是视频链接
  181. this.showUrl = this.applyInfo.videoUrl
  182. uni.hideLoading()
  183. },
  184. /**
  185. * 取消视频作品
  186. */
  187. cancelUpload(){
  188. uploadTask.abort();
  189. },
  190. /**
  191. * 选择视频
  192. */
  193. chooseVideo() {
  194. var that = this;
  195. return new Promise((resolve, reject) => {
  196. uni.chooseVideo({
  197. count: 1,
  198. sourceType: ['album'],
  199. success: function(res) {
  200. let fileSize = (res.size/1024/1024).toFixed(2)
  201. console.log("视频大小", fileSize)
  202. if(fileSize > 50){
  203. that.$refs.toast.error('上传视频不能大于50M')
  204. return
  205. }
  206. resolve(res)
  207. },
  208. fail() {
  209. uni.hideLoading()
  210. }
  211. });
  212. })
  213. },
  214. /**
  215. * 上传视频
  216. */
  217. uploadVideo(tempFilePath) {
  218. let that = this;
  219. return new Promise((resolve, reject) => {
  220. uploadTask = uni.uploadFile({
  221. url: `${config.baseURL}/blade-resource/oss/endpoint/put-file`,
  222. filePath: tempFilePath,
  223. name: 'file',
  224. formData: { user: 'test' },
  225. header: { "Blade-Auth": uni.getStorageSync('token') },
  226. success(res) {
  227. resolve(JSON.parse(res.data))
  228. that.$refs.uploadAlert.show = false;
  229. that.updateProgress = '';
  230. },
  231. fail(err) {
  232. //用户取消上传
  233. if(err.errMsg === 'uploadFile:fail abort'){
  234. that.$refs.uploadAlert.show = false;
  235. that.updateProgress = '';
  236. that.$refs.toast.warn('取消上传')
  237. }
  238. }
  239. });
  240. uploadTask.onProgressUpdate(function(res) {
  241. that.updateProgress = res;
  242. console.log('上传进度' + res.progress);
  243. console.log('已经上传的数据长度' + res.totalBytesSent);
  244. console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
  245. });
  246. });
  247. },
  248. /**
  249. * 压缩视频
  250. */
  251. compressVideo() {
  252. uni.compressVideo({
  253. src: tempFilePath,
  254. quality: 'high', //'low':低,'medium':中,'high':高
  255. bitrate: 0,
  256. fps: 0,
  257. resolution: 0,
  258. success: function(csRes) {
  259. // 未进入
  260. console.log('压缩后大小')
  261. console.log(csRes.size)
  262. },
  263. fail: function(cfRes) {
  264. console.log(cfRes)
  265. uni.showToast({
  266. title: '视频压缩失败',
  267. icon: 'none'
  268. })
  269. }
  270. });
  271. },
  272. submit() {
  273. if (this.activeType == 'VIDEO_TEXT') {
  274. //视频
  275. if (this.$isEmpty(this.applyInfo.videoUrl)) {
  276. this.$refs.toast.warn('请上传视频作品')
  277. return
  278. }
  279. if (this.$isEmpty(this.applyInfo.imgUrl)) {
  280. this.$refs.toast.warn('请上传作品封面')
  281. return
  282. }
  283. } else {
  284. //图文
  285. if (this.$isEmpty(this.applyInfo.imgUrl)) {
  286. this.$refs.toast.warn('请上传图文作品')
  287. return
  288. }
  289. }
  290. if (this.$isEmpty(this.applyInfo.title)) {
  291. this.$refs.toast.warn('请输入标题内容')
  292. return
  293. }
  294. if (this.$isEmpty(this.applyInfo.player)) {
  295. this.$refs.toast.warn('请输入参赛者名称')
  296. return
  297. }
  298. if (this.$isEmpty(this.applyInfo.content)) {
  299. this.$refs.toast.warn('请输入详细介绍')
  300. return
  301. }
  302. if (this.$isEmpty(this.applyInfo.phone)) {
  303. this.$refs.toast.warn('请输入手机号')
  304. return
  305. }
  306. this.$api.activity.submitForm(this.applyInfo).then(res => {
  307. if (res.data.success) {
  308. this.$dialog.showModalAndBack('添加成功', this.vuex_theme.bgColor)
  309. }
  310. })
  311. }
  312. }
  313. };
  314. </script>
  315. <style lang="scss" scoped>
  316. .add-media {
  317. width: 700rpx;
  318. height: 428rpx;
  319. border-radius: 14rpx;
  320. background: #FFFFFF;
  321. margin: 40rpx auto;
  322. display: flex;
  323. flex-direction: column;
  324. justify-content: center;
  325. align-items: center;
  326. }
  327. .fill-info {
  328. width: 700rpx;
  329. border-radius: 14rpx;
  330. background: #FFFFFF;
  331. margin: 0 auto;
  332. display: flex;
  333. flex-direction: column;
  334. padding: 40rpx 54rpx 50rpx;
  335. margin-bottom: 88rpx;
  336. .info-title {
  337. position: relative;
  338. margin-bottom: 60rpx;
  339. &:before {
  340. content: '';
  341. width: 8rpx;
  342. height: 32rpx;
  343. background: var(--bgColor);
  344. position: absolute;
  345. left: -18rpx;
  346. top: 50%;
  347. transform: translateY(-50%);
  348. }
  349. }
  350. }
  351. </style>