detailDialog.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <template>
  2. <uni-popup ref="detailPopup" :animation="false" :is-mask-click="false"
  3. mask-background-color="rgba(51, 137, 217, 0.65);">
  4. <view class="mall-detail-dialog">
  5. <view class="detail-content-box">
  6. <icon class="yfmx-title"></icon>
  7. <icon class="dialog-close-btn" @click="detailCloseBtn"></icon>
  8. <view class="detail-body-box">
  9. <!-- 全选/取消全选 -->
  10. <view class="select-all-box" @click="toggleSelectAll">
  11. <checkbox :checked="isAllSelected" class="detail-checkbox" />
  12. <text>全选</text>
  13. </view>
  14. <!-- 使用 checkbox-group 管理多选 -->
  15. <checkbox-group @change="handleCheckboxChange">
  16. <view class="detail-item-box" v-for="item in localList" :key="item.id">
  17. <checkbox :value="item.id.toString()" :checked="selectedIds.includes(item.id)"
  18. class="detail-checkbox" />
  19. <img :src="item.cover" class="mall-image" />
  20. <view class="content-body-box">
  21. <view class="content-name">
  22. <view class="name-text">{{item.name}}</view>
  23. </view>
  24. <view class="content-text">{{item.intro}}</view>
  25. <view class="content-row">
  26. <view class="content-yuanjia">¥{{item.xianjia}}</view>
  27. </view>
  28. </view>
  29. </view>
  30. </checkbox-group>
  31. </view>
  32. </view>
  33. <!-- 子组件自己的底部结算栏 -->
  34. <view class="footer-mall-pay-box">
  35. <view class="mall-left-box">
  36. <view class="price-icon-box">
  37. <text class="red-price fh-text">¥</text>
  38. <text class="red-price">{{totalPrice}}</text>明细
  39. <icon :class="mxjtClass"></icon>
  40. </view>
  41. </view>
  42. <view class="pay-status-box" v-if="showPayWay" @click="switchPayWay">
  43. <icon class="wx-icon"></icon>微信
  44. </view>
  45. <view class="pay-status-box" v-if="!showPayWay" @click="switchPayWay">
  46. <icon class="zfb-icon"></icon>支付宝
  47. </view>
  48. <view class="pay-btn" @click="handlePay">立即支付</view>
  49. </view>
  50. </view>
  51. </uni-popup>
  52. </template>
  53. <script setup>
  54. import {
  55. ref,
  56. computed,
  57. watch
  58. } from 'vue';
  59. const props = defineProps({
  60. selectedList: { // 父组件传入的初始选中商品列表
  61. type: Array,
  62. default: () => []
  63. }
  64. });
  65. const showPayWay = ref(true);
  66. const mxjtClass = ref('mxjt-sq-icon');
  67. // 本地维护的商品列表(独立于父组件)
  68. const localList = ref([]);
  69. const selectedIds = ref([]); // 存储选中项的id
  70. // 本地选中状态管理
  71. const localSelectedMap = ref({});
  72. // 初始化本地数据
  73. // 初始化数据
  74. watch(() => props.selectedList, (newVal) => {
  75. localList.value = [...newVal];
  76. selectedIds.value = newVal.map(item => item.id); // 初始全部选中
  77. }, {
  78. immediate: true
  79. });
  80. // 是否全选
  81. const isAllSelected = computed(() => {
  82. return localList.value.length > 0 &&
  83. selectedIds.value.length === localList.value.length;
  84. });
  85. // 处理checkbox变化
  86. function handleCheckboxChange(e) {
  87. selectedIds.value = e.detail.value.map(id => parseInt(id));
  88. }
  89. // 全选/取消全选
  90. function toggleSelectAll() {
  91. if (isAllSelected.value) {
  92. selectedIds.value = []; // 取消全选
  93. } else {
  94. selectedIds.value = localList.value.map(item => item.id); // 全选
  95. }
  96. }
  97. // 计算总价
  98. const totalPrice = computed(() => {
  99. return localList.value
  100. .filter(item => selectedIds.value.includes(item.id))
  101. .reduce((sum, item) => sum + parseFloat(item.xianjia || 0), 0)
  102. .toFixed(2);
  103. });
  104. // 支付方式切换
  105. function switchPayWay() {
  106. showPayWay.value = !showPayWay.value;
  107. }
  108. // 支付处理
  109. function handlePay() {
  110. // 获取选中商品的完整信息和cardId
  111. const selectedItems = localList.value
  112. .filter(item => selectedIds.value.includes(item.id));
  113. console.log('selectedItems',selectedItems);
  114. const cardIds = selectedItems.map(item => item.id);
  115. const total = selectedItems.reduce((sum, item) => sum + parseFloat(item.xianjia || 0), 0);
  116. if (cardIds.length === 0) {
  117. uni.showToast({
  118. title: '请选择至少一个商品',
  119. icon: 'none'
  120. });
  121. return;
  122. }
  123. console.log('cardIds',cardIds);
  124. // 构造支付数据
  125. const paymentData = {
  126. cardIds: cardIds,
  127. items: selectedItems,
  128. totalAmount: total.toFixed(2),
  129. paymentMethod: showPayWay.value ? 'wechat' : 'alipay'
  130. };
  131. }
  132. const detailPopup = ref(null);
  133. function detailShow() {
  134. detailPopup.value.open();
  135. }
  136. function detailCloseBtn() {
  137. detailPopup.value.close();
  138. }
  139. defineExpose({
  140. detailShow,
  141. detailCloseBtn
  142. });
  143. </script>
  144. <style>
  145. </style>