index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. <template>
  2. <div class="solve-page">
  3. <div class="solve-bos">
  4. <img class="solve-img" :src="dataInfo.coverImage" alt="" />
  5. <div v-for="(item, index) in dataList" :key="index">
  6. <!-- 标题 -->
  7. <div class="solve-title">
  8. <div class="title1">{{ item.title }}</div>
  9. <div class="title2">{{ item.subtitle }}</div>
  10. </div>
  11. <!-- 数据 -->
  12. <div class="data-bos">
  13. <div class="data-box">
  14. <div v-for="(item1, index1) in item.list" :key="index1" class="data-list" @click="onPath('/item?id=' + item1.id)">
  15. <img class="data-img" :src="item1.productImage" alt="" />
  16. <div class="data-title ellipsis">{{ item1.itemName }}</div>
  17. <div class="money">
  18. <span class="money1">¥{{ item1.memberPrice }}</span>
  19. <span class="money2">¥{{ item1.marketPrice }}</span>
  20. </div>
  21. <div class="data-cat" @click.stop="onCart(item1)">加入购物车</div>
  22. </div>
  23. </div>
  24. <!-- 游标分页控制 -->
  25. <pagination
  26. v-show="item.list.length > 0"
  27. v-model:page="item.pageNum"
  28. v-model:limit="item.pageSize"
  29. :cursor-mode="true"
  30. :has-more="item.hasMore"
  31. @pagination="getList(item)"
  32. />
  33. </div>
  34. </div>
  35. </div>
  36. </div>
  37. </template>
  38. <script setup lang="ts">
  39. import { onPath } from '@/utils/siteConfig';
  40. import { getProcurementProgramDetail, getProcurementProgramGroupList, getProcurementProgramGroupProductList } from '@/api/plan/index';
  41. import { addProductShoppingCart } from '@/api/goods/index';
  42. const id = ref<any>(null);
  43. const dataInfo = ref<any>({});
  44. const dataList = ref<any>({});
  45. const route = useRoute();
  46. onMounted(() => {
  47. id.value = route.query.id;
  48. getInfo();
  49. });
  50. const getInfo = async () => {
  51. try {
  52. // 获取采购计划详情
  53. const detailRes = await getProcurementProgramDetail(id.value);
  54. if (detailRes.code === 200) {
  55. dataInfo.value = detailRes.data;
  56. }
  57. // 获取采购计划分组列表
  58. const groupRes = await getProcurementProgramGroupList(id.value);
  59. if (groupRes.code === 200) {
  60. // 使用 Promise.all 等待所有 onGoods 异步操作完成
  61. const updatedData = await Promise.all(
  62. groupRes.data.map(async (item: any) => {
  63. item.pageSize = 10;
  64. item.pageNum = 1;
  65. item.hasMore = false;
  66. const productList: any = await onGoods(item); // 等待每个分组的商品列表加载完成
  67. item.hasMore = productList.total > item.pageSize * item.pageNum;
  68. return {
  69. ...item,
  70. list: productList.rows // 将商品列表赋值给 item.List
  71. };
  72. })
  73. );
  74. dataList.value = updatedData; // 更新 dataList
  75. console.log(dataList.value);
  76. }
  77. } catch (error) {
  78. console.error('获取数据失败:', error);
  79. }
  80. };
  81. // 修改 onGoods 返回 Promise
  82. const onGoods = async (item: any) => {
  83. try {
  84. const res = await getProcurementProgramGroupProductList({ groupId: item.id, pageSize: item.pageSize, pageNum: item.pageNum });
  85. if (res.code === 200) {
  86. return res; // 返回商品列表
  87. }
  88. return []; // 如果请求失败,返回空数组
  89. } catch (error) {
  90. console.error('获取商品列表失败:', error);
  91. return []; // 异常情况下也返回空数组
  92. }
  93. };
  94. const getList = (row: any) => {
  95. getProcurementProgramGroupProductList({ groupId: row.id, pageSize: row.pageSize, pageNum: row.pageNum }).then((res) => {
  96. if (res.code == 200) {
  97. row.list = res.rows;
  98. // 判断是否还有更多数据
  99. row.hasMore = res.total > row.pageSize * row.pageNum;
  100. }
  101. });
  102. };
  103. import { cartStore } from '@/store/modules/cart';
  104. const cart = cartStore();
  105. //加入购物车
  106. const onCart = (row: any) => {
  107. addProductShoppingCart({
  108. productId: row.id,
  109. productNum: 1
  110. }).then((res) => {
  111. if (res.code == 200) {
  112. cart.onCartCount();
  113. ElMessage.success('加入购物车成功');
  114. }
  115. });
  116. };
  117. </script>
  118. <style lang="scss" scoped>
  119. .solve-page {
  120. width: 100%;
  121. .solve-bos {
  122. width: 1200px;
  123. margin: 0 auto;
  124. padding-bottom: 30px;
  125. .solve-img {
  126. width: 1200px;
  127. height: 380px;
  128. border-radius: 10px;
  129. margin-top: 20px;
  130. }
  131. .solve-title {
  132. width: 1200px;
  133. padding: 10px 20px;
  134. background-color: #ffffff;
  135. border-radius: 10px;
  136. margin-top: 20px;
  137. .title1 {
  138. font-size: 24px;
  139. font-weight: bold;
  140. margin-bottom: 20px;
  141. }
  142. .title2 {
  143. background-color: #f2f2f2;
  144. padding: 17px 20px;
  145. font-size: 14px;
  146. color: #666666;
  147. border-radius: 10px;
  148. }
  149. }
  150. //数据
  151. .data-bos {
  152. background-color: #ffffff;
  153. padding: 20px 20px;
  154. margin-top: 20px;
  155. border-radius: 10px;
  156. .data-box {
  157. width: 100%;
  158. display: flex;
  159. flex-wrap: wrap;
  160. gap: 20px;
  161. .data-list {
  162. flex: 0 0 calc((100% - 80px) / 5);
  163. width: 0;
  164. background: #f4f4f4;
  165. border-radius: 10px;
  166. padding: 20px 20px 22px 20px;
  167. cursor: pointer;
  168. .data-img {
  169. width: 184px;
  170. height: 184px;
  171. border-radius: 10px;
  172. }
  173. .data-title {
  174. margin-top: 4px;
  175. font-size: 14px;
  176. color: #101828;
  177. height: 40px;
  178. }
  179. .money {
  180. margin-top: 4px;
  181. .money1 {
  182. font-size: 16px;
  183. color: #e7000b;
  184. }
  185. .money2 {
  186. font-size: 12px;
  187. color: #99a1af;
  188. text-decoration: line-through;
  189. padding-left: 6px;
  190. }
  191. }
  192. .data-cat {
  193. width: 86px;
  194. height: 26px;
  195. background: #e7000b;
  196. border-radius: 2px;
  197. font-size: 14px;
  198. color: #ffffff;
  199. line-height: 26px;
  200. text-align: center;
  201. margin-top: 16px;
  202. }
  203. }
  204. }
  205. }
  206. .title {
  207. font-weight: 600;
  208. font-size: 20px;
  209. color: #101828;
  210. margin-top: 20px;
  211. }
  212. .info {
  213. font-size: 14px;
  214. color: #364153;
  215. margin-top: 8px;
  216. border-bottom: 1px solid #e5e7eb;
  217. padding-bottom: 20px;
  218. }
  219. .filter-bos {
  220. padding-bottom: 20px;
  221. border-bottom: 1px solid #e5e7eb;
  222. .filter-list {
  223. margin-top: 20px;
  224. .filter-title {
  225. font-size: 14px;
  226. color: #101828;
  227. margin-right: 40px;
  228. }
  229. .filter-item {
  230. font-size: 14px;
  231. color: #364153;
  232. margin-right: 30px;
  233. cursor: pointer;
  234. &.hig {
  235. color: #e7000b;
  236. }
  237. }
  238. }
  239. }
  240. .nav-bos {
  241. width: 1200px;
  242. padding: 20px 0;
  243. .nav-list {
  244. height: 32px;
  245. padding: 0 12px;
  246. background: #f7f8fa;
  247. border-radius: 2px 2px 2px 2px;
  248. font-size: 14px;
  249. color: #4e5969;
  250. margin-right: 8px;
  251. line-height: 32px;
  252. cursor: pointer;
  253. &.hig {
  254. background: #ffe8e8;
  255. color: #e7000b;
  256. }
  257. &:hover {
  258. color: #e7000b;
  259. }
  260. }
  261. }
  262. }
  263. }
  264. </style>