敢为人鲜小程序前端代码仓库
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.

364 lines
9.8 KiB

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