index.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <template>
  2. <view class="requestList">
  3. <!-- header -->
  4. <cu-custom custom bgColor="bg-gradual-blue"><view slot="content">购物车</view></cu-custom>
  5. <view class="setting">
  6. <view class="setting-content flex align-center justify-center padding-sm bg-white">
  7. <view v-if="Object.keys(addressValue).length>0" @click="addressListFunc" class="left text-cut text-grey">
  8. <text class="cuIcon-locationfill text-green"></text>
  9. 配送至{{ addressValue.province }}{{ addressValue.city }}{{ addressValue.area }}{{ addressValue.address }}
  10. </view>
  11. <view v-else class="left"> </view>
  12. <view @click="status = !status" class="right margin-left">{{ status ? '完成' : '管理' }}</view>
  13. </view>
  14. </view>
  15. <!-- section -->
  16. <cu-scrollView @refresherpulling="refresherpulling" @scroll="scroll" :height="height">
  17. <view class="section">
  18. <checkbox-group :value="group" @change="chooseShop">
  19. <view v-for="(item, index) in ListValue" :key="index" class="item flex align-center bg-white radius padding">
  20. <checkbox :value="index" :checked="group.some(it => it == index)" style="transform: scale(0.6);" />
  21. <view class="right flex margin-left">
  22. <image @click="detailFunc(item.commodity_details)" mode="aspectFit" :src="item.image | lazyImage" class="image radius margin-right-sm"></image>
  23. <view class="right-right">
  24. <view class="text-black">{{ item.name }}</view>
  25. <view class="flex justify-between margin-top-xs margin-bottom-sm">
  26. <view class="text-red text-price"><cu-price :value="item.price" /></view>
  27. <view>{{ item.point_price }}积分</view>
  28. </view>
  29. <view style="float: right;"><cu-stepper @change="val => changeNum(index, val)" :value="item.quantity" /></view>
  30. </view>
  31. </view>
  32. </view>
  33. </checkbox-group>
  34. <!-- 状态管理 -->
  35. <view v-if="bind==1" class="cu-load" :class="{ loading: currentPage <= totalPage, over: currentPage > totalPage }"></view>
  36. </view>
  37. </cu-scrollView>
  38. <!-- footer -->
  39. <view class="tool">
  40. <!-- 结算 -->
  41. <view v-if="!status" class="bg-white tool-contentA flex align-center justify-center padding-lr padding-tb-sm">
  42. <view class="left flex align-center">
  43. <checkbox-group @change="totalFunc('total_lockA')" class="margin-right flex align-center">
  44. <checkbox :checked="total_lockA" style="transform: scale(0.6);" />
  45. <text class="text-lg margin-left-sm">全选</text>
  46. </checkbox-group>
  47. <view class="text-red margin-left">
  48. 合计:
  49. <cu-price :value="price" size="52" />
  50. <text class="margin-left-sm text-grey left">{{ point_price }}积分</text>
  51. </view>
  52. </view>
  53. <view class="right"><button :disabled="disabled" @click="payFunc" class="cu-btn bg-red round shadow-blur">结算</button></view>
  54. </view>
  55. <!-- 管理 -->
  56. <view v-else class="bg-white tool-contentA flex align-center justify-center padding-lr padding-tb-sm">
  57. <view class="left flex ">
  58. <checkbox-group @change="totalFunc('total_lockB')" class="margin-right flex align-center">
  59. <checkbox :checked="total_lockB" style="transform: scale(0.6);" />
  60. <text class="text-lg margin-left-sm">全选</text>
  61. </checkbox-group>
  62. </view>
  63. <view class="right">
  64. <button @click="deleteFunc" :disabled="disabled" class="cu-btn bg-red round shadow-blur margin-right">删除</button>
  65. <button @click="collectFunc" :disabled="disabled" class="cu-btn bg-green round shadow-blur">移入收藏</button>
  66. </view>
  67. </view>
  68. </view>
  69. <cu-bar active="3" />
  70. </view>
  71. </template>
  72. <script>
  73. import { CustomBarHeight } from '@/common/device/index.js';
  74. import { mapState, mapActions, mapMutations } from 'vuex';
  75. import {debounce} from "@/common/debounceThrottle/index.js"
  76. import api from './api.js';
  77. export default {
  78. data() {
  79. return {
  80. status: false, // false 结算 true 管理
  81. total_lockA: false, //购买 全选
  82. total_lockB: false, //管理 全选
  83. price: 0, //合计
  84. point_price: 0, //积分
  85. group: []
  86. };
  87. },
  88. computed: {
  89. ...mapState(['bind']),
  90. ...mapState('addressDefault', ['addressValue']),
  91. ...mapState('requestList', ['ListValue', 'currentPage', 'totalPage']),
  92. height() {
  93. return `calc(100vh - 280rpx - ${CustomBarHeight}px)`;
  94. },
  95. disabled() {
  96. let bind = this.bind;
  97. let group = this.group;
  98. return bind != 1 || group.length == 0;
  99. }
  100. },
  101. onLoad() {
  102. },
  103. async onShow() {
  104. await this.reset();
  105. if(this.bind!=1) return false;
  106. await this.requestFunc({ method: 'get', url: `/customer/order/cart/`, data: { limit: 10 } });
  107. await this.$store.dispatch('addressDefault/requestFunc');
  108. },
  109. methods: {
  110. ...mapMutations('requestList', ['changeValue']),
  111. ...mapActions('requestList', ['reset', 'requestFunc']),
  112. totalFunc(type) {
  113. let totalStutas = !this[type];
  114. let group = [];
  115. if (totalStutas) this.ListValue.forEach((item, index) => group.push(index));
  116. this.group = group;
  117. this[type] = totalStutas;
  118. },
  119. addressListFunc() {
  120. uni.navigateTo({
  121. url: '/loginPages/addressList/index'
  122. });
  123. },
  124. //合计
  125. computer() {
  126. let point_price = 0,
  127. price = 0;
  128. if (!this.status && this.group.length > 0)
  129. this.ListValue.forEach(item => {
  130. if (this.group.findIndex(it => it == item.id) != -1) {
  131. point_price += item.point_price * 1 * item.quantity;
  132. price += item.price * 1 * item.quantity;
  133. }
  134. });
  135. this.point_price = point_price;
  136. this.price = price;
  137. },
  138. detailFunc(id) {
  139. uni.navigateTo({
  140. url: `/pages/detail/index?id=${id}`
  141. });
  142. },
  143. chooseShop(e) {
  144. let { value } = e.detail;
  145. if (value.length == this.ListValue.length) {
  146. if (this.status) {
  147. this.total_lockB = true;
  148. } else {
  149. this.total_lockA = true;
  150. }
  151. } else {
  152. if (this.status) {
  153. this.total_lockB = false;
  154. } else {
  155. this.total_lockA = false;
  156. }
  157. }
  158. this.group = value;
  159. },
  160. // 更改商品数量
  161. async changeNum(index, val) {
  162. let ListValue = JSON.parse(JSON.stringify(this.ListValue));
  163. let { id } = ListValue[index];
  164. var result = await api.quantity({ id, quantity: val });
  165. if (result.code === 0) {
  166. ListValue[index]['quantity'] = val;
  167. this.changeValue(ListValue);
  168. this.computer();
  169. }
  170. },
  171. // 下拉刷新
  172. async refresherpulling() {
  173. await this.reset();
  174. if(this.bind!=1) return false;
  175. await this.requestFunc({ method: 'get', url: `/customer/order/cart/`, data: { limit: 10 } });
  176. },
  177. // 上拉加载
  178. async scroll() {
  179. if(this.bind!=1) return false;
  180. await this.requestFunc({ method: 'get', url: `/customer/order/cart/`, data: { limit: 10 } });
  181. },
  182. payFunc(){
  183. debounce(this._payFunc(),3000)
  184. },
  185. _payFunc() {
  186. let listValue = JSON.parse(JSON.stringify(this.ListValue));
  187. let group = JSON.parse(JSON.stringify(this.group));
  188. group = group.map(item => {
  189. let ItemDate = listValue[item];
  190. let img = ItemDate['image'];
  191. let count = ItemDate['quantity'];
  192. delete ItemDate['image'];
  193. delete ItemDate['quantity'];
  194. return { ...ItemDate, img, count };
  195. });
  196. uni.navigateTo({
  197. url: `/indexPages/pay/index?list=${JSON.stringify(group)}`
  198. });
  199. },
  200. deleteFunc(){
  201. debounce(this._deleteFunc(),3000)
  202. },
  203. async _deleteFunc() {
  204. let listValue = JSON.parse(JSON.stringify(this.ListValue));
  205. let group = JSON.parse(JSON.stringify(this.group));
  206. group = group.map(item => listValue[item]['id']);
  207. await api.deleteShop({ids:JSON.stringify(group)});
  208. this.group=[];
  209. this.total_lockB = false;
  210. await this.reset();
  211. await this.requestFunc({ method: 'get', url: `/customer/order/cart/`, data: { limit: 10 } });
  212. },
  213. collectFunc(){
  214. debounce(this._collectFunc(),3000)
  215. },
  216. async _collectFunc(){
  217. let listValue = JSON.parse(JSON.stringify(this.ListValue));
  218. let group = JSON.parse(JSON.stringify(this.group));
  219. group = group.map(item => listValue[item]['commodity_details']);
  220. var result= await api.favorite({ids:JSON.stringify(group)})
  221. if(result.code==0) uni.showToast({
  222. title:"成功移入收藏",
  223. icon:"success",
  224. success:()=>{
  225. this.group=[];
  226. this.total_lockB = false;
  227. }
  228. })
  229. }
  230. },
  231. watch: {
  232. group: {
  233. handler(newVal, oldVal) {
  234. this.computer();
  235. },
  236. deep: true
  237. },
  238. status: {
  239. handler(newVal, oldVal) {
  240. this.group = [];
  241. this.total_lockA = false;
  242. this.total_lockB = false;
  243. },
  244. deep: true
  245. }
  246. },
  247. // 下拉刷新
  248. async onPullDownRefresh() {
  249. // await this.$store.requestList.dispatch('requestFunc',true);
  250. uni.stopPullDownRefresh({});
  251. }
  252. };
  253. </script>
  254. <style lang="scss" scoped>
  255. .requestList {
  256. .section {
  257. .item {
  258. position: relative;
  259. .image {
  260. width: 160upx;
  261. min-width: 160upx;
  262. height: 160upx;
  263. background-size: cover;
  264. background-position: center;
  265. }
  266. .right {
  267. flex: auto;
  268. .right-right {
  269. flex: auto;
  270. }
  271. }
  272. &::after {
  273. content: '';
  274. border-bottom: 1upx solid #eee;
  275. position: absolute;
  276. left: 0;
  277. bottom: 0;
  278. transform: scale(1, 0.5);
  279. width: 100%;
  280. }
  281. }
  282. }
  283. .setting {
  284. height: 80upx;
  285. .setting-content {
  286. position: fixed;
  287. left: 0;
  288. z-index: 9998;
  289. width: 100%;
  290. .left {
  291. flex: auto;
  292. }
  293. .right {
  294. min-width: 60upx;
  295. }
  296. }
  297. }
  298. .tool {
  299. height: 100rpx;
  300. .tool-contentA {
  301. position: fixed;
  302. bottom: calc(100rpx + env(safe-area-inset-bottom));
  303. left: 0;
  304. z-index: 9998;
  305. width: 100%;
  306. .left {
  307. flex: auto;
  308. }
  309. &::before {
  310. content: '';
  311. border-top: 1upx solid #aaa;
  312. position: absolute;
  313. left: 0;
  314. top: 0;
  315. transform: scale(1, 0.5);
  316. width: 100%;
  317. }
  318. }
  319. }
  320. }
  321. </style>