buyBackModel.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <template>
  2. <Popup ref="popRef" title="申请回购" isClose closeOnClickOverlay>
  3. <template #content>
  4. <view class="popup-content">
  5. <!-- 图片上传 -->
  6. <view class="image-section">
  7. <view class="section-title">
  8. <trans _t="上传图片" />
  9. </view>
  10. <imageUpload v-model="imageList" :maxCount="maxImages" multiple />
  11. </view>
  12. <view class="image-section">
  13. <view class="section-title _required">
  14. <trans _t="上传视频" />
  15. </view>
  16. <videoUpload v-model="videoUrl" />
  17. </view>
  18. </view>
  19. </template>
  20. <template #footer>
  21. <view class="popup-footer">
  22. <view class="btn-group">
  23. <view class="btn cancel-btn" @click="close">
  24. <trans _t="取消" />
  25. </view>
  26. <view class="btn submit-btn" @click="submitReview">
  27. <trans _t="提交" />
  28. </view>
  29. </view>
  30. </view>
  31. </template>
  32. </Popup>
  33. </template>
  34. <script setup>
  35. import { ref, computed, watch } from "vue";
  36. import { Toast, TimeOut } from "@/utils";
  37. import { t } from "@/locale";
  38. import { SHOP_SUBMIT_BUYBACK } from "@/api";
  39. import imageUpload from "@/components/imageUpload";
  40. import videoUpload from "@/components/videoUpload";
  41. import Popup from "@/components/popup";
  42. const props = defineProps({
  43. id: {
  44. type: [String, Number],
  45. default: "",
  46. },
  47. maxImages: {
  48. type: Number,
  49. default: 6,
  50. },
  51. });
  52. const emit = defineEmits(["submit", "close", "open"]);
  53. const popRef = ref(null);
  54. const reviewContent = ref("");
  55. const imageList = ref([]);
  56. const videoUrl = ref([]);
  57. // 是否可以提交
  58. const canSubmit = computed(() => {
  59. return reviewContent.value.trim().length > 0 && imageList.value.length;
  60. });
  61. // 打开弹框
  62. const open = (data = {}) => {
  63. popRef.value && popRef.value.open();
  64. // 重置数据
  65. videoUrl.value = [];
  66. imageList.value = [];
  67. };
  68. // 关闭弹框
  69. const close = () => {
  70. popRef.value && popRef.value.close();
  71. emit("close");
  72. };
  73. // 提交评价
  74. const submitReview = async () => {
  75. let images = "";
  76. let videos = "";
  77. if (imageList.value.length) {
  78. images = imageList.value.map((item) => item.url).join(",");
  79. }
  80. if (videoUrl.value.length) {
  81. videos = videoUrl.value.map((item) => item.url).join(",");
  82. } else {
  83. return Toast("请上传视频");
  84. }
  85. try {
  86. const submitData = {
  87. pid: props.id,
  88. video: videos,
  89. images: images,
  90. };
  91. const res = await SHOP_SUBMIT_BUYBACK(submitData);
  92. Toast(res.msg).then(() => {
  93. TimeOut(() => {
  94. close();
  95. emit("submit", submitData);
  96. });
  97. });
  98. } catch (error) {
  99. console.error("提交评价失败:", error);
  100. Toast(error.msg || "提交失败,请重试");
  101. }
  102. };
  103. // 暴露方法
  104. defineExpose({
  105. open,
  106. close,
  107. });
  108. </script>
  109. <style lang="less" scoped>
  110. .popup-content {
  111. flex: 1;
  112. overflow-y: auto;
  113. }
  114. .review-section,
  115. .image-section,
  116. .rating-section {
  117. margin-bottom: 32rpx;
  118. .section-title {
  119. font-size: 28rpx;
  120. font-weight: 600;
  121. color: var(--text);
  122. margin-bottom: 16rpx;
  123. &._required {
  124. &::before {
  125. content: "";
  126. margin-right: 0rpx;
  127. }
  128. }
  129. }
  130. }
  131. .image-upload {
  132. .upload-tip {
  133. font-size: 24rpx;
  134. color: var(--text-02);
  135. }
  136. }
  137. .popup-footer {
  138. padding: 24rpx 32rpx;
  139. .btn-group {
  140. display: flex;
  141. gap: 16rpx;
  142. .btn {
  143. flex: 1;
  144. height: 88rpx;
  145. border-radius: 16rpx;
  146. display: flex;
  147. align-items: center;
  148. justify-content: center;
  149. font-size: 28rpx;
  150. font-weight: 600;
  151. }
  152. .cancel-btn {
  153. background: #f5f5f5;
  154. color: var(--text);
  155. }
  156. .submit-btn {
  157. background: var(--black);
  158. color: var(--light);
  159. &.disabled {
  160. background: #ccc;
  161. color: #999;
  162. }
  163. }
  164. }
  165. }
  166. </style>