shopConfirm.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. <template>
  2. <Theme>
  3. <view class="wrap">
  4. <Navbar title="确认订单" fixed border autoBack @leftClick="leftClick">
  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
  13. class="card_wrapper"
  14. v-for="(item, index) in orderList"
  15. :key="index"
  16. >
  17. <view class="card_header">
  18. <!-- <view class="header_img">
  19. <image
  20. class="img"
  21. :src="`../../static/shop/icon_${item.channel}.png`"
  22. ></image>
  23. </view> -->
  24. <view class="header_name">{{ item.seller_name }}</view>
  25. </view>
  26. <view class="card_item">
  27. <view
  28. class="card_item_wrapper"
  29. v-for="(val, num) in item.goods"
  30. :key="num"
  31. >
  32. <view class="item_top">
  33. <view class="item_left">
  34. <image :src="val.picurl" class="item_img"></image>
  35. </view>
  36. <view class="item_middle">
  37. <view class="title">{{ val.goodsName }}</view>
  38. <view class="desc">{{ val.skudesc }}</view>
  39. </view>
  40. <view class="item_right">
  41. <view class="price">
  42. <text>{{ symbol.symbol }}</text>
  43. <text>{{ Moneyhtml(val.price) }}</text>
  44. </view>
  45. <view class="total_num">X {{ val.total }}</view>
  46. </view>
  47. </view>
  48. </view>
  49. <view class="card_footer">
  50. <up-collapse :border="false" :value="collapseValue">
  51. <up-collapse-item :name="item.seller_id" :border="false">
  52. <template #title>
  53. <view class="collapse_title">
  54. <trans _t="订单总价" />:
  55. </view>
  56. </template>
  57. <template #value>
  58. <view class="collapse_value">
  59. <text>{{ symbol.symbol }} </text>
  60. <text class="item_num">{{
  61. Moneyhtml(totalAmount)
  62. }}</text>
  63. </view>
  64. </template>
  65. <view class="card_footer_item" style="padding-top: 24rpx">
  66. <view class="item_label"> <trans _t="总价" />: </view>
  67. <view class="item_value item_red">
  68. <text>{{ symbol.symbol }} </text>
  69. <text class="item_num">{{
  70. Moneyhtml(item.allAmt)
  71. }}</text>
  72. </view>
  73. </view>
  74. <!-- <view class="card_footer_item">
  75. <view class="item_label">
  76. <trans _t="运费到仓库" />:
  77. </view>
  78. <view class="item_value">
  79. <text>{{ symbol.symbol }}</text>
  80. <text class="item_num">{{
  81. Moneyhtml(item.postAmt)
  82. }}</text>
  83. </view>
  84. </view>
  85. <view class="card_footer_item">
  86. <view class="item_label"> <trans _t="折扣" />: </view>
  87. <view class="item_value item_red">
  88. <text>-{{ symbol.symbol }}</text>
  89. <text class="item_num">{{
  90. Moneyhtml(item.disAMt)
  91. }}</text>
  92. </view>
  93. </view> -->
  94. </up-collapse-item>
  95. </up-collapse>
  96. </view>
  97. </view>
  98. </view>
  99. <!-- <view class="friendly_reminder">
  100. <trans class="reminder_title" _t="温馨提示" />
  101. <view class="reminder_desc">
  102. <trans _t="提示内容" />
  103. </view>
  104. </view> -->
  105. <!-- <couponModel
  106. :item="couponList"
  107. @change="changeId"
  108. isWidth
  109. style="margin-top: 24rpx"
  110. v-if="isFree == 0"
  111. /> -->
  112. </view>
  113. <view class="footer">
  114. <view class="footer_protocol">
  115. <view class="protocol">
  116. <view
  117. class="protocol_item"
  118. v-for="(item, index) in protocolList"
  119. :key="index"
  120. @click="openAgent(item)"
  121. >
  122. <trans :_t="item.text" />
  123. </view>
  124. </view>
  125. <view class="agreed_protocol">
  126. <view
  127. class="confirm_box"
  128. :class="lang == 'zh' ? 'zh_protocol' : ''"
  129. >
  130. <Tip title="请阅读并同意" :show="tipShow">
  131. <up-checkbox
  132. activeColor="var(--black)"
  133. labelSize="14"
  134. labelColor="#676969"
  135. iconSize="16"
  136. name="agree"
  137. usedAlone
  138. v-model:checked="selectAllChecked"
  139. class="right-check"
  140. >
  141. <template #label>
  142. <trans class="text" _t="我已阅读并同意" />
  143. </template>
  144. </up-checkbox>
  145. </Tip>
  146. </view>
  147. </view>
  148. </view>
  149. <view class="footer_confirm">
  150. <view class="total_info">
  151. <view class="price_num">
  152. <text class="price_text" v-if="postAmt > 0">
  153. (
  154. <trans _t="增值费用" />:
  155. <text class="amont_num"
  156. >{{ symbol.symbol }}{{ Moneyhtml(postAmt) }}</text
  157. >)
  158. </text>
  159. <text>{{ symbol.symbol }}</text>
  160. <text class="num">{{ Moneyhtml(totalAmount) }}</text>
  161. </view>
  162. <view class="price_text">
  163. <trans _t="总计不含国际运费" />
  164. </view>
  165. </view>
  166. <view class="total_btn" @click="submit">
  167. <trans _t="提交" />
  168. </view>
  169. </view>
  170. </view>
  171. </view>
  172. </view>
  173. <SimpleAgreementModal ref="agreementModal" />
  174. </Theme>
  175. </template>
  176. <script setup>
  177. import Navbar from "@/components/navbar";
  178. import navMenu from "@/components/nav_menu";
  179. import { onLoad } from "@dcloudio/uni-app";
  180. import { ref, nextTick, computed, watch } from "vue";
  181. import { SELLER_CART_CONFIRM, SELLER_ORDER_SUBMIT } from "@/api";
  182. import { Toast, Moneyhtml } from "@/utils";
  183. import { useSystemStore, useTabbarStore, useShopStore } from "@/store";
  184. import Tip from "@/components/tooltip";
  185. import SimpleAgreementModal from "@/components/simpleAgreementModal";
  186. import addressModel from "@/pages/address/components/addressModel";
  187. import { t } from "@/locale";
  188. const useSystem = useSystemStore();
  189. const useTabbar = useTabbarStore();
  190. const useShop = useShopStore();
  191. const symbol = computed(() => useSystem.getSymbol);
  192. const lang = computed(() => useSystem.getLang);
  193. const logistics = computed(() => useShop.getLogistics);
  194. const confirmId = ref("");
  195. const totalAmount = ref(0);
  196. const selectAllChecked = ref(false);
  197. const selectIsChecked = ref(false);
  198. const orderList = ref([]);
  199. const couponId = ref("");
  200. const isPage = ref("");
  201. const tipShow = ref(false);
  202. const qualityAmount = ref(0);
  203. const agreementModal = ref(null);
  204. const couponList = ref([]);
  205. const checkDate = ref(null);
  206. const postAmt = ref(0);
  207. const selectItem = ref(null);
  208. const valueAddedModel = ref(null);
  209. watch(selectAllChecked, (newVal) => {
  210. if (newVal) tipShow.value = false;
  211. });
  212. watch(selectIsChecked, (newVal) => {
  213. buyCart();
  214. });
  215. const protocolList = [
  216. {
  217. text: "违禁物品说明",
  218. type: "violation",
  219. },
  220. {
  221. text: "《服务条款》",
  222. type: "agree",
  223. },
  224. {
  225. text: "退货说明",
  226. type: "retreat",
  227. },
  228. {
  229. text: "免责声明",
  230. type: "disclaimer",
  231. },
  232. ];
  233. const addressConfirm = (item) => {
  234. selectItem.value = item;
  235. };
  236. const openAgent = (item) => {
  237. agreementModal.value && agreementModal.value.open(item.type);
  238. };
  239. const collapseValue = computed(() => {
  240. let arr = orderList.value.reduce((acc, item) => {
  241. acc.push(item.seller_id);
  242. return acc;
  243. }, []);
  244. return arr;
  245. });
  246. const calculateAll = (arr) => {
  247. let totalQuantity = arr.reduce((sum, item) => sum + item.total, 0);
  248. return totalQuantity;
  249. };
  250. const leftClick = () => {
  251. uni.navigateBack();
  252. // if (isPage.value == "order") {
  253. // uni.navigateBack();
  254. // } else {
  255. // uni.navigateTo({ url: "/pages/index/products?channel=1" });
  256. // }
  257. };
  258. const issubnum = ref(0);
  259. const submit = () => {
  260. if (issubnum.value == 0) {
  261. if (!selectItem.value.id) return Toast(t("请先添加收件地址"));
  262. if (!selectAllChecked.value) return (tipShow.value = true);
  263. shopConfirm();
  264. }
  265. };
  266. const getCoupon = async (money) => {
  267. try {
  268. const res = await SHOP_GET_SHOPCOUPON(money);
  269. couponList.value = res.data || [];
  270. } catch (error) {}
  271. };
  272. const changeId = (id, data) => {
  273. if (id) {
  274. couponId.value = id;
  275. checkDate.value = data;
  276. buyCart();
  277. } else {
  278. couponId.value = "";
  279. checkDate.value = null;
  280. }
  281. };
  282. onLoad((options) => {
  283. confirmId.value = options.comfirmId;
  284. isPage.value = options.page || "";
  285. nextTick(() => {
  286. buyCart();
  287. });
  288. });
  289. const shopConfirm = async () => {
  290. try {
  291. const res = await SELLER_ORDER_SUBMIT({
  292. cartids: confirmId.value,
  293. address_id: selectItem.value?.id,
  294. });
  295. uni.navigateTo({
  296. url: `/pages/shop/payment?oid=${res.data.sid}&type=sellerorder`,
  297. });
  298. } catch (error) {
  299. Toast(error.msg);
  300. }
  301. };
  302. const buyCart = async () => {
  303. try {
  304. const res = await SELLER_CART_CONFIRM({
  305. cartids: confirmId.value,
  306. });
  307. orderList.value = res.data.cartList || [];
  308. totalAmount.value = res.data.totalAmount || 0;
  309. postAmt.value = res.data.postAmt || 0;
  310. } catch (error) {
  311. Toast(error.msg);
  312. }
  313. };
  314. </script>
  315. <style lang="less" scoped>
  316. @import url("@/style.less");
  317. .uni-stat-tooltip {
  318. min-width: 400rpx;
  319. max-height: 400rpx;
  320. overflow: scroll;
  321. word-break: break-word;
  322. }
  323. .wrap {
  324. max-height: 100vh;
  325. .confirm_box {
  326. width: 100%;
  327. .hor(end);
  328. .confirm_item {
  329. .ver();
  330. }
  331. }
  332. .zh_protocol {
  333. // .flex_position(flex-end);
  334. // .right-check {
  335. // margin-left: 30rpx;
  336. // }
  337. }
  338. background-color: var(--bg);
  339. .flex();
  340. flex-direction: column;
  341. overflow: hidden;
  342. .content {
  343. flex-grow: 1;
  344. height: calc(100vh - 44px);
  345. overflow: hidden scroll;
  346. .flex();
  347. flex-direction: column;
  348. .cont {
  349. padding: 0 24rpx 48rpx;
  350. flex-grow: 1;
  351. overflow: hidden scroll;
  352. .card_wrapper {
  353. padding: 16rpx 0;
  354. background-color: var(--light);
  355. margin-top: 24rpx;
  356. border-radius: 16rpx;
  357. .card_header {
  358. .ver();
  359. padding: 0 32rpx;
  360. .header_img {
  361. width: 48rpx;
  362. height: 48rpx;
  363. .img {
  364. width: inherit;
  365. height: inherit;
  366. }
  367. }
  368. .header_name {
  369. margin-left: 16rpx;
  370. font-weight: 700;
  371. .size(28rpx);
  372. color: var(--text);
  373. }
  374. }
  375. .card_item {
  376. &_wrapper {
  377. padding: 0 32rpx;
  378. padding-top: 16rpx;
  379. .item_top {
  380. .flex();
  381. column-gap: 16rpx;
  382. padding-bottom: 16rpx;
  383. .item_left {
  384. width: 128rpx;
  385. height: 128rpx;
  386. .item_img {
  387. width: inherit;
  388. height: inherit;
  389. border-radius: 16rpx;
  390. }
  391. }
  392. .item_middle {
  393. flex: 1;
  394. .title {
  395. color: var(--text);
  396. .size(24rpx);
  397. line-height: 48rpx;
  398. font-weight: 700;
  399. .ellipsis(2);
  400. }
  401. .desc {
  402. color: var(--text-01);
  403. .size(24rpx);
  404. font-weight: 400;
  405. line-height: 40rpx;
  406. margin-top: 8rpx;
  407. }
  408. }
  409. .item_right {
  410. flex: 0 0 180rpx;
  411. text-align: right;
  412. .price {
  413. .size(24rpx);
  414. color: var(--red);
  415. font-weight: 700;
  416. line-height: 60rpx;
  417. }
  418. .total_num {
  419. color: #7d8fb3;
  420. .size(24rpx);
  421. font-weight: 400;
  422. line-height: 40rpx;
  423. }
  424. }
  425. }
  426. }
  427. .card_footer {
  428. border-top: 1px solid var(--bg);
  429. /deep/ .u-collapse {
  430. .u-cell--clickable {
  431. background-color: transparent;
  432. }
  433. .u-cell__body {
  434. padding: 0 40rpx;
  435. height: 48rpx;
  436. margin-top: 4rpx;
  437. .u-cell__left-icon-wrap {
  438. margin-right: 0;
  439. }
  440. }
  441. // .u-collapse-item__content{
  442. // padding-top: 24rpx;
  443. // }
  444. .u-collapse-item__content__text {
  445. padding: 0 40rpx;
  446. }
  447. .uicon-arrow-right {
  448. color: var(--black) !important;
  449. .size() !important;
  450. font-weight: 700 !important;
  451. }
  452. }
  453. .collapse_title {
  454. .size(24rpx);
  455. color: var(--text);
  456. font-weight: 500;
  457. }
  458. .collapse_value {
  459. color: var(--red);
  460. font-weight: 700;
  461. .size();
  462. .item_num {
  463. display: inline-block;
  464. margin-left: 8rpx;
  465. }
  466. }
  467. .card_footer_item {
  468. color: var(--text-01);
  469. .size(24rpx);
  470. height: 40rpx;
  471. .flex_position(space-between);
  472. box-sizing: content-box;
  473. .item_value {
  474. &.item_red {
  475. color: var(--red);
  476. }
  477. .item_num {
  478. // .blocked();
  479. display: inline-block;
  480. margin-left: 8rpx;
  481. }
  482. }
  483. }
  484. }
  485. }
  486. }
  487. .friendly_reminder {
  488. padding: 16rpx 24rpx 24rpx;
  489. background-color: var(--light);
  490. margin-top: 20rpx;
  491. border-radius: 16rpx;
  492. color: #346;
  493. .size(24rpx);
  494. min-height: 260rpx;
  495. .reminder_title {
  496. font-weight: 700;
  497. color: var(--text);
  498. .size(28rpx);
  499. line-height: 60rpx;
  500. }
  501. }
  502. .add_on_box {
  503. width: 100%;
  504. padding: 16rpx 24rpx;
  505. background-color: var(--bg-primary);
  506. border-radius: 16rpx;
  507. .title {
  508. color: var(--text);
  509. .size(28rpx);
  510. font-weight: 700;
  511. line-height: 60rpx;
  512. .title-tips {
  513. margin: 0 12rpx;
  514. padding: 2rpx 6rpx;
  515. color: #fff;
  516. .size(24rpx);
  517. background-color: red;
  518. border-radius: 8rpx;
  519. }
  520. }
  521. .add_on_content {
  522. .hor(space-between);
  523. flex-wrap: wrap;
  524. .checkbox-row {
  525. .ver();
  526. }
  527. .question-icon {
  528. margin-left: 8rpx;
  529. font-size: 32rpx;
  530. }
  531. }
  532. }
  533. }
  534. .footer {
  535. padding-bottom: env(safe-area-inset-bottom);
  536. padding-bottom: constant(safe-area-inset-bottom);
  537. box-sizing: border-box;
  538. &_protocol {
  539. background-color: #fff3ea;
  540. padding: 16rpx 24rpx;
  541. .protocol {
  542. .flex_position(flex-end);
  543. flex-wrap: wrap;
  544. &_item {
  545. text-wrap: nowrap;
  546. color: var(--black);
  547. .size(24rpx);
  548. margin-left: 8rpx;
  549. }
  550. }
  551. .agreed_protocol {
  552. // .flex_position(flex-end);
  553. // height: 60rpx;
  554. .text {
  555. .size(28rpx);
  556. color: var(--black);
  557. }
  558. }
  559. }
  560. &_confirm {
  561. background-color: var(--light);
  562. border-top: var(--bor);
  563. height: 120rpx;
  564. .flex_position(flex-end);
  565. padding: 0 24rpx;
  566. .total_info {
  567. .ver(flex-end);
  568. flex-direction: column;
  569. .price_num {
  570. color: var(--red);
  571. .size();
  572. font-weight: 700;
  573. line-height: 48rpx;
  574. .num {
  575. display: inline-block;
  576. margin-left: 8rpx;
  577. }
  578. .icon-question2 {
  579. color: var(--text-01);
  580. font-weight: 400;
  581. .size(40rpx);
  582. margin-left: 8rpx;
  583. }
  584. }
  585. .price_text {
  586. color: var(--text-01);
  587. .size(24rpx);
  588. line-height: 40rpx;
  589. .amont_num {
  590. color: var(--red);
  591. }
  592. }
  593. }
  594. .total_btn {
  595. background-color: var(--black);
  596. color: var(--light);
  597. height: 76rpx;
  598. .size(28rpx);
  599. font-weight: 700;
  600. min-width: 180rpx;
  601. margin-left: 24rpx;
  602. border-radius: 16rpx;
  603. .flex_center();
  604. padding: 16rpx 30rpx;
  605. }
  606. }
  607. }
  608. }
  609. }
  610. </style>