apply.vue 12 KB

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