index.tsx 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. import { moneyFormat } from '@/helpers/utils'
  2. import {
  3. Button,
  4. Cell,
  5. Dialog,
  6. Image,
  7. Loading,
  8. Radio,
  9. RadioGroup,
  10. Stepper,
  11. Tag,
  12. Toast
  13. } from 'vant'
  14. import { defineComponent, PropType } from 'vue'
  15. import styles from './index.module.less'
  16. import iconSellOut from '../../images/icon-sell-out.png'
  17. import request from '@/helpers/request'
  18. import { getCartCount } from '../../shop-mall'
  19. export default defineComponent({
  20. name: 'add-goods-cart',
  21. props: {
  22. show: {
  23. type: Boolean,
  24. default: false
  25. },
  26. item: {
  27. type: Object,
  28. default: {}
  29. },
  30. defaultRadio: {
  31. type: Number,
  32. default: 0
  33. },
  34. showType: {
  35. type: String,
  36. default: 'cart'
  37. },
  38. onGetCartCount: {
  39. type: Function,
  40. default: (n: any) => {}
  41. }
  42. },
  43. watch: {
  44. show(val) {
  45. // 添加购物车显示
  46. if (val) {
  47. this.totalData = {}
  48. this.total = 1
  49. this.radio = ''
  50. this.setList()
  51. }
  52. }
  53. },
  54. data() {
  55. return {
  56. radio: '',
  57. total: 1,
  58. totalData: {},
  59. skuStockList: []
  60. }
  61. },
  62. computed: {
  63. selectItem() {
  64. const radio = this.radio
  65. const select = this.skuStockList.find((n: any) => n.id == radio) as any
  66. if (select) {
  67. let stock: number = select.stock - select.lockStock //- select.cartNum
  68. return {
  69. ...select,
  70. stock
  71. }
  72. }
  73. return {
  74. stock: 0
  75. }
  76. }
  77. },
  78. mounted() {
  79. this.setList()
  80. },
  81. methods: {
  82. setList() {
  83. // 处理规格
  84. let skuStockList = [] as any
  85. const item = JSON.parse(JSON.stringify(this.item))
  86. if (Array.isArray(item.skuStockList)) {
  87. skuStockList = item.skuStockList.map((n: any) => {
  88. n.pic = n.pic || item.pic
  89. n.cartNum = 0
  90. if (n.spData) {
  91. const spData = JSON.parse(n.spData)
  92. let str = ''
  93. spData.forEach((sp: any) => {
  94. str += `${sp.value}`
  95. })
  96. n.spDataJson = str
  97. } else {
  98. n.spDataJson = '默认'
  99. }
  100. n.lockStock = n.lockStock > 0 ? n.lockStock : 0
  101. return {
  102. ...n
  103. }
  104. })
  105. }
  106. if (!skuStockList.length) return skuStockList
  107. // 处理默认显示
  108. let index = 0
  109. if (this.defaultRadio) {
  110. let i = skuStockList.findIndex(n => n.id == this.defaultRadio)
  111. index = i > -1 ? i : 0
  112. }
  113. this.radio = skuStockList[index].id
  114. this.skuStockList = skuStockList
  115. // this.getProductAddCartCount(skuStockList[index].id)
  116. },
  117. async onAddCart() {
  118. const selectItem = this.selectItem
  119. const item = this.item
  120. const body = {
  121. price: selectItem.price, //添加到购物车的价格
  122. productSkuId: selectItem.id,
  123. quantity: this.total, // 数量
  124. productId: item.id,
  125. hidden: this.showType === 'cart' ? 0 : 1,
  126. promoterId: this.$route.query.promoterId
  127. ? this.$route.query.promoterId
  128. : undefined
  129. }
  130. // console.log(body)
  131. try {
  132. let { code, data } = await request.post('/api-mall-portal/cart/add', {
  133. data: body
  134. })
  135. if (code === 200) {
  136. // this.getProductAddCartCount(selectItem.id, true)
  137. if (this.showType === 'cart') {
  138. this.onGetCartCount()
  139. this.$nextTick(() => {
  140. setTimeout(() => {
  141. Toast({
  142. icon: 'success',
  143. message: '添加商品成功'
  144. })
  145. }, 500)
  146. })
  147. } else {
  148. this.$router.push({
  149. path: '/cartConfirm',
  150. query: {
  151. cartIds: data.id
  152. }
  153. })
  154. }
  155. getCartCount()
  156. }
  157. } catch (error) {
  158. // let msg : string = (error as any).message
  159. // if (msg === "库存不足") {
  160. // for(let i = 0; i < this.skuStockList.length; i++){
  161. // if ((this.skuStockList[i] as any).id === this.selectItem.id){
  162. // (this.skuStockList[i] as any).stock = 0
  163. // }
  164. // }
  165. // }
  166. }
  167. },
  168. // 获取购物车当前产品的数量
  169. async getProductAddCartCount(id?: any, isRest = false) {
  170. id = id ? id : this.selectItem.id
  171. if (this.totalData.hasOwnProperty(id) && !isRest) {
  172. this.setProductStock(this.totalData[id])
  173. return
  174. }
  175. if (!id) return
  176. try {
  177. let res = await request.get(`/api-mall-portal/product/cart/${id}`)
  178. this.setProductStock(res.data || 0)
  179. this.totalData[id] = res.data || 0
  180. } catch (err) {}
  181. },
  182. // 更新产品规格的库存
  183. setProductStock(n: number) {
  184. // 根据当前用户的购物车,当前产品规格的数量,限制库存
  185. for (let i = 0; i < this.skuStockList.length; i++) {
  186. if ((this.skuStockList[i] as any).id === this.radio) {
  187. ;(this.skuStockList[i] as any).cartNum = n
  188. }
  189. }
  190. }
  191. },
  192. render() {
  193. return (
  194. <div class={styles.addGoodsCart}>
  195. <Cell
  196. titleStyle={{ paddingLeft: '12px' }}
  197. v-slots={{
  198. icon: () => (
  199. <div class={styles.goodsSection}>
  200. <Image
  201. src={this.selectItem.pic}
  202. class={styles.goodsImg}
  203. fit="cover"
  204. />
  205. {this.selectItem.stock <= 0 && (
  206. <div class={styles.sellOut}>
  207. <Image
  208. src={iconSellOut}
  209. fit="cover"
  210. class={styles.sellOutImg}
  211. />
  212. </div>
  213. )}
  214. </div>
  215. ),
  216. title: () => (
  217. <div class={styles.goodsInfo}>
  218. <p class={styles.goodsPrice}>
  219. <span>¥</span>
  220. {moneyFormat(this.selectItem.price)}
  221. </p>
  222. <p class={styles.goodsStore}>库存:{this.selectItem.stock}</p>
  223. </div>
  224. )
  225. }}
  226. />
  227. <Cell
  228. v-slots={{
  229. title: () => <div class={styles.title}>规格</div>,
  230. label: () => (
  231. <RadioGroup class={styles['radio-group']} modelValue={this.radio}>
  232. {this.skuStockList.map((item: any) => {
  233. const isActive = item.id === this.radio
  234. const type = isActive ? 'primary' : 'default'
  235. return (
  236. <Radio
  237. class={styles.radio}
  238. name={item.id}
  239. onClick={() => {
  240. if (this.radio == item.id) return
  241. this.radio = item.id
  242. // this.getProductAddCartCount(item.id)
  243. }}
  244. >
  245. <Tag size="large" plain={isActive} type={type}>
  246. {item.spDataJson}
  247. </Tag>
  248. </Radio>
  249. )
  250. })}
  251. </RadioGroup>
  252. )
  253. }}
  254. />
  255. <Cell
  256. title="购买数量"
  257. style={{ margin: '12px 0' }}
  258. border={false}
  259. titleClass={styles.title}
  260. center
  261. >
  262. <Stepper
  263. v-model={this.total}
  264. inputWidth="50px"
  265. theme="round"
  266. buttonSize="24px"
  267. max={this.selectItem.stock > 200 ? 200 : this.selectItem.stock}
  268. min={1}
  269. disabled={this.selectItem.stock <= 0}
  270. integer
  271. />
  272. </Cell>
  273. <div class={['btnGroup']} style={{ marginBottom: '8px' }}>
  274. <Button
  275. block
  276. round
  277. type="primary"
  278. text="确定"
  279. disabled={this.selectItem.stock <= 0}
  280. onClick={() => this.onAddCart()}
  281. />
  282. </div>
  283. </div>
  284. )
  285. }
  286. })