classify.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <template>
  2. <view class="w-full">
  3. <view>
  4. <u-row justify="space-between" customStyle="margin-bottom: 10px">
  5. <u-col span="3">
  6. <view class="icon-container-l" @click="onOrder">
  7. <uni-badge size="normal" :text="txts" absolute="rightTop">
  8. <u-icon :name="iconCooking" label="自提" labelPos="bottom" size="32"></u-icon>
  9. </uni-badge>
  10. </view>
  11. </u-col>
  12. <view class="container">
  13. <u-tag plain :text="cList.openState ? '营业中' : '离线'" :type="cList.openState ? 'success' : 'error'"
  14. size="mini"></u-tag>
  15. <view @click="btnIc">
  16. <u-icon :label="cList.name" labelPos="left" size="16" name="arrow-down"></u-icon>
  17. </view>
  18. </view>
  19. <u-col span="3">
  20. <view class="icon-container-r" @click="onMyInfo">
  21. <u-icon label="我的" labelPos="bottom" size="32" :name="iconPeople"></u-icon>
  22. </view>
  23. </u-col>
  24. </u-row>
  25. </view>
  26. <view class="w-full dflex-b padding-xs box-sizing-b dflex-wrap-w">
  27. <view class="goods-item margin-bottom-sm" v-for="(item, gindex) in goods" :key="gindex">
  28. <view class="img dflex-c" @click="toDetial(item)">
  29. <image mode="aspectFit" :src="item.imgList[0].url"></image>
  30. </view>
  31. <view class="title">{{item.spuName}}</view>
  32. <view class="dflex padding-bottom-xs">
  33. <u-tag plain text="销量: 199" borderColor="#FF6D20" color="#FF6D20" size="mini"></u-tag>
  34. </view>
  35. <view class="w-full dflex-b">
  36. <view class="price">{{item.minPrice ? item.minPrice : '无'}}</view>
  37. <view>
  38. <u-button type="primary" shape="circle" size="small"
  39. color="linear-gradient(to right, #F54319, #FF6D20)" @click="goCart(item)">
  40. <u-icon name="shopping-cart-fill" size="28" color="#fff"></u-icon>
  41. </u-button>
  42. </view>
  43. </view>
  44. </view>
  45. </view>
  46. <my-gap :height="10" />
  47. <specPopup class='spec-box' ref="specPopup" :cardMsg="cardMsg" @update-shopmsg="handleUpdateShopMsg">
  48. </specPopup>
  49. <view class="cart-bottom padding-sm dflex-b">
  50. <view class="cart padding-lr">
  51. <uni-badge size="small" :text="buyCount" absolute="rightTop">
  52. <u-icon name="shopping-cart-fill" size="28" color="#FF873D" @click="showCart"></u-icon>
  53. </uni-badge>
  54. <text class="cart-total">总计:¥{{total}}</text>
  55. </view>
  56. <view class="balance dflex-c background-gradient" @click="toBuy">去结算</view>
  57. </view>
  58. <cartPopupVue ref="cartPopup" :carList="carList" @selected-changed="handleSelectedChanged"
  59. @numChanged="numChanged" />
  60. </view>
  61. </template>
  62. <script>
  63. import cartPopupVue from '../../components/cartPopup.vue'
  64. import specPopup from '@/components/specPopup.vue'
  65. import iconCooking from '../../static/cooking.png'
  66. import iconPeople from '../../static/people.png'
  67. import shoppingCart from '../../static/shoppingCart.png'
  68. export default {
  69. components: {
  70. cartPopupVue,
  71. specPopup
  72. },
  73. data() {
  74. return {
  75. onIndex: 0,
  76. show: false,
  77. iconCooking: iconCooking,
  78. iconPeople: iconPeople,
  79. shoppingCart: shoppingCart,
  80. tags: 1,
  81. txts: 1,
  82. carList: {},
  83. goods: [],
  84. total: 0,
  85. cList: {},
  86. cardMsg: {},
  87. selectedList: [],
  88. buyCount: 0
  89. }
  90. },
  91. onLoad() {
  92. const e = uni.getStorageSync('carl')
  93. this.cList = e
  94. this.fatchDate(e)
  95. },
  96. methods: {
  97. // 加购
  98. goCart(e) {
  99. console.log('================', e)
  100. this.cardMsg = e
  101. this.$nextTick(() => {
  102. this.$refs.specPopup.open();
  103. });
  104. this.carList = e
  105. },
  106. handleSelectedChanged(selectedItems) {
  107. console.log('选中的数据:', selectedItems)
  108. this.carList = selectedItems
  109. if (selectedItems.length > 0) {
  110. this.buyCount = this.carList.length
  111. } else {
  112. this.buyCount = 0
  113. }
  114. this.totalPrice();
  115. },
  116. handleUpdateShopMsg(shopMsg) {
  117. console.log('接收到的购物信息:', shopMsg);
  118. const specString = shopMsg.spec + ',' + shopMsg.specs;
  119. const item = this.goods.find(item => item.id === shopMsg.id);
  120. if (item) {
  121. // 检查购物车列表中是否已存在相同id和规格的商品
  122. const existingCartItem = this.carList.find(cartItem => cartItem.id === item.id && cartItem
  123. .goods_type === specString);
  124. if (existingCartItem) {
  125. // 如果已存在,则增加商品数量
  126. existingCartItem.goods_num += shopMsg.num;
  127. } else {
  128. // 如果不存在,则复制item并添加到购物车列表,同时设置商品数量和规格
  129. const newItem = {
  130. ...item
  131. };
  132. newItem.goods_num = shopMsg.num;
  133. newItem.goods_type = specString;
  134. this.carList.push(newItem);
  135. }
  136. this.buyCount = this.carList.length
  137. // 您可以在这里执行其他逻辑,比如保存到本地存储或发送到服务器
  138. }
  139. console.log('购物车列表更新:', this.carList);
  140. this.totalPrice();
  141. },
  142. //数量的加减
  143. numChanged(value, index) {
  144. console.log('更新后的数量????????????:', value, '索引:', index);
  145. // 假设 carList 是一个 Map,其中 id 是键
  146. const item = this.carList.find(item => item.id === index)
  147. if (item) {
  148. // 更新对应商品的 goods_num
  149. item.goods_num = value;
  150. // 您可以在这里执行其他逻辑,比如保存到本地存储或发送到服务器
  151. console.log('更新后的数量:', value, '索引:', index);
  152. }
  153. this.totalPrice()
  154. },
  155. //计算selected为true的
  156. totalPrice() {
  157. let total = 0;
  158. for (let i = 0; i < this.carList.length; i++) {
  159. // 检查商品是否有 selected 属性
  160. if (this.carList[i].hasOwnProperty('selected')) {
  161. // 如果 selected 属性存在,只有当它为 true 时才计算
  162. if (this.carList[i].selected) {
  163. let priceInCents = Math.round(this.carList[i].goods_price * 100);
  164. let quantity = this.carList[i].goods_num;
  165. total += priceInCents * quantity;
  166. }
  167. } else {
  168. // 如果 selected 属性不存在,直接计算所有商品
  169. let priceInCents = Math.round(this.carList[i].goods_price * 100);
  170. let quantity = this.carList[i].goods_num;
  171. total += priceInCents * quantity;
  172. }
  173. }
  174. // 将总价格转换回浮点数(以元为单位)
  175. this.total = (total / 100).toFixed(2);
  176. console.log('total', this.total);
  177. },
  178. showCart() {
  179. this.$refs.cartPopup.setShow(true);
  180. },
  181. btnIc() {
  182. uni.navigateTo({
  183. url: `/pages/diningList/diningList`
  184. })
  185. },
  186. toDetial(e) {
  187. uni.navigateTo({
  188. url: `/pages/goodDetail/goodDetail?id=${e}`
  189. })
  190. },
  191. toBuy() {
  192. uni.navigateTo({
  193. url: `/pages/order/submitOrder/submitOrder`
  194. })
  195. },
  196. onOrder() {
  197. uni.navigateTo({
  198. url: `/pages/order/myOrder/myOrder`
  199. })
  200. },
  201. onMyInfo() {
  202. const info = {
  203. customerPhone: this.cList.customerPhone
  204. }
  205. console.log('======================', info)
  206. uni.setStorageSync("info", info)
  207. uni.navigateTo({
  208. url: `/pages/user/user`
  209. })
  210. },
  211. // 获取餐车列表
  212. async fatchDate(e) {
  213. var queryParmas = {
  214. id: e.id
  215. }
  216. console.log('idididididid', queryParmas)
  217. const result = await this.$request('post', '/sale/diningCarProduct/queryDiningCarProduct', queryParmas,
  218. true)
  219. if (result) {
  220. const queIds = new Set(result.rows.map(item => item.spuId));
  221. const spuIds = Array.from(queIds).join(',');
  222. const res = await this.$request('get', `/item/spu/queryByIds?spuIds=${spuIds}`)
  223. const data = res.data
  224. this.goods = data.filter(item => item.status !== 1)
  225. console.log('res', res.data)
  226. }
  227. }
  228. }
  229. }
  230. </script>
  231. <style scoped lang="scss">
  232. .goods-category {
  233. width: calc(100% - 100rpx);
  234. border-radius: 14rpx;
  235. overflow: hidden;
  236. .category-box {
  237. height: 70rpx;
  238. width: 100%;
  239. display: flex;
  240. align-items: center;
  241. .category-item {
  242. font-size: 14px;
  243. flex-shrink: 0;
  244. height: 100%;
  245. line-height: 70rpx;
  246. }
  247. .on-category {
  248. color: #FFF;
  249. background-color: #000;
  250. }
  251. }
  252. .classify-icon {
  253. width: 100rpx;
  254. display: flex;
  255. align-items: center;
  256. justify-content: flex-end;
  257. }
  258. }
  259. .goods-item {
  260. width: 48%;
  261. overflow: hidden;
  262. box-sizing: border-box;
  263. border: solid 4px #FFF;
  264. border-radius: 5px;
  265. box-shadow: 0px 3px 10px 0px rgba(213, 221, 232, 0.5);
  266. .img {
  267. width: 100%;
  268. height: 180rpx;
  269. overflow: hidden;
  270. background: #EEE;
  271. }
  272. .title {
  273. width: 100%;
  274. overflow: hidden;
  275. white-space: nowrap;
  276. text-overflow: ellipsis;
  277. padding: 10rpx;
  278. }
  279. }
  280. .cart-bottom {
  281. width: 100%;
  282. position: fixed;
  283. left: 0;
  284. bottom: 0;
  285. height: 130rpx;
  286. box-sizing: border-box;
  287. background-color: #FFF;
  288. box-shadow: 0px -4px 16px 0px rgba(0, 0, 0, 0.15);
  289. z-index: 10800;
  290. .cart {
  291. width: calc(100% - 220rpx);
  292. border-radius: 5px;
  293. background-color: #FEEEE4;
  294. display: flex;
  295. align-items: center;
  296. height: 100%;
  297. .cart-total {
  298. padding-left: 40rpx;
  299. font-size: 16px;
  300. font-weight: 700;
  301. }
  302. }
  303. .balance {
  304. width: 200rpx;
  305. height: 100%;
  306. background-color: #FF0000;
  307. font-size: $uni-font-size-lg;
  308. border-radius: 5px;
  309. color: #FFF;
  310. }
  311. }
  312. .spec-box {
  313. position: relative;
  314. z-index: 99999;
  315. }
  316. .classify-popup {
  317. width: 400rpx;
  318. }
  319. .container {
  320. display: flex;
  321. flex-direction: column;
  322. /* 垂直排列子元素 */
  323. align-items: center;
  324. /* 垂直居中子元素 */
  325. justify-content: center;
  326. /* 水平居中子元素 */
  327. }
  328. .icon-container-l {
  329. margin-top: 10px;
  330. margin-left: 15px;
  331. }
  332. .icon-container-r {
  333. margin-left: 20px;
  334. }
  335. </style>