Ver código fonte

feat(order): 优化订单详情展示逻辑并统一金额格式化方式

- 引入 formatCurrency 工具函数统一处理金额显示
- 更新订单详情字段映射以匹配后端接口返回结构
- 修改券码列表渲染逻辑支持嵌套数据结构
- 调整优惠券状态及类型显示枚举值
- 替换模拟数据为真实 API 接口调用
- 修复数量字段显示逻辑并添加单位标识
- 完善库存相关字段的展示格式
- 移除冗余的临时测试代码和无用注释
- 修正有效期类型判断条件及相关配置项
- 扩展小时选项范围至 24 点
- 重构部分组件导入语句提升可读性
- 删除已弃用的旧接口方法和未使用的工具函数
- 优化空值处理确保页面容错能力
- 规范货币符号使用全角人民币符号"¥"
congxuesong 4 meses atrás
pai
commit
c0885338ba

+ 2 - 20
src/api/modules/orderManagement.ts

@@ -8,24 +8,6 @@ export const getThaliList = params => {
 export const getCpList = params => {
   return http.get<ResPage<StoreUser.ResStoreUserList>>(PORT_NONE + `/PcGroupBuy/getCpList`, params);
 };
-export const deleteThali = (params: { id: string }) => {
-  return http.delete(PORT_NONE + `/PcGroupBuy/deleteThali`, params);
-};
-export const sjxj = params => {
-  return http.get(PORT_NONE + `/PcGroupBuy/sjxj`, params);
-};
-export const xgkc = params => {
-  return http.get(PORT_NONE + `/PcGroupBuy/xgkc`, params);
-};
-export const saveDraft = params => {
-  return http.post(PORT_NONE + `/PcGroupBuy/saveDraft`, params);
-};
-export const getMenuByStoreId = params => {
-  return http.get(PORT_NONE + `/menuPlatform/getMenuByStoreId`, params);
-};
-export const getHolidayList = (params: any) => {
-  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/couponPlatform/getHolidayList`, params);
-};
-export const getStoreDetail = (params: StoreUser.ReqUserParams) => {
-  return http.get<StoreUser.ResStoreUserList>(PORT_NONE + `/store/info/getStoreDetail`, params);
+export const queryUserOrderDetail = (params: StoreUser.ReqUserParams) => {
+  return http.get(PORT_NONE + `/userOrderPlatform/queryUserOrderDetail`, params);
 };

+ 22 - 0
src/utils/formatCurrency.ts

@@ -0,0 +1,22 @@
+export function formatCurrency(num, decimalPlaces = 2, prefix = "", suffix = "") {
+  // 处理非数字情况
+  if (isNaN(num)) return "0.00";
+
+  // 转换为数字并四舍五入
+  const number = Number(num);
+  const rounded = Math.round(number * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces);
+
+  // 分割整数和小数部分
+  const parts = rounded.toString().split(".");
+  const integerPart = parts[0];
+  const decimalPart = parts[1] || "";
+
+  // 整数部分添加千位分隔符
+  const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+
+  // 处理小数部分(补零)
+  const formattedDecimal = decimalPart.padEnd(decimalPlaces, "0").slice(0, decimalPlaces);
+
+  // 组合结果
+  return `${prefix}${formattedInteger}${decimalPlaces > 0 ? "." + formattedDecimal : ""}${suffix}`;
+}

+ 95 - 77
src/views/orderManagement/detail.vue

@@ -15,7 +15,7 @@
           <div class="detail-item">
             <div class="detail-label">订单名称</div>
             <div class="detail-value">
-              {{ formData.productName || "--" }}
+              {{ formData.couponName || "--" }}
             </div>
           </div>
           <!-- 订单编号 -->
@@ -29,56 +29,54 @@
           <div class="detail-item">
             <div class="detail-label">下单时间</div>
             <div class="detail-value">
-              {{ formData.orderTime || "--" }}
+              {{ formData.createdTime || "--" }}
             </div>
           </div>
           <!-- 原价 -->
           <div class="detail-item">
             <div class="detail-label">原价</div>
             <div class="detail-value">
-              {{ formData.originalPrice ? `¥${formData.originalPrice}` : "--" }}
+              {{ formatCurrency(formData.originalPrice, 2, "¥") }}
             </div>
           </div>
           <!-- 优惠价 -->
           <div class="detail-item">
             <div class="detail-label">优惠价</div>
             <div class="detail-value">
-              {{ formData.discountedPrice ? `¥${formData.discountedPrice}` : "--" }}
+              {{ formatCurrency(formData.price, 2, "¥") }}
             </div>
           </div>
           <!-- 数量 -->
           <div class="detail-item">
             <div class="detail-label">数量</div>
-            <div class="detail-value">
-              {{ formData.quantity || "--" }}
-            </div>
+            <div class="detail-value">x{{ formData.orderCouponMiddleList ? formData.orderCouponMiddleList.length : 0 }}</div>
           </div>
           <!-- 优惠券减免 -->
           <div class="detail-item">
             <div class="detail-label">优惠券减免</div>
             <div class="detail-value">
-              {{ formData.couponDiscount ? `¥${formData.couponDiscount}` : "--" }}
+              {{ formatCurrency(formData.nominalValue, 2, "¥") }}
             </div>
           </div>
           <!-- 优惠券类型 -->
           <div class="detail-item">
             <div class="detail-label">优惠券类型</div>
             <div class="detail-value">
-              {{ formData.couponType || "--" }}
+              {{ getCouponType(formData.type) }}
             </div>
           </div>
           <!-- 预留手机号 -->
           <div class="detail-item">
             <div class="detail-label">预留手机号</div>
             <div class="detail-value">
-              {{ formData.phone || "--" }}
+              {{ formData.userPhone || "--" }}
             </div>
           </div>
           <!-- 预计收入 -->
           <div class="detail-item">
             <div class="detail-label">预计收入</div>
             <div class="detail-value">
-              {{ formData.estimatedIncome ? `¥${formData.estimatedIncome}` : "--" }}
+              {{ formatCurrency(formData.expectIncome, 2, "¥") }}
             </div>
           </div>
         </div>
@@ -97,29 +95,31 @@
                   {{ getCouponStatusName(coupon.status) }}
                 </div>
               </div>
-              <!-- 券码 -->
-              <div class="detail-item">
-                <div class="detail-label">券码</div>
-                <div class="detail-value">
-                  {{ coupon.code || "--" }}
+              <template v-for="(item, index) in coupon.list" :key="index">
+                <!-- 券码 -->
+                <div class="detail-item">
+                  <div class="detail-label">券码</div>
+                  <div class="detail-value">
+                    {{ item.couponCode || "--" }}
+                  </div>
                 </div>
-              </div>
-              <!-- 核销时间 -->
-              <div v-if="coupon.status === '2'" class="detail-item">
-                <div class="detail-label">核销时间</div>
-                <div class="detail-value">
-                  {{ coupon.verifyTime || "--" }}
+                <!-- 核销时间 -->
+                <div v-if="item.usedTime && coupon.status == 2" class="detail-item">
+                  <div class="detail-label">核销时间</div>
+                  <div class="detail-value">
+                    {{ item.usedTime || "--" }}
+                  </div>
                 </div>
-              </div>
-              <!-- 退款时间 -->
-              <div v-if="coupon.status === '3'" class="detail-item">
-                <div class="detail-label">退款时间</div>
-                <div class="detail-value">
-                  {{ coupon.refundTime || "--" }}
+                <!-- 退款时间 -->
+                <div v-if="item.refundTime && coupon.status == 5" class="detail-item">
+                  <div class="detail-label">退款时间</div>
+                  <div class="detail-value">
+                    {{ item.refundTime || "--" }}
+                  </div>
                 </div>
-              </div>
-              <!-- 分隔线 -->
-              <el-divider v-if="index < couponList.length - 1" style="margin: 20px 0" />
+                <!-- 分隔线 -->
+                <el-divider v-if="index < couponList.length - 1" style="margin: 20px 0" />
+              </template>
             </div>
           </div>
           <div v-else class="empty-text">--</div>
@@ -134,10 +134,12 @@
  * 订单管理 - 详情页面
  * 功能:显示订单的详细信息
  */
-import { ref, onMounted } from "vue";
+import { ref, onMounted, computed } from "vue";
 import { useRoute, useRouter } from "vue-router";
 import { ElMessage } from "element-plus";
 import { getStaffConfigDeatail } from "@/api/modules/staffConfig";
+import { queryUserOrderDetail } from "@/api/modules/orderManagement";
+import { formatCurrency } from "@/utils/formatCurrency";
 
 // ==================== 响应式数据定义 ====================
 
@@ -157,15 +159,40 @@ const couponList = ref<any[]>([]);
 /**
  * 获取券码状态名称
  */
-const getCouponStatusName = (status: string) => {
-  const statusMap: Record<string, string> = {
-    "1": "未核销",
-    "2": "已核销",
-    "3": "已退款"
+const getCouponStatusName = computed(() => {
+  return status => {
+    switch (status) {
+      case 0:
+        return "待支付";
+      case 1:
+        return "未核销";
+      case 2:
+        return "已核销";
+      case 3:
+        return "已过期";
+      case 4:
+        return "已取消";
+      case 5:
+        return "已退款";
+      default:
+        return "--";
+    }
   };
-  return statusMap[status] || "--";
-};
-
+});
+const getCouponType = computed(() => {
+  return status => {
+    switch (status) {
+      case 1:
+        return "优惠券";
+      case 2:
+        return "红包";
+      case 3:
+        return "平台优惠券";
+      default:
+        return "--";
+    }
+  };
+});
 // ==================== 生命周期钩子 ====================
 
 /**
@@ -193,48 +220,39 @@ const goBack = () => {
 const initData = async () => {
   if (id.value) {
     try {
-      // TODO: 根据实际API获取订单详情
-      // const response = await getOrderDetail({ id: id.value });
-      // if (response.code === 200) {
-      //   formData.value = response.data;
-      //   couponList.value = response.data.couponList || [];
-      // }
-
-      // 临时模拟数据
-      formData.value = {
-        productName: "4拼冰淇淋蛋糕套餐",
-        orderNo: "17554469202966300062",
-        orderTime: "2025/01/01 12:00:00",
-        originalPrice: 400,
-        discountedPrice: 380,
-        quantity: 3,
-        couponDiscount: 20,
-        couponType: "商家优惠券/平台优惠券",
-        phone: "18900000000",
-        estimatedIncome: 380
-      };
-
-      couponList.value = [
-        {
-          status: "1",
-          code: "B844556562220"
-        },
-        {
-          status: "2",
-          code: "B844556562220",
-          verifyTime: "2025/01/01 12:00:00"
-        },
-        {
-          status: "3",
-          code: "B844556562220",
-          refundTime: "2025/01/01 12:00:00"
-        }
-      ];
+      const res: any = await queryUserOrderDetail({ orderId: id.value });
+      if (res.code === 200) {
+        formData.value = res.data;
+        couponList.value = groupByA(formData.value.orderCouponMiddleList) || [];
+      }
     } catch (error) {
       ElMessage.error("获取详情失败");
     }
   }
 };
+const groupByA = arr => {
+  // 创建一个映射表存储每个status值对应的条目
+  const map = {};
+
+  // 遍历原始数组
+  arr.forEach(item => {
+    // 从当前项中提取status字段
+    const { status, ...rest } = item;
+    // 如果当前status值在映射表中不存在,则创建一个新条目
+    if (!map[status]) {
+      map[status] = {
+        status: status,
+        list: []
+      };
+    }
+
+    // 将剩余的所有字段添加到对应status的list中
+    map[status].list.push(rest);
+  });
+
+  // 将映射表的值转换为数组并返回
+  return Object.values(map);
+};
 </script>
 
 <style scoped lang="scss">

+ 8 - 4
src/views/orderManagement/index.vue

@@ -38,6 +38,7 @@ import ProTable from "@/components/ProTable/index.vue";
 import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
 import { getThaliList, getCpList } from "@/api/modules/orderManagement";
 import { localGet, usePermission } from "@/utils";
+import { formatCurrency } from "@/utils/formatCurrency";
 
 const router = useRouter();
 const proTable = ref<ProTableInstance>();
@@ -91,20 +92,23 @@ const columns = reactive<ColumnProps<any>[]>([
   },
   {
     prop: "couponCount",
-    label: "数量"
+    label: "数量",
+    render: (scope: any) => {
+      return scope.row.couponCount ? `x${scope.row.couponCount}` : "--";
+    }
   },
   {
-    prop: "finalPrice",
+    prop: "price",
     label: "实付款",
     render: (scope: any) => {
-      return scope.row.finalPrice ? `¥${scope.row.finalPrice}` : "--";
+      return formatCurrency(scope.row.price, 2, "¥") || "--";
     }
   },
   {
     prop: "estimatedIncome",
     label: "本单预计收入",
     render: (scope: any) => {
-      return scope.row.estimatedIncome ? `¥${scope.row.estimatedIncome}` : "--";
+      return formatCurrency(scope.row.expectIncome, 2, "¥") || "--";
     }
   },
   {

+ 2 - 1
src/views/ticketManagement/couponDetail.vue

@@ -22,7 +22,7 @@
           <div class="detail-item">
             <div class="detail-label">面值(元)</div>
             <div class="detail-value">
-              {{ couponModel.nominalValue ? `¥${couponModel.nominalValue}` : "--" }}
+              {{ formatCurrency(couponModel.nominalValue, 2, "¥") }}
             </div>
           </div>
           <!-- 开始领取时间 -->
@@ -112,6 +112,7 @@ import { ref, onMounted } from "vue";
 import { useRouter, useRoute } from "vue-router";
 import { ElMessage } from "element-plus";
 import { getCouponDetail } from "@/api/modules/couponManagement";
+import { formatCurrency } from "@/utils/formatCurrency";
 
 // ==================== 响应式数据定义 ====================
 

+ 7 - 7
src/views/ticketManagement/detail.vue

@@ -22,14 +22,14 @@
           <div class="detail-item">
             <div class="detail-label">抵扣价格</div>
             <div class="detail-value">
-              {{ voucherModel.offprice ? `¥${voucherModel.offprice}` : "--" }}
+              {{ formatCurrency(voucherModel.offprice, 2, "¥") || "--" }}
             </div>
           </div>
           <!-- 售卖价格 -->
           <div class="detail-item">
             <div class="detail-label">售卖价格</div>
             <div class="detail-value">
-              {{ voucherModel.price ? `¥${voucherModel.price}` : "--" }}
+              {{ formatCurrency(voucherModel.price, 2, "¥") || "--" }}
             </div>
           </div>
           <!-- 开始售卖时间 -->
@@ -75,7 +75,7 @@
           <div class="detail-item">
             <div class="detail-label">库存</div>
             <div class="detail-value">
-              {{ voucherModel.singleQty || "--" }}
+              {{ voucherModel.singleQty + "张" || "--" }}
             </div>
           </div>
         </div>
@@ -126,6 +126,7 @@ import { ref, onMounted } from "vue";
 import { useRouter, useRoute } from "vue-router";
 import { ElMessage } from "element-plus";
 import { getVoucherDetail, getHolidayList } from "@/api/modules/voucherManagement";
+import { formatCurrency } from "@/utils/formatCurrency";
 
 // ==================== 响应式数据定义 ====================
 
@@ -368,12 +369,11 @@ const getExpirationText = () => {
  * 获取不可用日期文本
  */
 const getUnavailableDateText = () => {
-  if (voucherModel.value.unusedType === "0" || voucherModel.value.unusedType == 0) {
+  if (voucherModel.value.unusedType == "1") {
     return "全部日期可用";
-  } else if (voucherModel.value.unusedType === "1" || voucherModel.value.unusedType == 1) {
+  } else if (voucherModel.value.unusedType === "2") {
     const weekdays: string[] = [];
     const holidays: string[] = [];
-
     // 处理星期
     if (voucherModel.value.unavailableWeekdays && voucherModel.value.unavailableWeekdays.length > 0) {
       voucherModel.value.unavailableWeekdays.forEach((day: string) => {
@@ -403,7 +403,7 @@ const getUnavailableDateText = () => {
     }
 
     return parts.length > 0 ? parts.join("、") : "--";
-  } else if (voucherModel.value.unusedType === "2" || voucherModel.value.unusedType == 2) {
+  } else if (voucherModel.value.unusedType == "3") {
     if (voucherModel.value.disableDateList && voucherModel.value.disableDateList.length > 0) {
       const dateStrings = voucherModel.value.disableDateList
         .filter((date: any) => date && Array.isArray(date) && date.length === 2)

+ 9 - 8
src/views/ticketManagement/index.vue

@@ -88,7 +88,8 @@
         <el-button
           v-if="
             isVoucher
-              ? canShowButton(scope.row.status, currentOperationPermissions.编辑) && scope.row.dataType == 1
+              ? canShowButton(scope.row.status, currentOperationPermissions.编辑) ||
+                (scope.row.dataType == 1 && scope.row.status == 0)
               : canShowButton(scope.row.status, currentOperationPermissions.编辑)
           "
           link
@@ -101,7 +102,8 @@
         <el-button
           v-if="
             isVoucher
-              ? canShowButton(scope.row.status, currentOperationPermissions.删除) && scope.row.dataType == 1
+              ? canShowButton(scope.row.status, currentOperationPermissions.删除) ||
+                (scope.row.dataType == 1 && scope.row.status == 0)
               : canShowButton(scope.row.status, currentOperationPermissions.删除)
           "
           link
@@ -117,9 +119,7 @@
         <el-form-item label="套餐名">
           {{ formInventory.name }}
         </el-form-item>
-        <el-form-item label="剩余库存">
-          {{ formInventory.singleQty }}
-        </el-form-item>
+        <el-form-item label="剩余库存"> {{ formInventory.singleQty }}张 </el-form-item>
         <el-form-item label="修改库存" prop="newInventory">
           <el-input v-model="formInventory.newInventory" placeholder="请输入" />
         </el-form-item>
@@ -168,6 +168,7 @@ import { delThaliById, getThaliList, updateNum, updateStatus } from "@/api/modul
 import { delCouponById, updateCouponSingleQty, updateCouponStatus } from "@/api/modules/couponManagement";
 import { ElMessageBox } from "element-plus/es";
 import { localGet, usePermission } from "@/utils";
+import { formatCurrency } from "@/utils/formatCurrency";
 
 const router = useRouter();
 const route = useRoute();
@@ -248,7 +249,7 @@ const voucherColumns = reactive<ColumnProps<any>[]>([
     prop: "price",
     label: "价格",
     render: (scope: any) => {
-      return scope.row.price ? `¥${scope.row.price}` : "--";
+      return formatCurrency(scope.row.price, 2, "¥") || "--";
     }
   },
   {
@@ -264,7 +265,7 @@ const voucherColumns = reactive<ColumnProps<any>[]>([
     render: scope => {
       return scope.row.singleQty === null || scope.row.singleQty === undefined || scope.row.singleQty === ""
         ? 0
-        : scope.row.singleQty;
+        : scope.row.singleQty + "张";
     }
   },
   {
@@ -308,7 +309,7 @@ const couponColumns = reactive<ColumnProps<any>[]>([
     render: scope => {
       return scope.row.singleQty === null || scope.row.singleQty === undefined || scope.row.singleQty === ""
         ? 0
-        : scope.row.singleQty;
+        : scope.row.singleQty + "张";
     }
   },
   {

+ 14 - 14
src/views/ticketManagement/newVoucher.vue

@@ -68,7 +68,7 @@
                 </el-radio>
               </el-radio-group>
             </el-form-item>
-            <el-form-item label="" prop="expirationDate" v-if="voucherModel.expirationType == 0">
+            <el-form-item label="" prop="expirationDate" v-if="voucherModel.expirationType == 1">
               <div class="expiration-date-container">
                 <span class="expiration-label">用户购买</span>
                 <el-input-number
@@ -385,7 +385,7 @@ const rules = reactive({
     {
       required: true,
       validator: (rule: any, value: any, callback: any) => {
-        if (voucherModel.value.expirationType == 0) {
+        if (voucherModel.value.expirationType == 1) {
           if (value === null || value === undefined || value === "") {
             callback(new Error("请输入用户购买天数"));
             return;
@@ -419,7 +419,7 @@ const rules = reactive({
     {
       required: true,
       validator: (rule: any, value: any, callback: any) => {
-        if (voucherModel.value.expirationType == 1) {
+        if (voucherModel.value.expirationType == 2) {
           if (!value || value.length !== 2) {
             callback(new Error("请选择指定时间段"));
             return;
@@ -601,10 +601,10 @@ const voucherModel = ref<any>({
   // 使用时间(虚拟字段,用于表单验证)
   usageTime: null,
   // 有效期类型:0-指定天数,1-指定时间段内可用
-  expirationType: "0",
-  // 有效期天数(当expirationType为0时使用)
+  expirationType: "1",
+  // 有效期天数(当expirationType为1时使用)
   expirationDate: 0,
-  // 有效期时间段(当expirationType为1时使用)
+  // 有效期时间段(当expirationType为2时使用)
   validityPeriod: [],
   // 不可用日期类型:0-全部日期可用,1-限制日期
   unusedType: "0",
@@ -630,9 +630,9 @@ const voucherModel = ref<any>({
 
 // ==================== 下拉选项数据 ====================
 
-// 小时选项列表(0-23点)
+// 小时选项列表(0-24点)
 const hourOptions = ref(
-  Array.from({ length: 24 }, (_, i) => ({
+  Array.from({ length: 25 }, (_, i) => ({
     value: String(i),
     label: `${i}点`
   }))
@@ -640,8 +640,8 @@ const hourOptions = ref(
 
 // 有效期类型列表
 const validityPeriodList = ref([
-  { value: "0", label: "指定天数" },
-  { value: "1", label: "指定时间段内可用" }
+  { value: "1", label: "指定天数" },
+  { value: "2", label: "指定时间段内可用" }
 ]);
 
 // 不可用日期类型列表
@@ -828,7 +828,7 @@ onMounted(async () => {
     let res: any = await getVoucherDetail({ id: id.value });
     voucherModel.value = { ...voucherModel.value, ...res.data };
     // 处理有效期时间段:将时间戳字符串转换为数字数组
-    if (voucherModel.value.validityPeriod && voucherModel.value.expirationType == 1) {
+    if (voucherModel.value.validityPeriod && voucherModel.value.expirationType == 2) {
       const periodArray = voucherModel.value.validityPeriod.split(",");
       voucherModel.value.validityPeriod = periodArray
         .map((item: string) => Number(item.trim()))
@@ -941,10 +941,10 @@ const handleSubmit = async (submitType?: string) => {
   let params: any = { ...voucherModel.value };
   params.storeId = localGet("createdId");
   params.status = 1;
-  // 处理有效期:只有当expirationType为1(指定时间段内可用)时才处理validityPeriod
-  if (params.expirationType == 1 && params.validityPeriod && Array.isArray(params.validityPeriod)) {
+  // 处理有效期:只有当expirationType为2(指定时间段内可用)时才处理validityPeriod
+  if (params.expirationType == 2 && params.validityPeriod && Array.isArray(params.validityPeriod)) {
     params.validityPeriod = params.validityPeriod.join(",");
-  } else if (params.expirationType == 0) {
+  } else if (params.expirationType == 1) {
     // 指定天数模式,不需要validityPeriod字段
     params.validityPeriod = "";
   }