goods-batch-buy.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. <template>
  2. <view>
  3. <component-popup :propShow="popup_status" propPosition="bottom" @onclose="popup_close_event">
  4. <view class="bg-white">
  5. <view class="close oh padding-horizontal-main padding-top-main">
  6. <view class="fr" @tap.stop="popup_close_event">
  7. <icon type="clear" size="20"></icon>
  8. </view>
  9. </view>
  10. <view class="plugins-batchbuy-container oh">
  11. <block v-if="(goods || null) != null && (batchbuy_data || null) != null && (batchbuy_data.goods_spec_data || null) != null && batchbuy_data.goods_spec_data.length > 0">
  12. <block v-if="batchbuy_data.is_only_level_one == 0">
  13. <view class="left-nav pa bg-base">
  14. <scroll-view :scroll-y="true" class="ht-auto">
  15. <block v-for="(item, index) in batchbuy_data.goods_spec_data" :key="index">
  16. <view :class="'padding-top-xxl padding-bottom-xxl tc cp oh pr ' + (nav_active_index == index ? 'bg-white cr-main' : '')" :data-index="index" @tap="nav_event">
  17. <image v-if="(item.images || null) != null" class="dis-inline-block va-m radius margin-right spec-images" :src="item.images" mode="widthFix"></image>
  18. <text class="text-size-xs cr-base va-m">{{item.name}}</text>
  19. <view v-if="(item.badge_total || 0) > 0" class="badge-icon pa">
  20. <component-badge :propNumber="item.badge_total"></component-badge>
  21. </view>
  22. </view>
  23. </block>
  24. </scroll-view>
  25. </view>
  26. <view class="right-conent ht-auto fr padding-main bs-bb">
  27. <scroll-view :scroll-y="true" class="ht-auto">
  28. <block v-for="(item, index) in batchbuy_data.goods_spec_data[nav_active_index]['data']" :key="index">
  29. <view :class="'oh padding-vertical-main '+(index > 0 ? 'br-t' : '')">
  30. <view class="fl item-left">
  31. <view class="text-size-xs">{{item.name}}</view>
  32. <view class="sales-price text-size-xs">{{currency_symbol}}{{item.base.price}}</view>
  33. </view>
  34. <view class="tc oh round fr item-right text-size-xs">
  35. <view @tap="batchbuy_goods_buy_number_event" class="number-submit tc cr-gray fl va-m" data-type="0" :data-index="index">-</view>
  36. <input @blur="batchbuy_goods_buy_number_blur" class="tc cr-gray bg-white fl va-m radius-0" type="number" :value="(item.buy_number || 0)" :data-index="index">
  37. <view @tap="batchbuy_goods_buy_number_event" class="number-submit tc cr-gray fl va-m" data-type="1" :data-index="index">+</view>
  38. </view>
  39. </view>
  40. </block>
  41. </scroll-view>
  42. </view>
  43. </block>
  44. <block v-else>
  45. <view class="right-conent ht-auto padding-main bs-bb right-conent-only-level-one">
  46. <scroll-view :scroll-y="true" class="ht-auto">
  47. <block v-for="(item, index) in batchbuy_data.goods_spec_data" :key="index">
  48. <view :class="'oh padding-vertical-main '+(index > 0 ? 'br-t' : '')">
  49. <view class="fl item-left">
  50. <view>
  51. <image v-if="(item.images || null) != null" class="dis-inline-block va-m radius margin-right spec-images" :src="item.images" mode="widthFix"></image>
  52. <text class="text-size-xs va-m">{{item.name}}</text>
  53. </view>
  54. <view class="sales-price text-size-xs">{{currency_symbol}}{{item.base.price}}</view>
  55. </view>
  56. <view class="tc oh round fr item-right text-size-xs margin-top-xs">
  57. <view @tap="batchbuy_goods_buy_number_event" class="number-submit tc cr-gray fl va-m" data-type="0" :data-index="index">-</view>
  58. <input @blur="batchbuy_goods_buy_number_blur" class="tc cr-gray bg-white fl va-m radius-0" type="number" :value="(item.buy_number || 0)" :data-index="index">
  59. <view @tap="batchbuy_goods_buy_number_event" class="number-submit tc cr-gray fl va-m" data-type="1" :data-index="index">+</view>
  60. </view>
  61. </view>
  62. </block>
  63. </scroll-view>
  64. </view>
  65. </block>
  66. <view class="confirm-submit pa wh-auto bottom-line-exclude bg-white padding-top-main">
  67. <view class="oh padding-horizontal-main padding-bottom-main cr-grey">
  68. <text class="text-size-xs">
  69. <text>已选</text>
  70. <text class="cr-red padding-left-xs padding-right-xs">{{base_data.kind}}</text>
  71. <text>种</text>
  72. <text class="cr-red padding-left-xs padding-right-xs">{{base_data.quantity}}</text>
  73. <text>{{goods.inventory_unit}}</text>
  74. </text>
  75. <text class="text-size-xs fr">金额:<text class="fw-b sales-price">{{currency_symbol}}{{base_data.amount_money}}</text></text>
  76. </view>
  77. <view v-if="(buy_button.data || null) != null && buy_button.data.length > 0" class="padding-bottom-main">
  78. <view :class="'oh buy-nav-btn-number-' + buy_button.count || 0">
  79. <block v-for="(item, index) in buy_button.data" :key="index">
  80. <view v-if="(item.name || null) != null && (item.type || null) != null" class="item fl bs-bb padding-horizontal-main">
  81. <button :class="'cr-white round text-size-sm bg-' + ((item.color || 'main') == 'main' ? 'main' : 'main-pair')" type="default" @tap="confirm_event" :data-type="item.type" hover-class="none">{{item.name}}</button>
  82. </view>
  83. </block>
  84. </view>
  85. </view>
  86. </view>
  87. </block>
  88. <block v-else>
  89. <view class="cr-grey tc padding-top-xl padding-bottom-xxxl">无相关信息</view>
  90. </block>
  91. </view>
  92. </view>
  93. </component-popup>
  94. </view>
  95. </template>
  96. <script>
  97. const app = getApp();
  98. import base64 from '../../common/js/lib/base64.js';
  99. import componentPopup from "../../components/popup/popup";
  100. import componentBadge from "../../components/badge/badge";
  101. export default {
  102. data() {
  103. return {
  104. currency_symbol: app.globalData.get_config('currency_symbol', app.globalData.data.currency_symbol),
  105. popup_status: false,
  106. nav_active_index: 0,
  107. goods: null,
  108. buy_button: null,
  109. batchbuy_data: null,
  110. back_data: null,
  111. base_data: {
  112. kind: 0,
  113. quantity: 0,
  114. amount_money: '0.00',
  115. }
  116. };
  117. },
  118. components: {
  119. componentPopup,
  120. componentBadge
  121. },
  122. created: function() {},
  123. methods: {
  124. // 初始化
  125. init(goods = null, batchbuy_data = null, buy_button = null, back_data = null) {
  126. if(!app.globalData.is_single_page_check()) {
  127. return false;
  128. }
  129. this.setData({
  130. popup_status: true,
  131. goods: goods || null,
  132. batchbuy_data: batchbuy_data || null,
  133. buy_button: buy_button || null,
  134. back_data: back_data,
  135. });
  136. },
  137. // 弹层关闭
  138. popup_close_event(e) {
  139. this.setData({
  140. popup_status: false
  141. });
  142. },
  143. // 弹层导航切换
  144. nav_event(e) {
  145. this.setData({
  146. nav_active_index: e.currentTarget.dataset.index
  147. });
  148. },
  149. // 商品批量下单数量操作事件
  150. batchbuy_goods_buy_number_event(e) {
  151. var type = e.currentTarget.dataset.type;
  152. var index = e.currentTarget.dataset.index;
  153. var temp_data = this.batchbuy_data
  154. var temp_spec_data = (parseInt(temp_data.is_only_level_one || 0) == 1) ? temp_data.goods_spec_data[index] : temp_data.goods_spec_data[this.nav_active_index]['data'][index];
  155. var number = parseInt(temp_spec_data.buy_number || 0);
  156. var min = parseInt(temp_spec_data.base.buy_min_number || 0);
  157. // 首次增加使用起购数量
  158. number = (type == 0) ? number-1 : ((number == 0 && min > 0) ? min : number+1);
  159. this.batch_goods_buy_number_handle(temp_data, temp_spec_data, index, number);
  160. },
  161. // 商品批量下单数量输入事件
  162. batchbuy_goods_buy_number_blur(e) {
  163. var number = parseInt(e.detail.value) || 0;
  164. var index = e.currentTarget.dataset.index;
  165. var temp_data = this.batchbuy_data
  166. var temp_spec_data = (parseInt(temp_data.is_only_level_one || 0) == 1) ? temp_data.goods_spec_data[index] : temp_data.goods_spec_data[this.nav_active_index]['data'][index];
  167. if(isNaN(number)) {
  168. number = 0;
  169. }
  170. this.batch_goods_buy_number_handle(temp_data, temp_spec_data, index, number);
  171. },
  172. // 商品批量下单数量处理
  173. batch_goods_buy_number_handle(temp_data, temp_spec_data, index, number) {
  174. var min = parseInt(temp_spec_data.base.buy_min_number || 0);
  175. var max = parseInt(temp_spec_data.base.buy_max_number || 0);
  176. var inventory = parseInt(temp_spec_data.base.inventory || 0);
  177. var inventory_unit = this.goods.inventory_unit;
  178. // 是否负数
  179. if(number < 0)
  180. {
  181. number = 0;
  182. }
  183. // 不能小于起购数则0
  184. if(number > 0 && min > 0 && number < min)
  185. {
  186. number = 0;
  187. app.globalData.showToast('起购' + min + inventory_unit);
  188. }
  189. // 不能超过最大限购
  190. if(max > 0 && number > max)
  191. {
  192. number = max;
  193. app.globalData.showToast('限购' + max + inventory_unit);
  194. }
  195. // 不能超过库存
  196. if(number > inventory)
  197. {
  198. number = inventory;
  199. app.globalData.showToast('库存数量' + inventory + inventory_unit);
  200. }
  201. temp_spec_data['buy_number'] = number;
  202. if(parseInt(temp_data.is_only_level_one || 0) == 1) {
  203. temp_data.goods_spec_data[index] = temp_spec_data;
  204. } else {
  205. temp_data.goods_spec_data[this.nav_active_index]['data'][index] = temp_spec_data
  206. }
  207. // 非仅一级则处理一级总数
  208. if(parseInt(temp_data.is_only_level_one || 0) != 1)
  209. {
  210. var badge_total = 0;
  211. temp_data.goods_spec_data[this.nav_active_index]['data'].forEach(item => {
  212. var temp_badge = parseInt(item.buy_number || 0);
  213. if(temp_badge > 0) {
  214. badge_total += temp_badge;
  215. }
  216. });
  217. temp_data.goods_spec_data[this.nav_active_index]['badge_total'] = badge_total;
  218. }
  219. // 总数、汇总
  220. var stock_total = 0;
  221. var kind_total = 0;
  222. var amount_money_total = 0;
  223. temp_data.goods_spec_data.forEach(item => {
  224. if(parseInt(temp_data.is_only_level_one || 0) == 1) {
  225. var temp_stock = parseInt(item.buy_number || 0);
  226. if(temp_stock > 0) {
  227. stock_total += temp_stock;
  228. kind_total += 1;
  229. amount_money_total += temp_stock*parseFloat(item.base.price);
  230. }
  231. } else {
  232. item.data.forEach(item2 => {
  233. var temp_stock = parseInt(item2.buy_number || 0);
  234. if(temp_stock > 0) {
  235. stock_total += temp_stock;
  236. kind_total += 1;
  237. amount_money_total += temp_stock*parseFloat(item2.base.price);
  238. }
  239. });
  240. }
  241. });
  242. // 设置数据
  243. this.setData({
  244. batchbuy_data: temp_data,
  245. base_data: {
  246. kind: kind_total,
  247. quantity: stock_total,
  248. amount_money: app.globalData.price_two_decimal(amount_money_total)
  249. }
  250. });
  251. // 下单数据
  252. var goods_data = [];
  253. var goods_id = this.goods.id;
  254. temp_data.goods_spec_data.forEach(item => {
  255. if(parseInt(temp_data.is_only_level_one || 0) == 1) {
  256. goods_data.push({
  257. id: goods_id,
  258. stock: stock_total,
  259. spec: item.spec || ''
  260. });
  261. } else {
  262. item.data.forEach(item2 => {
  263. goods_data.push({
  264. id: goods_id,
  265. stock: stock_total,
  266. spec: item2.spec || ''
  267. });
  268. });
  269. }
  270. });
  271. // 数量更新获取最新数据
  272. uni.request({
  273. url: app.globalData.get_request_url('stock', 'goods'),
  274. method: 'POST',
  275. data: {goods_data: goods_data},
  276. dataType: 'json',
  277. success: res => {
  278. if (res.data.code == 0) {
  279. res.data.data.forEach(item => {
  280. if(item.code == 0)
  281. {
  282. for(var i1 in temp_data.goods_spec_data) {
  283. if(parseInt(temp_data.is_only_level_one || 0) == 1) {
  284. temp_data.goods_spec_data[i1].base.price = item.data.spec_base.price;
  285. temp_data.goods_spec_data[i1].base.original_price = item.data.spec_base.original_price;
  286. temp_data.goods_spec_data[i1].base.inventory = item.data.spec_base.inventory;
  287. } else {
  288. for(var i2 in temp_data.goods_spec_data[i1].data) {
  289. if(temp_data.goods_spec_data[i1].data[i2].base.id == item.data.spec_base.id) {
  290. temp_data.goods_spec_data[i1].data[i2].base.price = item.data.spec_base.price;
  291. temp_data.goods_spec_data[i1].data[i2].base.original_price = item.data.spec_base.original_price;
  292. temp_data.goods_spec_data[i1].data[i2].base.inventory = item.data.spec_base.inventory;
  293. }
  294. }
  295. }
  296. }
  297. }
  298. });
  299. this.setData({
  300. batchbuy_data: temp_data
  301. });
  302. } else {
  303. app.globalData.showToast(res.data.msg);
  304. }
  305. },
  306. fail: () => {
  307. app.globalData.showToast('服务器请求出错');
  308. }
  309. });
  310. },
  311. // 确认事件
  312. confirm_event(e) {
  313. var user = app.globalData.get_user_info(this, 'confirm_event');
  314. if (user != false) {
  315. // 用户未绑定用户则转到登录页面
  316. if (app.globalData.user_is_need_login(user)) {
  317. uni.navigateTo({
  318. url: "/pages/login/login?event_callback=confirm_event"
  319. });
  320. return false;
  321. } else {
  322. // 获取数据
  323. var goods_data = [];
  324. var goods_id = this.goods.id;
  325. this.batchbuy_data.goods_spec_data.forEach(item => {
  326. if(parseInt(this.batchbuy_data.is_only_level_one || 0) == 1) {
  327. var buy_number = parseInt(item.buy_number || 0);
  328. if(buy_number > 0) {
  329. goods_data.push({
  330. goods_id: goods_id,
  331. stock: buy_number,
  332. spec: item.spec || ''
  333. });
  334. }
  335. } else {
  336. item.data.forEach(item2 => {
  337. var buy_number = parseInt(item2.buy_number || 0);
  338. if(buy_number > 0) {
  339. goods_data.push({
  340. goods_id: goods_id,
  341. stock: buy_number,
  342. spec: item2.spec || ''
  343. });
  344. }
  345. });
  346. }
  347. });
  348. if(goods_data.length <= 0) {
  349. app.globalData.showToast('请选择规格');
  350. return false;
  351. }
  352. // 操作类型
  353. switch (e.currentTarget.dataset.type) {
  354. case 'plugins-batchbuy-button-buy':
  355. // 进入订单确认页面
  356. var data = {
  357. buy_type: "goods",
  358. goods_data: encodeURIComponent(base64.encode(JSON.stringify(goods_data)))
  359. };
  360. uni.navigateTo({
  361. url: '/pages/buy/buy?data=' + encodeURIComponent(base64.encode(JSON.stringify(data)))
  362. });
  363. this.popup_close_event();
  364. break;
  365. // 加入购物车
  366. case 'plugins-batchbuy-button-cart':
  367. this.goods_cart_event(goods_data);
  368. break;
  369. default:
  370. app.globalData.showToast("操作事件类型有误");
  371. }
  372. }
  373. }
  374. },
  375. // 加入购物车事件
  376. goods_cart_event(goods_data) {
  377. uni.showLoading({
  378. title: '处理中...'
  379. });
  380. uni.request({
  381. url: app.globalData.get_request_url('save', 'cart'),
  382. method: 'POST',
  383. data: {goods_data: goods_data},
  384. dataType: 'json',
  385. success: res => {
  386. uni.hideLoading();
  387. if (res.data.code == 0) {
  388. app.globalData.showToast(res.data.msg, 'success');
  389. // 调用父级
  390. this.$emit('BatchCartSuccessEvent', {
  391. cart_number: res.data.data.buy_number,
  392. back_data: this.back_data,
  393. });
  394. // 关闭购买弹窗窗口
  395. this.popup_close_event();
  396. } else {
  397. if (app.globalData.is_login_check(res.data, this, 'confirm_event')) {
  398. app.globalData.showToast(res.data.msg);
  399. }
  400. }
  401. },
  402. fail: () => {
  403. uni.hideLoading();
  404. app.globalData.showToast('服务器请求出错');
  405. }
  406. });
  407. }
  408. }
  409. };
  410. </script>
  411. <style>
  412. .plugins-batchbuy-container {
  413. height: 60vh;
  414. padding-bottom: 160rpx;
  415. }
  416. .plugins-batchbuy-container .left-nav {
  417. width: 200rpx;
  418. top: 0;
  419. left: 0;
  420. height: calc(100% - 160rpx);
  421. }
  422. .plugins-batchbuy-container .left-nav .badge-icon {
  423. top: 8rpx;
  424. right: 36rpx;
  425. }
  426. .plugins-batchbuy-container .left-nav .spec-images {
  427. width: 50rpx;
  428. height: 50rpx !important;
  429. }
  430. .plugins-batchbuy-container .right-conent {
  431. width: calc(100% - 200rpx);
  432. }
  433. .plugins-batchbuy-container .right-conent .item-left {
  434. width: calc(100% - 290rpx);
  435. }
  436. .plugins-batchbuy-container .item-right {
  437. background: #fbfbfb;
  438. border: 1px solid #f0f0f0;
  439. }
  440. .plugins-batchbuy-container .item-right .number-submit {
  441. width: 80rpx;
  442. font-weight: bold;
  443. }
  444. .plugins-batchbuy-container .item-right input {
  445. width: 50px;
  446. }
  447. .plugins-batchbuy-container .item-right .number-submit,
  448. .plugins-batchbuy-container .item-right input {
  449. padding: 0;
  450. height: 60rpx;
  451. line-height: 60rpx;
  452. }
  453. .plugins-batchbuy-container .right-conent-only-level-one {
  454. width: 100%;
  455. }
  456. .plugins-batchbuy-container .right-conent-only-level-one .spec-images {
  457. width: 34rpx;
  458. height: 34rpx !important;
  459. }
  460. .plugins-batchbuy-container .confirm-submit {
  461. left: 0;
  462. bottom: 0;
  463. }
  464. .plugins-batchbuy-container .buy-nav-btn-number-0 .item,
  465. .plugins-batchbuy-container .buy-nav-btn-number-1 .item {
  466. width: 100% !important;
  467. }
  468. .plugins-batchbuy-container .buy-nav-btn-number-2 .item {
  469. width: 50% !important;
  470. }
  471. .plugins-batchbuy-container .buy-nav-btn-number-3 .item {
  472. width: 33.33% !important;
  473. }
  474. .plugins-batchbuy-container .buy-nav-btn-number-4 .item {
  475. width: 25% !important;
  476. }
  477. </style>