select-package.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. <template>
  2. <div class="select-package">
  3. <div class="popup-mask"></div>
  4. <div class="popup-box">
  5. <div class="tit">
  6. <div class="text">{{ $t("package.selectPackage") }}</div>
  7. <div class="close" @click="hidePop"></div>
  8. </div>
  9. <div class="con">
  10. <div class="prod-item" v-if="mainProd">
  11. <img class="img" :src="mainProdDefaultSku.pic || mainProd.pic" alt="" />
  12. <div class="prod-info">
  13. <div class="prod-name">{{ mainProd.prodName }}</div>
  14. <div class="prod-sku">
  15. <SelectSku
  16. v-if="mainProdDefaultSku.skuName && mainProd.skuList.length"
  17. :sku-id="mainProdDefaultSku.skuId"
  18. :sku-name="mainProdDefaultSku.skuName"
  19. @getSku="getMainSku"
  20. :sku-list="mainProd.skuList"
  21. />
  22. </div>
  23. <div class="prod-price">
  24. <div class="price-box">
  25. <span class="price-text"
  26. >¥{{ mainProdDefaultSku.matchingPrice | price }}</span
  27. >
  28. <span class="old-price" v-if="mainProd.price"
  29. >¥{{ mainProdDefaultSku.price | price }}</span
  30. >
  31. </div>
  32. <div class="count">×{{ mainProd.leastNum * packageNum }}</div>
  33. </div>
  34. </div>
  35. </div>
  36. <div
  37. class="prod-item"
  38. v-if="comboInfo.matchingProds"
  39. v-for="item in comboInfo.matchingProds"
  40. >
  41. <img class="img" :src="item.defaultSku.pic || item.pic" alt="" />
  42. <div class="prod-info">
  43. <div class="prod-name">{{ item.prodName }}</div>
  44. <div class="prod-sku">
  45. <SelectSku
  46. v-if="item.defaultSku.skuName && item.skuList.length"
  47. :sku-id="item.defaultSku.skuId"
  48. :sku-name="item.defaultSku.skuName"
  49. :sku-list="item.skuList"
  50. @getSku="getSku"
  51. />
  52. </div>
  53. <div class="prod-price">
  54. <div class="price-box">
  55. <span class="price-text"
  56. >¥{{ item.defaultSku.matchingPrice | price }}</span
  57. >
  58. <span class="old-price">¥{{ item.defaultSku.price | price }}</span>
  59. </div>
  60. <div class="count">×{{ item.leastNum * packageNum }}</div>
  61. </div>
  62. </div>
  63. </div>
  64. <div class="footer">
  65. <div class="left">
  66. <div class="text">{{ $t("package.packageNumber") }}:</div>
  67. <InputNumber v-model="packageNum" />
  68. </div>
  69. <div class="right">
  70. <div class="red-btn btn" @click="buy">{{ $t("buyNow") }}</div>
  71. <div class="cart-btn btn" @click="addCart">{{ $t("prodDetail.addToCart") }}</div>
  72. </div>
  73. </div>
  74. </div>
  75. </div>
  76. </div>
  77. </template>
  78. <script>
  79. import SelectSku from './select-sku.vue'
  80. import InputNumber from './input-number.vue'
  81. import Cookie from 'js-cookie'
  82. import bus from '~/plugins/bus'
  83. export default {
  84. filters: {
  85. price(value) {
  86. if (value) {
  87. return value.toFixed(2)
  88. }
  89. return 0.0
  90. }
  91. },
  92. props: {
  93. shopInfo: {
  94. type: Object,
  95. default() {
  96. return {}
  97. }
  98. },
  99. comboId: {
  100. type: Number,
  101. default: 0
  102. },
  103. selectMatchIds: {
  104. type: Array,
  105. default() {
  106. return []
  107. }
  108. }
  109. },
  110. data() {
  111. return {
  112. packageNum: 1,
  113. comboInfo: {},
  114. mainProdDefaultSku: ''
  115. }
  116. },
  117. components: {
  118. SelectSku,
  119. InputNumber
  120. },
  121. created() {
  122. // this.getComboData()
  123. },
  124. computed: {
  125. mainProd() {
  126. return this.comboInfo.mainProd
  127. }
  128. },
  129. methods: {
  130. hidePop() {
  131. this.$emit('hideSelectPackage')
  132. },
  133. getComboData(data) {
  134. this.comboInfo = data
  135. const mainSkus = this.comboInfo.mainProd.skuList
  136. if (mainSkus.length > 0) {
  137. this.setDefaultMainProdSku(mainSkus)
  138. }
  139. this.setComboProdDefaultSku(data.matchingProds)
  140. },
  141. // 设置主商品的默认sku
  142. setDefaultMainProdSku(skuList) {
  143. // debugger
  144. for (let i = 0; i < skuList.length; i++) {
  145. if (skuList[i].matchingPrice === this.comboInfo.mainProd.comboPrice) {
  146. this.mainProdDefaultSku = skuList[i]
  147. break
  148. }
  149. }
  150. },
  151. setComboProdDefaultSku(comboList) {
  152. comboList.forEach(item => {
  153. let defaultSku = null
  154. let flag = false
  155. // debugger
  156. for (let i = 0; i < item.skuList.length; i++) {
  157. if (
  158. item.comboPrice === item.skuList[i].matchingPrice &&
  159. item.skuList[i].stocks
  160. ) {
  161. defaultSku = item.skuList[i]
  162. flag = true
  163. break
  164. }
  165. }
  166. if (!flag && item.skuList.length) {
  167. item.defaultSku = item.skuList[0]
  168. } else {
  169. item.defaultSku = defaultSku
  170. }
  171. })
  172. },
  173. getSku(sku) {
  174. const matchingProds = this.comboInfo.matchingProds
  175. for (let i = 0; i < matchingProds.length; i++) {
  176. if (matchingProds[i].comboProdId === sku.comboProdId) {
  177. matchingProds[i].defaultSku = sku
  178. this.$forceUpdate()
  179. break
  180. }
  181. }
  182. },
  183. getMainSku(sku) {
  184. this.mainProdDefaultSku = sku
  185. this.$forceUpdate()
  186. },
  187. addMatchingSkus(matchingProds) {
  188. let matchingSkuIds = []
  189. matchingProds.forEach(item => {
  190. matchingSkuIds.push(item.defaultSku.skuId)
  191. })
  192. return matchingSkuIds
  193. },
  194. messageStock(prodName) {
  195. let msg = `[${
  196. prodName.length > 10 ? prodName.slice(0, 10) + '......' : prodName
  197. }]`
  198. this.$message({
  199. message: msg + this.$t('prodDetail.insufficientInventory'),
  200. type: 'warning',
  201. duration: 1000
  202. })
  203. },
  204. validatorStocks() {
  205. // debugger
  206. // this.packageNum
  207. if (
  208. !this.mainProdDefaultSku.stocks ||
  209. this.packageNum > this.mainProdDefaultSku.stocks
  210. ) {
  211. let prodName = this.comboInfo.mainProd.prodName
  212. this.messageStock(prodName)
  213. return false
  214. }
  215. const matchingProds = this.comboInfo.matchingProds
  216. for (let item of matchingProds) {
  217. if (
  218. !item.defaultSku.stocks ||
  219. this.packageNum > item.defaultSku.stocks
  220. ) {
  221. let prodName = item.prodName
  222. this.messageStock(prodName)
  223. return false
  224. }
  225. }
  226. return true
  227. },
  228. /**
  229. * 立即购买
  230. */
  231. buy() {
  232. if (!this.validatorStocks()) {
  233. return
  234. }
  235. if (this.packageNum < 1) {
  236. this.$message({
  237. message: this.$t('prodDetail.pleaseEnterTheCorrectNumberOfItems'),
  238. type: 'warning',
  239. duration: 1000
  240. })
  241. return
  242. }
  243. const matchingSkuIds = this.addMatchingSkus(this.comboInfo.matchingProds)
  244. const orderItem = {
  245. prodCount: this.packageNum,
  246. prodId: this.comboInfo.mainProd.prodId,
  247. shopId: this.shopInfo.shopId,
  248. skuId: this.mainProdDefaultSku.skuId,
  249. comboId: this.comboId,
  250. matchingSkuIds
  251. }
  252. if (!Cookie.get('token')) {
  253. bus.$emit('showLogin', true)
  254. } else {
  255. sessionStorage.setItem('orderItem', JSON.stringify(orderItem))
  256. this.$router.push({
  257. path: '/submit-order?orderEntry=1'
  258. })
  259. }
  260. },
  261. // 加入购物车
  262. addCart() {
  263. // {
  264. // "basketId": 0,
  265. // "comboId": 0,
  266. // "count": 0,
  267. // "distributionCardNo": "",
  268. // "matchingSkuIds": [],
  269. // "prodId": 0,
  270. // "shopId": 0,
  271. // "skuId": 0
  272. // }
  273. if (!this.packageNum || this.packageNum <= 0) {
  274. this.$message({
  275. message: this.$t('prodDetail.pleaseEnterTheCorrectNumberOfItems'),
  276. type: 'warning',
  277. duration: 1000
  278. })
  279. return
  280. }
  281. if (!this.validatorStocks()) {
  282. return
  283. }
  284. const matchingSkuIds = this.addMatchingSkus(this.comboInfo.matchingProds)
  285. this.$axios
  286. .post('/p/shopCart/changeItem', {
  287. basketId: 0,
  288. count: this.packageNum,
  289. prodId: Number(this.$route.params.prodId),
  290. shopId: this.shopInfo.shopId,
  291. shopName: this.shopInfo.shopName,
  292. skuId: this.mainProdDefaultSku.skuId,
  293. matchingSkuIds: matchingSkuIds,
  294. comboId: this.comboId
  295. // distributionCardNo: this.distributionCardNo
  296. })
  297. .then(({ data }) => {
  298. // this.getCartCount()
  299. this.$message.success(this.$t('prodDetail.successfullyAddedCart'))
  300. this.$router.push('/cart')
  301. this.getCartCount()
  302. })
  303. },
  304. /**
  305. * 获取购物车商品总数
  306. */
  307. getCartCount() {
  308. this.$axios.get('/p/shopCart/prodCount').then(({ data }) => {
  309. this.$store.commit('cartNumber/changeCartNumber', data)
  310. })
  311. },
  312. }
  313. }
  314. </script>
  315. <style scoped>
  316. .popup-mask {
  317. z-index: 190 !important;
  318. }
  319. .popup-box {
  320. z-index: 200 !important;
  321. }
  322. /* .popup-box {
  323. position: absolute;
  324. top: 50%;
  325. left: 50%;
  326. transform: translate(-50%,-50%);
  327. } */
  328. .select-package .con .prod-item {
  329. display: flex;
  330. margin-bottom: 20px;
  331. }
  332. .select-package .con .prod-item:last-child {
  333. margin-bottom: 0;
  334. }
  335. .select-package .con .prod-item .img {
  336. width: 80px;
  337. height: 80px;
  338. background: #ffffff;
  339. border: 1px solid #f2f2f2;
  340. margin-right: 10px;
  341. }
  342. .select-package .con .prod-item .prod-info {
  343. width: 345px;
  344. display: flex;
  345. flex-direction: column;
  346. justify-content: space-between;
  347. padding: 3px 0;
  348. }
  349. .prod-item .prod-info .prod-name {
  350. font-size: 14px;
  351. color: #000000;
  352. overflow: hidden;
  353. text-overflow: ellipsis;
  354. white-space: nowrap;
  355. }
  356. .prod-price {
  357. font-size: 12px;
  358. color: #999999;
  359. display: flex;
  360. justify-content: space-between;
  361. }
  362. .prod-price .price-box .price-text {
  363. color: #e1251b;
  364. }
  365. .prod-price .price-box .old-price {
  366. text-decoration: line-through;
  367. }
  368. .footer {
  369. display: flex;
  370. justify-content: space-between;
  371. align-items: center;
  372. }
  373. .footer .left {
  374. display: flex;
  375. align-items: center;
  376. justify-content: center;
  377. }
  378. .footer .left .text {
  379. font-size: 12px;
  380. color: #999999;
  381. margin-right: 10px;
  382. }
  383. .footer .right {
  384. display: flex;
  385. }
  386. .footer .right .btn {
  387. min-width: 92px;
  388. height: 26px;
  389. font-size: 12px;
  390. border-radius: 13px;
  391. cursor: pointer;
  392. display: flex;
  393. align-items: center;
  394. justify-content: center;
  395. }
  396. .footer .right .red-btn {
  397. background: #e1251b;
  398. color: #ffffff;
  399. margin-right: 10px;
  400. border: 1px solid #e1251b;
  401. }
  402. .footer .right .cart-btn {
  403. background: #ffecec;
  404. border: 1px solid #e43130;
  405. color: #e1251b;
  406. }
  407. </style>