Răsfoiți Sursa

feat: 回收订单静态开发

liangan 1 lună în urmă
părinte
comite
9b7a19bf25

+ 1 - 1
src/components/DialogBox/DialogBox.vue

@@ -93,7 +93,7 @@ function handleCancel() {
 </script>
 
 <template>
-  <wd-overlay :show="props.show" @click="handleOverlayClick">
+  <wd-overlay :show="props.show" :z-index="999" @click="handleOverlayClick">
     <view class="wrapper">
       <view class="w-full rounded-24rpx bg-white p-40rpx text-center" @click.stop>
         <slot>

+ 12 - 0
src/locale/bn.json

@@ -36,6 +36,18 @@
   "myOrders.order.id": "অর্ডার আইডি",
   "myOrders.order.color": "রং",
   "myOrders.order.quantity": "পরিমাণ",
+  "myOrders.selectTip": "আপনি পুনর্ব্যবহারের জন্য {0}টি অর্ডার বেছে নিতে পারেন",
+  "myOrders.total": "মোট",
+  "myOrders.recycleOrder": "অর্ডার পুনর্ব্যবহার করুন",
+  "myOrders.recycleSuccess": "অর্ডার সফলভাবে পুনর্ব্যবহার করা হয়েছে",
+  "myOrders.recycleFailed": "অর্ডার পুনর্ব্যবহার করতে ব্যর্থ",
+  "myOrders.dialog.title": "অর্ডার বিক্রয় করুন",
+  "myOrders.dialog.notesTitle": "নোট:",
+  "myOrders.dialog.note1": "① আপনি BandhuBuy কে গ্রুপ অর্ডারের আইটেমগুলি বিক্রয় করতে বেছে নিতে পারেন।",
+  "myOrders.dialog.note2": "② বিক্রয় মূল্য পণ্যের 100%।",
+  "myOrders.dialog.note3": "③ পুনরুদ্ধার করা পরিমাণ আপনার আয় অ্যাকাউন্টে বিতরণ করা হবে।",
+  "myOrders.dialog.priceLabel": "বিক্রয় মূল্য",
+  "myOrders.dialog.confirm": "নিশ্চিত করুন",
   "orderDetail.title": "অর্ডারের বিস্তারিত",
   "orderDetail.loading": "লোড হচ্ছে...",
   "orderDetail.congrats": "অভিনন্দন, আপনি এই গ্রুপে পুরস্কার জিতেছেন!",

+ 12 - 0
src/locale/en.json

@@ -36,6 +36,18 @@
   "myOrders.order.id": "Order ID",
   "myOrders.order.color": "Color",
   "myOrders.order.quantity": "Quantity",
+  "myOrders.selectTip": "You can choose {0} orders for recycling",
+  "myOrders.total": "Total",
+  "myOrders.recycleOrder": "Recycle Order",
+  "myOrders.recycleSuccess": "Order recycled successfully",
+  "myOrders.recycleFailed": "Failed to recycle order",
+  "myOrders.dialog.title": "Sell Back Order",
+  "myOrders.dialog.notesTitle": "Notes:",
+  "myOrders.dialog.note1": "① You can choose to have BandhuBuy sell back the items in the group order.",
+  "myOrders.dialog.note2": "② The sell back price is 100% of the product.",
+  "myOrders.dialog.note3": "③ The recovered amount will be distributed to your earnings account.",
+  "myOrders.dialog.priceLabel": "Sell Back Price",
+  "myOrders.dialog.confirm": "Confirm",
   "orderDetail.title": "Order Detail",
   "orderDetail.loading": "Loading...",
   "orderDetail.congrats": "Congrats, You won the prize in this group!",

+ 12 - 0
src/locale/zh-Hans.json

@@ -36,6 +36,18 @@
   "myOrders.order.id": "订单号",
   "myOrders.order.color": "颜色",
   "myOrders.order.quantity": "数量",
+  "myOrders.selectTip": "您可以选择 {0} 个订单进行回收",
+  "myOrders.total": "总计",
+  "myOrders.recycleOrder": "回收订单",
+  "myOrders.recycleSuccess": "订单回收成功",
+  "myOrders.recycleFailed": "订单回收失败",
+  "myOrders.dialog.title": "回售订单",
+  "myOrders.dialog.notesTitle": "注意事项:",
+  "myOrders.dialog.note1": "① 您可以选择让 BandhuBuy 回售团购订单中的商品。",
+  "myOrders.dialog.note2": "② 回售价格为商品价格的 100%。",
+  "myOrders.dialog.note3": "③ 回收金额将分配到您的收益账户。",
+  "myOrders.dialog.priceLabel": "回售价格",
+  "myOrders.dialog.confirm": "确认",
   "orderDetail.title": "订单详情",
   "orderDetail.loading": "加载中...",
   "orderDetail.congrats": "恭喜,您在这个团中中奖了!",

+ 155 - 3
src/pages/myOrders/myOrders.vue

@@ -14,9 +14,11 @@
 import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
 import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
 import { orderList, orderStatusEnum } from '@/api/order'
+import { DialogBox } from '@/components/DialogBox'
 import { t } from '@/locale'
 import { formatNumber } from '@/utils'
 import { toPage } from '@/utils/page'
+import { toast } from '@/utils/toast'
 
 defineOptions({
   name: 'MyOrders', // 我的订单
@@ -27,6 +29,7 @@ const paging = ref(null)
 // 类似mixins,如果是页面滚动务必要写这一行,并传入当前ref绑定的paging,注意此处是paging,而非paging.value
 useZPaging(paging)
 const isPageLoading = ref(true) // 页面加载状态
+const systemInfo = ref(uni.getSystemInfoSync()) // 获取系统信息
 const tab = ref<number>(0)
 const tabList = ref<any>([
   {
@@ -65,6 +68,87 @@ async function getOrderStatus() {
 
 // 搜索结果
 const dataList = ref<any[]>([])
+
+// TODO: 后期从接口获取最大可选订单数量
+const maxSelectCount = ref<number>(5) // 最大可选订单数量
+const selectedOrders = ref<string[]>([]) // 已选中的订单ID列表
+
+// 判断订单是否已选中
+function isOrderSelected(orderId: string) {
+  return selectedOrders.value.includes(orderId)
+}
+
+// 判断订单是否可以勾选(未选中且未达到上限,或已选中)
+function canSelectOrder(orderId: string) {
+  return isOrderSelected(orderId) || selectedOrders.value.length < maxSelectCount.value
+}
+
+// 切换订单选中状态
+function toggleOrderSelection(orderId: string) {
+  const index = selectedOrders.value.indexOf(orderId)
+  if (index > -1) {
+    // 已选中,取消选中
+    selectedOrders.value.splice(index, 1)
+  }
+  else if (selectedOrders.value.length < maxSelectCount.value) {
+    // 未选中且未达到上限,添加选中
+    selectedOrders.value.push(orderId)
+  }
+}
+
+// 切换tab时清空选中状态
+function handleTabChange() {
+  selectedOrders.value = []
+  queryList(1, 20)
+}
+
+// 计算选中订单的总金额
+const totalAmount = computed(() => {
+  if (selectedOrders.value.length === 0)
+    return 0
+  return dataList.value
+    .filter(item => selectedOrders.value.includes(item.orderId))
+    .reduce((sum, item) => {
+      const price = Number(item?.orderInfoVO?.[0]?.price) || 0
+      const quantity = Number(item?.orderInfoVO?.[0]?.payNum) || 0
+      return sum + (price * quantity)
+    }, 0)
+})
+
+// 弹框状态
+const showRecycleDialog = ref(false)
+
+// 点击 Recycle Order 按钮,显示二次确认弹框
+function handleRecycleOrder() {
+  showRecycleDialog.value = true
+}
+
+// 确认回收订单
+async function confirmRecycle() {
+  try {
+    // TODO: 后续调用回收订单的接口
+    console.log('选中的订单ID:', selectedOrders.value)
+    console.log('总金额:', totalAmount.value)
+
+    // 模拟接口调用
+    // const res = await recycleOrderApi({ orderIds: selectedOrders.value })
+    // if (res.code === '200') {
+    //   toast.success(t('myOrders.recycleSuccess'))
+    //   selectedOrders.value = []
+    //   queryList(1, 20) // 刷新列表
+    // }
+
+    // 临时模拟成功
+    toast.success(t('myOrders.recycleSuccess'))
+    selectedOrders.value = []
+    // 刷新列表
+    paging.value?.reload()
+  }
+  catch (error) {
+    console.error('回收订单失败:', error)
+    toast.error(t('myOrders.recycleFailed'))
+  }
+}
 async function queryList(pageNo: number, pageSize: number) {
   // 此处请求仅为演示,请替换为自己项目中的请求
   try {
@@ -109,7 +193,7 @@ onLoad((options) => {
 <template>
   <z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
     <template #top>
-      <wd-tabs v-model="tab" :auto-line-width="true" custom-class="bg-transparent!" slidable="always" @click="() => queryList(1, 20)">
+      <wd-tabs v-model="tab" :auto-line-width="true" custom-class="bg-transparent!" slidable="always" @click="handleTabChange">
         <wd-tab v-for="tabItem in tabList" :key="tabItem.value" :title="t(tabItem.label)" :name="tabItem.value" />
       </wd-tabs>
     </template>
@@ -149,12 +233,26 @@ onLoad((options) => {
 
     <!-- 实际内容 -->
     <template v-else>
+      <!-- Success tab 选择提示 -->
+      <view v-if="tab === 2" class="pt-24rpx text-center font-bold">
+        {{ t('myOrders.selectTip', [maxSelectCount]) }}
+      </view>
       <view class="pt-24rpx">
         <wd-card v-for="item in dataList" :key="item.orderId" type="rectangle" custom-class="px-24rpx! py-6rpx!" custom-content-class="py-18rpx!" custom-title-class="py-18rpx!" @click="toPage({ url: '/pages/myOrders/orderDetail', params: { orderNo: item?.orderId } })">
           <template #title>
             <view class="flex items-center justify-between">
-              <view class="text-28rpx text-#000">
-                {{ t('myOrders.order.id') }}:{{ item.orderId }}
+              <view class="flex items-center text-28rpx text-#000">
+                <!-- 仅在 success tab (tab=2) 时显示勾选框 -->
+                <wd-checkbox
+                  v-if="tab === 2"
+                  :model-value="isOrderSelected(item.orderId)"
+                  :disabled="!canSelectOrder(item.orderId)"
+                  custom-class="mr-16rpx"
+                  @click.stop="toggleOrderSelection(item.orderId)"
+                />
+                <view>
+                  {{ t('myOrders.order.id') }}:{{ item.orderId }}
+                </view>
               </view>
               <wd-text size="26rpx" type="primary" :text="orderStatusEnumData.find((i:any) => i.code === item.status)?.name" />
             </view>
@@ -189,7 +287,61 @@ onLoad((options) => {
         </wd-card>
       </view>
     </template>
+
+    <!-- 底部提交信息块 -->
+    <template #bottom>
+      <view
+        v-if="tab === 2 && selectedOrders.length > 0"
+        class="flex items-center justify-end bg-white px-24rpx pt-30rpx shadow-[0_-2rpx_8rpx_0_rgba(0,0,0,0.1)]"
+        :style="{ paddingBottom: `${systemInfo.safeAreaInsets?.bottom + 30 || 30}rpx` }"
+      >
+        <view>
+          <text>
+            {{ $t('myOrders.total') }}:
+          </text>
+          <text class="text-[var(--wot-color-theme)]">
+            ৳{{ formatNumber(totalAmount) }}
+          </text>
+        </view>
+        <wd-button
+          custom-class="ml-16rpx! min-w-260rpx! bg-[var(--wot-color-theme)]"
+          @click="handleRecycleOrder"
+        >
+          {{ $t('myOrders.recycleOrder') }}
+        </wd-button>
+      </view>
+    </template>
   </z-paging>
+
+  <!-- 回收订单确认弹框 -->
+  <DialogBox
+    v-model:show="showRecycleDialog"
+    :show-cancel="false"
+    :confirm-text="$t('myOrders.dialog.confirm')"
+    @confirm="confirmRecycle"
+  >
+    <view class="text-left">
+      <view class="pb-24rpx text-center text-32rpx font-bold">
+        {{ $t('myOrders.dialog.title') }}
+      </view>
+      <view class="pb-24rpx text-24rpx font-bold">
+        {{ $t('myOrders.dialog.notesTitle') }}
+      </view>
+      <view class="pb-32rpx text-24rpx text-#666">
+        <view class="space-y-16rpx">
+          <view>{{ $t('myOrders.dialog.note1') }}</view>
+          <view>{{ $t('myOrders.dialog.note2') }}</view>
+          <view>{{ $t('myOrders.dialog.note3') }}</view>
+        </view>
+      </view>
+      <view class="mb-44rpx text-center">
+        <text>{{ $t('myOrders.dialog.priceLabel') }}: </text>
+        <text class="text-[var(--wot-color-theme)]">
+          ৳{{ formatNumber(totalAmount) }}
+        </text>
+      </view>
+    </view>
+  </DialogBox>
 </template>
 
 <style lang="scss" scoped>

BIN
src/static/images/buy-flow.png