pack.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. <template>
  2. <Theme>
  3. <view class="wrap">
  4. <Navbar title="打包" fixed border>
  5. <template #right>
  6. <navMenu :options="{ icon: 'icon-home', text: '主页' }" />
  7. </template>
  8. </Navbar>
  9. <view class="content">
  10. <view class="cont">
  11. <addressModel @confirm="addressConfirm" />
  12. <view class="logistics">
  13. <view class="logistics_item" @click="toLogistics">
  14. <logisticsList
  15. :item="logistics"
  16. :isShowBottom="false"
  17. v-if="islogistics"
  18. >
  19. </logisticsList>
  20. <view class="logistics_empty" v-else>
  21. <trans _t="请选择物流路线" />
  22. <up-icon name="arrow-right"></up-icon>
  23. </view>
  24. </view>
  25. </view>
  26. <view class="card_wrapper">
  27. <view class="card_item">
  28. <view
  29. class="card_item_wrapper"
  30. v-for="(item, index) in orderList"
  31. :key="index"
  32. >
  33. <view class="item_top">
  34. <view class="item_left">
  35. <image :src="item.pic_url" class="item_img"></image>
  36. </view>
  37. <view class="item_middle">
  38. <view class="title">{{ item.goodTitle }}</view>
  39. <view class="desc">{{ item.sku_desc }}</view>
  40. </view>
  41. <view class="item_right">
  42. <view class="price">
  43. <text>{{ symbol.symbol }}</text>
  44. <text>{{ item.price }}</text>
  45. </view>
  46. <view class="total_num">X {{ item.total }}</view>
  47. </view>
  48. </view>
  49. <view class="order_status">
  50. <text>{{ item.status_txt }}&nbsp;</text>
  51. <!-- <i class="icon-font icon-question2"></i> -->
  52. </view>
  53. <view class="text_box">
  54. <trans class="title" _t="体积"></trans>
  55. <text>{{ item?.volume }}m³</text>
  56. </view>
  57. <view class="text_box">
  58. <trans class="title" _t="重量"></trans>
  59. <text>{{ item?.weight }}kg</text>
  60. </view>
  61. </view>
  62. <!-- <view class="card_footer">
  63. <up-collapse :border="false" :value="collapseValue">
  64. <up-collapse-item :name="item.seller_id" :border="false">
  65. <template #title>
  66. <view class="collapse_title">
  67. <trans _t="店铺总数" />:
  68. </view>
  69. </template>
  70. <template #value>
  71. <view class="collapse_value">
  72. <text>{{ symbol.symbol }} </text>
  73. <text class="item_num">{{ item.allAmt }}</text>
  74. </view>
  75. </template>
  76. <view class="card_footer_item" style="padding-top: 24rpx;">
  77. <view class="item_label">
  78. <trans _t="总价" />:
  79. </view>
  80. <view class="item_value">
  81. <text>{{ symbol.symbol }} </text>
  82. <text class="item_num">{{ item.allAmt }}</text>
  83. </view>
  84. </view>
  85. <view class="card_footer_item">
  86. <view class="item_label">
  87. <trans _t="运费到仓库" />:
  88. </view>
  89. <view class="item_value">
  90. <text>{{ symbol.symbol }}</text>
  91. <text class="item_num">{{ item.postAmt }}</text>
  92. </view>
  93. </view>
  94. <view class="card_footer_item">
  95. <view class="item_label">
  96. <trans _t="折扣" />:
  97. </view>
  98. <view class="item_value" style="color:var(--primary)">
  99. <text>-{{ symbol.symbol }}</text>
  100. <text class="item_num">{{ item.disAMt }}</text>
  101. </view>
  102. </view>
  103. </up-collapse-item>
  104. </up-collapse>
  105. </view> -->
  106. </view>
  107. </view>
  108. <view class="friendly_reminder">
  109. <trans class="reminder_title" _t="温馨提示" />
  110. <view class="reminder_desc">
  111. <trans _t="提示内容" />
  112. </view>
  113. </view>
  114. </view>
  115. <view class="footer">
  116. <view class="footer_confirm">
  117. <view class="total_info">
  118. <view class="price_num">
  119. <text>{{ symbol.symbol }}</text>
  120. <text class="num">{{ deatil.money }}</text>
  121. <i
  122. class="icon-font icon-question2 question-icon"
  123. @click="openpack"
  124. ></i>
  125. </view>
  126. </view>
  127. <view class="total_btn" @click="submit">
  128. <trans _t="提交" />
  129. </view>
  130. </view>
  131. </view>
  132. </view>
  133. </view>
  134. <successModel ref="successModels" />
  135. <packModel ref="packModelRef" :deatil="deatil" />
  136. </Theme>
  137. </template>
  138. <script setup>
  139. import Navbar from "@/components/navbar";
  140. import navMenu from "@/components/nav_menu";
  141. import Address from "@/components/address";
  142. import { onLoad } from "@dcloudio/uni-app";
  143. import popup from "@/components/popup";
  144. import { ref, nextTick, computed, watch, onMounted } from "vue";
  145. import { SHOP_PACKAGES_SUBMIT, SHOP_PACKAGES_CREATED } from "@/api";
  146. import { Toast } from "@/utils";
  147. import { useSystemStore, useTabbarStore, useShopStore } from "@/store";
  148. import Tip from "@/components/tooltip";
  149. import { t } from "@/locale";
  150. import logisticsList from "./components/logistics_list";
  151. import successModel from "./components/successModel";
  152. import packModel from "./components/packModel";
  153. import addressModel from "@/pages/address/components/addressModel";
  154. const packModelRef = ref(null);
  155. const successModels = ref(null);
  156. const popRef = ref(null);
  157. const addressRef = ref(null);
  158. const useSystem = useSystemStore();
  159. const useTabbar = useTabbarStore();
  160. const useShop = useShopStore();
  161. const symbol = computed(() => useSystem.getSymbol);
  162. const confirmId = ref("");
  163. const totalAmount = ref(0);
  164. const selectAllChecked = ref(false);
  165. const orderList = ref([]);
  166. const address_id = ref("");
  167. const couponId = ref("");
  168. const isPage = ref("");
  169. const tipShow = ref(false);
  170. const deatil = ref({});
  171. watch(selectAllChecked, (newVal) => {
  172. if (newVal) tipShow.value = false;
  173. });
  174. const logistics = computed(() => useShop.getLogistics);
  175. const islogistics = computed(() => Object.keys(logistics.value).length > 0);
  176. watch(
  177. () => logistics.value.id,
  178. (newId) => {
  179. if (newId && confirmId.value) {
  180. buyCart();
  181. }
  182. },
  183. { immediate: true }
  184. );
  185. const selectItem = ref(null);
  186. const addressConfirm = (item) => {
  187. selectItem.value = item;
  188. };
  189. const openpack = () => {
  190. packModelRef.value && packModelRef.value.open();
  191. };
  192. const submit = () => {
  193. // if (!selectAllChecked.value) return tipShow.value = true;
  194. if (!selectItem.value.id) return Toast(t("请先添加收件地址"));
  195. if (!logistics.value.id) return Toast(t("请选择物流路线"));
  196. shopConfirm();
  197. };
  198. const toLogistics = () => {
  199. uni.navigateTo({ url: "/pages/dashboard/logistics" });
  200. };
  201. onLoad((options) => {
  202. confirmId.value = options.ids;
  203. nextTick(() => {
  204. buyCart();
  205. });
  206. });
  207. const shopConfirm = async () => {
  208. try {
  209. const res = await SHOP_PACKAGES_CREATED({
  210. ids: confirmId.value,
  211. address_id: selectItem.value.id,
  212. couponId: couponId.value,
  213. templateId: logistics.value.id,
  214. });
  215. successModels.value && successModels.value.open(res.data.id);
  216. // uni.switchTab({ url: '/pages/order/index' });
  217. // useTabbar.getPageCur('order')
  218. // uni.navigateTo({ url: `/pages/shop/payment?oid=${res.data.id}&type=package&money=${logistics.value?.first_price}` })
  219. } catch (error) {
  220. Toast(error.msg);
  221. }
  222. };
  223. const buyCart = async () => {
  224. try {
  225. const res = await SHOP_PACKAGES_SUBMIT({
  226. ids: confirmId.value,
  227. templateId: logistics.value.id,
  228. });
  229. deatil.value = res.data || {};
  230. orderList.value = res.data.lists || [];
  231. } catch (error) {
  232. Toast(error.msg);
  233. }
  234. };
  235. onMounted(() => {
  236. nextTick(() => {
  237. useShop.setAddressList();
  238. });
  239. });
  240. </script>
  241. <style lang="less" scoped>
  242. @import url("@/style.less");
  243. .wrap {
  244. background-color: var(--bg);
  245. .flex();
  246. flex-direction: column;
  247. overflow: hidden;
  248. max-height: 100vh;
  249. .content {
  250. flex-grow: 1;
  251. height: calc(100vh - 44px);
  252. overflow: hidden scroll;
  253. .flex();
  254. flex-direction: column;
  255. .cont {
  256. padding: 0 24rpx 48rpx;
  257. flex-grow: 1;
  258. overflow: hidden scroll;
  259. .logistics {
  260. margin-top: 24rpx;
  261. border: var(--bor);
  262. border-radius: 16rpx;
  263. &_item {
  264. padding: 10rpx 20rpx;
  265. border: var(--bor);
  266. border-radius: 16rpx;
  267. color: var(--text-01);
  268. .logistics_empty {
  269. height: inherit;
  270. flex: 1;
  271. .flex_position(space-between);
  272. color: var(--text-01);
  273. line-height: 60rpx;
  274. .size(28rpx);
  275. .icon-left {
  276. .size(36rpx);
  277. transform: rotate(180deg);
  278. }
  279. }
  280. }
  281. }
  282. .card_wrapper {
  283. padding: 16rpx 0;
  284. background-color: var(--light);
  285. margin-top: 24rpx;
  286. border-radius: 16rpx;
  287. .card_item {
  288. &_wrapper {
  289. border-top: 1px solid var(--bg);
  290. padding: 0 32rpx;
  291. padding-top: 16rpx;
  292. .item_top {
  293. .flex();
  294. column-gap: 16rpx;
  295. padding-bottom: 16rpx;
  296. .item_left {
  297. width: 128rpx;
  298. height: 128rpx;
  299. .item_img {
  300. width: inherit;
  301. height: inherit;
  302. border-radius: 16rpx;
  303. }
  304. }
  305. .item_middle {
  306. flex: 1;
  307. .title {
  308. color: var(--text);
  309. .size(24rpx);
  310. line-height: 48rpx;
  311. font-weight: 700;
  312. .ellipsis(2);
  313. }
  314. .desc {
  315. color: var(--text-01);
  316. .size(24rpx);
  317. font-weight: 400;
  318. line-height: 40rpx;
  319. margin-top: 8rpx;
  320. }
  321. }
  322. .item_right {
  323. flex: 0 0 180rpx;
  324. text-align: right;
  325. .price {
  326. .size(24rpx);
  327. color: var(--text);
  328. font-weight: 700;
  329. line-height: 60rpx;
  330. }
  331. .total_num {
  332. color: #7d8fb3;
  333. .size(24rpx);
  334. font-weight: 400;
  335. line-height: 40rpx;
  336. }
  337. }
  338. }
  339. &:first-child {
  340. border-top: none;
  341. }
  342. .text_box {
  343. .flex_position(space-between, flex-end);
  344. margin: 8rpx 0;
  345. .size(24rpx);
  346. .title {
  347. color: var(--text-01);
  348. }
  349. .currency,
  350. .texts {
  351. color: var(--red);
  352. .size(28rpx);
  353. font-weight: 500;
  354. }
  355. .right_value {
  356. .flex();
  357. }
  358. }
  359. }
  360. .card_footer {
  361. /deep/ .u-collapse {
  362. .u-cell--clickable {
  363. background-color: transparent;
  364. }
  365. .u-cell__body {
  366. padding: 0 40rpx;
  367. height: 48rpx;
  368. margin-top: 4rpx;
  369. .u-cell__left-icon-wrap {
  370. margin-right: 0;
  371. }
  372. }
  373. // .u-collapse-item__content{
  374. // padding-top: 24rpx;
  375. // }
  376. .u-collapse-item__content__text {
  377. padding: 0 40rpx;
  378. }
  379. .uicon-arrow-right {
  380. color: var(--black) !important;
  381. .size() !important;
  382. font-weight: 700 !important;
  383. }
  384. }
  385. .collapse_title {
  386. .size(24rpx);
  387. color: var(--text);
  388. font-weight: 500;
  389. }
  390. .collapse_value {
  391. color: var(--primary);
  392. font-weight: 700;
  393. .size();
  394. .item_num {
  395. display: inline-block;
  396. margin-left: 8rpx;
  397. }
  398. }
  399. .card_footer_item {
  400. color: var(--text-01);
  401. .size(24rpx);
  402. height: 40rpx;
  403. .flex_position(space-between);
  404. box-sizing: content-box;
  405. .item_value {
  406. .item_num {
  407. // .blocked();
  408. display: inline-block;
  409. margin-left: 8rpx;
  410. }
  411. }
  412. }
  413. }
  414. }
  415. }
  416. .friendly_reminder {
  417. padding: 16rpx 24rpx 24rpx;
  418. background-color: var(--light);
  419. margin-top: 20rpx;
  420. border-radius: 16rpx;
  421. color: #346;
  422. .size(24rpx);
  423. min-height: 260rpx;
  424. .reminder_title {
  425. font-weight: 700;
  426. color: var(--text);
  427. .size(28rpx);
  428. line-height: 60rpx;
  429. }
  430. }
  431. }
  432. .footer {
  433. padding-bottom: constant(safe-area-inset-bottom);
  434. padding-bottom: env(safe-area-inset-bottom);
  435. &_protocol {
  436. background-color: #fff3ea;
  437. padding: 16rpx 24rpx;
  438. .protocol {
  439. .flex_position(flex-end);
  440. flex-wrap: wrap;
  441. &_item {
  442. text-wrap: nowrap;
  443. color: var(--primary);
  444. .size(24rpx);
  445. margin-left: 8rpx;
  446. }
  447. }
  448. .agreed_protocol {
  449. .flex_position(flex-end);
  450. height: 60rpx;
  451. .text {
  452. .size(28rpx);
  453. color: var(--primary);
  454. }
  455. }
  456. }
  457. &_confirm {
  458. background-color: var(--light);
  459. border-top: var(--bor);
  460. height: 120rpx;
  461. .flex_position(flex-end);
  462. padding: 0 24rpx;
  463. .total_info {
  464. .ver(flex-end);
  465. flex-direction: column;
  466. .price_num {
  467. .hor();
  468. color: var(--red);
  469. .size();
  470. font-weight: 700;
  471. line-height: 48rpx;
  472. .num {
  473. display: inline-block;
  474. margin-left: 8rpx;
  475. }
  476. .icon-question2 {
  477. color: var(--text-01);
  478. font-weight: 400;
  479. .size(40rpx);
  480. margin-left: 8rpx;
  481. }
  482. }
  483. .price_text {
  484. color: var(--text-01);
  485. .size(24rpx);
  486. line-height: 40rpx;
  487. }
  488. }
  489. .total_btn {
  490. background-color: var(--black);
  491. color: var(--light);
  492. height: 76rpx;
  493. .size(28rpx);
  494. font-weight: 700;
  495. min-width: 180rpx;
  496. margin-left: 24rpx;
  497. border-radius: 16rpx;
  498. .flex_center();
  499. padding: 16rpx 30rpx;
  500. }
  501. }
  502. }
  503. }
  504. }
  505. </style>