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

365 lines
9.9 KiB

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