index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. <template>
  2. <div class="shoppingCart">
  3. <el-tabs v-model="listIdx">
  4. <el-tab-pane label="购物车列表" name="1">
  5. <template>
  6. <div class="top">
  7. <div class="btn-list">
  8. <el-button type="primary" @click="openBox"
  9. >删除所选商品</el-button
  10. >
  11. <el-button type="info" @click="removeCart">清空购物车</el-button>
  12. </div>
  13. <div class="select-info">
  14. <template v-if="Object.keys(addressObj).length > 0">
  15. <el-descriptions title="选择的地址信息(用于购物车的发货)">
  16. <el-descriptions-item label="收货人姓名">{{
  17. addressObj.receiveName
  18. }}</el-descriptions-item>
  19. <el-descriptions-item label="收货人电话号码">{{
  20. addressObj.receivePhone
  21. }}</el-descriptions-item>
  22. <el-descriptions-item label="地址标签">
  23. <el-tag size="small">{{ addressObj.label }}</el-tag>
  24. </el-descriptions-item>
  25. <el-descriptions-item label="是否是默认地址">
  26. {{ addressObj.ifDefault == 1 ? "是" : "否" }}
  27. </el-descriptions-item>
  28. <el-descriptions-item label="收货地址"
  29. >{{ addressObj.receiveAdress
  30. }}{{ addressObj.address }}</el-descriptions-item
  31. >
  32. </el-descriptions>
  33. </template>
  34. <template v-else>
  35. <el-empty
  36. :image-size="50"
  37. description="暂未选择你的收货地址"
  38. >
  39. <el-button type="primary" @click="gpAddress"
  40. >去选择收货地址</el-button
  41. >
  42. </el-empty>
  43. </template>
  44. </div>
  45. </div>
  46. <el-table
  47. v-loading="loading"
  48. ref="multipleTable"
  49. border
  50. :data="tableData"
  51. tooltip-effect="dark"
  52. style="width: 100%"
  53. @selection-change="handleSelectionChange"
  54. >
  55. <el-table-column type="selection" width="55" align="center">
  56. </el-table-column>
  57. <el-table-column
  58. label="商品名称"
  59. align="center"
  60. prop="productName"
  61. width="200"
  62. ></el-table-column>
  63. <el-table-column label="商品图片" align="center">
  64. <template slot-scope="scope">
  65. <img :src="scope.row.image" style="width: 50px; height: 50px" />
  66. </template>
  67. </el-table-column>
  68. <el-table-column label="商品价格" align="center">
  69. <template slot-scope="scope">
  70. ¥{{ scope.row.price || 0 }}
  71. </template>
  72. </el-table-column>
  73. <el-table-column label="商品库存" prop="stockNumber" align="center">
  74. </el-table-column>
  75. <el-table-column label="商品数量" align="center">
  76. <template #header="scope">
  77. <div class="number-box">
  78. <p>商品数量</p>
  79. <span style="color: red; font-size: 12px"
  80. >最大商品数量不得超过商品库存且最小数量为1</span
  81. >
  82. </div>
  83. </template>
  84. <template slot-scope="scope">
  85. <el-input-number
  86. size="mini"
  87. :min="1"
  88. :max="scope.row.stockNumber"
  89. v-model="scope.row.number"
  90. @change="changeNum(scope.row)"
  91. ></el-input-number>
  92. </template>
  93. </el-table-column>
  94. <el-table-column
  95. label="商品规格"
  96. align="center"
  97. prop="value"
  98. ></el-table-column>
  99. <el-table-column label="该商品总价" align="center">
  100. <template slot-scope="scope">
  101. ¥{{ scope.row.price * scope.row.number }}
  102. </template>
  103. </el-table-column>
  104. <el-table-column label="操作" align="center">
  105. <template slot-scope="scope">
  106. <el-button type="text" @click="clearnShop(scope.row)"
  107. >删除该商品</el-button
  108. >
  109. </template>
  110. </el-table-column>
  111. </el-table>
  112. <div class="settlement">
  113. <div class="txt-price">
  114. <p>总价:¥{{ allPrice }}</p>
  115. <p>商家代金券余额:{{ voucherNum.toFixed(2) }}</p>
  116. </div>
  117. <el-button type="danger" @click="settleShop">结算商品</el-button>
  118. </div>
  119. </template>
  120. </el-tab-pane>
  121. <el-tab-pane label="地址列表" name="2">
  122. <AddressCom :addressObj="addressObj" @selectAddress="selectAddress" />
  123. </el-tab-pane>
  124. </el-tabs>
  125. </div>
  126. </template>
  127. <script>
  128. import {
  129. getShopCarList,
  130. updateShopCar,
  131. deleteShopCar,
  132. clearShopCar,
  133. getSettlement,
  134. requertVoucher,
  135. shopSysGetById,
  136. voucherPay,
  137. } from "@/api/threeSelection";
  138. import { getShopId } from "@/utils/auth";
  139. import AddressCom from "./components/addressCom.vue";
  140. export default {
  141. created() {
  142. this.getList();
  143. this.getVoucher();
  144. this.getShopInfo();
  145. // 拿到商铺 id
  146. // this.settlementQuery.shopId = getShopId();
  147. },
  148. components: {
  149. AddressCom,
  150. },
  151. data() {
  152. return {
  153. // 传递给 地址组件的数据
  154. addressObj: {},
  155. // tab 切换
  156. listIdx: "1",
  157. tableData: [],
  158. multipleSelection: [],
  159. // 加载状态
  160. loading: false,
  161. settlementQuery: {
  162. type: "1",
  163. shopId: null,
  164. shops: [],
  165. receiveId: "",
  166. voucherTotalAll: "",
  167. isVoucher: false,
  168. voucherId: "",
  169. },
  170. // 代金券数量
  171. voucherNum: 0,
  172. // 店铺信息
  173. shopInfo: {},
  174. };
  175. },
  176. computed: {
  177. allPrice() {
  178. let price = this.multipleSelection.reduce((prev, item) => {
  179. prev += item.price * item.number;
  180. return prev;
  181. }, 0);
  182. return price.toFixed(2);
  183. },
  184. },
  185. methods: {
  186. // 选中的地址
  187. selectAddress(val) {
  188. this.addressObj = val;
  189. },
  190. async getList() {
  191. this.loading = true;
  192. try {
  193. let res = await getShopCarList();
  194. this.tableData = res.data[0]?.skus;
  195. } finally {
  196. this.loading = false;
  197. }
  198. },
  199. // 请求店铺信息
  200. async getShopInfo() {
  201. let res = await shopSysGetById({});
  202. this.shopInfo = res.data;
  203. },
  204. // 获取代金券数量
  205. async getVoucher() {
  206. let res = await requertVoucher();
  207. // console.log(res);
  208. if (res.code == "") {
  209. this.voucherNum = res.data;
  210. }
  211. },
  212. handleSelectionChange(val) {
  213. this.multipleSelection = val;
  214. },
  215. // 修改商品数量
  216. async changeNum(item) {
  217. let { skuId, number } = item;
  218. let res = await updateShopCar({ skuId, number });
  219. if (res.code == "") {
  220. this.$message({
  221. message: "修改数量成功",
  222. type: "success",
  223. });
  224. }
  225. // console.log(res);
  226. },
  227. // 删除所选商品
  228. async delShopCar() {
  229. if (this.multipleSelection.length <= 0) {
  230. this.$message({
  231. message: "请选择你要删除购物车的商品",
  232. type: "warning",
  233. });
  234. return;
  235. }
  236. let skuIdList = this.multipleSelection.map((item) => {
  237. return item.skuId;
  238. });
  239. let res = await deleteShopCar({ ids: skuIdList });
  240. if (res.code == "") {
  241. this.$message({
  242. message: "删除商品成功",
  243. type: "success",
  244. });
  245. this.getList();
  246. }
  247. },
  248. openBox() {
  249. this.$confirm("请确定是否需要删除购物车中所选择的商品?", "提示", {
  250. confirmButtonText: "确定",
  251. cancelButtonText: "取消",
  252. type: "warning",
  253. }).then(() => {
  254. this.delShopCar();
  255. });
  256. },
  257. // 删除所选商品
  258. async clearnShop(row) {
  259. this.$confirm("请确定是否需要该商品?", "提示", {
  260. confirmButtonText: "确定",
  261. cancelButtonText: "取消",
  262. type: "warning",
  263. }).then(async () => {
  264. let res = await deleteShopCar({ ids: [row.skuId] });
  265. if (res.code == "") {
  266. this.$message({
  267. message: "删除商品成功",
  268. type: "success",
  269. });
  270. this.getList();
  271. }
  272. });
  273. },
  274. // 清空购物车
  275. removeCart() {
  276. this.$confirm("此操作将清空购物车, 是否继续?", "提示", {
  277. confirmButtonText: "确定",
  278. cancelButtonText: "取消",
  279. type: "warning",
  280. })
  281. .then(async () => {
  282. let res = await clearShopCar();
  283. if (res.code == "") {
  284. this.$message({
  285. message: "清空成功",
  286. type: "success",
  287. });
  288. this.getList();
  289. }
  290. })
  291. .catch(() => {});
  292. },
  293. // 结算
  294. async settleShop() {
  295. if (this.multipleSelection.length <= 0) {
  296. this.$message({
  297. message: "请选择要结算的商品",
  298. type: "warning",
  299. });
  300. return;
  301. }
  302. if (!this.addressObj.receiveId) {
  303. this.$message({
  304. message: "请选择收货地址",
  305. type: "warning",
  306. });
  307. return;
  308. }
  309. this.settlementQuery.shops = this.multipleSelection.reduce(
  310. (prev, item) => {
  311. console.log(item.shopId);
  312. let obj = {
  313. ifWork: 0,
  314. shopId: item.shopId,
  315. shopName: item.shopName,
  316. shopDiscountId: "",
  317. shopSeckillId: "",
  318. skus: [
  319. {
  320. productId: item.productId,
  321. skuId: item.skuId,
  322. productName: item.productName,
  323. image: item.image,
  324. price: item.price,
  325. number: item.number,
  326. weight: item.weight,
  327. SKU: "",
  328. total: item.total,
  329. ifLogistics: item.ifLogistics,
  330. },
  331. ],
  332. };
  333. prev.push(obj);
  334. return prev;
  335. },
  336. []
  337. );
  338. this.settlementQuery.shopId = this.multipleSelection[0].shopId
  339. console.log(this.settlementQuery);
  340. let res = await getSettlement(this.settlementQuery);
  341. // console.log("到这里了");
  342. // let res2 = await voucherPay(res.data)
  343. this.$confirm("是否使用代金券支付该产品, 是否继续?", "提示", {
  344. confirmButtonText: "确定",
  345. cancelButtonText: "取消",
  346. type: "warning",
  347. })
  348. .then(() => {
  349. this.pay(res.data);
  350. })
  351. .catch(() => {});
  352. },
  353. // 下单
  354. async pay(data) {
  355. // console.log(data);
  356. // return
  357. let skusData = data.shops.reduce((prev, item) => {
  358. prev.push(...item.skus);
  359. return prev;
  360. }, []);
  361. let queryData = {
  362. procureType: 1,
  363. shopDiscountId: null,
  364. collageId: 0,
  365. type: "",
  366. shopGroupWorkId: 0,
  367. receiveId: null,
  368. areaId: 0,
  369. communityId: "",
  370. couponId: 0,
  371. remark: "",
  372. discountPrice: 0,
  373. shopSeckillId: null,
  374. voucherTotalAll: 0,
  375. isVoucher: false,
  376. voucherId: 0,
  377. communityPhone: "",
  378. franchiseeRule: [],
  379. paymentMode: 4,
  380. _isShowToast: false,
  381. shops: [
  382. {
  383. shopId: 186,
  384. distribution: {
  385. distributionPrice: 0,
  386. distributionName: "结算类型-拼团商品单独立即购买",
  387. },
  388. skus: [],
  389. },
  390. ],
  391. };
  392. queryData.receiveId = this.addressObj.receiveId;
  393. queryData.shops[0].skus = skusData;
  394. let res = await voucherPay(queryData);
  395. if (res.code == "") {
  396. this.$message({
  397. message: "支付成功",
  398. type: "success",
  399. });
  400. this.getVoucher();
  401. this.getList();
  402. }
  403. },
  404. // 去选择收货地址
  405. gpAddress() {
  406. this.listIdx = "2";
  407. },
  408. },
  409. };
  410. </script>
  411. <style lang="scss" scoped>
  412. .shoppingCart {
  413. padding: 50px;
  414. .top {
  415. display: flex;
  416. align-items: center;
  417. justify-content: space-between;
  418. .btn-list {
  419. margin: 20px 0;
  420. flex:1;
  421. }
  422. .select-info {
  423. margin: 30px 0;
  424. flex:2;
  425. ::v-deep .el-descriptions__body {
  426. padding: 20px;
  427. box-sizing: border-box;
  428. }
  429. ::v-deep .el-descriptions-item {
  430. margin-top: 20px;
  431. }
  432. }
  433. }
  434. .settlement {
  435. margin: 30px 0;
  436. display: flex;
  437. align-items: center;
  438. justify-content: space-between;
  439. padding: 0 30px;
  440. box-sizing: border-box;
  441. .txt-price {
  442. p {
  443. font-size: 32px;
  444. color: red;
  445. font-weight: 700;
  446. margin-top: 10px;
  447. }
  448. }
  449. }
  450. }
  451. .number-box {
  452. display: flex;
  453. align-items: center;
  454. flex-direction: column;
  455. gap: 5px;
  456. }
  457. </style>