index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. <template>
  2. <Theme>
  3. <view class="wrap">
  4. <Navbar fixed border :navShow="navShow" title="我的订单"> </Navbar>
  5. <view class="content1">
  6. <view class="cont_tab">
  7. <up-tabs
  8. :key="tabActive"
  9. :current="tabActive"
  10. :list="tabList"
  11. keyName="text"
  12. @click="tabConfirm"
  13. lineColor="var(--black)"
  14. :activeStyle="{
  15. color: 'var(--black)',
  16. fontWeight: 'bold',
  17. transform: 'scale(1.05)',
  18. }"
  19. :inactiveStyle="{
  20. color: '#606266',
  21. transform: 'scale(1)',
  22. }"
  23. >
  24. </up-tabs>
  25. </view>
  26. <view
  27. class="cont"
  28. :style="{ '--height': footerHeight + tabbarHeight + 'px' }"
  29. >
  30. <List
  31. url="/seller/order/lists"
  32. :topHeight="tabHeight"
  33. :defaultParams="{ keywords: searchValue, ...params }"
  34. ref="listRef"
  35. @datas="getAllData"
  36. >
  37. <template #item="{ item }">
  38. <view class="order_list">
  39. <view class="order_header">
  40. <template v-if="tabActive == 1 && navShow">
  41. <up-checkbox-group
  42. :modelValue="ids"
  43. activeColor="var(--black)"
  44. labelSize="14"
  45. labelColor="#676969"
  46. iconSize="16"
  47. @change="checkedChanges(item.id)"
  48. >
  49. <up-checkbox :name="item.id" />
  50. </up-checkbox-group>
  51. </template>
  52. <view class="create_time">
  53. <trans _t="创建时间" />:
  54. {{ useGlobal().$format(item.indate) }}
  55. </view>
  56. </view>
  57. <view class="order_item">
  58. <view
  59. class="order_item_wrapper"
  60. v-for="(val, num) in item.goods"
  61. :key="num"
  62. @click="listClick(item)"
  63. >
  64. <view class="_item_wrapper">
  65. <view class="thumb_img">
  66. <image :src="val.pic_url" class="_img"></image>
  67. </view>
  68. <view class="goods_info">
  69. <view class="info_name">
  70. <view class="_name">{{ val.goodTitle }}</view>
  71. <view class="_price"
  72. >{{ symbol.symbol }}&nbsp;{{
  73. Moneyhtml(val.price)
  74. }}</view
  75. >
  76. </view>
  77. <view class="spec_info">
  78. <view class="spec_desc">{{ val.sku_desc }}</view>
  79. <view class="spec_num">x{{ val.total }}</view>
  80. </view>
  81. </view>
  82. </view>
  83. <view class="order_status">
  84. <text>{{ item.status_txt }}&nbsp;</text>
  85. <!-- <i class="icon-font icon-question2"></i> -->
  86. </view>
  87. </view>
  88. <view class="order_footer">
  89. <view class="order_price">
  90. <view class="price_text"> <trans _t="总价" />: </view>
  91. <text
  92. >{{ symbol.symbol }}{{ Moneyhtml(item.amount) }}</text
  93. >
  94. <!-- <i class="icon-font icon-question2"></i> -->
  95. </view>
  96. <!-- <view class="end_time" v-if="item.payStatus == 100">
  97. <trans _t="结束时间" />:
  98. {{ useGlobal().$format(item.enddate) }}
  99. </view> -->
  100. <view class="order_btns" v-if="item.status == 900">
  101. <view class="btn">
  102. <trans _t="删除订单" />
  103. </view>
  104. </view>
  105. <view class="order_btns" v-if="item.status == 100">
  106. <view class="btn" @click="orderCancel(item)">
  107. <trans _t="取消" />
  108. </view>
  109. <view class="btn pay_btn" @click="paySubmit(item)">
  110. <trans _t="支付" />
  111. </view>
  112. </view>
  113. </view>
  114. </view>
  115. </view>
  116. </template>
  117. </List>
  118. </view>
  119. <view
  120. class="cont_footer"
  121. id="footer"
  122. v-if="tabActive == 1 && navShow"
  123. :style="{ '--tabbarHeight': tabbarHeight + 'px' }"
  124. >
  125. <up-checkbox
  126. :label="t('全选')"
  127. :disabled="!allId.length"
  128. activeColor="var(--black)"
  129. labelSize="14"
  130. labelColor="#676969"
  131. iconSize="16"
  132. name="agree"
  133. usedAlone
  134. v-model:checked="selectAllChecked"
  135. @change="selectAllChange"
  136. >
  137. </up-checkbox>
  138. <view
  139. class="total_btn"
  140. @click.stop="submit"
  141. :style="{ opacity: ids.length ? 1 : 0.5 }"
  142. >
  143. <trans _t="合并付款" />
  144. </view>
  145. </view>
  146. </view>
  147. </view>
  148. <cancelModel ref="cancelModelRef" isBuyer />
  149. </Theme>
  150. </template>
  151. <script setup>
  152. import Navbar from "@/components/navbar";
  153. import navMenu from "@/components/nav_menu";
  154. import navFilter from "@/components/nav_filter";
  155. import Search from "@/components/input";
  156. import Tab from "@/components/tabs";
  157. import List from "@/components/list";
  158. import cancelModel from "@/pages/dashboard/components/cancelModel.vue";
  159. import { ref, onMounted, nextTick, computed, watch, watchEffect } from "vue";
  160. import { t } from "@/locale";
  161. import { useGlobal, Toast, Moneyhtml, query } from "@/utils";
  162. import { useSystemStore, useShopStore } from "@/store";
  163. import { SELLER_ORDER_GETPAY } from "@/api";
  164. import { onShow, onReachBottom, onLoad } from "@dcloudio/uni-app";
  165. const props = defineProps({
  166. tabHeight: {
  167. type: Number,
  168. default: 0,
  169. },
  170. tabbarHeight: {
  171. type: Number,
  172. default: 0,
  173. },
  174. tabParams: {
  175. type: Object,
  176. },
  177. navShow: Boolean,
  178. });
  179. const useSystem = useSystemStore();
  180. const useShop = useShopStore();
  181. const searchValue = ref("");
  182. const tabActive = ref(0);
  183. const footerHeight = ref(0);
  184. const listRef = ref(null);
  185. const tabList = ref([]);
  186. watchEffect(() => {
  187. tabList.value = [
  188. { text: t("全部"), status: 0 },
  189. { text: t("待付款"), status: 100 },
  190. ];
  191. });
  192. const params = ref({
  193. status: 0,
  194. });
  195. const symbol = computed(() => useSystem.getSymbol);
  196. const selectAllChecked = ref(false);
  197. const allId = ref([]);
  198. const ids = ref([]);
  199. watch(
  200. () => props.tabParams,
  201. (newVal) => {
  202. if (newVal && newVal.tab == 0) {
  203. tabActive.value = newVal.type;
  204. params.value.status = newVal.status;
  205. useShop.setTabParams(null);
  206. nextTick(() => {
  207. listRef.value?.handleRefresh();
  208. getHeight();
  209. });
  210. }
  211. },
  212. { immediate: true }
  213. );
  214. const searchConfirm = () => {
  215. nextTick(() => {
  216. listRef.value && listRef.value.handleRefresh();
  217. });
  218. };
  219. const getAllData = (list) => {
  220. if (tabActive.value == 0) return;
  221. if (!list.length) return (selectAllChecked.value = false);
  222. allId.value = list.reduce((acc, item) => {
  223. acc.push(item.id);
  224. return acc;
  225. }, []);
  226. };
  227. const checkedChanges = (id) => {
  228. let arr = JSON.parse(JSON.stringify(ids.value));
  229. let findIndex = ids.value.findIndex((item) => item == id);
  230. if (findIndex != -1) {
  231. arr = arr.filter((item) => item != id);
  232. } else {
  233. arr.push(id);
  234. }
  235. ids.value = arr;
  236. let flag = allId.value.every((value) => arr.includes(value));
  237. selectAllChecked.value = flag;
  238. };
  239. const selectAllChange = (e) => {
  240. selectAllChecked.value = e;
  241. ids.value = e ? allId.value : [];
  242. };
  243. const paySubmit = (item) => {
  244. ids.value = [item.id];
  245. nextTick(() => {
  246. shopConfirm();
  247. });
  248. };
  249. const cancelModelRef = ref(null);
  250. const orderCancel = (item) => {
  251. cancelModelRef.value && cancelModelRef.value.open(item.id);
  252. };
  253. const listClick = (item) => {
  254. uni.navigateTo({ url: `/pagesBuyer/order/details?orderid=${item.id}` });
  255. };
  256. const submit = () => {
  257. if (!ids.value.length) return;
  258. shopConfirm();
  259. };
  260. const tabConfirm = (item, index) => {
  261. if (!item) return;
  262. tabActive.value = index;
  263. params.value.status = item.status;
  264. nextTick(() => {
  265. listRef.value && listRef.value.handleRefresh();
  266. });
  267. };
  268. const filterSubmit = (obj) => {
  269. params.value = obj;
  270. nextTick(() => {
  271. listRef.value && listRef.value.handleRefresh();
  272. });
  273. };
  274. const shopConfirm = async () => {
  275. try {
  276. const res = await SELLER_ORDER_GETPAY(ids.value.join(","));
  277. uni.navigateTo({
  278. url: `/pages/shop/payment?oid=${res.data.sid}&page=order&type=sellerorder`,
  279. });
  280. ids.value = [];
  281. selectAllChecked.value = false;
  282. } catch (error) {
  283. Toast(error.msg);
  284. }
  285. };
  286. const getHeight = async () => {
  287. try {
  288. const res = await query("#footer");
  289. nextTick(() => {
  290. footerHeight.value = res.height;
  291. });
  292. } catch (error) {}
  293. };
  294. onLoad((options) => {
  295. params.value.status = options.status || 0;
  296. });
  297. onShow(() => {
  298. nextTick(() => {
  299. listRef.value && listRef.value.getData();
  300. });
  301. });
  302. onReachBottom(() => {
  303. nextTick(() => {
  304. listRef.value && listRef.value.scrolltolower();
  305. });
  306. });
  307. </script>
  308. <style lang="less" scoped>
  309. @import url("@/style.less");
  310. .wrap {
  311. max-height: calc(100vh - 44rpx);
  312. background-color: var(--bg);
  313. .nav_search {
  314. .icon-search {
  315. color: #a8abb2;
  316. .size(28px);
  317. }
  318. }
  319. .content1 {
  320. flex-grow: 1;
  321. flex-direction: column;
  322. .flex();
  323. // height: calc(100vh - 44px - var(--height));
  324. .cont_tab {
  325. background-color: var(--light);
  326. padding: 0 48rpx;
  327. :deep(.tab) {
  328. .active {
  329. color: var(--text) !important;
  330. &::before {
  331. background-color: var(--text) !important;
  332. }
  333. }
  334. }
  335. }
  336. .cont {
  337. flex-grow: 1;
  338. overflow: hidden scroll;
  339. padding: 0 24rpx var(--height);
  340. .order_list {
  341. margin-top: 24rpx;
  342. padding: 16rpx 24rpx;
  343. background-color: var(--light);
  344. border-radius: 16rpx;
  345. .order_header {
  346. .ver();
  347. margin-bottom: 16rpx;
  348. .header_img {
  349. width: 48rpx;
  350. height: 48rpx;
  351. .img {
  352. width: inherit;
  353. height: inherit;
  354. border-radius: 8rpx;
  355. }
  356. }
  357. .create_time {
  358. .size(24rpx);
  359. color: var(--text);
  360. font-weight: 700;
  361. text {
  362. font-weight: 500;
  363. }
  364. }
  365. }
  366. .order_item {
  367. &_wrapper {
  368. margin-top: 16rpx;
  369. ._item_wrapper {
  370. .flex();
  371. .thumb_img {
  372. width: 140rpx;
  373. height: 140rpx;
  374. ._img {
  375. width: inherit;
  376. height: inherit;
  377. border-radius: 16rpx;
  378. }
  379. }
  380. .goods_info {
  381. margin-left: 16rpx;
  382. flex: 1;
  383. .info_name {
  384. color: var(--text);
  385. .size(24rpx);
  386. font-weight: 700;
  387. line-height: 44rpx;
  388. .ver();
  389. ._name {
  390. flex: 1;
  391. .ellipsis();
  392. margin-right: 8rpx;
  393. }
  394. }
  395. .spec_info {
  396. .flex();
  397. flex: 1;
  398. margin-top: 8rpx;
  399. color: var(--text-01);
  400. .size(24rpx);
  401. line-height: 40rpx;
  402. .spec_desc {
  403. flex: 1;
  404. margin-right: 8rpx;
  405. }
  406. }
  407. .no_return {
  408. border: var(--danger-bor);
  409. border-radius: 40rpx;
  410. color: var(--danger);
  411. cursor: pointer;
  412. .size(24rpx);
  413. line-height: 40rpx;
  414. margin-top: 16rpx;
  415. padding: 0 24rpx;
  416. width: max-content;
  417. }
  418. }
  419. }
  420. .order_status {
  421. color: var(--primary);
  422. .size(24rpx);
  423. height: 40rpx;
  424. .flex_position(flex-end);
  425. margin-top: 16rpx;
  426. .icon-question2 {
  427. .size(36rpx);
  428. }
  429. }
  430. .order-cancel {
  431. margin-top: 16rpx;
  432. color: var(--text-01);
  433. .size(24rpx);
  434. line-height: 40rpx;
  435. .time {
  436. color: var(--danger);
  437. font-weight: 700;
  438. }
  439. .content {
  440. margin-top: 8rpx;
  441. color: var(--text);
  442. font-weight: 500;
  443. }
  444. }
  445. }
  446. .order_footer {
  447. margin-top: 16rpx;
  448. border-top: 1px solid #f5f6f7;
  449. .order_price {
  450. padding-top: 16rpx;
  451. .flex_position(flex-end);
  452. color: var(--primary);
  453. color: var(--red);
  454. .size();
  455. font-weight: 700;
  456. height: 48rpx;
  457. line-height: 1;
  458. .price_text {
  459. color: var(--text);
  460. .size(24rpx);
  461. font-weight: 400;
  462. }
  463. .icon-question2 {
  464. font-weight: 400;
  465. color: var(--text-01);
  466. margin-left: 8rpx;
  467. }
  468. }
  469. .end_time {
  470. .flex_position(flex-end);
  471. margin-top: 16rpx;
  472. color: #e62e2e;
  473. font-weight: 700;
  474. .size(24rpx);
  475. text {
  476. font-weight: 400;
  477. }
  478. }
  479. .order_btns {
  480. .flex_position(flex-end);
  481. margin-top: 16rpx;
  482. gap: 16rpx;
  483. .btn {
  484. .flex_center();
  485. border-radius: 16rpx;
  486. padding: 0 30rpx;
  487. .size(24rpx);
  488. height: 48rpx;
  489. border: 1px solid var(--black);
  490. background-color: var(--light);
  491. color: var(--black);
  492. }
  493. .pay_btn {
  494. color: var(--light);
  495. background-color: var(--black);
  496. }
  497. }
  498. }
  499. }
  500. }
  501. }
  502. .cont_footer {
  503. position: fixed;
  504. bottom: var(--tabbarHeight);
  505. left: 0;
  506. right: 0;
  507. line-height: 100rpx;
  508. background-color: var(--light);
  509. box-shadow: 0 -4px 6px #0000000d;
  510. padding: 0 24rpx;
  511. .flex_position(space-between);
  512. .total_btn {
  513. .size(24rpx);
  514. height: 38px;
  515. margin-left: 16rpx;
  516. min-width: 180rpx;
  517. background-color: var(--primary);
  518. background-color: var(--black);
  519. color: var(--light);
  520. border-radius: 16rpx;
  521. padding: 16rpx 30rpx;
  522. text-align: center;
  523. .flex_center();
  524. margin-left: 24rpx;
  525. }
  526. }
  527. }
  528. }
  529. </style>