selectQuantity.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <!-- @format -->
  2. <script lang="ts" setup>
  3. import { useUserStore } from '@/stores/modules/user'
  4. import { ossUploadApi } from '@/api/model/common'
  5. import { addShopCartApi } from '~/api/model/goods'
  6. const props = defineProps({
  7. data: {
  8. type: Object,
  9. default: () => ({}),
  10. },
  11. })
  12. const emit = defineEmits(['update:data'])
  13. const { openLoginModal } = useLoginModal()
  14. const temporaryData = ref()
  15. const input = ref(null)
  16. const loading = ref(false)
  17. const price = ref(0)
  18. const fileArrList = ref<any>([])
  19. const params = ref<any>({
  20. file: '',
  21. mid: '',
  22. quantity: '',
  23. remark: '',
  24. })
  25. const userStore = useUserStore()
  26. const { isLogin } = storeToRefs(userStore)
  27. const visible = defineModel('visible', { type: Boolean, required: true })
  28. function handleClose() {
  29. console.log('close')
  30. }
  31. watch(
  32. () => props.data,
  33. (data: any) => {
  34. temporaryData.value = JSON.parse(JSON.stringify(data))
  35. params.value.quantity = +data.moq
  36. params.value.mid = data.id
  37. price.value = +data.sellPrice
  38. },
  39. {
  40. immediate: true,
  41. deep: true,
  42. },
  43. )
  44. const totalPrice = computed(() => {
  45. return (params.value.quantity * price.value).toFixed(2)
  46. })
  47. function changeQuantity(currentValue: any) {
  48. params.value.quantity = currentValue
  49. }
  50. function uploadData() {
  51. input.value?.click()
  52. }
  53. function inputChange(e: any) {
  54. const fileList = e.target.files
  55. // fileList 转化为正式数组
  56. const fileArr = Array.from(fileList)
  57. fileArr.forEach(async (file: any) => {
  58. const resourceUrl = await getResource(file)
  59. fileArrList.value.push(resourceUrl)
  60. })
  61. }
  62. async function getResource(file: any) {
  63. try {
  64. if (file.size > 1024 * 1024 * 10)
  65. return ElMessage.error('Image size cannot exceed 10M')
  66. return await ossUploadApi(file)
  67. }
  68. catch (error) {
  69. ElMessage.error('send failed')
  70. }
  71. }
  72. function getFileTitle(file: string) {
  73. const fileArr = file.split('/')
  74. return fileArr[fileArr.length - 1]
  75. }
  76. function del(i: number) {
  77. fileArrList.value = fileArrList.value.filter((item, index) => index !== i)
  78. }
  79. async function addShopCart() {
  80. try {
  81. loading.value = true
  82. const { status, isFirstLogin }: any = await openLoginModal()
  83. if (status) {
  84. params.value.file = fileArrList.value.join(',')
  85. await addShopCartApi(params.value)
  86. ElMessage({
  87. message: 'Add to cart successfully',
  88. type: 'success',
  89. plain: true,
  90. })
  91. loading.value = false
  92. visible.value = false
  93. if (isFirstLogin)
  94. emit('update:data')
  95. }
  96. }
  97. catch (error) {
  98. loading.value = false
  99. console.log(error)
  100. }
  101. finally {
  102. loading.value = false
  103. }
  104. }
  105. </script>
  106. <template>
  107. <el-dialog
  108. v-model="visible"
  109. :append-to-body="true"
  110. width="800"
  111. modal-class="custom-select-modal"
  112. @close="handleClose"
  113. >
  114. <template #header>
  115. <div
  116. class="px-40px py-25px bg-#F5F5F5 b-rd-lt-6px b-rd-rt-6px text-18px fw-700 text-#333"
  117. >
  118. Select quantity
  119. </div>
  120. </template>
  121. <div class="py-20px px-40px pb-0">
  122. <div class="r-rd-8px bg-#F9F9F9 p-24px flex">
  123. <img
  124. :src="data?.goodsImgOrVideoList[0]"
  125. alt=""
  126. srcset=""
  127. class="w-120px h-120px b-solid b-1px b-#e0e0e0 mr-24px"
  128. >
  129. <div>
  130. <div class="mb-34px custom-title-font !text-20px !fw-700">
  131. {{ data.merchandiseEnglishName }}
  132. </div>
  133. <div class="text-#666">
  134. MOQ: {{ data.moq }} {{ data.unitCode_dictText }}
  135. </div>
  136. </div>
  137. </div>
  138. <div class="flex justify-end items-center mt-24px mb-20px">
  139. <!-- <div class="fw-500 mr-20px">
  140. $ {{ price }}
  141. </div> -->
  142. <el-input-number
  143. :disabled="!isLogin"
  144. :model-value="params.quantity"
  145. class="!w-150px custom-input"
  146. :step="1"
  147. :min="data.moq"
  148. @change="changeQuantity"
  149. />
  150. </div>
  151. <div class="mb-24px text-20px fw-700">
  152. Remark
  153. </div>
  154. <div>
  155. <el-input
  156. v-model="params.remark"
  157. style="width: 100%"
  158. :rows="5"
  159. type="textarea"
  160. placeholder="Please input"
  161. />
  162. <div class="my-20px py-8px px-20px b-rd-4px cursor-pointer bg-#f0f6ff inline-block" @click="uploadData">
  163. <svgo-enclosure class="!w-32px !h-32px text-#0068FF" />
  164. <input
  165. ref="input"
  166. multiple="true"
  167. type="file"
  168. class="hidden"
  169. @change="inputChange"
  170. >
  171. </div>
  172. <div>
  173. <div
  174. v-for="(items, index) in fileArrList"
  175. :key="index"
  176. class="py-14px px-16px bg-#F7F8FA flex items-center justify-between mb-16px b-solid b-1px b-#E0E0E0 b-rd-4px"
  177. >
  178. <div class="flex items-center">
  179. <svgo-file
  180. class="!w-20px cursor-pointer !h-20px text-#333 mr-16px"
  181. />
  182. 附件{{ index }}:
  183. <a :href="items"> {{ getFileTitle(items) }}</a>
  184. </div>
  185. <img src="@/assets/images/file_delete.png" class="!w-20px cursor-pointer !h-20px" alt="" srcset="" @click="del(index)">
  186. </div>
  187. </div>
  188. </div>
  189. </div>
  190. <template #footer>
  191. <div>
  192. <!-- <div class="mb-8px">
  193. Subtotal
  194. </div>
  195. <div class="text-20px fw-700 text-#333">
  196. $ {{ totalPrice }}
  197. </div> -->
  198. </div>
  199. <el-button
  200. plain
  201. :loading="loading"
  202. class="!bg-#C58C46 !text-#fff !w-240px !h-48px !text-16px !b-rd-6px"
  203. @click="addShopCart"
  204. >
  205. <!-- Add to Cart (${{ quantity * price ? (quantity * price).toFixed(2) : 0 }}) -->
  206. Add to Cart
  207. </el-button>
  208. </template>
  209. </el-dialog>
  210. </template>
  211. <style lang="less">
  212. .custom-select-modal {
  213. .el-dialog {
  214. padding: unset !important;
  215. .el-dialog__header {
  216. padding: 0 !important;
  217. .el-dialog__headerbtn {
  218. right: 10px;
  219. top: 10px;
  220. }
  221. }
  222. .el-dialog__footer {
  223. padding-top: 25px !important;
  224. padding-bottom: 24px !important;
  225. padding-left: 40px !important;
  226. padding-right: 40px !important;
  227. border-top: 1px solid #E0E0E0;
  228. display: flex;
  229. justify-content: space-between;
  230. align-items: center;
  231. text-align: left;
  232. }
  233. }
  234. }
  235. </style>