Browse Source

fix: 功能优化

7746 1 week ago
parent
commit
5c1a93b0cc

+ 14 - 0
src/api/order.js

@@ -49,3 +49,17 @@ export const remindNotice = params => request({
   method: 'post',
   method: 'post',
   data: params
   data: params
 })
 })
+
+// 获取正常订单的详情
+export const getOrderDetail = params => request({
+  url: '/order/detail',
+  method: 'get',
+  params: params
+})
+
+// 获取退款订单的详情
+export const getRefundDetail = params => request({
+  url: '/order/refund/detail',
+  method: 'get',
+  params: params
+})

+ 9 - 0
src/components/card/index.vue

@@ -0,0 +1,9 @@
+<template>
+  <a-card
+    v-bind="$attrs"
+    :headStyle="{padding: '0 15px', minHeight: '50px'}"
+    :bodyStyle="{padding: '15px'}"
+  >
+    <slot />
+  </a-card>
+</template>

+ 25 - 7
src/pages/home/components/CartList.vue

@@ -217,22 +217,32 @@ const toggleCheckAll = () => {
 }
 }
 
 
 const delCount = index => {
 const delCount = index => {
-  if (mainData.goodsList[index].num <= 1) return
-  if (mainData.disabled) return
+  const { stockQty, num } = mainData.goodsList[index]
+  if (num <= 1) return;
+  if (stockQty <= 0) {
+    message.info('当前商品库存为 0');
+    return;
+  }
+  if (mainData.disabled) return;
   mainData.disabled = true
   mainData.disabled = true
   mainData.goodsList[index].num -= 1
   mainData.goodsList[index].num -= 1
-  changeCartApiFn()
+  changeCartApiFn(index, 'DELETE')
 }
 }
 
 
 const addCount = index => {
 const addCount = index => {
-  if (mainData.disabled) return
+  const { stockQty, num } = mainData.goodsList[index];
+  if (num >= stockQty) {
+    message.info(`当前商品库存为 ${stockQty}`);
+    return;
+  }
+  if (mainData.disabled) return;
   mainData.disabled = true
   mainData.disabled = true
   mainData.goodsList[index].num += 1
   mainData.goodsList[index].num += 1
-  changeCartApiFn()
+  changeCartApiFn(index, 'ADD')
 }
 }
 
 
-const changeCartApiFn = () => {
-  const buyGoods = mainData.goodsList.map(item => {
+const changeCartApiFn = (index, type) => {
+  const buyGoods = mainData.goodsList.filter(item => item.stockQty > 0).map(item => {
     return {
     return {
       storageId: props.storageId,
       storageId: props.storageId,
       goodsId: item.goodsId,
       goodsId: item.goodsId,
@@ -249,6 +259,14 @@ const changeCartApiFn = () => {
   }).then((res) => {
   }).then((res) => {
     mainData.allNum = res.data.totalNum
     mainData.allNum = res.data.totalNum
     getTotalPrice()
     getTotalPrice()
+  }).catch(() => {
+    setTimeout(() => {
+      if (type === 'ADD') {
+        mainData.goodsList[index].num -= 1
+      } else {
+        mainData.goodsList[index].num += 1
+      }
+    }, 500)
   }).finally(() => {
   }).finally(() => {
     mainData.disabled = false
     mainData.disabled = false
   })
   })

+ 14 - 5
src/pages/home/components/CartModal.vue

@@ -9,20 +9,21 @@
     <div class="drawer-box" style="height: 100%;">
     <div class="drawer-box" style="height: 100%;">
       <CartList
       <CartList
         v-if="mainData.stepNum == 1"
         v-if="mainData.stepNum == 1"
-        key="1"
         :user-id="userId"
         :user-id="userId"
         :storage-id="storageId"
         :storage-id="storageId"
         @next-step="handleNext"
         @next-step="handleNext"
       />
       />
       <SubmitCart
       <SubmitCart
         v-if="mainData.stepNum == 2"
         v-if="mainData.stepNum == 2"
-        key="2"
         :user-id="userId"
         :user-id="userId"
         :storage-id="storageId"
         :storage-id="storageId"
         :buy-goods="mainData.buyGoods"
         :buy-goods="mainData.buyGoods"
         @prev-step="handlePrev"
         @prev-step="handlePrev"
-        @finish="emits('close')"
-        
+        @next-step="viewDetail"
+      />
+      <OrderDetail
+        v-if="mainData.stepNum == 3"
+        :orderId="mainData.orderId"
       />
       />
     </div>
     </div>
   </a-drawer>
   </a-drawer>
@@ -31,6 +32,7 @@
 <script setup lang="js">
 <script setup lang="js">
 import CartList from './CartList.vue';
 import CartList from './CartList.vue';
 import SubmitCart from './SubmitCart.vue';
 import SubmitCart from './SubmitCart.vue';
+import OrderDetail from './OrderDetail.vue';
 import { reactive, nextTick, watch } from 'vue'
 import { reactive, nextTick, watch } from 'vue'
 
 
 const props = defineProps({
 const props = defineProps({
@@ -52,7 +54,8 @@ const emits = defineEmits(['close']);
 
 
 const mainData = reactive({
 const mainData = reactive({
   stepNum: 1,
   stepNum: 1,
-  buyGoods: []
+  buyGoods: [],
+  orderId: ''
 })
 })
 
 
 const handleNext = (selectedList = []) => {
 const handleNext = (selectedList = []) => {
@@ -65,8 +68,14 @@ const handlePrev = () => {
   mainData.stepNum -= 1;
   mainData.stepNum -= 1;
 }
 }
 
 
+const viewDetail = orderId => {
+  mainData.orderId = orderId;
+  mainData.stepNum += 1;
+}
+
 watch(() => props.open, newVal => {
 watch(() => props.open, newVal => {
   if (newVal) {
   if (newVal) {
+    mainData.orderId = '';
     mainData.buyGoods = [];
     mainData.buyGoods = [];
     mainData.stepNum = -1;
     mainData.stepNum = -1;
     nextTick(() => {
     nextTick(() => {

+ 202 - 0
src/pages/home/components/LevelMessage.vue

@@ -0,0 +1,202 @@
+<template>
+  <a-modal
+    :open="open"
+    :title="contactUs ? '联系我们' : '留言板'"
+    :footer="null"
+    @cancel="emits('close')"
+  >
+    <div style="text-align: center;">
+      <Logo size="120px" />
+    </div>
+    <a-form
+      ref="formRef"
+      name="form"
+      :model="form"
+      :labelCol="{style: {width: '100px'}}"
+      @finish="submitForm"
+    >
+      <a-form-item
+        v-if="contactUs"
+        label="问题类型"
+        name="question"
+        :rules="[{ required: true, message: '不能为空' }]"
+      >
+        <a-select
+          v-model:value="form.question"
+          style="width: 100%"
+          placeholder="请选择"
+          :options="questionOptions"
+        />
+      </a-form-item>
+      <a-form-item
+        label="姓"
+        name="firstName"
+        :rules="[{ required: true, message: '不能为空' }]"
+      >
+        <a-input
+          v-model:value="form.firstName"
+          placeholder="请输入"
+          allowClear
+        />
+      </a-form-item>
+      <a-form-item
+        label="名"
+        name="lastName"
+        :rules="[{ required: true, message: '不能为空' }]"
+      >
+        <a-input
+          v-model:value="form.lastName"
+          placeholder="请输入"
+          allowClear
+        />
+      </a-form-item>
+      <a-form-item
+        label="公司名称"
+        name="companyName"
+        :rules="[{ required: true, message: '不能为空' }]"
+      >
+        <a-input
+          v-model:value="form.companyName"
+          placeholder="请输入"
+          allowClear
+        />
+      </a-form-item>
+      <a-form-item
+        v-if="contactUs"
+        label="账户号码"
+        name="accountNumber"
+      >
+        <a-input
+          v-model:value="form.accountNumber"
+          placeholder="请输入"
+          allowClear
+        />
+      </a-form-item>
+      <a-form-item
+        label="手机号码"
+        name="mobile"
+        :rules="[{ required: true, validator: checkMobile }]"
+      >
+        <a-input
+          v-model:value="form.mobile"
+          placeholder="请输入"
+          allowClear
+        />
+      </a-form-item>
+      <a-form-item
+        label="留言内容"
+        name="message"
+        :rules="[{ required: true, message: '不能为空' }]"
+      >
+        <a-textarea
+          v-model:value="form.message"
+          placeholder="请输入"
+          :auto-size="{minRows: 2, maxRows: 5}"
+          allowClear
+        />
+      </a-form-item>
+      <a-form-item label=" " :colon="false">
+        <a-button type="primary" html-type="submit" block :disabled="mainData.disabled">发 送</a-button>
+      </a-form-item>
+    </a-form>
+  </a-modal>
+</template>
+
+<script setup lang="js">
+import Logo from '@/components/logo/index.vue';
+import { ref, reactive, watch, nextTick } from 'vue';
+import { message } from 'ant-design-vue';
+import { userLeaveMessage } from '@/api/user';
+import { validPhone } from '@/utils/validate';
+
+const props = defineProps({
+  open:{
+    type: Boolean,
+    default: false
+  },
+  // 联系我们
+  contactUs: {
+    type: Boolean,
+    default: false
+  }
+})
+
+const emits = defineEmits(['close']);
+
+const questionOptions = [
+  {
+    value: '订单',
+    label: '订单'
+  },
+  {
+    value: '账户',
+    label: '账户'
+  },
+  {
+    value: '一般信息',
+    label: '一般信息'
+  },
+  {
+    value: '新产品',
+    label: '新产品'
+  },
+  {
+    value: '请求报价',
+    label: '请求报价'
+  },
+  {
+    value: '建议',
+    label: '建议'
+  },
+  {
+    value: '商业设备',
+    label: '商业设备'
+  }
+]
+
+const formRef = ref()
+const form = reactive({
+  question: undefined,
+  firstName: '',
+  lastName: '',
+  companyName: '',
+  accountNumber: '',
+  mobile: '',
+  message: ''
+})
+
+const mainData = reactive({
+  disabled: false
+})
+
+const submitForm = () => {
+  mainData.disabled = true
+  userLeaveMessage(form).then(() => {
+    message.success('发送成功')
+    emits('close')
+  }).finally(() => {
+    mainData.disabled = false
+  })
+}
+
+const checkMobile = (rule, value) => {
+  if (value === '') return Promise.reject('不能为空')
+  if (!validPhone(value)) return Promise.reject('格式有误')
+  return Promise.resolve()
+}
+
+watch(() => props.open, newVal => {
+  if (newVal) {
+    form.question = undefined
+    form.firstName = ''
+    form.lastName = ''
+    form.companyName = ''
+    form.accountNumber = ''
+    form.mobile = ''
+    form.message = ''
+    nextTick(() => {
+      formRef.value?.clearValidate()
+    })
+  }
+})
+</script>

+ 263 - 0
src/pages/home/components/OrderDetail.vue

@@ -0,0 +1,263 @@
+<template>
+  <div class="order-detail">
+    <a-page-header
+      v-if="showBack"
+      style="padding: 0;margin-bottom: 10px;"
+      title="返回"
+      @back="emits('prev-step')"
+    />
+    <div class="status">
+      <a-alert v-if="mainData.detail.orderStatus == 'DQR'" message="订单已提交,待工作人员确认" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'NOPAY'" message="待付款,30分钟内未付款将会关闭订单" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'DJH'" message="订单已确认,待拣货!" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'JHZ'" message="订单拣货中!" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'DFH' && mainData.detail.takeGoodsType == TakeTypeEnum.PICK" message="已拣货完成,待发货!" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'DPS' && mainData.detail.takeGoodsType == TakeTypeEnum.DISPATCH" message="已拣货完成,待派配送员!" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'PSDQ' && mainData.detail.takeGoodsType == TakeTypeEnum.DISPATCH" message="已派配送员,待配送员取货!" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'PSZ' && mainData.detail.takeGoodsType == TakeTypeEnum.DISPATCH" message="配送员已取货,配送中!" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'OVER' && mainData.detail.takeGoodsType == TakeTypeEnum.PICK" message="已发货完成" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'OVER' && mainData.detail.takeGoodsType == TakeTypeEnum.DISPATCH" message="配送完成" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'CLOSE'" message="订单已关闭" type="info" />
+      <a-alert v-if="mainData.detail.orderStatus == 'TIMEOUT'" message="订单超时未支付" type="info" />
+    </div>
+    <MainCard v-if="mainData.detail.takeGoodsType == TakeTypeEnum.DISPATCH" title="收货人信息" style="margin-bottom: 15px;">
+      <div class="row-text__content">{{ mainData.detail.receUserName }} {{ mainData.detail.recePhone }}</div>
+      <div class="row-text__content">{{ mainData.detail.province }}{{ mainData.detail.city }}{{ mainData.detail.area }}{{ mainData.detail.street }}{{ mainData.detail.receAddress}}{{ mainData.detail.houseNo ? mainData.detail.houseNo : '' }}</div>
+    </MainCard>
+    <MainCard title="商品信息" style="margin-bottom: 15px;">
+      <div class="goods-box">
+        <div v-for="(item, index) in mainData.detail.orderDetails" :key="index" class="goods-item">
+          <img class="goods-image" :src="item.imgUrl" />
+          <div class="goods-content">
+            <div class="left">
+              <div class="name">{{ item.goodsName }}</div>
+              <div class="desc">{{ item.goodsSpecValue }}</div>
+              <div v-if="item.promotionFullPieceId" class="tag">
+                <a-tag color="red">满件打折</a-tag>
+              </div>
+            </div>
+            <div class="right">
+              <div class="price">¥{{ item.price }}</div>
+              <div class="num">x{{ item.num }}</div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </MainCard>
+    <MainCard style="margin-bottom: 15px;">
+      <div class="row-item__box">
+        <div class="row-item__content">
+          <div class="row-item__label">{{ mainData.detail.takeGoodsType == TakeTypeEnum.DISPATCH ? '配送时间' : '提货时间' }}</div>
+          <div class="row-item__value">{{ pickDispatchTime }}</div>
+        </div>
+        <div class="row-item__content">
+          <div class="row-item__label">订单备注</div>
+          <div class="row-item__value">{{ mainData.detail.buyerMsg }}</div>
+        </div>
+      </div>
+    </MainCard>
+    <MainCard style="margin-bottom: 15px;">
+      <div class="row-item__box">
+        <div class="row-item__content">
+          <div class="row-item__label">商品金额</div>
+          <div class="row-item__value">¥{{ formatPriceText(mainData.detail.totalProductAmount) }}</div>
+        </div>
+        <div class="row-item__content">
+          <div class="row-item__label">运费</div>
+          <div class="row-item__value">¥{{ formatPriceText(mainData.detail.freight) }}</div>
+        </div>
+        <div class="row-item__content">
+          <div class="row-item__label">订单总金额</div>
+          <div class="row-item__value">¥{{ formatPriceText(mainData.detail.payAmount) }}</div>
+        </div>
+      </div>
+    </MainCard>
+    <MainCard title="订单信息">
+      <div class="row-item__box">
+        <div class="row-item__content">
+          <div class="row-item__label">订单编码</div>
+          <div class="row-item__value">{{ mainData.detail.orderId }}</div>
+        </div>
+        <div class="row-item__content">
+          <div class="row-item__label">创建时间</div>
+          <div class="row-item__value">{{ mainData.detail.createTime }}</div>
+        </div>
+        <div v-if="mainData.detail.payTime" class="row-item__content">
+          <div class="row-item__label">支付时间</div>
+          <div class="row-item__value">{{ mainData.detail.payTime }}</div>
+        </div>
+        <div v-if="mainData.detail.payTime" class="row-item__content">
+          <div class="row-item__label">支付方式</div>
+          <div class="row-item__value">{{ mainData.detail.payType }}</div>
+        </div>
+        <div v-if="mainData.detail.deliverTime" class="row-item__content">
+          <div class="row-item__label">发货时间</div>
+          <div class="row-item__value">{{ mainData.detail.deliverTime }}</div>
+        </div>
+        <div v-if="mainData.detail.overTime" class="row-item__content">
+          <div class="row-item__label">完成时间</div>
+          <div class="row-item__value">{{ mainData.detail.overTime }}</div>
+        </div>
+      </div>
+    </MainCard>
+  </div>
+</template>
+
+<script setup lang="js">
+import MainCard from '@/components/card/index.vue';
+import { reactive, onMounted, computed } from 'vue';
+import { getOrderDetail, getRefundDetail } from '@/api/order';
+import { TakeTypeEnum } from '@/utils/enum';
+
+const props = defineProps({
+  orderId: {
+    type: String,
+    default: ''
+  },
+  //  退款id
+  orderRefundId: {
+    type: String,
+    default: ''
+  },
+  showBack: {
+    type: Boolean,
+    default: false
+  }
+})
+
+const emits = defineEmits(['prev-step'])
+
+const mainData = reactive({
+  detail: {
+    orderStatus: '',
+    orderDetails: []
+  }
+})
+
+const pickDispatchTime = computed(() => {
+  if (mainData.detail.appointmentPickStartTime) {
+    return mainData.detail.appointmentPickStartTime.slice(0, 10) + ' ' + mainData.detail.appointmentPickStartTime.slice(11, 16) + '-' + mainData.detail.appointmentPickEndTime.slice(11, 16)
+  }
+  return ''
+})
+
+const fetchOrderDetail = async () => {
+  const res = await getOrderDetail({
+    orderId: props.orderId
+  })
+  mainData.detail = res.data || {}
+}
+
+const fetchRefundDetail = async() => {
+  const res = await getRefundDetail({
+    orderRefundId: props.orderRefundId
+  })
+  mainData.detail = res.data || {}
+}
+
+const formatPriceText = price => {
+  if (!price) return '0.00'
+  price = Number(price)
+  return price.toFixed(2)
+}
+
+onMounted(() => {
+  if (props.orderRefundId) {
+    fetchRefundDetail()
+  } else if (props.orderId) {
+    fetchOrderDetail()
+  }
+
+})
+
+</script>
+
+<style lang="less" scoped>
+.order-detail {
+  padding-bottom: 50px;
+  .status {
+    margin-bottom: 15px;
+  }
+  .row-item__box {
+    .row-item__content {
+      width: 100%;
+      min-height: 32px;
+      display: flex;
+      align-items: center;
+      .row-item__label {
+        color: #666;
+        font-size: 14px;
+        width: 100px;
+        flex-shrink: 0;
+      }
+      .row-item__value {
+        flex: 1;
+        min-width: 1px;
+        color: #222;
+        font-size: 14px;
+        word-break: break-all;
+        text-align: right;
+      }
+    }
+    .row-text__content {
+      color: #222;
+      font-size: 14px;
+      line-height: 1.5;
+    }
+  }
+
+  .goods-box {
+    .goods-item {
+      width: 100%;
+      display: flex;
+      margin-bottom: 10px;
+      &:last-of-type {
+        margin-bottom: 0;
+      }
+      .goods-image {
+        width: 80px;
+        height: 80px;
+        margin-right: 10px;
+        object-fit: cover;
+        flex-shrink: 0;
+      }
+      .goods-content {
+        flex: 1;
+        display: flex;
+        min-width: 1px;
+        justify-content: space-between;
+        .left {
+          .name {
+            font-size: 14px;
+            line-height: 1.2;
+            margin-bottom: 5px;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            display: -webkit-box;
+            -webkit-line-clamp: 2;
+            -webkit-box-orient: vertical;
+          }
+          .desc {
+            color: #666;
+            font-size: 13px;
+            margin-bottom: 5px;
+          }
+        }
+        .right {
+          .price {
+            color: #222;
+            font-size: 16px;
+            font-weight: 500;
+            text-align: right;
+          }
+          .num {
+            color: #666;
+            font-size: 13px;
+            text-align: right;
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 503 - 0
src/pages/home/components/OrderList.vue

@@ -0,0 +1,503 @@
+<template>
+  <div class="order-list__box">
+    <div class="tabs-content">
+      <a-tabs v-model:activeKey="mainData.tabIndex" @change="changeTab">
+        <a-tab-pane v-for="(item, index) in mainData.tabs" :key="index" :tab="item.name" />
+      </a-tabs>
+    </div>
+    <div v-if="mainData.list.length > 0" class="list-container">
+      <div v-for="(item, index) in mainData.list" :key="index">
+        <div class="item" @click="toOrderDetail(item.orderId, item.orderRefundId)">
+          <!-- 普通订单 -->
+          <div v-if="tabCurrent != 'REFUND'">
+            <div class="top">
+              <div class="left">{{ item.orderId }}</div>
+              <div class="right">{{ statusFilter(item) }}</div>
+            </div>
+
+            <div v-for="(goodsItem, goodsIndex) in item.orderDetails" :key="goodsIndex">
+              <div class="goods" :class="'goods' + goodsIndex">
+                <img :src="goodsItem.imgUrl" />
+                <div class="main">
+                  <div class="left">
+                    <div class="name ellipsis-2">{{ goodsItem.goodsName }}</div>
+                    <div class="des">{{ goodsItem.goodsSpecValue }}</div>
+                  </div>
+                  <div class="right">
+                    <div class="price">¥{{ formatPriceText(goodsItem.price) }}</div>
+                    <div class="num">x{{ goodsItem.num }}</div>
+                  </div>
+                </div>
+              </div>
+            </div>
+
+            <div class="total">
+              <div class="left">{{ item.createTime }}</div>
+              <div class="right">共{{ item.totalNum }}件 订单总额:<span>¥{{ formatPriceText(item.payAmount) }}</span></div>
+            </div>
+          </div>
+
+          <!-- 售后订单 -->
+          <div v-if="tabCurrent == 'REFUND'">
+            <div class="top">
+              <div class="left">{{ item.orderId }}</div>
+              <div class="right">{{ statusFilter2(item.orderStatus) }}</div>
+            </div>
+
+            <!-- 拒绝申请 -->
+            <div v-if="item.examineStatus === 'FAIL'">
+              <div v-for="(goodsItem, goodsIndex) in item.orderDetails" :key="goodsIndex">
+                <div class="goods" :class="'goods' + goodsIndex">
+                  <image :src="goodsItem.imgUrl" mode="aspectFill"></image>
+                  <div class="main">
+                    <div class="left">
+                      <div class="name ellipsis-2">{{ goodsItem.goodsName }}</div>
+                      <div class="des">{{ goodsItem.goodsSpecValue }}</div>
+                    </div>
+                    <div class="right">
+                      <div class="price">¥{{ formatPriceText(goodsItem.price) }}</div>
+                      <div class="num">x{{ goodsItem.refundNum }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="total">
+                <div class="left">{{ item.createTime }}</div>
+                <div class="right">共{{ item.totalNum }}件 {{ item.orderStatus == 'NOPAY' ? '应付' : '实付' }}总额:<span>¥{{
+                  formatPriceText(item.payAmount) }}</span></div>
+              </div>
+            </div>
+            <!-- 其他 -->
+            <div v-else>
+              <div v-for="(goodsItem, goodsIndex) in item.orderDetails" :key="goodsIndex">
+                <div class="goods" :class="'goods' + goodsIndex" v-if="goodsItem.refund">
+                  <image :src="goodsItem.imgUrl" mode="aspectFill"></image>
+                  <div class="main">
+                    <div class="left">
+                      <div class="name ellipsis-2">{{ goodsItem.goodsName }}</div>
+                      <div class="des">{{ goodsItem.goodsSpecValue }}</div>
+                    </div>
+                    <div class="right">
+                      <div class="price">¥{{ formatPriceText(goodsItem.price) }}</div>
+                      <div class="num">x{{ goodsItem.refundNum }}</div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="total">
+                <div class="left">{{ item.createTime }}</div>
+                <div class="right">共{{ getRefundNum(item.orderDetails) }}件
+                  {{ item.orderStatus == 'OVER' ? '实退' : '应退' }}总额:<span>¥{{ formatPriceText(item.refundAmount)
+                    }}</span>
+                </div>
+              </div>
+            </div>
+          </div>
+
+          <div v-if="item.isShareOrder">
+            <div class="btn-group btn-group2">
+              <div class="tips">分销订单</div>
+              <div class="btns">
+                <div class="button gray">查看订单</div>
+              </div>
+            </div>
+          </div>
+          <div v-else>
+            <!-- 按钮:待付款 -->
+            <div class="btn-group btn-group2" v-if="item.orderStatus == 'NOPAY'">
+              <div class="tips">请在30分钟内付款</div>
+              <div class="btns">
+                <div class="button red">立即付款</div>
+              </div>
+            </div>
+            <!-- 按钮:待发货 -->
+            <!-- <div class="btn-group" v-if="item.orderStatus == 'DFH'">
+            </div> -->
+            <!-- 按钮:待服务 -->
+            <!-- <div class="btn-group" v-if="item.orderStatus == 'YFH'">
+            </div> -->
+            <!-- 按钮:待评价 -->
+            <!-- <div class="btn-group" v-if="item.orderStatus == 'OVER' && tabCurrent != 'REFUND'">
+            </div> -->
+            <!-- 按钮:超时未支付 -->
+            <div class="btn-group" v-if="item.orderStatus == 'TIMEOUT'">
+              <div class="button gray">查看订单</div>
+            </div>
+            <!-- 按钮:售后中 -->
+            <div class="btn-group" v-if="item.orderStatus == 'REFUND'">
+              <div class="button gray">查看订单</div>
+            </div>
+            <!-- 按钮:售后中 待商家处理 -->
+            <div class="btn-group" v-if="item.orderStatus == 'DSJCL'">
+              <div class="button gray" @click="toReturnDetail(item.orderRefundId)">售后详情</div>
+            </div>
+            <!-- 按钮:售后中 待买家处理 -->
+            <div class="btn-group" v-if="item.orderStatus == 'DMJCL'">
+              <div class="button red" @click="toReturnDetail(item.orderRefundId)" v-if="item.examineStatus == 'OK'">
+                提交资料
+              </div>
+              <div class="button white" @click="toApplyReturn(item.orderId)" v-if="item.examineStatus == 'FAIL'">
+                重新申请
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <a-flex v-if="mainData.total > mainData.list.length" align="center" justify="center">
+        <a-button type="link" @click="handleLoadMore">点击查看更多订单</a-button>
+      </a-flex>
+    </div>
+    <div v-else class="list-container">
+      <a-empty />
+    </div>
+  </div>
+</template>
+
+<script setup lang="js">
+import { onMounted, reactive, computed } from 'vue';
+import { message, Modal } from 'ant-design-vue';
+import {
+  cancelOrder,
+  ackComplete,
+  remindNotice,
+  getMyOrderList
+} from '@/api/order';
+import { useUserStore } from '@/store/user';
+
+const emits = defineEmits(['view-detail']);
+
+const userStore = useUserStore();
+
+const tabCurrent = computed(() => mainData.tabs[mainData.tabIndex].key);
+
+
+const mainData = reactive({
+  tabs: [
+    { key: '', name: '全部' },
+    { key: 'NOPAY', name: '待付款' },
+    { key: 'DQR', name: '待确认' },
+    { key: 'DJH', name: '待拣货' },
+    { key: 'JHZ', name: '拣货中' },
+    { key: 'DFH', name: '待发货' },
+    { key: 'DPS', name: '待配送' },
+    { key: 'PSDQ', name: '配送待取' },
+    { key: 'PSZ', name: '配送中' },
+    { key: 'OVER', name: '已完成' },
+    { key: 'CLOSE', name: '已关闭' }
+  ],
+  tabIndex: 0,
+  list: [],
+  pageNo: 1,
+  total: 0,
+  canRemindShipment: true
+})
+
+const statusFilter = item => {
+  const statusMap = {
+    DQR: '待确认',
+    NOPAY: '待付款',
+    DJH: '待拣货',
+    JHZ: '拣货中',
+    DFH: '待发货',
+    DTK: '待退款',
+    DPS: '待配送',
+    PSZ: '配送中',
+    OVER: '已完成',
+    CLOSE: '已关闭',
+    REFUND: '售后/退款',
+    TIMEOUT: '超时未支付'
+  }
+  if (item.orderStatus == 'OVER' && item.commentService) {
+    return '已完成'
+  } else {
+    return statusMap[item.orderStatus]
+  }
+}
+
+const statusFilter2 = (val) => {
+  const statusMap = {
+    DSJCL: '待商家处理',
+    DSJSH: '待商家收货',
+    DMJCL: '待买家处理',
+    OVER: '退款成功',
+    CANCEL: '已取消'
+  }
+  return statusMap[val]
+}
+
+const getRefundNum = (orderDetails) => {
+  let refundNum = 0
+  orderDetails.forEach(item => {
+    if (item.refund) {
+      refundNum = refundNum + item.refundNum
+    }
+  })
+  return refundNum
+}
+
+const changeTab = tabIndex => {
+  mainData.tabIndex = tabIndex;
+  resetParams();
+  fetchOrderList();
+}
+
+const resetParams = () => {
+  mainData.list = []
+  mainData.pageNo = 1
+  mainData.total = 0
+}
+
+const fetchOrderList = async () => {
+  const orderStatus = mainData.tabs[mainData.tabIndex].key || ''
+  const res = await getMyOrderList({
+    pageNo: mainData.pageNo,
+    pageSize: 10,
+    orderStatus: orderStatus,
+    userId: userStore.userInfo?.userId || ''
+  })
+  mainData.list = mainData.list.concat(res.data?.records || []);
+  mainData.total = res.data?.total || 0;
+}
+
+const handleLoadMore = () => {
+  mainData.pageNo += 1;
+  fetchOrderList();
+}
+
+
+// 申请退款
+const toApplyReturn = (orderId) => {
+  // url: '/packageMine/pages/order/return/apply?orderId=' + orderId
+}
+
+// 去订单详情
+const toOrderDetail = (orderId = '', orderRefundId = '') => {
+  emits('view-detail', { orderId, orderRefundId })
+}
+
+// 去售后详情
+const toReturnDetail = (orderRefundId) => {
+  // this.$navToPage({
+  //   url: '/packageMine/pages/order/return/detail?orderRefundId=' + orderRefundId
+  // })
+}
+
+// 提醒发货
+const remindShipment = (orderId) => {
+  mainData.canRemindShipment = false
+  setTimeout(() => {
+    mainData.canRemindShipment = true
+  }, 3000)
+  remindNotice({
+    orderId: orderId,
+    userId: userStore.userInfo?.userId || ''
+  }).then(() => {
+    message.success('提醒发货成功')
+  })
+}
+
+// 取消订单
+const handleCancelOrder = orderId => {
+  cancelOrder({
+    orderId: orderId
+  }).then(() => {
+    resetParams()
+    fetchOrderList()
+    message.success('取消成功')
+  })
+}
+
+// 服务完成
+const confirmReceipt = orderId => {
+  Modal.confirm({
+    title: '完成服务',
+    content: '请确认是否已完成服务?',
+    onOk() {
+      ackComplete({
+        orderId: orderId
+      }).then(() => {
+        message.success('完成服务成功')
+      })
+    }
+  })
+}
+
+const formatPriceText = price => {
+  if (!price) return '0.00'
+  price = Number(price)
+  return price.toFixed(2)
+}
+
+onMounted(() => {
+  fetchOrderList()
+})
+
+</script>
+
+<style lang="less" scoped>
+.order-list__box {
+  .tab-container {
+    background: #ffffff;
+  }
+
+  .list-container {
+    .item {
+      padding-bottom: 10px;
+      border-bottom: 1px solid @border-color;
+
+      .top {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 10px 0;
+
+        .left {
+          font-size: 14px;
+          font-weight: 500;
+        }
+
+        .right {
+          font-size: 14px;
+        }
+      }
+
+      .goods {
+        display: flex;
+        justify-content: space-between;
+        margin-top: 10px;
+        img {
+          width: 70px;
+          height: 70px;
+          object-fit: cover;
+        }
+
+        &.goods0 {
+          margin-top: 0;
+        }
+
+        image {
+          width: 70px;
+          height: 70px;
+          display: div;
+          flex-shrink: 0;
+          margin-right: 10px;
+        }
+
+        .main {
+          margin-left: 10px;
+          flex: 1;
+          display: flex;
+          justify-content: space-between;
+
+          .left {
+            .name {
+              font-size: 14px;
+              color: #333333;
+              line-height: 18px;
+            }
+
+            .des {
+              font-size: 14px;
+              color: #999999;
+              margin-top: 5px;
+            }
+          }
+
+          .right {
+            flex-shrink: 0;
+            margin-left: 10px;
+            text-align: right;
+
+            .price {
+              font-size: 14px;
+              color: #333333;
+              line-height: 14px;
+              font-weight: 600;
+              margin-top: 3;
+            }
+
+            .num {
+              font-size: 14px;
+              color: #999999;
+              line-height: 14px;
+              margin-top: 8px;
+            }
+          }
+        }
+      }
+
+      .total {
+        display: flex;
+        justify-content: space-between;
+        height: 25px;
+        align-items: center;
+
+        .left {
+          font-size: 12px;
+          color: #666666;
+        }
+
+        .right {
+          font-size: 12;
+          color: #666666;
+
+          text {
+            color: #ff577e;
+            ;
+            font-size: 16px;
+            font-weight: 600;
+            margin-left: 4px;
+          }
+        }
+      }
+
+      .btn-group {
+        border-top: 1px solid #eaeaea;
+        height: 50px;
+        display: flex;
+        justify-content: flex-end;
+        align-items: center;
+
+        &.btn-group2 {
+          justify-content: space-between;
+
+          .tips {
+            font-size: 14px;
+            color: #ff577e;
+          }
+
+          .btns {
+            display: flex;
+          }
+        }
+
+        .button {
+          width: 70px;
+          height: 24px;
+          border-radius: 24px;
+          text-align: center;
+          line-height: 24px;
+          font-size: 12px;
+          margin-left: 10px;
+          flex-shrink: 0;
+
+          &:first-child {
+            margin-left: 0;
+          }
+
+          &.gray {
+            color: #999999;
+            border: 1px solid #999999;
+          }
+
+          &.white {
+          }
+
+          &.red {
+          }
+        }
+      }
+    }
+  }
+}
+</style>

+ 33 - 490
src/pages/home/components/OrderModal.vue

@@ -1,170 +1,25 @@
 <template>
 <template>
   <a-drawer :open="open" title="我的订单" width="800px" placement="right" @close="emits('close')">
   <a-drawer :open="open" title="我的订单" width="800px" placement="right" @close="emits('close')">
     <div class="drawer-box">
     <div class="drawer-box">
-      <div class="tabs-content">
-        <a-tabs v-model:activeKey="mainData.tabIndex" @change="changeTab">
-          <a-tab-pane v-for="(item, index) in mainData.tabs" :key="index" :tab="item.name" />
-        </a-tabs>
-      </div>
-      <div v-if="mainData.list.length > 0" class="list-container">
-        <div v-for="(item, index) in mainData.list" :key="index">
-          <div class="item" @click="toOrderDetail(item.orderId, item.orderRefundId)">
-            <!-- 普通订单 -->
-            <div v-if="tabCurrent != 'REFUND'">
-              <div class="top">
-                <div class="left">{{ item.orderId }}</div>
-                <div class="right">{{ statusFilter(item) }}</div>
-              </div>
-
-              <div v-for="(goodsItem, goodsIndex) in item.orderDetails" :key="goodsIndex">
-                <div class="goods" :class="'goods' + goodsIndex">
-                  <img :src="goodsItem.imgUrl" />
-                  <div class="main">
-                    <div class="left">
-                      <div class="name ellipsis-2">{{ goodsItem.goodsName }}</div>
-                      <div class="des">{{ goodsItem.goodsSpecValue }}</div>
-                    </div>
-                    <div class="right">
-                      <div class="price">¥{{ formatPriceText(goodsItem.price) }}</div>
-                      <div class="num">x{{ goodsItem.num }}</div>
-                    </div>
-                  </div>
-                </div>
-              </div>
-
-              <div class="total">
-                <div class="left">{{ item.createTime }}</div>
-                <div class="right">共{{ item.totalNum }}件 订单总额:<span>¥{{ formatPriceText(item.payAmount) }}</span></div>
-              </div>
-            </div>
-
-            <!-- 售后订单 -->
-            <div v-if="tabCurrent == 'REFUND'">
-              <div class="top">
-                <div class="left">{{ item.orderId }}</div>
-                <div class="right">{{ statusFilter2(item.orderStatus) }}</div>
-              </div>
-
-              <!-- 拒绝申请 -->
-              <div v-if="item.examineStatus === 'FAIL'">
-                <div v-for="(goodsItem, goodsIndex) in item.orderDetails" :key="goodsIndex">
-                  <div class="goods" :class="'goods' + goodsIndex">
-                    <image :src="goodsItem.imgUrl" mode="aspectFill"></image>
-                    <div class="main">
-                      <div class="left">
-                        <div class="name ellipsis-2">{{ goodsItem.goodsName }}</div>
-                        <div class="des">{{ goodsItem.goodsSpecValue }}</div>
-                      </div>
-                      <div class="right">
-                        <div class="price">¥{{ formatPriceText(goodsItem.price) }}</div>
-                        <div class="num">x{{ goodsItem.refundNum }}</div>
-                      </div>
-                    </div>
-                  </div>
-                </div>
-                <div class="total">
-                  <div class="left">{{ item.createTime }}</div>
-                  <div class="right">共{{ item.totalNum }}件 {{ item.orderStatus == 'NOPAY' ? '应付' : '实付' }}总额:<span>¥{{
-                    formatPriceText(item.payAmount) }}</span></div>
-                </div>
-              </div>
-              <!-- 其他 -->
-              <div v-else>
-                <div v-for="(goodsItem, goodsIndex) in item.orderDetails" :key="goodsIndex">
-                  <div class="goods" :class="'goods' + goodsIndex" v-if="goodsItem.refund">
-                    <image :src="goodsItem.imgUrl" mode="aspectFill"></image>
-                    <div class="main">
-                      <div class="left">
-                        <div class="name ellipsis-2">{{ goodsItem.goodsName }}</div>
-                        <div class="des">{{ goodsItem.goodsSpecValue }}</div>
-                      </div>
-                      <div class="right">
-                        <div class="price">¥{{ formatPriceText(goodsItem.price) }}</div>
-                        <div class="num">x{{ goodsItem.refundNum }}</div>
-                      </div>
-                    </div>
-                  </div>
-                </div>
-                <div class="total">
-                  <div class="left">{{ item.createTime }}</div>
-                  <div class="right">共{{ getRefundNum(item.orderDetails) }}件
-                    {{ item.orderStatus == 'OVER' ? '实退' : '应退' }}总额:<span>¥{{ formatPriceText(item.refundAmount)
-                      }}</span>
-                  </div>
-                </div>
-              </div>
-            </div>
-
-            <div v-if="item.isShareOrder">
-              <div class="btn-group btn-group2">
-                <div class="tips">分销订单</div>
-                <div class="btns">
-                  <div class="button gray">查看订单</div>
-                </div>
-              </div>
-            </div>
-            <div v-else>
-              <!-- 按钮:待付款 -->
-              <div class="btn-group btn-group2" v-if="item.orderStatus == 'NOPAY'">
-                <div class="tips">请在30分钟内付款</div>
-                <div class="btns">
-                  <div class="button red">立即付款</div>
-                </div>
-              </div>
-              <!-- 按钮:待发货 -->
-              <!-- <div class="btn-group" v-if="item.orderStatus == 'DFH'">
-              </div> -->
-              <!-- 按钮:待服务 -->
-              <!-- <div class="btn-group" v-if="item.orderStatus == 'YFH'">
-              </div> -->
-              <!-- 按钮:待评价 -->
-              <!-- <div class="btn-group" v-if="item.orderStatus == 'OVER' && tabCurrent != 'REFUND'">
-              </div> -->
-              <!-- 按钮:超时未支付 -->
-              <div class="btn-group" v-if="item.orderStatus == 'TIMEOUT'">
-                <div class="button gray">查看订单</div>
-              </div>
-              <!-- 按钮:售后中 -->
-              <div class="btn-group" v-if="item.orderStatus == 'REFUND'">
-                <div class="button gray">查看订单</div>
-              </div>
-              <!-- 按钮:售后中 待商家处理 -->
-              <div class="btn-group" v-if="item.orderStatus == 'DSJCL'">
-                <div class="button gray" @click="toReturnDetail(item.orderRefundId)">售后详情</div>
-              </div>
-              <!-- 按钮:售后中 待买家处理 -->
-              <div class="btn-group" v-if="item.orderStatus == 'DMJCL'">
-                <div class="button red" @click="toReturnDetail(item.orderRefundId)" v-if="item.examineStatus == 'OK'">
-                  提交资料
-                </div>
-                <div class="button white" @click="toApplyReturn(item.orderId)" v-if="item.examineStatus == 'FAIL'">
-                  重新申请
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-        <a-flex v-if="mainData.total > mainData.list.length" align="center" justify="center">
-          <a-button type="link" @click="handleLoadMore">点击查看更多订单</a-button>
-        </a-flex>
-      </div>
-      <div v-else class="list-container">
-        <a-empty />
-      </div>
+      <OrderList
+        v-if="mainData.stepNum == 1"
+        @view-detail="viewDetail"
+      />
+      <OrderDetail
+        v-if="mainData.stepNum == 2"
+        :show-back="true"
+        :order-id="mainData.orderId"
+        :order-refund-id="mainData.orderRefundId"
+        @prev-step="handlePrevStep"
+      />
     </div>
     </div>
   </a-drawer>
   </a-drawer>
 </template>
 </template>
 
 
 <script setup lang="js">
 <script setup lang="js">
-import { onMounted, reactive, computed } from 'vue';
-import { message, Modal } from 'ant-design-vue';
-import {
-  cancelOrder,
-  ackComplete,
-  remindNotice,
-  getMyOrderList
-} from '@/api/order';
-import { useUserStore } from '@/store/user'
+import OrderList from './OrderList.vue';
+import OrderDetail from './OrderDetail.vue';
+import { reactive, watch, nextTick } from 'vue';
 
 
 defineProps({
 defineProps({
   open: {
   open: {
@@ -175,344 +30,32 @@ defineProps({
 
 
 const emits = defineEmits(['close']);
 const emits = defineEmits(['close']);
 
 
-const userStore = useUserStore();
-
-const tabCurrent = computed(() => mainData.tabs[mainData.tabIndex].key);
-
 const mainData = reactive({
 const mainData = reactive({
-  tabs: [
-    { key: '', name: '全部' },
-    { key: 'NOPAY', name: '待付款' },
-    { key: 'DQR', name: '待确认' },
-    { key: 'DJH', name: '待拣货' },
-    { key: 'JHZ', name: '拣货中' },
-    { key: 'DFH', name: '待发货' },
-    { key: 'DPS', name: '待配送' },
-    { key: 'PSDQ', name: '配送待取' },
-    { key: 'PSZ', name: '配送中' },
-    { key: 'OVER', name: '已完成' },
-    { key: 'CLOSE', name: '已关闭' }
-  ],
-  tabIndex: 0,
-  list: [],
-  pageNo: 1,
-  total: 0,
-  canRemindShipment: true
+  stepNum: 1,
+  orderId: '',
+  orderRefundId: ''
 })
 })
 
 
-const statusFilter = item => {
-  const statusMap = {
-    DQR: '待确认',
-    NOPAY: '待付款',
-    DJH: '待拣货',
-    JHZ: '拣货中',
-    DFH: '待发货',
-    DTK: '待退款',
-    DPS: '待配送',
-    PSZ: '配送中',
-    OVER: '已完成',
-    CLOSE: '已关闭',
-    REFUND: '售后/退款',
-    TIMEOUT: '超时未支付'
-  }
-  if (item.orderStatus == 'OVER' && item.commentService) {
-    return '已完成'
-  } else {
-    return statusMap[item.orderStatus]
-  }
-}
-
-const statusFilter2 = (val) => {
-  const statusMap = {
-    DSJCL: '待商家处理',
-    DSJSH: '待商家收货',
-    DMJCL: '待买家处理',
-    OVER: '退款成功',
-    CANCEL: '已取消'
-  }
-  return statusMap[val]
-}
-
-const getRefundNum = (orderDetails) => {
-  let refundNum = 0
-  orderDetails.forEach(item => {
-    if (item.refund) {
-      refundNum = refundNum + item.refundNum
-    }
-  })
-  return refundNum
-}
-
-const changeTab = tabIndex => {
-  mainData.tabIndex = tabIndex;
-  resetParams();
-  fetchOrderList();
-}
-
-const resetParams = () => {
-  mainData.list = []
-  mainData.pageNo = 1
-  mainData.total = 0
-}
-
-const fetchOrderList = async () => {
-  const orderStatus = mainData.tabs[mainData.tabIndex].key || ''
-  const res = await getMyOrderList({
-    pageNo: mainData.pageNo,
-    pageSize: 10,
-    orderStatus: orderStatus,
-    userId: userStore.userInfo?.userId || ''
-  })
-  mainData.list = mainData.list.concat(res.data?.records || []);
-  mainData.total = res.data?.total || 0;
+const viewDetail = ({ orderId, orderRefundId }) => {
+  mainData.stepNum += 1;
+  mainData.orderId = orderId;
+  mainData.orderRefundId = orderRefundId;
 }
 }
 
 
-const handleLoadMore = () => {
-  mainData.pageNo += 1;
-  fetchOrderList();
+const handlePrevStep = () => {
+  mainData.stepNum -= 1;
 }
 }
 
 
-
-// 申请退款
-const toApplyReturn = (orderId) => {
-  // url: '/packageMine/pages/order/return/apply?orderId=' + orderId
-}
-
-// 去订单详情
-const toOrderDetail = (orderId = '', orderRefundId = '') => {
-  // if (orderRefundId) {
-  //       return this.$navToPage({
-  //         url: '/packageMine/pages/order/return/detail?orderRefundId=' + orderRefundId
-  //       })
-  //     }
-  //     this.$navToPage({
-  //       url: '/packageMine/pages/order/detail?orderId=' + orderId + '&orderRefundId=' + orderRefundId
-  //     })
-}
-
-// 去售后详情
-const toReturnDetail = (orderRefundId) => {
-  // this.$navToPage({
-  //   url: '/packageMine/pages/order/return/detail?orderRefundId=' + orderRefundId
-  // })
-}
-
-// 提醒发货
-const remindShipment = (orderId) => {
-  mainData.canRemindShipment = false
-  setTimeout(() => {
-    mainData.canRemindShipment = true
-  }, 3000)
-  remindNotice({
-    orderId: orderId,
-    userId: userStore.userInfo?.userId || ''
-  }).then(() => {
-    message.success('提醒发货成功')
-  })
-}
-
-// 取消订单
-const handleCancelOrder = orderId => {
-  cancelOrder({
-    orderId: orderId
-  }).then(() => {
-    resetParams()
-    fetchOrderList()
-    message.success('取消成功')
-  })
-}
-
-// 服务完成
-const confirmReceipt = orderId => {
-  Modal.confirm({
-    title: '完成服务',
-    content: '请确认是否已完成服务?',
-    onOk() {
-      ackComplete({
-        orderId: orderId
-      }).then(() => {
-        message.success('完成服务成功')
-      })
-    }
-  })
-}
-
-const formatPriceText = price => {
-  if (!price) return '0.00'
-  price = Number(price)
-  return price.toFixed(2)
-}
-
-onMounted(() => {
-  fetchOrderList()
-})
-
-</script>
-
-<style lang="less" scoped>
-.drawer-box {
-  .tab-container {
-    background: #ffffff;
+watch(() => mainData.open, newVal => {
+  if (newVal) {
+    mainData.stepNum = -1;
+    nextTick(() => {
+      mainData.stepNum = 1;
+      mainData.orderId = '';
+      mainData.orderRefundId = '';
+    })
   }
   }
+})
 
 
-  .list-container {
-    .item {
-      padding-bottom: 10px;
-      border-bottom: 1px solid @border-color;
-
-      .top {
-        display: flex;
-        justify-content: space-between;
-        align-items: center;
-        padding: 10px 0;
-
-        .left {
-          font-size: 14px;
-          font-weight: 500;
-        }
-
-        .right {
-          font-size: 14px;
-        }
-      }
-
-      .goods {
-        display: flex;
-        justify-content: space-between;
-        margin-top: 10px;
-        img {
-          width: 70px;
-          height: 70px;
-          object-fit: cover;
-        }
-
-        &.goods0 {
-          margin-top: 0;
-        }
-
-        image {
-          width: 70px;
-          height: 70px;
-          display: div;
-          flex-shrink: 0;
-          margin-right: 10px;
-        }
-
-        .main {
-          margin-left: 10px;
-          flex: 1;
-          display: flex;
-          justify-content: space-between;
-
-          .left {
-            .name {
-              font-size: 14px;
-              color: #333333;
-              line-height: 18px;
-            }
-
-            .des {
-              font-size: 14px;
-              color: #999999;
-              margin-top: 5px;
-            }
-          }
-
-          .right {
-            flex-shrink: 0;
-            margin-left: 10px;
-            text-align: right;
-
-            .price {
-              font-size: 14px;
-              color: #333333;
-              line-height: 14px;
-              font-weight: 600;
-              margin-top: 3;
-            }
-
-            .num {
-              font-size: 14px;
-              color: #999999;
-              line-height: 14px;
-              margin-top: 8px;
-            }
-          }
-        }
-      }
-
-      .total {
-        display: flex;
-        justify-content: space-between;
-        height: 25px;
-        align-items: center;
-
-        .left {
-          font-size: 12px;
-          color: #666666;
-        }
-
-        .right {
-          font-size: 12;
-          color: #666666;
-
-          text {
-            color: #ff577e;
-            ;
-            font-size: 16px;
-            font-weight: 600;
-            margin-left: 4px;
-          }
-        }
-      }
-
-      .btn-group {
-        border-top: 1px solid #eaeaea;
-        height: 50px;
-        display: flex;
-        justify-content: flex-end;
-        align-items: center;
-
-        &.btn-group2 {
-          justify-content: space-between;
-
-          .tips {
-            font-size: 14px;
-            color: #ff577e;
-          }
-
-          .btns {
-            display: flex;
-          }
-        }
-
-        .button {
-          width: 70px;
-          height: 24px;
-          border-radius: 24px;
-          text-align: center;
-          line-height: 24px;
-          font-size: 12px;
-          margin-left: 10px;
-          flex-shrink: 0;
-
-          &:first-child {
-            margin-left: 0;
-          }
-
-          &.gray {
-            color: #999999;
-            border: 1px solid #999999;
-          }
-
-          &.white {
-          }
 
 
-          &.red {
-          }
-        }
-      }
-    }
-  }
-}
-</style>
+</script>

+ 12 - 21
src/pages/home/components/SubmitCart.vue

@@ -38,8 +38,8 @@
       </div>
       </div>
       <a-form
       <a-form
         ref="formRef"
         ref="formRef"
+        name="formRef"
         :model="mainData"
         :model="mainData"
-        name="basic"
         :label-col="{style: { width: '100px' }}"
         :label-col="{style: { width: '100px' }}"
       >
       >
         <a-form-item
         <a-form-item
@@ -103,7 +103,7 @@
           />
           />
         </a-form-item>
         </a-form-item>
         <a-form-item
         <a-form-item
-          label="家留言"
+          label="家留言"
           name="remark"
           name="remark"
         >
         >
           <a-textarea
           <a-textarea
@@ -165,20 +165,11 @@ import { MinusOutlined, PlusOutlined } from '@ant-design/icons-vue';
 import { ref, reactive, onMounted, computed } from 'vue';
 import { ref, reactive, onMounted, computed } from 'vue';
 import { ackOrder, orderBuy } from '@/api/order';
 import { ackOrder, orderBuy } from '@/api/order';
 import { getAddressList, getPickTimeList } from '@/api/user';
 import { getAddressList, getPickTimeList } from '@/api/user';
-import { useUserStore } from '@/store/user'
-import { useStorageStore } from '@/store/storage'
+import { useUserStore } from '@/store/user';
+import { useStorageStore } from '@/store/storage';
+import { TakeTypeEnum, PayTypeEnum } from '@/utils/enum';
 
 
-const emits = defineEmits(['prev-step', 'finish']);
-
-const TakeTypeEnum = {
-  PICK: 0,// 自提
-  DISPATCH: 1,// 商家配送
-}
-
-const PayTypeEnum = {
-  STORE: 2,// 到店
-  CREDIT: 3,// 授信
-}
+const emits = defineEmits(['prev-step', 'next-step']);
 
 
 const userStore = useUserStore();
 const userStore = useUserStore();
 const storageStore = useStorageStore();
 const storageStore = useStorageStore();
@@ -203,7 +194,7 @@ const mainData = reactive({
   goodsList: [],
   goodsList: [],
   addressList: [],
   addressList: [],
   orderInfo: {},
   orderInfo: {},
-  userAddressId: null,
+  userAddressId: undefined,
   takeGoodsType: '',
   takeGoodsType: '',
   pickTime: '',
   pickTime: '',
   dispatchTime: '',
   dispatchTime: '',
@@ -240,7 +231,7 @@ const fetchAddressList = async() => {
       ...item
       ...item
     }
     }
   })
   })
-  mainData.userAddressId = mainData.addressList.find(item => item.defaultAddr)?.userAddressId || '';
+  mainData.userAddressId = mainData.addressList.find(item => item.defaultAddr)?.userAddressId || undefined;
 }
 }
 
 
 const fetchPickTimeList = async () => {
 const fetchPickTimeList = async () => {
@@ -359,8 +350,8 @@ const handleSubmit = () => {
       appointmentPickStartTime: obj.startTime,
       appointmentPickStartTime: obj.startTime,
       appointmentPickEndTime: obj.endTime
       appointmentPickEndTime: obj.endTime
     }
     }
-    if (mainData.takeGoodsType === TakeTypeEnum.PICK) {
-      params.userAddressId = mainData.userAddressId
+    if (mainData.takeGoodsType === TakeTypeEnum.DISPATCH) {
+      params.userAddressId = mainData.userAddressId || ''
     }
     }
     mainData.disabled = false
     mainData.disabled = false
     orderBuy(params).then(res => {
     orderBuy(params).then(res => {
@@ -370,10 +361,10 @@ const handleSubmit = () => {
       if (res.data.isPay === false) {
       if (res.data.isPay === false) {
         if (mainData.payType === PayTypeEnum.STORE) {
         if (mainData.payType === PayTypeEnum.STORE) {
           message.success('购买成功,待商家确认')
           message.success('购买成功,待商家确认')
-          emits('finish')
+          emits('next-step', res.data.id)
         } else if (mainData.payType === PayTypeEnum.CREDIT) {
         } else if (mainData.payType === PayTypeEnum.CREDIT) {
           message.success('购买成功')
           message.success('购买成功')
-          emits('finish')
+          emits('next-step', res.data.id)
         }
         }
       }
       }
     }).finally(() => {
     }).finally(() => {

+ 7 - 1
src/pages/home/components/Toolbar.vue

@@ -4,7 +4,7 @@
       <div class="toolbar-item" @click="viewOrder">我的订单</div>
       <div class="toolbar-item" @click="viewOrder">我的订单</div>
       <div class="toolbar-item">分支</div>
       <div class="toolbar-item">分支</div>
       <div class="toolbar-item" title="点击查看培训信息" @click="handleTrain">培训</div>
       <div class="toolbar-item" title="点击查看培训信息" @click="handleTrain">培训</div>
-      <div class="toolbar-item">联系方式</div>
+      <div class="toolbar-item" @click="handleContact">联系我们</div>
       <a-dropdown placement="bottom">
       <a-dropdown placement="bottom">
         <div class="toolbar-item">语言切换</div>
         <div class="toolbar-item">语言切换</div>
         <template #overlay>
         <template #overlay>
@@ -44,6 +44,8 @@ const props = defineProps({
   }
   }
 })
 })
 
 
+const emits = defineEmits(['contact-us']);
+
 const router = useRouter()
 const router = useRouter()
 const mainData = reactive({
 const mainData = reactive({
   open: false,
   open: false,
@@ -71,6 +73,10 @@ const handleTrain = async () => {
     path: '/train'
     path: '/train'
   })
   })
 }
 }
+
+const handleContact = () => {
+  emits('contact-us')
+}
 </script>
 </script>
 
 
 <style lang="less" scoped>
 <style lang="less" scoped>

+ 43 - 120
src/pages/home/index.vue

@@ -5,6 +5,7 @@
       <Toolbar
       <Toolbar
         :isLogin="isLogin"
         :isLogin="isLogin"
         :storageId="storageId"
         :storageId="storageId"
+        @contact-us="contactUsFn"
       />
       />
       <HandleBar
       <HandleBar
         :isLogin="isLogin"
         :isLogin="isLogin"
@@ -18,67 +19,34 @@
       <RouterView />
       <RouterView />
     </main>
     </main>
     <LinkList v-if="mainData.linkList" :data="mainData.linkList" />
     <LinkList v-if="mainData.linkList" :data="mainData.linkList" />
-    <div v-if="showBackIcon" class="back-icon__box">
-      <a-button type="primary" shape="round" @click="router.back()">back</a-button>
-    </div>
-    <div class="back-icon__box msg-icon__box" @click="handleMessage">
-      <MessageOutlined :style="{fontSize: '42px', color: '#666', cursor: 'pointer'}" />
-    </div>
-    <a-modal
-      v-model:open="msgForm.open"
-      title="留言板"
-      :footer="null"
+    <LevelMessage :open="mainData.msgOpen" :contact-us="mainData.contactUs" @close="mainData.msgOpen = false" />
+    <a-float-button
+      shape="circle"
+      type="primary"
+      :style="{
+        right: '20px',
+        bottom: '20px'
+      }"
+      @click="handleLevelMsg"
     >
     >
-      <div style="text-align: center;">
-        <Logo size="120px" />
-      </div>
-      <a-form
-        ref="msgFormRef"
-        :model="msgForm"
-        name="msgForm"
-        layout="vertical"
-        @finish="submitMessage"
-      >
-        <a-form-item
-          label="姓"
-          name="firstName"
-          :rules="[{ required: true, message: '不能为空' }]"
-        >
-          <a-input v-model:value="msgForm.firstName" placeholder="请输入" allowClear />
-        </a-form-item>
-        <a-form-item
-          label="名"
-          name="lastName"
-          :rules="[{ required: true, message: '不能为空' }]"
-        >
-          <a-input v-model:value="msgForm.lastName" placeholder="请输入" allowClear />
-        </a-form-item>
-        <a-form-item
-          label="公司名称"
-          name="companyName"
-          :rules="[{ required: true, message: '不能为空' }]"
-        >
-          <a-input v-model:value="msgForm.companyName" placeholder="请输入" allowClear />
-        </a-form-item>
-        <a-form-item
-          label="手机号码"
-          name="mobile"
-          :rules="[{ required: true, validator: checkMobile }]"
-        >
-          <a-input v-model:value="msgForm.mobile" placeholder="请输入" allowClear />
-        </a-form-item>
-        <a-form-item
-          label="留言内容"
-          name="message"
-          :rules="[{ required: true, message: '不能为空' }]"
-        >
-          <a-input v-model:value="msgForm.message" placeholder="请输入" allowClear />
-        </a-form-item>
-        <a-form-item>
-          <a-button type="primary" html-type="submit" block :disabled="mainData.disabled">发 送</a-button>
-        </a-form-item>
-      </a-form>
-    </a-modal>
+      <template #icon>
+        <MessageOutlined />
+      </template>
+    </a-float-button>
+    <a-float-button
+      v-if="showBackIcon"
+      shape="circle"
+      type="primary"
+      :style="{
+        right: '70px',
+        bottom: '20px'
+      }"
+      @click="router.back()"
+    >
+      <template #icon>
+        <ArrowLeftOutlined />
+      </template>
+    </a-float-button>
   </div>
   </div>
 </template>
 </template>
 
 
@@ -88,9 +56,8 @@ import Toolbar from './components/Toolbar.vue';
 import HandleBar from './components/HandleBar.vue';
 import HandleBar from './components/HandleBar.vue';
 import Category from './components/Category.vue';
 import Category from './components/Category.vue';
 import LinkList from './components/LinkList.vue';
 import LinkList from './components/LinkList.vue';
-import Logo from '@/components/logo/index.vue'
-import { message } from 'ant-design-vue';
-import { MessageOutlined } from '@ant-design/icons-vue';
+import LevelMessage from './components/LevelMessage.vue';
+import { MessageOutlined, ArrowLeftOutlined } from '@ant-design/icons-vue';
 import { onMounted, computed, ref, reactive, nextTick } from 'vue';
 import { onMounted, computed, ref, reactive, nextTick } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import { useRoute, useRouter } from 'vue-router';
 import { useUserStore } from '@/store/user';
 import { useUserStore } from '@/store/user';
@@ -100,8 +67,6 @@ import { useCategoryStore } from '@/store/category';
 import { useStorageStore } from '@/store/storage';
 import { useStorageStore } from '@/store/storage';
 import { getNotice } from '@/api/common';
 import { getNotice } from '@/api/common';
 import { getAmityList } from '@/api/home';
 import { getAmityList } from '@/api/home';
-import { userLeaveMessage } from '@/api/user';
-import { validPhone } from '@/utils/validate';
 
 
 const route = useRoute();
 const route = useRoute();
 const router = useRouter();
 const router = useRouter();
@@ -120,56 +85,14 @@ const showBackIcon = computed(() => route.path !== '/category');
 const storeList = computed(() => storageStore.list);
 const storeList = computed(() => storageStore.list);
 const storageId = computed(() => storageStore.activedId);
 const storageId = computed(() => storageStore.activedId);
 
 
-const msgFormRef = ref()
 const mainData = reactive({
 const mainData = reactive({
   linkList: [],
   linkList: [],
   noticeContent: '',
   noticeContent: '',
-  disabled: false
-})
-
-const msgForm = reactive({
-  open: false,
-  firstName: '',
-  lastName: '',
-  companyName: '',
-  mobile: '',
-  message: ''
+  disabled: false,
+  msgOpen: false,
+  contactUs: false
 })
 })
 
 
-const handleMessage = () => {
-  msgForm.open = true
-  msgForm.firstName = ''
-  msgForm.lastName = ''
-  msgForm.companyName = ''
-  msgForm.mobile = ''
-  msgForm.message = ''
-  nextTick(() => {
-    msgFormRef.value?.clearValidate()
-  })
-}
-
-const submitMessage = () => {
-  mainData.disabled = true
-  userLeaveMessage({
-    firstName: msgForm.firstName,
-    lastName: msgForm.lastName,
-    companyName: msgForm.companyName,
-    mobile: msgForm.mobile,
-    message: msgForm.message
-  }).then(() => {
-    msgForm.open = false
-    message.success('留言成功')
-  }).finally(() => {
-    mainData.disabled = false
-  })
-}
-
-const checkMobile = (rule, value) => {
-  if (value === '') return Promise.reject('不能为空')
-  if (!validPhone(value)) return Promise.reject('格式有误')
-  return Promise.resolve()
-}
-
 const changeTabsFn = async (newTabIndex) => {
 const changeTabsFn = async (newTabIndex) => {
   homeStore.changeTab(newTabIndex);
   homeStore.changeTab(newTabIndex);
   goodsStore.resetParams();
   goodsStore.resetParams();
@@ -208,6 +131,16 @@ const fetchgetAmityList = async () => {
   mainData.linkList = res.data || []
   mainData.linkList = res.data || []
 }
 }
 
 
+const handleLevelMsg = () => {
+  mainData.msgOpen = true;
+  mainData.contactUs = false;
+}
+
+const contactUsFn = () => {
+  mainData.msgOpen = true;
+  mainData.contactUs = true;
+}
+
 onMounted(async () => {
 onMounted(async () => {
   await storageStore.fetchListData();
   await storageStore.fetchListData();
   if (storeList.value && storeList.value.length > 0) {
   if (storeList.value && storeList.value.length > 0) {
@@ -236,14 +169,4 @@ onMounted(async () => {
   padding: 20px;
   padding: 20px;
 }
 }
 
 
-.back-icon__box,
-.msg-icon__box {
-  position: fixed;
-  bottom: 50px;
-  right: 30px;
-  z-index: 9999;
-}
-.msg-icon__box {
-  bottom: 0;
-}
 </style>
 </style>

+ 3 - 14
src/pages/login/index.vue

@@ -6,11 +6,9 @@
       </div>
       </div>
       <a-form
       <a-form
         ref="formRef"
         ref="formRef"
-        name="form"
+        name="formRef"
         :model="mainForm"
         :model="mainForm"
-        :label-col="{ style: {width: '100px'}}"
-        :wrapper-col="{ span: 16 }"
-        autocomplete="off"
+        :label-col="{ style: {width: '80px'}}"
         @finish="onFinish"
         @finish="onFinish"
       >
       >
         <a-form-item
         <a-form-item
@@ -57,15 +55,6 @@
         </a-form-item>
         </a-form-item>
       </a-form>
       </a-form>
     </div>
     </div>
-    <!-- <a-modal
-      v-model:open="mainForm.open"
-      title="验证"
-      centered
-      :footer="null"
-    >
-      <div style="margin: 0 auto;">
-      </div>
-    </a-modal> -->
     <div v-if="mainForm.open">
     <div v-if="mainForm.open">
       <SliderVerify
       <SliderVerify
         ref="verification"
         ref="verification"
@@ -209,7 +198,7 @@ const checkAccount = (rule, value) => {
   justify-content: center;
   justify-content: center;
   background: #f2f2f2;
   background: #f2f2f2;
   .form-content {
   .form-content {
-    width: 520px;
+    width: 480px;
     padding: 24px;
     padding: 24px;
     background: #fff;
     background: #fff;
     border-radius: 10px;
     border-radius: 10px;

+ 0 - 2
src/pages/register/index.vue

@@ -8,8 +8,6 @@
         name="form"
         name="form"
         :model="mainForm"
         :model="mainForm"
         :label-col="{ style: {width: '100px'}}"
         :label-col="{ style: {width: '100px'}}"
-        :wrapper-col="{ span: 16 }"
-        autocomplete="off"
         @finish="onFinish"
         @finish="onFinish"
       >
       >
         <a-form-item
         <a-form-item

+ 9 - 0
src/utils/enum.js

@@ -0,0 +1,9 @@
+export const TakeTypeEnum = {
+  PICK: 0,// 自提
+  DISPATCH: 1,// 商家配送
+}
+
+export const PayTypeEnum = {
+  STORE: 2,// 到店
+  CREDIT: 3,// 授信
+}