videoForm.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. <template>
  2. <view class="container">
  3. <u-cell-group class="form-info" :border="false">
  4. <u-field label="视频名称" placeholder="请输入视频名称" label-width="180" v-model="videoInfo.videoName"></u-field>
  5. <u-cell-item title="请上传视频" :arrow="false" v-if="type == 'add'">
  6. <cover-image slot="label" class="" :src="videoImg" v-if="videoImg"></cover-image>
  7. <view slot="label" class="upload-video" @tap="chooseVideoImage" v-else>
  8. <u-icon name="plus" size="40"></u-icon>
  9. <view class="u-add-tips" style="margin-top: 6px;">选择视频</view>
  10. </view>
  11. </u-cell-item>
  12. <u-cell-item title="请上传视频海报" :arrow="false" v-if="type == 'add'">
  13. <view slot="label">
  14. <u-upload :action="uploadUrl" :file-list="defaultList" :form-data="uploadData" @on-success="uploadSuccess"
  15. @on-error="uploadError" @on-remove="uploadRemove" max-count="5"></u-upload>
  16. </view>
  17. </u-cell-item>
  18. <u-cell-item title="绑定商品(可多选)" @click="popupShow = true" class="good-arrow">
  19. <view slot="label">
  20. <view class="good-card" v-for="(item, index) in goodList.filter(site => site.check)" :key="index">
  21. <cover-image class="goods-img" :src="item.imgPath"></cover-image>
  22. <view class="good-info">
  23. <view class="good-name">{{item.productName}}</view>
  24. <view class="good-text">销量:{{item.sellCount}}</view>
  25. <view class="good-price">
  26. <text class="goods-spec">¥{{item.bizPrice}}/{{item.unit}}</text>
  27. <text class="goods-original">原价:{{item.originalPrice}}</text>
  28. </view>
  29. </view>
  30. </view>
  31. </view>
  32. </u-cell-item>
  33. </u-cell-group>
  34. <view class="form-handle">
  35. <u-button type="success" shape="circle" :ripple="true" @click="submitData" :disabled="getPermit()" class="handle-custom">提交</u-button>
  36. </view>
  37. <u-popup v-model="popupShow" mode="bottom" closeable border-radius="30">
  38. <scroll-view scroll-y="true" class="good-select-box">
  39. <view class="select-good-row" v-for="(item, index) in goodList" :key="index">
  40. <view class="good-check">
  41. <view class="iconfont" :class="item.check ? 'iconqueding' : 'iconfeigouxuan'" @click="item.check = !item.check"></view>
  42. </view>
  43. <view class="good-card" style="width: calc(100% - 60px);">
  44. <cover-image class="goods-img" :src="item.imgPath"></cover-image>
  45. <view class="good-info">
  46. <view class="good-name">{{item.productName}}</view>
  47. <view class="good-text">销量:{{item.sellCount}}</view>
  48. <view class="good-price">
  49. <text class="goods-spec">¥{{item.bizPrice}}/{{item.unit}}</text>
  50. <text class="goods-original">原价:{{item.originalPrice}}</text>
  51. </view>
  52. </view>
  53. </view>
  54. </view>
  55. </scroll-view>
  56. </u-popup>
  57. <u-top-tips ref="uTips"></u-top-tips>
  58. </view>
  59. </template>
  60. <script>
  61. const NET = require('@/utils/request')
  62. const API = require('@/config/api')
  63. export default {
  64. data() {
  65. return {
  66. type: 'add',
  67. videoId: '',
  68. videoInfo: {
  69. videoName: '',
  70. mediaFilePath: '',
  71. },
  72. productIds: '',
  73. videoImg: '',
  74. uploadData: {
  75. folderId: 0,
  76. },
  77. uploadUrl: '',
  78. fileList: [],
  79. defaultList: [],
  80. goodList: [],
  81. popupShow: false,
  82. }
  83. },
  84. onLoad(options) {
  85. this.uploadUrl = API.uploadFile
  86. this.type = options.type
  87. this.videoInfo.videoId = options.videoId
  88. if (this.type == 'edit') {
  89. this.getDetail()
  90. }
  91. NET.request(API.getVideoGoods, {}, 'GET').then(res => {
  92. res.data.forEach(site => {
  93. site.check = this.productIds && this.productIds.indexOf(site.productId) != -1
  94. })
  95. this.goodList = res.data
  96. }).catch(res => {
  97. this.$refs.uTips.show({
  98. title: '获取可绑定商品失败',
  99. type: 'warning',
  100. })
  101. })
  102. },
  103. onReady() {},
  104. methods: {
  105. // 上传视频
  106. chooseVideoImage() {
  107. uni.chooseVideo({
  108. count: 1,
  109. sourceType: ['camera', 'album'],
  110. success: (res) => {
  111. this.videoImg = res.thumbTempFilePath
  112. uni.uploadFile({
  113. url: API.uploadFile,
  114. filePath: res.tempFilePath,
  115. name: 'file',
  116. formData: this.uploadData,
  117. success: (uploadFileRes) => {
  118. let resData = JSON.parse(uploadFileRes.data)
  119. this.videoInfo.mediaFilePath = resData.data.url
  120. this.$refs.uTips.show({
  121. title: '文件上传成功',
  122. type: 'success',
  123. })
  124. }
  125. });
  126. }
  127. });
  128. },
  129. // 获取详情
  130. getDetail() {
  131. NET.request(API.getVideoDetail, {
  132. videoId: this.videoInfo.videoId
  133. }, 'GET').then(res => {
  134. this.videoInfo.videoName = res.data.videoName
  135. res.data.products = res.data.products.map(site => {
  136. return site.productId
  137. }).join(',')
  138. if (this.goodList.length && res.data.products) {
  139. this.goodList.forEach(site => {
  140. site.check = res.data.products.indexOf(site.productId) != -1
  141. })
  142. } else {
  143. this.productIds = res.data.products ? res.data.products : []
  144. }
  145. }).catch(res => {
  146. this.$refs.uTips.show({
  147. title: '获取详情失败',
  148. type: 'warning',
  149. })
  150. })
  151. },
  152. // 文件上传成功回调
  153. uploadSuccess(res, index, lists, name) {
  154. this.fileList.push(res.data.url)
  155. this.$refs.uTips.show({
  156. title: '文件上传成功',
  157. type: 'success',
  158. })
  159. return true
  160. },
  161. // 文件上传失败回调
  162. uploadError(res, index, lists, name) {
  163. this.$refs.uTips.show({
  164. title: '文件上传失败',
  165. type: 'warning',
  166. })
  167. },
  168. // 移除文件回调
  169. uploadRemove(index, lists, name) {
  170. this.fileList.splice(index, 1)
  171. },
  172. // 检查必填项
  173. getPermit() {
  174. if (!this.videoInfo.videoName || !this.goodList.filter(site => site.check).length) {
  175. return true
  176. }
  177. if (this.type == 'add' && (!this.videoInfo.mediaFilePath || !this.fileList.length)) {
  178. return true
  179. }
  180. return false
  181. },
  182. // 提交
  183. submitData() {
  184. if (this.type == 'add') {
  185. NET.request(API.addVideo, {
  186. ...this.videoInfo,
  187. coverFilePath: this.fileList[0],
  188. coverFileId: 0,
  189. mediaFileId: 0,
  190. productIds: this.goodList.filter(site => site.check).map(site => {
  191. return site.productId
  192. })
  193. }, 'POST').then(res => {
  194. this.$refs.uTips.show({
  195. title: '新增短视频成功',
  196. type: 'success',
  197. })
  198. setTimeout(() => {
  199. uni.navigateBack()
  200. }, 1000)
  201. }).catch(res => {
  202. this.$refs.uTips.show({
  203. title: '新增短视频失败',
  204. type: 'warning',
  205. })
  206. })
  207. } else {
  208. NET.request(API.editVideo, {
  209. ...this.videoInfo,
  210. productIds: this.goodList.filter(site => site.check).map(site => {
  211. return site.productId
  212. })
  213. }, 'POST').then(res => {
  214. this.$refs.uTips.show({
  215. title: '编辑短视频成功',
  216. type: 'success',
  217. })
  218. setTimeout(() => {
  219. uni.navigateBack()
  220. }, 1000)
  221. }).catch(res => {
  222. this.$refs.uTips.show({
  223. title: '编辑短视频失败',
  224. type: 'warning',
  225. })
  226. })
  227. }
  228. },
  229. },
  230. }
  231. </script>
  232. <style lang="less" scoped>
  233. page {
  234. width: 100%;
  235. height: 100%;
  236. }
  237. .container {
  238. width: 100%;
  239. height: 100%;
  240. float: left;
  241. box-sizing: border-box;
  242. padding-bottom: 60px;
  243. overflow-y: auto;
  244. .form-info {
  245. width: 100%;
  246. float: left;
  247. /deep/.u-label-text {
  248. color: #333333;
  249. }
  250. /deep/.u-cell_title {
  251. color: #333333;
  252. }
  253. .upload-video {
  254. width: 100px;
  255. height: 100px;
  256. background: #f4f5f6;
  257. margin: 5px;
  258. color: #606266;
  259. display: flex;
  260. justify-content: center;
  261. align-items: center;
  262. flex-direction: column;
  263. }
  264. .good-arrow {
  265. /deep/.u-cell__right-icon-wrap {
  266. position: absolute;
  267. top: 18px;
  268. right: 10px;
  269. }
  270. }
  271. }
  272. .form-handle {
  273. width: 100%;
  274. height: 60px;
  275. position: fixed;
  276. z-index: 10;
  277. padding: 10px 15px 20px 15px;
  278. box-sizing: border-box;
  279. bottom: 0;
  280. background-color: #FFFFFF;
  281. border-top: 1px solid #EEEEEE;
  282. .handle-custom {
  283. background-color: #51A539;
  284. }
  285. }
  286. .good-select-box {
  287. width: 100%;
  288. height: 400px;
  289. float: left;
  290. overflow-y: auto;
  291. padding: 40px 0 10px 0;
  292. }
  293. .select-good-row {
  294. width: 100%;
  295. height: 114px;
  296. float: left;
  297. }
  298. .good-check {
  299. width: 30px;
  300. height: 104px;
  301. float: left;
  302. line-height: 104px;
  303. margin-right: 10px;
  304. .iconfont {
  305. font-size: 40px;
  306. text-align: right;
  307. color: #51A539;
  308. }
  309. }
  310. .good-card {
  311. width: 100%;
  312. float: left;
  313. margin: 5px;
  314. background: #FFFFFF;
  315. border-radius: 15px;
  316. box-shadow: 0px 1px 5px 0px rgba(102, 102, 102, 0.43);
  317. padding: 12px;
  318. box-sizing: border-box;
  319. .goods-img {
  320. width: 80px;
  321. height: 80px;
  322. float: left;
  323. border-radius: 10px;
  324. object-fit: cover;
  325. }
  326. .good-info {
  327. width: calc(100% - 86px);
  328. height: 80px;
  329. float: right;
  330. .good-name {
  331. width: 100%;
  332. height: 40px;
  333. float: left;
  334. font-size: 15px;
  335. font-family: PingFang SC;
  336. color: #333333;
  337. line-height: 20px;
  338. overflow: hidden;
  339. text-overflow: ellipsis;
  340. display: -webkit-box;
  341. -webkit-line-clamp: 2;
  342. -webkit-box-orient: vertical;
  343. word-wrap: break-word;
  344. }
  345. .good-price {
  346. width: 100%;
  347. height: 20px;
  348. float: left;
  349. line-height: 20px;
  350. font-family: PingFang SC;
  351. white-space: nowrap;
  352. margin: 3px 0 3px 0;
  353. .goods-spec {
  354. font-size: 15px;
  355. color: #52A63A;
  356. margin-right: 6px;
  357. }
  358. .goods-original {
  359. font-size: 12px;
  360. text-decoration: line-through;
  361. color: #A67954;
  362. }
  363. }
  364. }
  365. }
  366. }
  367. </style>