演示项目-图书馆
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.

570 lines
14 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div class="main">
  3. <div class="cart-main">
  4. <div class="cart-top">
  5. <div class="cart-num">
  6. 图书数量<span>({{ totalLength }})</span>
  7. </div>
  8. <span @click="cartDelt">{{
  9. !isDeltHandle ? '管理' : '完成'
  10. }}</span>
  11. </div>
  12. <div class="cart-list">
  13. <div v-for="(bookItem, index) in list" :key="index" >
  14. <div class="cart-item" v-if="bookItem.length !== 0">
  15. <div class="list-top">
  16. <van-checkbox v-model="bookItem.activeSelect" @change="handleselectedAll(index)"></van-checkbox>
  17. <div class="top-info" @click="toActive(bookItem[0].selectId)">
  18. <p class="active-name">
  19. {{ bookItem[0] && bookItem[0].selectName }}<i></i>
  20. </p>
  21. <p class="dealer">{{ bookItem[0] && bookItem[0].supplierName}}</p>
  22. </div>
  23. </div>
  24. <div class="product-list" v-for="(item, i) in bookItem" :key="item.id">
  25. <div class="product-item">
  26. <!-- @change="handleSingle(index)" -->
  27. <van-checkbox v-model="item.checked"></van-checkbox>
  28. <div
  29. class="product-cont"
  30. @click="getOnlineBookDetail(item.bookId)"
  31. >
  32. <div class="product-img">
  33. <img
  34. :src="
  35. 'http://192.168.99.67:8080/demoOnlineSelect/getBookCover.do?id=' +
  36. item.bookId
  37. "
  38. alt=""
  39. />
  40. </div>
  41. <div class="product-txt">
  42. <div class="product-info">
  43. <h4 class="overflow-txt-only">
  44. {{ item.bookName }}
  45. </h4>
  46. <div class="author-date">
  47. <p class="author overflow-txt-only">
  48. {{ item.author }}
  49. </p>
  50. <p class="date overflow-txt-only">
  51. {{ item.createdDate }}
  52. </p>
  53. </div>
  54. <div class="intro overflow-txt">
  55. {{ item.introduce }}
  56. </div>
  57. </div>
  58. <div class="product-bottom">
  59. <p class="product-price">
  60. 实付款
  61. <span><i class="rmb"></i>0</span
  62. ><i><em></em>{{ item.price }}</i>
  63. </p>
  64. <span
  65. v-if="!isDeltHandle"
  66. class="product-num"
  67. >x1</span
  68. >
  69. <span
  70. v-else
  71. class="item-delt"
  72. @click.stop="
  73. deltCurrentItem(item.id)
  74. "
  75. ></span>
  76. </div>
  77. </div>
  78. </div>
  79. </div>
  80. </div>
  81. </div>
  82. </div>
  83. <div class="empty-data" v-if="list.length === 0">
  84. <img src="@assets/images/empty.png" alt="" />
  85. </div>
  86. </div>
  87. </div>
  88. <div class="cart-pay" v-if="list.length !== 0">
  89. <van-checkbox v-model="allSelected">全选</van-checkbox>
  90. <div v-if="!isDeltHandle" class="payment-right">
  91. <div class="total-num">
  92. 合计:<span><i class="rmb"></i>0</span>
  93. </div>
  94. <p class="pay-btn" @click="goPay">下单</p>
  95. </div>
  96. <div v-else class="payment-right">
  97. <p class="delt-btn" @click="confirmDelt">删除</p>
  98. </div>
  99. </div>
  100. <TabBar :tabCur.sync="tabCur" />
  101. <van-dialog v-model:show="showDetial" :show-confirm-button="false">
  102. <div class="bookItem-dialog-detail">
  103. <div class="list-top">
  104. <div class="top-info" @click="toActive(detailBook.listId)">
  105. <p class="active-name">{{ detailBook.listName }}<i></i></p>
  106. </div>
  107. </div>
  108. <div class="product-cont">
  109. <div class="product-cont-left">
  110. <div class="product-img">
  111. <img
  112. :src="
  113. $coverUrl+'/demoOnlineSelect/getBookCover.do?id=' +
  114. detailBook.id
  115. "
  116. alt=""
  117. />
  118. </div>
  119. <div class="book-inventory">
  120. <p>剩余库存</p>
  121. <span
  122. ><i>{{
  123. parseInt(detailBook.total) -
  124. parseInt(detailBook.purchase)
  125. }}</i
  126. ></span
  127. >
  128. </div>
  129. </div>
  130. <div class="product-txt">
  131. <div class="product-info">
  132. <h4>{{ detailBook.bookName }}</h4>
  133. <div class="bookItem-txt">
  134. <span>著者</span>
  135. <p class="author">{{ detailBook.author }}</p>
  136. </div>
  137. <div class="bookItem-txt">
  138. <span>出版社</span>
  139. <p>{{ detailBook.publish }}</p>
  140. </div>
  141. <div class="bookItem-txt">
  142. <span>出版时间</span>
  143. <p>{{ detailBook.createdDate }}</p>
  144. </div>
  145. <div class="bookItem-txt">
  146. <span class="txt-title">简介</span>
  147. <p class="intro-txt">
  148. {{
  149. detailBook.introduce !== ''
  150. ? detailBook.introduce
  151. : '暂无简介'
  152. }}
  153. </p>
  154. </div>
  155. </div>
  156. </div>
  157. </div>
  158. <div class="order-dealer">
  159. <p class="dealer">{{ detailBook.supplierName }}</p>
  160. <div class="order-pay">
  161. <p>
  162. 实付款<span><i></i>0</span>
  163. </p>
  164. <span class="yj-price"
  165. ><i></i><em>{{ detailBook.price }}</em></span
  166. >
  167. </div>
  168. </div>
  169. </div>
  170. <div class="dialog-btn">
  171. <span @click="showDetial = false">关闭</span>
  172. </div>
  173. </van-dialog>
  174. </div>
  175. </template>
  176. <script>
  177. import { Toast } from 'vant'
  178. import { reactive, computed, watch, onMounted, getCurrentInstance, toRefs } from 'vue'
  179. import TabBar from '@/components/tabBar/index.vue'
  180. export default {
  181. name: 'Cart',
  182. components: { TabBar },
  183. setup() {
  184. const { proxy } = getCurrentInstance()
  185. let data = reactive({
  186. tabCur: 1,
  187. allSelected: false,
  188. isDeltHandle: false,
  189. showDetial: false,
  190. list: [],
  191. totalLength: 0,
  192. checkedCount: [],
  193. detailBook: null,
  194. checkedBooks:[],
  195. checkedBooksPay:[]
  196. })
  197. watch(data.list, () => {
  198. data.allSelected = allSelected;
  199. }, { deep: true });
  200. onMounted(() => {
  201. getMyshoppingCart()
  202. })
  203. const allSelected = computed({
  204. get() {
  205. return data.list.every(bookItem => {
  206. return bookItem.every(item => item.checked);
  207. });
  208. },
  209. set(checked) {
  210. data.list.forEach(bookItem => {
  211. bookItem.forEach(item => {
  212. item.checked = checked;
  213. });
  214. });
  215. }
  216. })
  217. let toActive = (id) =>{
  218. proxy.$router.push({
  219. path: '/BookList',
  220. query: {
  221. activeId: id
  222. }
  223. })
  224. }
  225. let getMyshoppingCart = () => {
  226. let param = {}
  227. proxy.$http
  228. .get(proxy.$API.MYSHOPPINGCART, {
  229. params: param,
  230. })
  231. .then((res) => {
  232. if(res.data.length === 0){
  233. data.list = []
  234. data.totalLength = 0
  235. }else{
  236. let allArraysEmpty = true;
  237. for (let i = 0; i < res.data.length; i++) {
  238. if (res.data[i].length !== 0) { // 如果当前子数组不为空
  239. allArraysEmpty = false; // 设置所有子数组都不为空的标记为 false
  240. break;
  241. }
  242. }
  243. if (allArraysEmpty) {
  244. data.list = []
  245. data.totalLength = 0
  246. } else {
  247. data.list = res.data
  248. data.list.forEach(bookItem => {
  249. watch(bookItem, () => {
  250. bookItem.activeSelect = bookItem.every(item => item.checked);
  251. }, { deep: true });
  252. })
  253. data.totalLength = data.list.map(books => books.length).reduce((total, length) => total + length, 0);
  254. }
  255. }
  256. })
  257. .catch((res) => {
  258. console.log(res)
  259. })
  260. }
  261. let getOnlineBookDetail = (bookId) => {
  262. proxy.$http
  263. .post(
  264. proxy.$API.BOOKONLINEDETAIL,
  265. {
  266. bookId: bookId,
  267. },
  268. {
  269. headers: {
  270. 'Content-Type': 'application/x-www-form-urlencoded',
  271. },
  272. }
  273. )
  274. .then((res) => {
  275. data.detailBook = res.data.book
  276. data.showDetial = true
  277. })
  278. .catch((res) => {
  279. console.log(res)
  280. })
  281. }
  282. let deltBookShoppingCart = (ids) => {
  283. let param = {
  284. ids: ids,
  285. }
  286. proxy.$http
  287. .put(
  288. proxy.$API.DELETBOOKTOSHOPPINGCART,
  289. param,
  290. {
  291. headers: {
  292. 'Content-Type': 'application/x-www-form-urlencoded'
  293. },
  294. }
  295. )
  296. .then((res) => {
  297. getMyshoppingCart()
  298. Toast("删除成功")
  299. })
  300. .catch((res) => {
  301. console.log(res)
  302. })
  303. }
  304. let confirmDelt = () => {
  305. data.checkedBooks = data.list
  306. .flat()
  307. .filter(item => item.checked === true)
  308. .map(item => item.id);
  309. if(data.checkedBooks.length === 0){
  310. Toast('请选择你需要删除的书籍')
  311. }else{
  312. const ids = data.checkedBooks.join(',')
  313. console.log(ids)
  314. deltBookShoppingCart(ids)
  315. }
  316. }
  317. let cartDelt = () => {
  318. data.isDeltHandle = !data.isDeltHandle
  319. }
  320. let deltCurrentItem = (bookId) => {
  321. deltBookShoppingCart(bookId)
  322. }
  323. // 商品单选
  324. let handleSingle = (index) => {
  325. }
  326. // 全选
  327. let handleselectedAll = (index) => {
  328. data.list[index].forEach(item=>{
  329. item.checked = data.list[index].activeSelect
  330. })
  331. }
  332. let goPay = () => {
  333. data.checkedBooksPay = data.list
  334. .flat()
  335. .filter(item => item.checked === true)
  336. .map(item => item);
  337. console.log(data.checkedBooksPay)
  338. if(data.checkedBooksPay.length === 0){
  339. Toast('请选择需要下单的书籍')
  340. }else{
  341. if(data.checkedBooksPay.length > 3){
  342. Toast('当前活动限选三本图书')
  343. }else{
  344. getMyAddress()
  345. }
  346. }
  347. }
  348. let addPlaceOrder = (param) => {
  349. proxy.$http
  350. .put(
  351. proxy.$API.PLACEORDER,
  352. param,
  353. {
  354. headers: {
  355. 'Content-Type': 'application/x-www-form-urlencoded',
  356. },
  357. }
  358. )
  359. .then((res) => {
  360. if(res.errCode === 0){
  361. proxy.$router.push({ path: '/CartResult' })
  362. }
  363. })
  364. .catch((res) => {
  365. console.log(res)
  366. })
  367. }
  368. let getMyAddress = () => {
  369. let param = {
  370. openid: 'ocHu-sysUQ6-xb9knAJ5mATqCOJE'
  371. }
  372. proxy.$http
  373. .get(proxy.$API.MYADDRESS, {
  374. params: param,
  375. })
  376. .then((res) => {
  377. if(res.data.myAddress.length !== 0){
  378. const defaultAddress = res.data.myAddress.find(function(address) {
  379. return address.isDefault === 1;
  380. });
  381. data.list.forEach((group) => {
  382. const checked_books = [];
  383. group.forEach((item) => {
  384. if (item.checked) {
  385. checked_books.push(item.bookId);
  386. }
  387. });
  388. var book_ids = checked_books.join(',');
  389. let param = {
  390. addressId: defaultAddress.id,
  391. bookIds: book_ids
  392. }
  393. addPlaceOrder(param)
  394. })
  395. }else{
  396. Toast('请先添加收货地址后再下单')
  397. }
  398. })
  399. .catch((res) => {
  400. console.log(res)
  401. })
  402. }
  403. return {
  404. ...toRefs(data),
  405. toActive,
  406. goPay,
  407. cartDelt,
  408. deltCurrentItem,
  409. handleselectedAll,
  410. handleSingle,
  411. confirmDelt,
  412. getMyshoppingCart,
  413. getOnlineBookDetail,
  414. deltBookShoppingCart,
  415. addPlaceOrder,
  416. allSelected,
  417. getMyAddress
  418. }
  419. },
  420. }
  421. </script>
  422. <style scoped lang="scss">
  423. .cart-main {
  424. padding: 0 0.16rem 2.2rem 0.16rem;
  425. color: #191a1a;
  426. .cart-top {
  427. position: fixed;
  428. top: 0;
  429. right: 0;
  430. left: 0;
  431. display: flex;
  432. justify-content: space-between;
  433. align-items: center;
  434. font-size: 0.32rem;
  435. height: 1rem;
  436. padding: 0 0.32rem;
  437. background-color: #fff;
  438. box-shadow: 0 0.06rem 0.1rem 1px #efecec;
  439. z-index: 999;
  440. .cart-num {
  441. font-size: 0.32rem;
  442. opacity: 0.6;
  443. span {
  444. font-size: 0.3rem;
  445. }
  446. }
  447. }
  448. }
  449. .cart-list {
  450. padding-top: 1.2rem;
  451. }
  452. .cart-item {
  453. padding: 0.24rem;
  454. margin-bottom: 0.2rem;
  455. box-shadow: 0px 0.03rem 0.6rem 1px rgba(0, 0, 0, 0.08);
  456. border-radius: 0.1rem;
  457. background-color: #fff;
  458. }
  459. .product-list {
  460. .product-item {
  461. display: flex;
  462. justify-content: flex-start;
  463. margin-top: 0.3rem;
  464. }
  465. }
  466. .cart-pay {
  467. position: fixed;
  468. left: 0;
  469. right: 0;
  470. bottom: 0.98rem;
  471. padding: 0 0.32rem;
  472. height: 1rem;
  473. background: linear-gradient(#fff, #f1f1f1);
  474. display: flex;
  475. justify-content: space-between;
  476. align-items: center;
  477. .payment-right {
  478. display: flex;
  479. justify-content: space-between;
  480. align-items: center;
  481. font-size: 0.28rem;
  482. .total-num {
  483. font-size: 0.28rem;
  484. span {
  485. font-size: 0.4rem;
  486. font-weight: bold;
  487. color: #ff3871;
  488. .rmb {
  489. font-style: normal;
  490. font-size: 0.28rem;
  491. text-decoration: none;
  492. }
  493. }
  494. }
  495. .pay-btn {
  496. width: 1.5rem;
  497. height: 0.6rem;
  498. margin-left: 0.4rem;
  499. line-height: 0.6rem;
  500. text-align: center;
  501. color: #fff;
  502. background: url('@assets/images/btn3.png') no-repeat center center;
  503. background-size: 100% 100%;
  504. }
  505. .delt-btn {
  506. width: 1.5rem;
  507. height: 0.6rem;
  508. line-height: 0.6rem;
  509. font-size: 0.28rem;
  510. color: #000;
  511. text-align: center;
  512. border: 0.02rem solid #000;
  513. opacity: 0.6;
  514. border-radius: 0.4rem;
  515. }
  516. }
  517. }
  518. .van-checkbox {
  519. margin-right: 0.2rem;
  520. }
  521. :deep(.van-checkbox__icon) {
  522. height: 0.35rem;
  523. }
  524. :deep(.van-checkbox__icon .van-icon) {
  525. width: 0.35rem;
  526. height: 0.35rem;
  527. border-color: rgba(0, 0, 0, 0.3);
  528. }
  529. :deep(.van-checkbox__icon--checked .van-icon) {
  530. border: none;
  531. background: url('@assets/images/selected.png') no-repeat transparent;
  532. background-size: 0.35rem 0.35rem;
  533. }
  534. :deep(.van-icon-success:before) {
  535. display: none;
  536. }
  537. :deep(.van-checkbox__label) {
  538. font-size: 0.28rem;
  539. }
  540. .bookItem-dialog-detail {
  541. border-bottom: none;
  542. }
  543. </style>