敢为人鲜小程序前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

372 lines
9.9 KiB

5 months ago
5 months ago
4 weeks ago
5 months ago
5 months ago
5 months ago
5 months ago
1 week ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
4 weeks ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
  1. <template>
  2. <view class="page">
  3. <!-- 白色字体 -->
  4. <navbar title="购物车" color="#fff" />
  5. <!-- 悬浮管理按钮 -->
  6. <view class="float-manage-btn" @tap="isManaged = !isManaged" v-if="cartList && cartList.length">
  7. <text>{{ isManaged ? '完成' : '管理' }}</text>
  8. </view>
  9. <view class="cart-items">
  10. <uv-checkbox-group shape="circle" v-model="checkboxValue">
  11. <view v-for="(item, index) in cartList" :key="item.id" class="cart-item">
  12. <view class="checkbox">
  13. <uv-checkbox :key="index" :name="item.id" size="40rpx" iconSize="35rpx" activeColor="#019245" />
  14. </view>
  15. <view class="item-content">
  16. <image class="food-image" :src="item.goods.image" mode="aspectFill" />
  17. <view class="food-info">
  18. <text class="food-name">{{ item.goods.title }}</text>
  19. <view class="food-sold">
  20. <uv-icon name="checkmark-circle" color="#ccc" size="24rpx"></uv-icon>
  21. <text>已售出 {{ item.goods.sales }}</text>
  22. </view>
  23. <view class="food-price-row">
  24. <text class="food-price">
  25. <text style="font-size: 22rpx; margin-right: 6rpx;">¥</text>
  26. {{ item.goods.price }}
  27. </text>
  28. <view class="number-box">
  29. <view class="number-btn minus" @tap="decreaseQuantity(item)">
  30. <text>-</text>
  31. </view>
  32. <text class="number-value">{{ item.num }}</text>
  33. <view class="number-btn plus" @tap="increaseQuantity(item)">
  34. <text>+</text>
  35. </view>
  36. </view>
  37. </view>
  38. </view>
  39. </view>
  40. </view>
  41. </uv-checkbox-group>
  42. <view style="padding-top: 300rpx;">
  43. <uv-empty mode="car" v-if="!cartList || !cartList.length" text="购物车空空如也~" />
  44. </view>
  45. </view>
  46. <view class="cart-footer" v-if="cartList && cartList.length">
  47. <view class="select-all">
  48. <uv-checkbox-group v-model="allCheckbox">
  49. <uv-checkbox size="40rpx" iconSize="35rpx" activeColor="#019245" shape="circle" name="all"
  50. @change="toggleSelectAll" />
  51. </uv-checkbox-group>
  52. <text>全选</text>
  53. </view>
  54. <view class="cart-total">
  55. <text v-if="!isManaged" style="font-size: 24rpx; color: #999;">已选{{ checkboxValue.length }}</text>
  56. <text v-if="!isManaged">合计</text>
  57. <text v-if="!isManaged" class="total-price">¥{{ (totalPrice).toFixed(2) }}</text>
  58. </view>
  59. <view v-if="!isManaged" class="checkout-btn checkbox-primary" @tap="checkout">
  60. <text>去下单</text>
  61. </view>
  62. <view v-if="isManaged" class="checkout-btn checkbox-primary" @tap="deleteCart">
  63. <text>删除</text>
  64. </view>
  65. </view>
  66. <tabber select="cart" />
  67. </view>
  68. </template>
  69. <script>
  70. import tabber from '@/components/base/tabbar.vue'
  71. import navbar from '@/components/base/navbar.vue'
  72. import mixinsList from '@/mixins/list.js'
  73. import { mapMutations } from 'vuex'
  74. export default {
  75. mixins: [mixinsList],
  76. components: {
  77. tabber,
  78. navbar
  79. },
  80. data() {
  81. return {
  82. cartData: {
  83. records: []
  84. },
  85. cartList: [],
  86. mixinsListKey: 'cartList',
  87. mixinsListApi: 'queryShopcarList',
  88. checkboxValue: [],
  89. isManaged: false,
  90. }
  91. },
  92. computed: {
  93. allSelected() {
  94. return this.cartList.every(item => this.checkboxValue.includes(item.id))
  95. },
  96. // 全选的值
  97. allCheckbox(){
  98. return this.allSelected ? ['all'] : []
  99. },
  100. totalPrice(){
  101. return this.cartList.reduce((total, item) => {
  102. if (this.checkboxValue.includes(item.id)){
  103. total += item.goods.price * item.num
  104. }
  105. return total
  106. }, 0)
  107. },
  108. deleteCartIds(){
  109. return this.checkboxValue.join(';')
  110. }
  111. },
  112. methods: {
  113. ...mapMutations(['setCartData']),
  114. // 增加或者减少数量
  115. modifyCart(item, type){
  116. this.$api('addShopcar', {
  117. goodsId: item.goodsId,
  118. id: item.id,
  119. num: type,
  120. }, res => {
  121. console.log(res);
  122. })
  123. },
  124. toggleSelectAll() {
  125. if (this.allSelected){
  126. this.checkboxValue = []
  127. }else{
  128. this.checkboxValue = this.cartList.map(item => item.id)
  129. }
  130. },
  131. increaseQuantity(item) {
  132. item.num += 1;
  133. this.modifyCart(item, 1)
  134. },
  135. decreaseQuantity(item) {
  136. if (item.num > 1) {
  137. item.num -= 1;
  138. this.modifyCart(item, -1)
  139. }
  140. },
  141. // 结账
  142. checkout() {
  143. if (this.checkboxValue.length === 0) {
  144. uni.showToast({
  145. title: '请选择商品',
  146. icon: 'error'
  147. });
  148. return;
  149. }
  150. const sendData = this.cartList.filter(item => this.checkboxValue.includes(item.id))
  151. this.$store.commit('setCartData', { sendData, priceAll: this.totalPrice } )
  152. // 跳转到创建订单页面
  153. this.$utils.navigateTo({
  154. url: '/pages_order/order/cartOrder'
  155. });
  156. },
  157. // 删除购物车
  158. deleteCart(){
  159. if (!this.checkboxValue.length) {
  160. uni.showToast({
  161. title: '请选择商品',
  162. icon: 'error'
  163. });
  164. return;
  165. }
  166. uni.showModal({
  167. title: '提示',
  168. content: '确定删除所选商品?',
  169. confirmColor: '#019245',
  170. success: (res) => {
  171. if (res.confirm) {
  172. this.$api('deleteShopcar', {
  173. shopcarId: this.deleteCartIds,
  174. }, res => {
  175. if (res.code == 200){
  176. uni.showToast({
  177. title: '删除成功',
  178. icon: 'success',
  179. duration: 1000,
  180. })
  181. this.getData()
  182. this.checkboxValue = []
  183. }
  184. })
  185. }
  186. }
  187. })
  188. }
  189. },
  190. // onShow(){
  191. // this.getData()
  192. // }
  193. }
  194. </script>
  195. <style lang="scss" scoped>
  196. .page {
  197. position: relative;
  198. .cart-items {
  199. .cart-item {
  200. width: 100%;
  201. display: flex;
  202. align-items: center;
  203. background-color: #fff;
  204. padding: 20rpx;
  205. margin-bottom: 20rpx;
  206. border-radius: 10rpx;
  207. .checkbox {
  208. margin-right: 20rpx;
  209. display: flex;
  210. align-items: center;
  211. }
  212. .item-content {
  213. flex: 1;
  214. display: flex;
  215. .food-image {
  216. width: 150rpx;
  217. height: 150rpx;
  218. margin-right: 20rpx;
  219. }
  220. .food-info {
  221. flex: 1;
  222. display: flex;
  223. flex-direction: column;
  224. justify-content: space-around;
  225. .food-name {
  226. font-size: 28rpx;
  227. margin-bottom: 10rpx;
  228. font-weight: 500;
  229. }
  230. .food-sold {
  231. display: flex;
  232. align-items: center;
  233. font-size: 24rpx;
  234. color: $uni-color-third;
  235. margin-bottom: 10rpx;
  236. }
  237. .food-price-row {
  238. display: flex;
  239. justify-content: space-between;
  240. align-items: center;
  241. .food-price {
  242. color: #ff0000;
  243. font-size: 32rpx;
  244. }
  245. .number-box {
  246. display: flex;
  247. align-items: center;
  248. border-radius: 28rpx;
  249. margin-right: 20rpx;
  250. contain: content;
  251. border: 2rpx solid $uni-color-third;
  252. .number-btn {
  253. width: 50rpx;
  254. height: 50rpx;
  255. display: flex;
  256. justify-content: center;
  257. align-items: center;
  258. }
  259. .number-value {
  260. width: 50rpx;
  261. height: 50rpx;
  262. display: flex;
  263. justify-content: center;
  264. align-items: center;
  265. font-size: 28rpx;
  266. border-left: 2rpx solid $uni-color-third;
  267. border-right: 2rpx solid $uni-color-third;
  268. }
  269. }
  270. }
  271. }
  272. }
  273. }
  274. }
  275. .cart-footer {
  276. position: fixed;
  277. bottom: calc(120rpx + env(safe-area-inset-bottom));
  278. left: 0;
  279. width: 100%;
  280. height: 100rpx;
  281. background-color: #fff;
  282. display: flex;
  283. align-items: center;
  284. padding: 0 20rpx ;
  285. box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
  286. box-sizing: border-box;
  287. .select-all {
  288. display: flex;
  289. align-items: center;
  290. font-size: 28rpx;
  291. text {
  292. margin-left: 10rpx;
  293. }
  294. }
  295. .cart-total {
  296. flex: 1;
  297. display: flex;
  298. align-items: center;
  299. justify-content: flex-end;
  300. font-size: 28rpx;
  301. margin-right: 20rpx;
  302. .total-price {
  303. color: $uni-color-second;
  304. font-size: 32rpx;
  305. font-weight: bold;
  306. margin-left: 10rpx;
  307. }
  308. }
  309. .checkout-btn {
  310. width: 200rpx;
  311. height: 60rpx;
  312. display: flex;
  313. justify-content: center;
  314. align-items: center;
  315. border-radius: 35rpx;
  316. font-size: 28rpx;
  317. }
  318. .checkbox-primary{
  319. background-color: $uni-color;
  320. color: #fff;
  321. }
  322. .checkbox-collect{
  323. color: $uni-color;
  324. background-color: $uni-color-fourth;
  325. }
  326. }
  327. /* 悬浮管理按钮 */
  328. .float-manage-btn {
  329. position: fixed;
  330. right: 30rpx;
  331. top: 200rpx;
  332. padding: 15rpx 30rpx;
  333. background-color: rgba(255, 255, 255, 0.9);
  334. border-radius: 40rpx;
  335. box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
  336. z-index: 100;
  337. border: 2rpx solid #019245;
  338. text {
  339. font-size: 28rpx;
  340. color: #019245;
  341. font-weight: 500;
  342. }
  343. }
  344. }
  345. </style>