Pārlūkot izejas kodu

fix 接口调试

haveyou 1 gadu atpakaļ
vecāks
revīzija
fce0b2c834

+ 142 - 0
src/components/CommonPage/CommonExportLog.vue

@@ -0,0 +1,142 @@
+<!-- 编辑弹窗 -->
+<template>
+  <ele-modal
+    form
+    :width="1160"
+    v-model="visible"
+    title="导出记录"
+    @open="handleOpen"
+    :body-style="{ padding: '0 20px' }"
+  >
+    <common-table
+      ref="pageRef"
+      :pageConfig="pageConfig"
+      :columns="columns"
+      :tools="false"
+    >
+      <template #toolbar>
+        <ProDatePicker
+          start-placeholder="申请时间(开始时间)"
+          end-placeholder="申请时间(结束时间)"
+          v-model="searchData"
+        />
+        <el-button type="primary" @click="reload" class="ml-4">查询</el-button>
+        <el-button type="info" @click="handleReset">重置</el-button>
+      </template>
+
+      <template #action="{ row }">
+        <el-button
+          type="primary"
+          link
+          :disabled="row.exportStatus != 3 || row.cleanStatus == 1"
+          @click="handleDownload(row)"
+          class="ml-4"
+          >[下载]</el-button
+        >
+        <el-button
+          type="danger"
+          link
+          @click="handleDelete(row)"
+          :disabled="row.exportStatus == 1"
+          >[删除]</el-button
+        >
+      </template>
+    </common-table>
+    <template #footer>
+      <el-button @click="handleCancel">关闭</el-button>
+    </template>
+  </ele-modal>
+</template>
+
+<script setup>
+  import { ref, reactive, nextTick } from 'vue';
+  import request from '@/utils/request';
+  import CommonTable from '@/components/CommonPage/CommonTable.vue';
+  import ProDatePicker from '@/components/CommonPage/ProDatePicker.vue';
+  import { download, toFormData, checkDownloadRes } from '@/utils/common';
+
+  const searchData = ref({ createTimeStart: '', createTimeEnd: '' });
+
+  const pageRef = ref(null);
+  function reload() {
+    pageRef.value?.reload(searchData.value);
+  }
+  function handleReset() {
+    searchData.value.createTimeStart = '';
+    searchData.value.createTimeEnd = '';
+    reload();
+  }
+
+  /** 弹窗是否打开 */
+  const visible = defineModel({ type: Boolean });
+
+  /** 关闭弹窗 */
+  const handleCancel = () => {
+    visible.value = false;
+  };
+
+  /** 弹窗打开事件 */
+  const handleOpen = () => {
+    visible.value = true;
+  };
+
+  let statusKeys = ['', '处理中', '失败', '成功'];
+  // cleanStatus 文件清理状态 0未清理 1已清理
+  /** 表格列配置 */
+  const columns = ref([
+    { label: '申请时间', prop: 'createTime', align: 'center', width: 160 },
+    { label: '导出名', prop: 'exportName', align: 'center' },
+    { label: '条数', prop: 'dataCount', align: 'center', width: 90 },
+    { label: '操作员', prop: 'createName', align: 'center', width: 120 },
+    {
+      label: '处理状态',
+      prop: 'exportStatus',
+      align: 'center',
+      formatter: (row) => statusKeys[row.exportStatus],
+      width: 90
+    },
+    {
+      label: '上次下载时间',
+      prop: 'downloadTime',
+      align: 'center',
+      width: 160
+    },
+    { label: '下载次数', prop: 'downloadNum', align: 'center', width: 90 },
+    {
+      columnKey: 'action',
+      label: '操作',
+      width: 150,
+      align: 'center',
+      slot: 'action'
+    }
+  ]);
+
+  const pageConfig = reactive({
+    pageUrl: '/common/exportrecord/pagelist',
+    fileName: '操作记录',
+    cacheKey: 'data-operation-log',
+    params: { logType: 1 }
+  });
+
+  async function handleDownload(row) {
+    const res = await request({
+      url: '/common/exportrecord/downLoadFile?id=' + row.id,
+      method: 'get',
+      responseType: 'blob'
+    });
+    await checkDownloadRes(res);
+    download(res.data, row.fileName);
+  }
+
+  //删除
+  function handleDelete(row) {
+    pageRef.value?.messageBoxConfirm({
+      message: '确定删除吗?',
+      fetch: () => request.get('/common/exportrecord/deleteRecord?id=' + row.id)
+    });
+  }
+
+  defineExpose({
+    handleOpen
+  });
+</script>

+ 2 - 1
src/components/CommonPage/SimpleFormModal.vue

@@ -6,7 +6,7 @@
     v-model="visible"
     :title="title"
     position="center"
-    :body-style="{ maxHeight: '84vh', position: 'relative' }"
+    :body-style="{ maxHeight: '84vh', position: 'relative', ...bodyStyle }"
   >
     <slot name="other"></slot>
 
@@ -54,6 +54,7 @@
     items: { type: Array, default: () => [] },
     title: { type: String, default: '编辑' },
     type: { type: String },
+    bodyStyle: { type: Object, default: () => ({}) },
     width: { type: String, default: '520px' },
     labelWidth: { type: String, default: '90px' },
     formProps: { type: Object, default: () => ({}) },

+ 18 - 1
src/layout/index.vue

@@ -81,6 +81,13 @@
           <ExpandOutlined v-else style="stroke-width: 4" />
         </el-icon>
       </layout-tool>
+      <!-- 导出记录 -->
+      <layout-tool class="hidden-sm-and-down" title="导出记录" @click="openExportLog">
+        <el-icon style="transform: scale(1.18)">
+          <DownloadOutlined />
+        </el-icon>
+      </layout-tool>
+
       <!-- 消息通知 -->
       <layout-tool :class="{ 'hidden-sm-and-down': tabBar && tabInHeader }">
         <header-notice />
@@ -156,9 +163,12 @@
   </ele-pro-layout>
   <!-- 主题设置抽屉 -->
   <setting-drawer v-model="settingVisible" />
+  <!-- 导出记录 -->
+  <common-export-log ref="exportLogRef" />
 </template>
 
 <script setup>
+  import CommonExportLog from '@/components/CommonPage/CommonExportLog.vue';
   import { ref, computed, markRaw } from 'vue';
   import { useRouter } from 'vue-router';
   import { storeToRefs } from 'pinia';
@@ -183,7 +193,8 @@
     MinusCircleOutlined,
     CloseCircleOutlined,
     MoonOutlined,
-    SunOutlined
+    SunOutlined,
+    DownloadOutlined
   } from '@/components/icons';
   import {
     PROJECT_NAME,
@@ -308,6 +319,12 @@
     ];
   });
 
+  //  打开导出记录
+  const exportLogRef = ref(null);
+  function openExportLog() {
+    exportLogRef.value?.handleOpen();
+  }
+
   /** 侧栏折叠切换 */
   const updateCollapse = (value) => {
     themeStore.setCollapse(value);

+ 0 - 1
src/styles/index.scss

@@ -200,7 +200,6 @@ body {
       line-height: 18px;
       padding: 0;
       width: fit-content !important;
-      background-color: #ffffff;
     }
   }
 

+ 133 - 122
src/utils/common.js

@@ -2,12 +2,11 @@ import { removeToken } from '@/utils/token-util';
 import axios from 'axios';
 
 export async function downloadOssLink(url, name) {
-  const res = await axios.get(url, {
-    responseType: 'blob' // 设置响应类型为blob,以便处理二进制数据
-  });
-  console.log(res, '12321321');
-  await checkDownloadRes(res);
-  download(res.data, `${name}_${Date.now()}.xlsx`);
+    const res = await axios.get(url, {
+        responseType: 'blob' // 设置响应类型为blob,以便处理二进制数据
+    });
+    await checkDownloadRes(res);
+    download(res.data, `${name}_${Date.now()}.xlsx`);
 }
 
 /**
@@ -17,18 +16,18 @@ export async function downloadOssLink(url, name) {
  * @param push 路由跳转方法
  */
 export function logout(route, from, push) {
-  removeToken();
-  if (route && push) {
-    push({
-      path: '/login',
-      query: from ? { from: encodeURIComponent(from) } : void 0
-    });
-    return;
-  }
-  // 这样跳转避免再次登录重复注册动态路由, hash 路由模式使用 location.reload();
-  const BASE_URL = import.meta.env.BASE_URL;
-  const url = BASE_URL + 'login';
-  location.replace(from ? `${url}?from=${encodeURIComponent(from)}` : url);
+    removeToken();
+    if (route && push) {
+        push({
+            path: '/login',
+            query: from ? { from: encodeURIComponent(from) } : void 0
+        });
+        return;
+    }
+    // 这样跳转避免再次登录重复注册动态路由, hash 路由模式使用 location.reload();
+    const BASE_URL = import.meta.env.BASE_URL;
+    const url = BASE_URL + 'login';
+    location.replace(from ? `${url}?from=${encodeURIComponent(from)}` : url);
 }
 
 /**
@@ -38,16 +37,16 @@ export function logout(route, from, push) {
  * @param type 文件类型
  */
 export function download(data, name, type) {
-  const blob = new Blob([data], { type: type || 'application/octet-stream' });
-  const url = URL.createObjectURL(blob);
-  const a = document.createElement('a');
-  a.href = url;
-  a.download = name;
-  a.style.display = 'none';
-  document.body.appendChild(a);
-  a.click();
-  document.body.removeChild(a);
-  URL.revokeObjectURL(url);
+    const blob = new Blob([data], { type: type || 'application/octet-stream' });
+    const url = URL.createObjectURL(blob);
+    const a = document.createElement('a');
+    a.href = url;
+    a.download = name;
+    a.style.display = 'none';
+    document.body.appendChild(a);
+    a.click();
+    document.body.removeChild(a);
+    URL.revokeObjectURL(url);
 }
 
 /**
@@ -56,16 +55,16 @@ export function download(data, name, type) {
  * @param url 需要拼接参数的地址
  */
 export function toURLSearch(params, url) {
-  if (typeof params !== 'object' || params == null) {
-    return '';
-  }
-  const result = transformParams(params)
-    .map((d) => `${encodeURIComponent(d[0])}=${encodeURIComponent(d[1])}`)
-    .join('&');
-  if (!url) {
-    return result;
-  }
-  return (url.includes('?') ? `${url}&` : `${url}?`) + result;
+    if (typeof params !== 'object' || params == null) {
+        return '';
+    }
+    const result = transformParams(params)
+        .map((d) => `${encodeURIComponent(d[0])}=${encodeURIComponent(d[1])}`)
+        .join('&');
+    if (!url) {
+        return result;
+    }
+    return (url.includes('?') ? `${url}&` : `${url}?`) + result;
 }
 
 /**
@@ -73,14 +72,14 @@ export function toURLSearch(params, url) {
  * @param params 参数
  */
 export function toFormData(params) {
-  const formData = new FormData();
-  if (typeof params !== 'object' || params == null) {
+    const formData = new FormData();
+    if (typeof params !== 'object' || params == null) {
+        return formData;
+    }
+    transformParams(params).forEach((d) => {
+        formData.append(d[0], d[1]);
+    });
     return formData;
-  }
-  transformParams(params).forEach((d) => {
-    formData.append(d[0], d[1]);
-  });
-  return formData;
 }
 
 /**
@@ -88,26 +87,26 @@ export function toFormData(params) {
  * @param params 参数
  */
 export function transformParams(params) {
-  const result = [];
-  if (params != null && typeof params === 'object') {
-    Object.keys(params).forEach((key) => {
-      const value = params[key];
-      if (value != null && value !== '') {
-        if (Array.isArray(value) && value.length && isBlobFile(value[0])) {
-          value.forEach((file) => {
-            result.push([key, file]);
-          });
-        } else if (typeof value === 'object' && !isBlobFile(value)) {
-          getObjectParamsArray(value).forEach((item) => {
-            result.push([`${key}${item[0]}`, item[1]]);
-          });
-        } else {
-          result.push([key, value]);
-        }
-      }
-    });
-  }
-  return result;
+    const result = [];
+    if (params != null && typeof params === 'object') {
+        Object.keys(params).forEach((key) => {
+            const value = params[key];
+            if (value != null && value !== '') {
+                if (Array.isArray(value) && value.length && isBlobFile(value[0])) {
+                    value.forEach((file) => {
+                        result.push([key, file]);
+                    });
+                } else if (typeof value === 'object' && !isBlobFile(value)) {
+                    getObjectParamsArray(value).forEach((item) => {
+                        result.push([`${key}${item[0]}`, item[1]]);
+                    });
+                } else {
+                    result.push([key, value]);
+                }
+            }
+        });
+    }
+    return result;
 }
 
 /**
@@ -115,21 +114,21 @@ export function transformParams(params) {
  * @param obj 对象
  */
 export function getObjectParamsArray(obj) {
-  const result = [];
-  Object.keys(obj).forEach((key) => {
-    const value = obj[key];
-    if (value != null && value !== '') {
-      const name = `[${key}]`;
-      if (typeof value === 'object' && !isBlobFile(value)) {
-        getObjectParamsArray(value).forEach((item) => {
-          result.push([`${name}${item[0]}`, item[1]]);
-        });
-      } else {
-        result.push([name, value]);
-      }
-    }
-  });
-  return result;
+    const result = [];
+    Object.keys(obj).forEach((key) => {
+        const value = obj[key];
+        if (value != null && value !== '') {
+            const name = `[${key}]`;
+            if (typeof value === 'object' && !isBlobFile(value)) {
+                getObjectParamsArray(value).forEach((item) => {
+                    result.push([`${name}${item[0]}`, item[1]]);
+                });
+            } else {
+                result.push([name, value]);
+            }
+        }
+    });
+    return result;
 }
 
 /**
@@ -137,7 +136,7 @@ export function getObjectParamsArray(obj) {
  * @param obj 对象
  */
 export function isBlobFile(obj) {
-  return obj != null && (obj instanceof Blob || obj instanceof File);
+    return obj != null && (obj instanceof Blob || obj instanceof File);
 }
 
 /**
@@ -145,13 +144,13 @@ export function isBlobFile(obj) {
  * @param res 请求结果
  */
 export async function checkDownloadRes(res) {
-  if (res.headers['content-type'].startsWith('application/json')) {
-    const json = await res.data.text();
-    return Promise.reject(
-      new Error(JSON.parse(json).msg || '系统未知错误,请反馈给管理员')
-    );
-  }
-  return true;
+    if (res.headers['content-type'].startsWith('application/json')) {
+        const json = await res.data.text();
+        return Promise.reject(
+            new Error(JSON.parse(json).msg || '系统未知错误,请反馈给管理员')
+        );
+    }
+    return true;
 }
 
 /**
@@ -161,39 +160,51 @@ export async function checkDownloadRes(res) {
  * @param isOut 是否是退出方向
  */
 export function doWithTransition(callback, el, isOut) {
-  if (!el || typeof document.startViewTransition !== 'function') {
-    callback().then(() => {});
-    return;
-  }
-  document.documentElement.classList.add('disabled-transition');
-  el.classList.add('view-transition-trigger');
-  el.style.setProperty('view-transition-name', 'view-transition-trigger');
-  const rect = el.getBoundingClientRect();
-  const x = rect.left + rect.width / 2;
-  const y = rect.top + rect.height / 2;
-  const endRadius = Math.hypot(
-    Math.max(x, innerWidth - x),
-    Math.max(y, innerHeight - y)
-  );
-  document.startViewTransition(callback).ready.then(() => {
-    const clipPath = [
-      `circle(0px at ${x}px ${y}px)`,
-      `circle(${endRadius}px at ${x}px ${y}px)`
-    ];
-    const anim = document.documentElement.animate(
-      { clipPath: isOut ? [...clipPath].reverse() : clipPath },
-      {
-        duration: 400,
-        easing: 'ease-in',
-        pseudoElement: isOut
-          ? `::view-transition-old(root)`
-          : `::view-transition-new(root)`
-      }
+    if (!el || typeof document.startViewTransition !== 'function') {
+        callback().then(() => { });
+        return;
+    }
+    document.documentElement.classList.add('disabled-transition');
+    el.classList.add('view-transition-trigger');
+    el.style.setProperty('view-transition-name', 'view-transition-trigger');
+    const rect = el.getBoundingClientRect();
+    const x = rect.left + rect.width / 2;
+    const y = rect.top + rect.height / 2;
+    const endRadius = Math.hypot(
+        Math.max(x, innerWidth - x),
+        Math.max(y, innerHeight - y)
     );
-    anim.onfinish = () => {
-      el.style.removeProperty('view-transition-name');
-      el.classList.remove('view-transition-trigger');
-      document.documentElement.classList.remove('disabled-transition');
-    };
-  });
+    document.startViewTransition(callback).ready.then(() => {
+        const clipPath = [
+            `circle(0px at ${x}px ${y}px)`,
+            `circle(${endRadius}px at ${x}px ${y}px)`
+        ];
+        const anim = document.documentElement.animate(
+            { clipPath: isOut ? [...clipPath].reverse() : clipPath },
+            {
+                duration: 400,
+                easing: 'ease-in',
+                pseudoElement: isOut
+                    ? `::view-transition-old(root)`
+                    : `::view-transition-new(root)`
+            }
+        );
+        anim.onfinish = () => {
+            el.style.removeProperty('view-transition-name');
+            el.classList.remove('view-transition-trigger');
+            document.documentElement.classList.remove('disabled-transition');
+        };
+    });
+}
+
+//格式化手机号
+export function formatPhone(phone) {
+    if (!phone) return '-';
+    return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
+}
+//格式化姓名 只保留第一个字,其他用*代替
+export function formatName(name) {
+    if (!name) return '-';
+    return name.substring(0, 1) + '*'.repeat(name.length - 1);
 }
+

+ 1 - 0
src/views/data/books/components/books-edit.vue

@@ -10,6 +10,7 @@
     :formatData="formatData"
     labelWidth="120px"
     @success="(data) => emit('success', data)"
+    :body-style="{ overflow: 'auto' }"
   >
     <template #other>
       <div class="image-pos" id="image-pos">

+ 38 - 38
src/views/recycleOrder/components/order-customer.vue

@@ -1,48 +1,48 @@
 <template>
-  <div class="recycle-order-number">
-    <div class="common-text" v-if="!isReturn">
-      <el-text>用户名:</el-text>
-      <el-text>{{ row.userNick }}</el-text>
+    <div class="recycle-order-number">
+        <div class="common-text" v-if="!isReturn">
+            <el-text>用户名:</el-text>
+            <el-text>{{ row.userNick }}</el-text>
+        </div>
+        <div class="common-text" v-if="isReturn">
+            <el-text>昵称:</el-text>
+            <el-text>{{ row.userNick }}
+                <el-tag type="success" size="small">{{
+                    row.orderFrom == 1 ? '微信' : '支付宝'
+                    }}</el-tag>
+            </el-text>
+        </div>
+        <div class="common-text">
+            <el-text>发件人:</el-text>
+            <el-text v-if="!row.sendName">暂无信息</el-text>
+            <el-text v-else>{{ formatName(row.sendName) }}({{ formatPhone(row.sendMobile) }})</el-text>
+        </div>
+        <div class="common-text">
+            <el-text>省市区:</el-text>
+            <el-text>{{ row.sendSsq || '-' }}</el-text>
+        </div>
+        <div class="common-text">
+            <el-text>地址:</el-text>
+            <el-text>{{ row.sendAddress || '-' }}</el-text>
+        </div>
+        <div class="common-text" v-if="!isReturn">
+            <el-text>标签:</el-text>
+            <el-text v-if="row.userTags">{{ row.userTags.join(',') }}</el-text>
+            <el-text v-else>暂无标签</el-text>
+        </div>
     </div>
-    <div class="common-text" v-if="isReturn">
-      <el-text>昵称:</el-text>
-      <el-text
-        >{{ row.userNick }}
-        <el-tag type="success" size="small">{{
-          row.orderFrom == 1 ? '微信' : '支付宝'
-        }}</el-tag>
-      </el-text>
-    </div>
-    <div class="common-text">
-      <el-text>发件人:</el-text>
-      <el-text v-if="!row.sendName">暂无信息</el-text>
-      <el-text v-else>{{ row.sendName }}({{ row.sendMobile }})</el-text>
-    </div>
-    <div class="common-text">
-      <el-text>省市区:</el-text>
-      <el-text>{{ row.sendSsq || '-' }}</el-text>
-    </div>
-    <div class="common-text">
-      <el-text>地址:</el-text>
-      <el-text>{{ row.sendAddress || '-' }}</el-text>
-    </div>
-    <div class="common-text" v-if="!isReturn">
-      <el-text>标签:</el-text>
-      <el-text v-if="row.userTags">{{ row.userTags.join(',') }}</el-text>
-      <el-text v-else>暂无标签</el-text>
-    </div>
-  </div>
 </template>
 
 <script setup>
-  const props = defineProps({
+import { formatName, formatPhone } from '@/utils/common';
+const props = defineProps({
     row: {
-      type: Object,
-      default: () => {}
+        type: Object,
+        default: () => { }
     },
     isReturn: {
-      type: Boolean,
-      default: false
+        type: Boolean,
+        default: false
     }
-  });
+});
 </script>

+ 2 - 2
src/views/recycleOrder/components/order-detail.vue

@@ -3,7 +3,7 @@
     <ele-modal form :width="1460" v-model="visible" title="用户详情" @open="handleOpen"
         :body-style="{ maxHeight: '84vh', position: 'relative', overflow: 'auto', background: '#f8f8f8', padding: '0' }"
         position="center">
-        <userDetail />
+        <userDetail :detail="orderDetail" />
 
         <template #footer>
             <el-button @click="handleCancel" type="danger">关闭弹窗</el-button>
@@ -33,7 +33,7 @@ const handleOpen = (data) => {
 };
 
 //获取订单详情
-const orderDetail = ref(null);
+const orderDetail = ref({});
 const getOrderDetail = (orderId) => {
     request.get(`/order/orderInfo/getInfo/${orderId}`).then((res) => {
         if (res.data.code === 200) {

+ 8 - 1
src/views/recycleOrder/detail/index.vue

@@ -4,7 +4,7 @@
             <orderStatus />
         </ele-card>
         <ele-card class="order-base" header="订单基本信息" :body-style="{ paddingTop: '0' }">
-            <orderBaseInfo />
+            <orderBaseInfo :detail="detail" />
         </ele-card>
         <ele-card class="order-book-list" header="图书清单" :body-style="{ paddingTop: '0' }">
             <orderBookList />
@@ -30,4 +30,11 @@ import orderStatus from '@/views/recycleOrder/detail/order-status.vue';
 import orderBaseInfo from '@/views/recycleOrder/detail/order-base-info.vue';
 import orderFreightStatus from '@/views/recycleOrder/detail/order-freight-status.vue';
 import orderBookList from '@/views/recycleOrder/detail/order-book-list.vue'
+
+const props = defineProps({
+    detail: {
+        type: Object,
+        default: () => ({}),
+    },
+});
 </script>

+ 146 - 88
src/views/recycleOrder/detail/order-base-info.vue

@@ -1,94 +1,152 @@
 <template>
-  <div class="base-info">
-    <ele-pro-table
-      ref="tableRef"
-      row-key="userId"
-      :columns="columns"
-      :datasource="datasource"
-      :tools="false"
-      :pagination="false"
-    >
-    </ele-pro-table>
-    <el-row :gutter="12" style="padding:16px 10px;padding-bottom:0">
-      <el-col :span="8">
-        <div class="common-text">
-          <el-text>物流类型:</el-text>
-          <el-text>平台物流</el-text>
-        </div>
-        <div class="common-text">
-          <el-text>快递单号:</el-text>
-          <el-text>QWD00090342255</el-text>
-        </div>
-        <div class="common-text">
-          <el-text>快递公司:</el-text>
-          <el-text>京东物流</el-text>
-        </div>
-        <div class="common-text">
-          <el-text>预约时间:</el-text>
-          <el-text>2024-07-27 17:00</el-text>
-        </div>
-      </el-col>
-      <el-col :span="8">
-        <div class="common-text">
-          <el-text>发件人:</el-text>
-          <el-text>杜**(ID:8854534)</el-text>
-        </div>
-        <div class="common-text">
-          <el-text>电 话:</el-text>
-          <el-text>178****8812</el-text>
-        </div>
-        <div class="common-text">
-          <el-text>地 址:</el-text>
-          <el-text>河南省/郑州市/中牟县/青年西路西坛巷</el-text>
-        </div>
-        <div class="common-text">
-          <el-text>备 注:</el-text>
-          <el-text>暂无信息</el-text>
-        </div>
-      </el-col>
-      <el-col :span="8">
-        <div class="common-text">
-          <el-text>收货仓库:</el-text>
-          <el-text>河南仓-谢雪武</el-text>
-        </div>
-        <div class="common-text">
-          <el-text>收 件 人:</el-text>
-          <el-text>谢雪武</el-text>
-        </div>
-        <div class="common-text">
-          <el-text>电  话:</el-text>
-          <el-text>18638621175</el-text>
-        </div>
-        <div class="common-text">
-          <el-text>地  址:</el-text>
-          <el-text>河南省/鹤壁市/浚县/黄河路南段 益民面业院内 4号仓库</el-text>
-        </div>
-      </el-col>
-    </el-row>
-  </div>
+    <div class="base-info">
+        <ele-data-table ref="tableRef" row-key="userId" :columns="columns" :data="datasource" :tools="false"
+            :pagination="false">
+            <template #orderTime="{ row }">
+                <div class="common-text">
+                    <el-text>建单:</el-text>
+                    <el-text>{{ row.createTime }}</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>提交:</el-text>
+                    <el-text>{{ row.orderTime || '-' }}</el-text>
+                </div>
+            </template>
+            <template #status="{ row }">
+                <el-tag effect="dark" :type="row.status < 5 ? 'warning' : 'success'">{{ row.status < 5 ? '未发货' : '已发货'
+                        }}</el-tag>
+                        <el-tag style="margin-left: 15px" effect="dark" :type="row.status < 8 ? 'warning' : 'success'">{{ row.status < 8 ? '未收货'
+                            : '已收货' }}</el-tag>
+
+                                <el-tag style="margin-left: 15px" effect="dark" :type="row.status == 11 ? ' success' : 'warning'">{{ row.status == 11
+                                    ? '已支付' : '未支付' }}</el-tag>
+            </template>
+        </ele-data-table>
+        <el-row :gutter="12" style="padding: 16px 10px; padding-bottom: 0">
+            <el-col :span="8">
+                <div class="common-text">
+                    <el-text>物流类型:</el-text>
+                    <el-text>平台物流</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>快递单号:</el-text>
+                    <el-text>{{ detail.waybillCode }}</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>快递公司:</el-text>
+                    <el-text>{{ finalExpressText }}</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>预约时间:</el-text>
+                    <el-text>{{ formatTime }}</el-text>
+                </div>
+            </el-col>
+            <el-col :span="8">
+                <div class="common-text">
+                    <el-text>发件人:</el-text>
+                    <el-text>{{ formatName(detail.sendName) }}(ID:{{ detail.userId }})</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>电 话:</el-text>
+                    <el-text>{{ formatPhone(detail.sendMobile) }}</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>地 址:</el-text>
+                    <el-text>{{ detail.sendAddress }}</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>备 注:</el-text>
+                    <el-text>{{ detail.userExpress || '暂无信息' }}</el-text>
+                </div>
+            </el-col>
+            <el-col :span="8">
+                <div class="common-text">
+                    <el-text>收货仓库:</el-text>
+                    <el-text>{{ detail.recipientGodown }}-{{ detail.recipientName }}</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>收 件 人:</el-text>
+                    <el-text>{{ detail.recipientName || '-' }}</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>电  话:</el-text>
+                    <el-text>{{ detail.recipientPhone || '-' }}</el-text>
+                </div>
+                <div class="common-text">
+                    <el-text>地  址:</el-text>
+                    <el-text>{{ detail.recipientAddress || '-' }}</el-text>
+                </div>
+            </el-col>
+        </el-row>
+    </div>
 </template>
 
 <script setup>
-  import { ref, reactive } from 'vue';
-  const datasource = reactive([
-    {
-      orderNumber: '123456789',
-      orderSource: '微信小程序',
-      user: '张三',
-      estimatedPayment: '¥12345.00',
-      reviewedPayment: '¥12345.00',
-      orderTime: '2022-08-09 16:27:00',
-      createTime: '2022-08-13 16:27:00',
-      transactionStatus: '已完成'
+import { formatName, formatPhone } from '@/utils/common';
+import { ref, reactive, watch } from 'vue';
+const props = defineProps({
+    detail: { type: Object, default: () => ({}) }
+});
+
+import { useDictData } from '@/utils/use-dict-data';
+
+/** 字典数据 */
+const [expressDicts, orderFormDicts] = useDictData([
+    'recycle_express_type',
+    'order_form'
+]);
+
+const finalExpressText = computed(() => {
+    if (props.detail.finalExpress == '0' || !props.detail.finalExpress) {
+        return '暂无信息';
     }
-  ]);
-  const columns = ref([
-    { label: '订单编号', prop: 'orderNumber' },
-    { label: '订单来源', prop: 'orderSource' },
-    { label: '用户', prop: 'user' },
-    { label: '预估书款', prop: 'estimatedPayment' },
-    { label: '审核书款', prop: 'reviewedPayment' },
-    { label: '下单时间', prop: 'orderTime' },
-    { label: '交易状态', prop: 'transactionStatus' }
-  ]);
+    return (
+        expressDicts.value.find((d) => d.dictValue == props.detail.finalExpress)
+            ?.dictLabel + '快递' || '暂无信息'
+    );
+});
+
+const formatTime = computed(() => {
+    if (!props.detail.schedulePickupStartTime) return '-';
+    return (
+        props.detail.schedulePickupStartTime +
+        '-' +
+        props.detail.schedulePickupEndTime.split(' ')[1]
+    );
+});
+
+const datasource = ref([]);
+watch(
+    () => props.detail,
+    (newVal) => {
+        console.log(newVal, 'newVal');
+        datasource.value = newVal ? [newVal] : [];
+        console.log(datasource.value);
+    },
+    { immediate: true, deep: true }
+);
+
+const columns = ref([
+    { label: '订单编号', prop: 'orderId' },
+    {
+        label: '订单来源',
+        prop: 'orderFrom',
+        formatter: (row) =>
+            orderFormDicts.value.find((d) => d.dictValue == row.orderFrom)
+                ?.dictLabel
+    },
+    { label: '用户', prop: 'userNick' },
+    {
+        label: '预估书款',
+        prop: 'expectMoney',
+        formatter: (row) => '¥' + row.expectMoney
+    },
+    {
+        label: '审核书款',
+        prop: 'finalMoney',
+        formatter: (row) => '¥' + row.finalMoney
+    },
+    { label: '下单时间', prop: 'orderTime', slot: 'orderTime', width: 200 },
+    { label: '交易状态', prop: 'status', slot: 'status', width: 240 }
+]);
 </script>