Переглянути джерело

```
feat: 更新生产环境API基础URL并重构订单管理功能

- 将生产环境API基础URL从 /plt 更新为 https://smqjh.api.zswlgz.com
- 添加订单管理模块,包括正常订单和订单详情页面
- 创建订单管理相关API接口和服务函数
- 更新商品中心渠道商获取接口路径
- 修复政府积分管理相关API路径错误
- 优化商品渠道及价格导入模板下载功能
- 重构政府用户列表状态修改逻辑
- 调整表格列配置和数据渲染方式
- 移除未使用的图标组件声明
- 更新路由配置和类型定义文件
```

wenjie 1 день тому
батько
коміт
5a72830463
30 змінених файлів з 1670 додано та 136 видалено
  1. 3 1
      .env.prod
  2. 5 4
      .env.test
  3. 1 1
      src/components/zt/importTemplate/z-import-template.vue
  4. 4 2
      src/locales/langs/en-us.ts
  5. 4 2
      src/locales/langs/zh-cn.ts
  6. 2 1
      src/router/elegant/imports.ts
  7. 26 6
      src/router/elegant/routes.ts
  8. 3 1
      src/router/elegant/transform.ts
  9. 3 3
      src/service/api/common.ts
  10. 11 0
      src/service/api/goods-center/store-goods/index.ts
  11. 1 1
      src/service/api/government/points/index.ts
  12. 12 2
      src/service/api/government/user-list/index.ts
  13. 100 0
      src/service/api/order-manage/normal-order/index.ts
  14. 1 1
      src/service/api/xsb-manage/store-info/index.ts
  15. 1 1
      src/typings/api.d.ts
  16. 0 30
      src/typings/components.d.ts
  17. 6 3
      src/typings/elegant-router.d.ts
  18. 69 39
      src/views/goods-center/store-goods/index.vue
  19. 9 6
      src/views/goods-center/type-admin/index.vue
  20. 3 3
      src/views/government/points/index.vue
  21. 21 8
      src/views/government/user-list/index.vue
  22. 5 5
      src/views/manage/department/department.data.ts
  23. 21 2
      src/views/manage/user/index.vue
  24. 156 0
      src/views/order-manage/normal-order/component/delivery-modal.vue
  25. 224 0
      src/views/order-manage/normal-order/component/normal-modal.vue
  26. 509 0
      src/views/order-manage/normal-order/index.vue
  27. 286 0
      src/views/order-manage/normal-order/normal-order.ts
  28. 180 0
      src/views/order-manage/order-detail/index.vue
  29. 0 12
      src/views/test/index.vue
  30. 4 2
      src/views/xsb-manage/fright-config/index.vue

+ 3 - 1
.env.prod

@@ -1,6 +1,8 @@
 # backend service base url, prod environment
 # VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default
-VITE_SERVICE_BASE_URL=/plt #服务器
+# VITE_SERVICE_BASE_URL=/plt #服务器
+VITE_SERVICE_BASE_URL=https://smqjh.api.zswlgz.com #服务器
+
 # other backend service base url, prod environment
 VITE_OTHER_SERVICE_BASE_URL= `{
   "demo": "http://localhost:9529"

+ 5 - 4
.env.test

@@ -1,12 +1,13 @@
 # backend service base url, test environment
 
+# VITE_SERVICE_BASE_URL=https://b8dbdde.r39.cpolar.top #王
 # VITE_SERVICE_BASE_URL=http://89561bkaq794.vicp.fun:53846 #张
-VITE_SERVICE_BASE_URL=https://70b4ca59.r9.vip.cpolar.cn #田
+# VITE_SERVICE_BASE_URL=https://33cb5a99.r9.vip.cpolar.cn#田
 # VITE_SERVICE_BASE_URL=https://2f3c6d21.r24.cpolar.top #邓
-# VITE_SERVICE_BASE_URL=http://74949mkfh190.vicp.fun #付
+VITE_SERVICE_BASE_URL=http://d7b0f86.r36.cpolar.top #付
 # VITE_SERVICE_BASE_URL=https://mock.apifox.cn/m1/3109515-0-default
-
-# VITE_SERVICE_BASE_URL=http://192.168.1.242:8080 #测试本地服务器
+# VITE_SERVICE_BASE_URL=http://47.109.84.152:8081 #测试本地服务器
+# VITE_SERVICE_BASE_URL=/plt #测试打包服务器
 
 # other backend service base url, test environment
 VITE_OTHER_SERVICE_BASE_URL= `{

+ 1 - 1
src/components/zt/importTemplate/z-import-template.vue

@@ -35,7 +35,7 @@ function handleDownloadTemplate() {
     return;
   }
   // window.open(`${import.meta.env.VITE_SERVICE_BASE_URL}${props.url}`, '_blank');
-  commonExport(`${import.meta.env.VITE_SERVICE_BASE_URL}${props.url}`, '', '商品渠道及价格导入模版.xlsx');
+  commonExport(`${import.meta.env.VITE_SERVICE_BASE_URL}${props.url}`, '', props.templateText);
   // downloadTemplate();
 }
 </script>

+ 4 - 2
src/locales/langs/en-us.ts

@@ -259,12 +259,14 @@ const local: App.I18n.Schema = {
     'government_government-list': '',
     government_points: '',
     'government_user-list': '',
-    test: '',
     'xsb-manage': '',
     'xsb-manage_advertisement': '',
     'xsb-manage_fright-config': '',
     'xsb-manage_search': '',
-    'xsb-manage_store-info': ''
+    'xsb-manage_store-info': '',
+    'order-manage': '',
+    'order-manage_normal-order': '',
+    'order-manage_order-detail': ''
   },
   page: {
     login: {

+ 4 - 2
src/locales/langs/zh-cn.ts

@@ -256,12 +256,14 @@ const local: App.I18n.Schema = {
     'government_government-list': '',
     government_points: '',
     'government_user-list': '',
-    test: '',
     'xsb-manage': '',
     'xsb-manage_advertisement': '',
     'xsb-manage_fright-config': '',
     'xsb-manage_search': '',
-    'xsb-manage_store-info': ''
+    'xsb-manage_store-info': '',
+    'order-manage': '',
+    'order-manage_normal-order': '',
+    'order-manage_order-detail': ''
   },
   page: {
     login: {

+ 2 - 1
src/router/elegant/imports.ts

@@ -34,7 +34,8 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
   manage_role: () => import("@/views/manage/role/index.vue"),
   manage_schedule: () => import("@/views/manage/schedule/index.vue"),
   manage_user: () => import("@/views/manage/user/index.vue"),
-  test: () => import("@/views/test/index.vue"),
+  "order-manage_normal-order": () => import("@/views/order-manage/normal-order/index.vue"),
+  "order-manage_order-detail": () => import("@/views/order-manage/order-detail/index.vue"),
   "user-center": () => import("@/views/user-center/index.vue"),
   "user-management_user-list": () => import("@/views/user-management/user-list/index.vue"),
   "xsb-manage_advertisement": () => import("@/views/xsb-manage/advertisement/index.vue"),

+ 26 - 6
src/router/elegant/routes.ts

@@ -237,13 +237,33 @@ export const generatedRoutes: GeneratedRoute[] = [
     ]
   },
   {
-    name: 'test',
-    path: '/test',
-    component: 'layout.base$view.test',
+    name: 'order-manage',
+    path: '/order-manage',
+    component: 'layout.base',
     meta: {
-      title: 'test',
-      i18nKey: 'route.test'
-    }
+      title: 'order-manage',
+      i18nKey: 'route.order-manage'
+    },
+    children: [
+      {
+        name: 'order-manage_normal-order',
+        path: '/order-manage/normal-order',
+        component: 'view.order-manage_normal-order',
+        meta: {
+          title: 'order-manage_normal-order',
+          i18nKey: 'route.order-manage_normal-order'
+        }
+      },
+      {
+        name: 'order-manage_order-detail',
+        path: '/order-manage/order-detail',
+        component: 'view.order-manage_order-detail',
+        meta: {
+          title: 'order-manage_order-detail',
+          i18nKey: 'route.order-manage_order-detail'
+        }
+      }
+    ]
   },
   {
     name: 'user-center',

+ 3 - 1
src/router/elegant/transform.ts

@@ -200,7 +200,9 @@ const routeMap: RouteMap = {
   "manage_role": "/manage/role",
   "manage_schedule": "/manage/schedule",
   "manage_user": "/manage/user",
-  "test": "/test",
+  "order-manage": "/order-manage",
+  "order-manage_normal-order": "/order-manage/normal-order",
+  "order-manage_order-detail": "/order-manage/order-detail",
   "user-center": "/user-center",
   "user-management": "/user-management",
   "user-management_user-list": "/user-management/user-list",

+ 3 - 3
src/service/api/common.ts

@@ -37,7 +37,7 @@ export function downloadTemplate() {
  */
 export function fetchGetAddOrEditTransport(data: any) {
   return request({
-    url: '/platform/transport2/addOrEdit',
+    url: '/smqjh-system/api/v1/transport2/addOrEdit',
     method: 'post',
     data
   });
@@ -68,7 +68,7 @@ export function fetchGetLoginUserList() {
  */
 export function fetchGetTransport(channelId: number) {
   return request<Api.delivery.Transport2>({
-    url: `/platform/transport2/queryTransport2ByChannelId/${channelId}`,
+    url: `/smqjh-system/api/v1/transport2/queryTransport2ByChannelId/${channelId}`,
     method: 'get'
   });
 }
@@ -80,7 +80,7 @@ export function fetchGetTransport(channelId: number) {
 
 export function fetchChannelList(data: any) {
   return request<{ records: Api.delivery.Transport2[] }>({
-    url: '/platform/transport2/transport2List',
+    url: '/smqjh-system/api/v1/transport2/transport2List',
     method: 'get',
     params: data
   });

+ 11 - 0
src/service/api/goods-center/store-goods/index.ts

@@ -35,6 +35,17 @@ export function fetchGetAllChannelList() {
     method: 'get'
   });
 }
+/**
+ * 获取一级渠道商
+ * @returns
+ */
+export function fetchGetChannelList() {
+  return request<Api.goods.Channel[]>({
+    url: '/smqjh-system/api/v1/channel/listFirstChannel',
+    method: 'get'
+  });
+}
+
 /**
  *
  * @param data 导入渠道商品数据

+ 1 - 1
src/service/api/government/points/index.ts

@@ -51,7 +51,7 @@ export function fetchGetPointsOutList(params: any) {
  */
 export function fetchGetFailPointsList() {
   return request<Api.government.PointsFailureRecordVO[]>({
-    url: '/platform/pointsFailureRecord/groupByCode',
+    url: '/smqjh-system/api/v1/pointsFailureRecord/groupByCode',
     method: 'get'
   });
 }

+ 12 - 2
src/service/api/government/user-list/index.ts

@@ -5,7 +5,7 @@ import { request } from '@/service/request';
  */
 export function fetchGetUserList(params: any) {
   return request<Api.government.userList[]>({
-    url: '/smqjh-smqjh-system/api/v1/members/enterprise/enterpriseUserList',
+    url: '/smqjh-system/api/v1/members/enterprise/enterpriseUserList',
     method: 'get',
     params
   });
@@ -65,7 +65,17 @@ export function fetchExportUser(data: { file: File }) {
 
 export function fetchGetImportRecordList() {
   return request<Api.government.importRecordList[]>({
-    url: '/smqjh-system/enterprise/enterpriseUserLogList',
+    url: '/smqjh-system/api/v1/members/enterprise/enterpriseUserLogList',
     method: 'get'
   });
 }
+/**
+ * 修改员工状态
+ */
+export function fetchEditUserStatus(data: any) {
+  return request({
+    url: '/smqjh-system/api/v1/members/enterprise/updateMemberStatus',
+    method: 'PUT',
+    data
+  });
+}

+ 100 - 0
src/service/api/order-manage/normal-order/index.ts

@@ -0,0 +1,100 @@
+import { request } from '@/service/request';
+
+/**
+ * 正常快递订单
+ * @param data
+ * @returns
+ */
+export function fetchGetDeliveryOrderList(data: any) {
+  return request<Api.Common.PaginatingQueryRecord<Api.delivery.deliveryOrder>>({
+    url: '/smqjh-oms/api/v1/order/backendOrderList',
+    method: 'get',
+    params: data
+  });
+}
+
+/**
+ * 导出正常快递订单
+ * @param data
+ * @returns
+ */
+export function fetchExportOrderList(data: any) {
+  return request({
+    url: '/platform/order/export',
+    method: 'get',
+    params: data
+  });
+}
+
+/**
+ * 导出正常快递订单记录
+ * @param data
+ * @returns
+ */
+export function fetchExportList(data: any) {
+  return request({
+    url: '/platform/exportTask/page',
+    method: 'get',
+    params: data
+  });
+}
+
+/**
+ * 下载
+ * @param data
+ * @returns
+ */
+export function fetchBreakDownload(fileId: any) {
+  return request({
+    url: `/platform/exportTask/cancel/${fileId}`,
+    method: 'get'
+  });
+}
+
+/**
+ *  获取快递订单状态数量
+ * @returns
+ */
+export function fetchGetDeliveryStatusNum(data: any) {
+  return request<Api.delivery.DeliveryStatusNum>({
+    url: '/smqjh-oms/api/v1/order/backendOrderListCount',
+    method: 'get',
+    params: data
+  });
+}
+
+/**
+ * 获取快递订单详情
+ * @param orderNumber
+ * @returns
+ */
+export function fetchGetNomalOrderInfo(orderNo: string) {
+  return request<Api.delivery.deliveryOrder>({
+    url: `/smqjh-oms/api/v1/order/backendOrderInfo`,
+    method: 'get',
+    params: { orderNo }
+  });
+}
+
+/**
+ *
+ * 快递公司列表
+ *  */
+export function fetchGetDevList(data: any) {
+  return request<Api.delivery.devList>({
+    url: '/platform/delivery/list',
+    method: 'get',
+    params: data
+  });
+}
+
+/**
+ * 发货
+ */
+export function fetchDeliveryOrder(data: any) {
+  return request({
+    url: '/platform/order/delivery',
+    method: 'PUT',
+    data
+  });
+}

+ 1 - 1
src/service/api/xsb-manage/store-info/index.ts

@@ -7,7 +7,7 @@ import { request } from '@/service/request';
  */
 export function fetchGetStoreList(data: any) {
   return request<Api.Store.ShopDetail[]>({
-    url: '/platform/shopDetail/page',
+    url: '/smqjh-pms/api/v1/shopDetail/page',
     method: 'GET',
     params: data
   });

+ 1 - 1
src/typings/api.d.ts

@@ -302,7 +302,7 @@ declare namespace Api {
       /**
        * 员工id
        */
-      userId: number;
+      memberId: number;
     }
     /**
      * 员工导入记录

+ 0 - 30
src/typings/components.d.ts

@@ -27,30 +27,18 @@ declare module 'vue' {
     IconAntDesignEnterOutlined: typeof import('~icons/ant-design/enter-outlined')['default']
     IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default']
     IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default']
-    'IconCharm:download': typeof import('~icons/charm/download')['default']
-    'IconF7:circleFill': typeof import('~icons/f7/circle-fill')['default']
-    'IconF7:flagCircleFill': typeof import('~icons/f7/flag-circle-fill')['default']
-    'IconFe:question': typeof import('~icons/fe/question')['default']
     'IconFileIcons:microsoftExcel': typeof import('~icons/file-icons/microsoft-excel')['default']
-    'IconGg:ratio': typeof import('~icons/gg/ratio')['default']
     IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default']
     IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default']
-    'IconIconParkOutline:equalRatio': typeof import('~icons/icon-park-outline/equal-ratio')['default']
     'IconIconParkTwotone:mailDownload': typeof import('~icons/icon-park-twotone/mail-download')['default']
     IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default']
     IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default']
-    IconLocalActivity: typeof import('~icons/local/activity')['default']
-    IconLocalCast: typeof import('~icons/local/cast')['default']
-    'IconMaterialSymbolsLight:rotate90DegreesCcwOutlineRounded': typeof import('~icons/material-symbols-light/rotate90-degrees-ccw-outline-rounded')['default']
-    'IconMdi:printer': typeof import('~icons/mdi/printer')['default']
     IconMdiArrowDownThin: typeof import('~icons/mdi/arrow-down-thin')['default']
     IconMdiArrowUpThin: typeof import('~icons/mdi/arrow-up-thin')['default']
     IconMdiDrag: typeof import('~icons/mdi/drag')['default']
     IconMdiKeyboardEsc: typeof import('~icons/mdi/keyboard-esc')['default']
     IconMdiKeyboardReturn: typeof import('~icons/mdi/keyboard-return')['default']
     IconMdiRefresh: typeof import('~icons/mdi/refresh')['default']
-    'IconMingcute:zoomInLine': typeof import('~icons/mingcute/zoom-in-line')['default']
-    'IconMingcute:zoomOutLine': typeof import('~icons/mingcute/zoom-out-line')['default']
     IconTooltip: typeof import('./../components/common/icon-tooltip.vue')['default']
     IconUilSearch: typeof import('~icons/uil/search')['default']
     LangSwitch: typeof import('./../components/common/lang-switch.vue')['default']
@@ -61,7 +49,6 @@ declare module 'vue' {
     NBreadcrumb: typeof import('naive-ui')['NBreadcrumb']
     NBreadcrumbItem: typeof import('naive-ui')['NBreadcrumbItem']
     NButton: typeof import('naive-ui')['NButton']
-    NButtonGroup: typeof import('naive-ui')['NButtonGroup']
     NCard: typeof import('naive-ui')['NCard']
     NCheckbox: typeof import('naive-ui')['NCheckbox']
     NCheckboxGroup: typeof import('naive-ui')['NCheckboxGroup']
@@ -77,7 +64,6 @@ declare module 'vue' {
     NDrawer: typeof import('naive-ui')['NDrawer']
     NDrawerContent: typeof import('naive-ui')['NDrawerContent']
     NDropdown: typeof import('naive-ui')['NDropdown']
-    NEllipsis: typeof import('naive-ui')['NEllipsis']
     NEmpty: typeof import('naive-ui')['NEmpty']
     NFlex: typeof import('naive-ui')['NFlex']
     NForm: typeof import('naive-ui')['NForm']
@@ -99,14 +85,12 @@ declare module 'vue' {
     NModal: typeof import('naive-ui')['NModal']
     NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
     NP: typeof import('naive-ui')['NP']
-    NPagination: typeof import('naive-ui')['NPagination']
     NPopconfirm: typeof import('naive-ui')['NPopconfirm']
     NPopover: typeof import('naive-ui')['NPopover']
     NRadio: typeof import('naive-ui')['NRadio']
     NRadioGroup: typeof import('naive-ui')['NRadioGroup']
     NScrollbar: typeof import('naive-ui')['NScrollbar']
     NSelect: typeof import('naive-ui')['NSelect']
-    NSkeleton: typeof import('naive-ui')['NSkeleton']
     NSpace: typeof import('naive-ui')['NSpace']
     NSpin: typeof import('naive-ui')['NSpin']
     NStep: typeof import('naive-ui')['NStep']
@@ -114,7 +98,6 @@ declare module 'vue' {
     NSwitch: typeof import('naive-ui')['NSwitch']
     NTab: typeof import('naive-ui')['NTab']
     NTable: typeof import('naive-ui')['NTable']
-    NTabPane: typeof import('naive-ui')['NTabPane']
     NTabs: typeof import('naive-ui')['NTabs']
     NTag: typeof import('naive-ui')['NTag']
     NTbody: typeof import('naive-ui')['NTbody']
@@ -122,27 +105,14 @@ declare module 'vue' {
     NText: typeof import('naive-ui')['NText']
     NTh: typeof import('naive-ui')['NTh']
     NThead: typeof import('naive-ui')['NThead']
-    NTimeline: typeof import('naive-ui')['NTimeline']
-    NTimelineItem: typeof import('naive-ui')['NTimelineItem']
     NTooltip: typeof import('naive-ui')['NTooltip']
     NTr: typeof import('naive-ui')['NTr']
-    NTransfer: typeof import('naive-ui')['NTransfer']
     NTree: typeof import('naive-ui')['NTree']
     NTreeSelect: typeof import('naive-ui')['NTreeSelect']
     NUpload: typeof import('naive-ui')['NUpload']
     NUploadDragger: typeof import('naive-ui')['NUploadDragger']
     NWatermark: typeof import('naive-ui')['NWatermark']
     PinToggler: typeof import('./../components/common/pin-toggler.vue')['default']
-    ProCard: typeof import('pro-naive-ui')['ProCard']
-    ProConfigProvider: typeof import('pro-naive-ui')['ProConfigProvider']
-    ProDataTable: typeof import('pro-naive-ui')['ProDataTable']
-    ProDate: typeof import('pro-naive-ui')['ProDate']
-    ProEditDataTable: typeof import('pro-naive-ui')['ProEditDataTable']
-    ProForm: typeof import('pro-naive-ui')['ProForm']
-    ProFormList: typeof import('pro-naive-ui')['ProFormList']
-    ProInput: typeof import('pro-naive-ui')['ProInput']
-    ProSearchForm: typeof import('pro-naive-ui')['ProSearchForm']
-    ProSelect: typeof import('pro-naive-ui')['ProSelect']
     ReloadButton: typeof import('./../components/common/reload-button.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']

+ 6 - 3
src/typings/elegant-router.d.ts

@@ -54,7 +54,9 @@ declare module "@elegant-router/types" {
     "manage_role": "/manage/role";
     "manage_schedule": "/manage/schedule";
     "manage_user": "/manage/user";
-    "test": "/test";
+    "order-manage": "/order-manage";
+    "order-manage_normal-order": "/order-manage/normal-order";
+    "order-manage_order-detail": "/order-manage/order-detail";
     "user-center": "/user-center";
     "user-management": "/user-management";
     "user-management_user-list": "/user-management/user-list";
@@ -118,7 +120,7 @@ declare module "@elegant-router/types" {
     | "iframe-page"
     | "login"
     | "manage"
-    | "test"
+    | "order-manage"
     | "user-center"
     | "user-management"
     | "xsb-manage"
@@ -159,7 +161,8 @@ declare module "@elegant-router/types" {
     | "manage_role"
     | "manage_schedule"
     | "manage_user"
-    | "test"
+    | "order-manage_normal-order"
+    | "order-manage_order-detail"
     | "user-center"
     | "user-management_user-list"
     | "xsb-manage_advertisement"

+ 69 - 39
src/views/goods-center/store-goods/index.vue

@@ -2,7 +2,7 @@
 import { computed, ref, useTemplateRef } from 'vue';
 import { NButton, NInputNumber, NSelect } from 'naive-ui';
 import dayjs from 'dayjs';
-// import { fetchGetAllStoreList } from '@/service/api/goods/desk-category';
+import { fetchGetStoreList } from '@/service/api/xsb-manage/store-info';
 // import {
 // fetchGetAllChannelList
 // fetchImportGoods,
@@ -10,7 +10,8 @@ import dayjs from 'dayjs';
 // } from '@/service/api/goods/store-goods';
 import { fetchGetDictDataList } from '@/service/api/system-manage';
 import {
-  fetchGetAllChannelList,
+  // fetchGetAllChannelList,
+  fetchGetChannelList,
   fetchImportGoods,
   fetchProductList,
   fetchSetUpChannels
@@ -20,7 +21,7 @@ import { commonExport } from '@/utils/common';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
 import SvgIcon from '@/components/custom/svg-icon.vue';
 import { useModal } from '@/components/zt/Modal/hooks/useModal';
-type Price = { channelId: number | undefined; channelProdPrice: number; id: number; channelName: string };
+type Price = { channelId: number | undefined; channelProdPrice: number; id: number; channelName?: string };
 const importTemplateRef = useTemplateRef('importTemplateRef');
 
 const options = ref<Api.goods.Channel[]>([]);
@@ -36,11 +37,24 @@ const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
   {
     key: 'supId',
     title: '商品ID',
-    align: 'center',
-    width: 120
+    align: 'left',
+    width: 200,
+    render: (row: any) => {
+      return (
+        <div>
+          <div>统一ID:</div>
+          <div>
+            {row.businessType}
+            {row.supId}
+          </div>
+          <div>业务系统商品ID:</div>
+          <div>{row.hbSkuId}</div>
+        </div>
+      );
+    }
   },
   {
-    key: 'shopName',
+    key: 'pic',
     title: '商品图片',
     align: 'center',
     width: 120,
@@ -77,12 +91,22 @@ const columns: NaiveUI.TableColumn<Api.goods.ShopSku>[] = [
     }
   },
   {
-    key: 'shopName',
+    key: 'channelVOS',
     title: '价格',
     align: 'center',
     width: 120,
-    ellipsis: {
-      tooltip: true
+    render: (row: any) => {
+      return (
+        <div>
+          {row.channelVOS.map((it: Api.government.ChannelVO) => {
+            return (
+              <div>
+                {it.channelName}:¥{it.price}
+              </div>
+            );
+          })}
+        </div>
+      );
     }
   },
   {
@@ -140,8 +164,10 @@ const PriceColumns: NaiveUI.TableColumn<Price>[] = [
               return it;
             });
             row.channelId = value ? Number(value) : undefined;
+            row.channelName = options.value.find(it => it.id == row.channelId)?.channelName;
           }}
           onUpdate:show={value => {
+            console.log('show', value);
             options.value.map(it => {
               if (it.id == row.channelId) {
                 if (value) {
@@ -191,9 +217,9 @@ const PriceColumns: NaiveUI.TableColumn<Price>[] = [
     key: 'action',
     width: 80,
     align: 'center',
-    render: row => {
+    render: (_row, index) => {
       return (
-        <div onClick={() => handleDelPrice(row.id)} class={'w-full flex items-center justify-center'}>
+        <div onClick={() => handleDelPrice(index)} class={'w-full flex items-center justify-center'}>
           <SvgIcon
             icon={'proicons:subtract-square'}
             class={'cursor-pointer text-24px'}
@@ -209,16 +235,17 @@ const selectData = ref<Api.goods.ShopSku>();
 const [registerTable, { getTableCheckedRowKeys, refresh, getTableData, getSeachForm, setTableLoading }] = useTable({
   searchFormConfig: {
     schemas: [
-      // {
-      //   label: '门店名称',
-      //   component: 'ApiSelect',
-      //   field: 'shopId',
-      //   componentProps: {
-      //     api: fetchGetAllStoreList,
-      //     labelFeild: 'shopName',
-      //     valueFeild: 'shopId'
-      //   }
-      // },
+      {
+        label: '门店名称',
+        component: 'ApiSelect',
+        field: 'shopId',
+        componentProps: {
+          api: fetchGetStoreList,
+          resultFeild: 'data.list',
+          labelFeild: 'shopName',
+          valueFeild: 'shopId'
+        }
+      },
       {
         label: '关键词',
         component: 'NInput',
@@ -263,12 +290,12 @@ const [registerTable, { getTableCheckedRowKeys, refresh, getTableData, getSeachF
           ]
         }
       },
-      {
-        label: '分类',
-        component: 'NCascader',
-        field: 'skuName',
-        componentProps: {}
-      },
+      // {
+      //   label: '分类',
+      //   component: 'NCascader',
+      //   field: 'skuName',
+      //   componentProps: {}
+      // },
       {
         label: '更新时间',
         component: 'NDatePicker',
@@ -348,8 +375,8 @@ function handleModalPrice(row: Api.goods.ShopSku) {
       return {
         channelName: it.channelName,
         channelId: Number(it.channelId),
-        channelProdPrice: Number(it.price),
-        id: Number(it.id)
+        channelProdPrice: Number(it.price)
+        // id: Number(it.id)
       };
     });
   }
@@ -357,19 +384,22 @@ function handleModalPrice(row: Api.goods.ShopSku) {
   openPriceModal();
 }
 function handleAddPrice() {
-  if (PriceData.value.length == 3) {
-    window.$message?.error('最多只能添加3条数据');
-    return;
-  }
+  // if (PriceData.value.length == 3) {
+  //   window.$message?.error('最多只能添加3条数据');
+  //   return;
+  // }
   PriceData.value.push({
     channelName: '',
     channelId: undefined,
     channelProdPrice: 1,
     id: dayjs().valueOf()
   });
+  console.log(PriceData.value);
 }
-function handleDelPrice(id: number) {
-  PriceData.value = PriceData.value.filter(item => item.id != id);
+function handleDelPrice(index: number) {
+  // PriceData.value = PriceData.value.filter(item => item.id != id);
+  PriceData.value.splice(index, 1);
+  console.log('删除', index, PriceData.value);
 }
 
 async function handleSubmitPrice() {
@@ -409,7 +439,7 @@ async function handleSubmitPrice() {
   console.log(PriceData.value, 'asdsad');
 }
 async function getData() {
-  const { data, error } = await fetchGetAllChannelList();
+  const { data, error } = await fetchGetChannelList();
   if (!error) {
     options.value = data;
   }
@@ -418,7 +448,7 @@ getData();
 async function handleExport() {
   setTableLoading(true);
   try {
-    await commonExport('/shop/shopProd/export', getSeachForm(), '商品列表.xlsx');
+    await commonExport('/smqjh-pms/api/v1/shopSku/export', getSeachForm(), '商品列表.xlsx');
   } finally {
     setTableLoading(false);
   }
@@ -438,7 +468,7 @@ async function handleExport() {
             导出全部
           </NButton>
           <NButton size="small" :disabled="isDisabledExport">导出选中数据</NButton>
-          <NButton size="small">修改记录</NButton>
+          <!-- <NButton size="small">修改记录</NButton> -->
         </NSpace>
       </template>
     </ZTable>
@@ -450,7 +480,7 @@ async function handleExport() {
       @submit="handleSubmitImport"
     ></ZImportTemplate>
     <BasicModal @register="registerModalPrice" @ok="handleSubmitPrice">
-      <NDataTable :columns="PriceColumns" :data="PriceData" :row-key="row => row.id" />
+      <NDataTable :columns="PriceColumns" :data="PriceData" :row-key="row => row.channelId" />
     </BasicModal>
   </LayoutTable>
 </template>

+ 9 - 6
src/views/goods-center/type-admin/index.vue

@@ -277,7 +277,7 @@ const [
                               <div>{item.shopName}</div>
                               <NTree
                                 data={item.shopCategoryVOS || []}
-                                key-field={'code'}
+                                key-field={'id'}
                                 label-field={'name'}
                                 onUpdate:checked-keys={(keys: Array<string | number>, options: Array<TreeOption>) =>
                                   handleCheckedKeys(code, keys, options)
@@ -339,7 +339,7 @@ const tableColumns: NaiveUI.TableColumn<Api.goods.ShopCategory>[] = [
   {
     title: '状态',
     key: 'visible',
-    render: row => <NSwitch uncheckedValue={0} checkedValue={1} value={row.visible}></NSwitch>
+    render: row => <NSwitch uncheckedValue={0} disabled checkedValue={1} value={row.visible}></NSwitch>
   },
   {
     title: '操作',
@@ -368,6 +368,8 @@ const tableColumns: NaiveUI.TableColumn<Api.goods.ShopCategory>[] = [
 ];
 
 async function edit(row: Api.goods.ShopCategory) {
+  chooseData.value = {};
+
   openModalForm(row);
   const { data } = await fetchGetCategoryDetail(row.id);
   data.businessType = Number(data.businessType);
@@ -375,9 +377,9 @@ async function edit(row: Api.goods.ShopCategory) {
   data.children?.forEach((item: Api.goods.ShopCategory) => {
     code.push(item.programCode);
     if (chooseData.value[item.programCode as string]) {
-      chooseData.value[item.programCode as string].push(item.code);
+      chooseData.value[item.programCode as string].push(item.id);
     } else {
-      chooseData.value[item.programCode] = [item.code];
+      chooseData.value[item.programCode] = [item.id];
     }
   });
   code = Array.from(new Set(code));
@@ -387,11 +389,12 @@ async function edit(row: Api.goods.ShopCategory) {
   //   });
   // }
   data.code = code;
-  console.log(data);
+  console.log(chooseData.value);
   setModalProps({ title: `修改${Number(row.level)}级分类` });
   setModalFormValue({ ...data, label: row.label });
 }
 function add(row: Api.goods.ShopCategory) {
+  chooseData.value = {};
   openModalForm();
   console.log(row, 'row-key');
   updateSchema({ field: 'iconUrl', required: true });
@@ -423,7 +426,7 @@ function handleOpenModal() {
 }
 async function handleSubmit() {
   const form = await getModalFormValue();
-  console.log(form, '表单');
+  console.log(form, '表单', selectChekedKeys.value);
   setSubLoading(false);
   // 二级分类数据处理
   if (form.parentId) {

+ 3 - 3
src/views/government/points/index.vue

@@ -274,7 +274,7 @@ async function hanleExportFailure(code: string) {
   }
   loading.value = true;
   try {
-    await commonExport('/platform/pointsFailureRecord/export', { code }, '失败的记录.xlsx');
+    await commonExport('/smqjh-system/api/v1/pointsFailureRecord/export', { code }, '失败的记录.xlsx');
   } finally {
     loading.value = false;
   }
@@ -283,7 +283,7 @@ async function hanleExportFailure(code: string) {
 async function exportIntegral() {
   setTableLoading(true);
   try {
-    await commonExport('/platform/pointsRecharge/export', getSeachForm(), '积分列表.xlsx');
+    await commonExport('/smqjh-system/api/v1/pointsRecharge/export', getSeachForm(), '积分列表.xlsx');
   } finally {
     setTableLoading(false);
   }
@@ -343,7 +343,7 @@ async function setSearchForm(value: Recordable) {
     </BasicModal>
     <ZImportTemplate
       ref="importTemplateRef"
-      url="/platform/pointsRecharge/exportTemplate"
+      url="/smqjh-system/api/v1/pointsRecharge/exportTemplate"
       template-text="导入积分模版.xlsx"
       modal-text="导入积分"
       @submit="handleSubmitImport"

+ 21 - 8
src/views/government/user-list/index.vue

@@ -5,6 +5,7 @@ import {
   fetchAddUser,
   fetchDeleteUser,
   fetchEditUser,
+  fetchEditUserStatus,
   fetchExportUser,
   fetchGetImportRecordList,
   fetchGetUserList
@@ -67,7 +68,7 @@ const columns: NaiveUI.TableColumn<Api.government.userList>[] = [
           disabled={!useAuth().hasAuth('user:list:statusbtn')}
           onUpdate:value={val => {
             row.status = val;
-            fetchEditUser(row);
+            editStatus(row);
           }}
         ></NSwitch>
       );
@@ -125,7 +126,7 @@ const [registerTable, { refresh, setTableLoading, setFieldsValue: setSearchValue
     isFull: false
   },
   tableConfig: {
-    keyField: 'userId',
+    keyField: 'memberId',
     title: '员工列表',
     showAddButton: useAuth().hasAuth('user:list:add'),
     defaultParamsNotReset: 'channelIdList'
@@ -192,11 +193,11 @@ const failColumns: NaiveUI.TableColumn<Api.government.importRecordList>[] = [
   }
 ];
 async function hanleExportFailure(batchNo: string) {
-  await commonExport(`/admin/enterprise/downloadErrorExcel`, { batchNo }, '员工失败列表.xlsx');
+  await commonExport(`/smqjh-system/api/v1/members/enterprise/downloadErrorExcel`, { batchNo }, '员工失败列表.xlsx');
 }
 async function handleDelete(row: Api.government.userList) {
   setTableLoading(true);
-  await fetchDeleteUser(row.userId);
+  await fetchDeleteUser(row.memberId);
   // console.log(row, 'row');
 
   refresh();
@@ -212,7 +213,7 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
     schemas: [
       {
         label: '',
-        field: 'userId',
+        field: 'memberId',
         component: 'NInput',
         show: false
       },
@@ -285,7 +286,7 @@ const [registerModalFail, { openModal: openModalFail }] = useModal({
 });
 async function handleSubmit() {
   const form = await getFieldsValue();
-  if (form.userId) {
+  if (form.memberId) {
     await fetchEditUser(form);
   } else {
     await fetchAddUser(form);
@@ -294,6 +295,18 @@ async function handleSubmit() {
   refresh();
 }
 
+function editStatus(row: Recordable) {
+  const obj = {
+    memberId: row.memberId,
+    channelId: row.channelId,
+    realName: row.realName,
+    userMobile: row.userMobile,
+    userAttrType: row.userAttrType,
+    status: row.status
+  };
+  fetchEditUserStatus(obj);
+}
+
 async function edit(row: Recordable) {
   openModal(row);
   setFieldsValue(row);
@@ -316,7 +329,7 @@ function handleSearch() {
 async function handleExport() {
   setTableLoading(true);
   try {
-    await commonExport('/admin/enterprise/export', getSeachForm(), '员工列表.xlsx');
+    await commonExport('/smqjh-system/api/v1/members/enterprise/export', getSeachForm(), '员工列表.xlsx');
   } finally {
     setTableLoading(false);
   }
@@ -363,7 +376,7 @@ async function handleExport() {
     </ZTable>
     <ZImportTemplate
       ref="importTemplateRef"
-      url="/admin/enterprise/downloadExcel"
+      url="/smqjh-system/api/v1/members/enterprise/downloadXlsx"
       template-text="员工导入模版.xlsx"
       modal-text="导入员工"
       @submit="handleSubmitImport"

+ 5 - 5
src/views/manage/department/department.data.ts

@@ -14,23 +14,23 @@ export const formSchems: FormSchema[] = [
     field: 'parentId',
     label: '上级部门',
     component: 'ApiTreeSelect',
-    required: true,
+    required: false,
     componentProps: {
       api: fetchGetDepartmentList,
-      labelFeild: 'deptName',
-      valueFeild: 'deptId',
+      labelFeild: 'name',
+      valueFeild: 'id',
       immediate: true,
       resultFeild: 'data'
     }
   },
   {
-    field: 'deptName',
+    field: 'name',
     label: '部门名称',
     component: 'NInput',
     required: true
   },
   {
-    field: 'seq',
+    field: 'sort',
     label: '显示排序',
     component: 'NInputNumber',
     required: true,

+ 21 - 2
src/views/manage/user/index.vue

@@ -9,6 +9,7 @@ import {
   fetchGetRoleAllList,
   fetchGetUserList
 } from '@/service/api';
+import { fetchGetChannelList } from '@/service/api/goods-center/store-goods';
 import { fetchGetDepartmentList } from '@/service/api/system-department';
 import imgs from '@/assets/imgs/logo.png';
 import { useTable } from '@/components/zt/Table/hooks/useTable';
@@ -150,6 +151,18 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
           component: 'NInput',
           required: true
         },
+        {
+          field: 'channelIdList',
+          label: '所属企业',
+          component: 'ApiSelect',
+          required: true,
+          componentProps: {
+            api: () => fetchGetChannelList(),
+            labelFeild: 'channelName',
+            valueFeild: 'id',
+            multiple: true
+          }
+        },
         {
           field: 'deptId',
           label: '归属部门',
@@ -157,8 +170,8 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
           required: true,
           componentProps: {
             api: fetchGetDepartmentList,
-            labelFeild: 'label',
-            valueFeild: 'value',
+            labelFeild: 'name',
+            valueFeild: 'id',
             immediate: true,
             resultFeild: 'data'
           }
@@ -207,6 +220,12 @@ const [registerModalForm, { openModal, closeModal, getFieldsValue, setFieldsValu
             }
           ]
         },
+        {
+          field: 'password',
+          label: '密码',
+          component: 'NInput',
+          required: true
+        },
         {
           field: 'roleIds',
           label: '角色',

+ 156 - 0
src/views/order-manage/normal-order/component/delivery-modal.vue

@@ -0,0 +1,156 @@
+<script setup lang="tsx">
+import { nextTick, ref, unref } from 'vue';
+import { fetchDeliveryOrder, fetchGetNomalOrderInfo } from '@/service/api/order-manage/normal-order';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+import { useForm } from '@/components/zt/Form/hooks/useForm';
+import { deliveryInfo } from '../normal-order';
+const [registerModal, { openModal, setModalProps, setSubLoading, closeModal, setModalLoading }] = useModal({
+  title: '订单发货',
+  width: 1200,
+  height: 800,
+  isShowHeaderText: false
+});
+const [registerForm, { validate, getFieldsValue, setFieldsValue }] = useForm({
+  schemas: deliveryInfo,
+  labelWidth: 120,
+  layout: 'horizontal',
+  gridProps: {
+    cols: '1',
+    itemResponsive: true
+  },
+  collapsedRows: 1,
+  showActionButtonGroup: false
+});
+const emit = defineEmits<{
+  (e: 'finish'): void;
+}>();
+
+const orderInfo = ref<Api.delivery.deliveryOrder>();
+const isRefundIng = ref(false);
+const ShipmentColumns: NaiveUI.TableColumn<Api.delivery.OrderItemElement>[] = [
+  {
+    title: '商品',
+    key: 'goodsName',
+    width: 300,
+    render: row => {
+      return (
+        <div class={'flex items-center'}>
+          <n-image src={row.pic} width={80} height={80} class={'min-w-80px'}></n-image>
+          <div class={'ml2'}>
+            <div class={'text-15px font-semibold'}> {row.skuName} </div>
+            <div class={'text-gray'}>规格: {row.spec || '---'}</div>
+          </div>
+        </div>
+      );
+    }
+  },
+  {
+    title: '可发货数量',
+    key: 'num',
+    width: 250,
+    render: row => {
+      const count = Number(row.prodCount) - Number(row.refundSuccessCount);
+      if (Number(row.refundIngCount)) {
+        isRefundIng.value = true;
+      }
+      return (
+        <div class={'flex items-center justify-center'}>
+          {count} {handleCreateTag(row)}
+        </div>
+      );
+    }
+  },
+  {
+    title: '状态',
+    key: 'status',
+    align: 'center',
+    render: _row => {
+      return orderInfo.value?.hbOrderStatus == 1 ? <n-tag>等待发货</n-tag> : <n-tag type="success">已发货</n-tag>;
+    }
+  },
+  {
+    title: '发货数量',
+    key: 'count',
+    align: 'center',
+    render: row => {
+      const count = Number(row.prodCount) - Number(row.refundSuccessCount);
+      return count;
+    }
+  }
+];
+
+defineExpose({
+  setModalProps,
+  handleOpenOrder
+});
+function handleCreateTag(row: Api.delivery.OrderItemElement) {
+  if (row.refundSuccessCount) {
+    return (
+      <n-tag type="success" class={'ml2'}>
+        已扣除退款成功:{row.refundSuccessCount}
+      </n-tag>
+    );
+  }
+  if (row.refundIngCount) {
+    return (
+      <n-tag type="error" class={'ml2'}>
+        售后处理:{row.refundIngCount}
+      </n-tag>
+    );
+  }
+  return '';
+}
+async function handleOpenOrder(orderNumber: string) {
+  openModal();
+  setModalLoading(true);
+  const { data, error } = await fetchGetNomalOrderInfo(orderNumber);
+  setModalLoading(false);
+  if (!error) {
+    orderInfo.value = data;
+    const Info = {
+      ...data.userAddrOrder,
+      ...data
+    };
+    nextTick(() => {
+      setFieldsValue(Info);
+    });
+  }
+}
+async function handleSubmit() {
+  if (unref(isRefundIng)) {
+    window.$message?.error('存在售后处理中的商品,请处理后再发货');
+    return;
+  }
+  await validate();
+  setSubLoading(true);
+  const form: Recordable = {
+    ...getFieldsValue(),
+    orderNumber: orderInfo.value?.orderNumber
+  };
+  delete form.receiver;
+  delete form.mobile;
+  delete form.address;
+  const { error } = await fetchDeliveryOrder(form);
+  if (!error) {
+    emit('finish');
+    closeModal();
+  } else {
+    setSubLoading(false);
+  }
+}
+</script>
+
+<template>
+  <BasicModal @register="registerModal" @ok="handleSubmit" @after-leave="isRefundIng = false">
+    <div v-if="orderInfo">
+      <NCard :bordered="false" title="商品信息">
+        <NDataTable :scroll-x="1000" :columns="ShipmentColumns" :data="orderInfo.orderItems" :bordered="false" />
+      </NCard>
+      <NCard :bordered="false" title="订单信息">
+        <BasicForm @register-form="registerForm"></BasicForm>
+      </NCard>
+    </div>
+  </BasicModal>
+</template>
+
+<style scoped></style>

+ 224 - 0
src/views/order-manage/normal-order/component/normal-modal.vue

@@ -0,0 +1,224 @@
+<script setup lang="ts">
+import { computed, ref, useTemplateRef } from 'vue';
+import dayjs from 'dayjs';
+import { fetchGetNomalOrderInfo } from '@/service/api/order-manage/normal-order';
+import { useAppStore } from '@/store/modules/app';
+import { copyTextToClipboard } from '@/utils/zt';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+import { ShippingButton, dvyStatus, orderColumns, orderStatusEnum } from '../normal-order';
+import DeliveryModal from './delivery-modal.vue';
+const [registerModal, { openModal, setModalLoading }] = useModal({
+  title: '订单详情',
+  isShowHeaderText: false,
+  showFooter: false,
+  width: 1200,
+  height: 800
+});
+const orderInfo = ref<Api.delivery.deliveryOrder>();
+const appStore = useAppStore();
+const TimeDown = ref<number>(0);
+const ShipmentRef = useTemplateRef('Shipment');
+const emit = defineEmits<{
+  (e: 'finish'): void;
+}>();
+async function open(orderNumber: string) {
+  openModal();
+  setModalLoading(true);
+  const { data, error } = await fetchGetNomalOrderInfo(orderNumber);
+  if (!error) {
+    orderInfo.value = data;
+    if (orderInfo.value.hbLogisticStatus == orderStatusEnum.WAIT_PAY) {
+      const createTime = dayjs(orderInfo.value.createTime);
+      const currentTime = dayjs();
+      const elapsed = currentTime.diff(createTime);
+      const fifteenMinutesInMillis = 15 * 60 * 1000;
+      TimeDown.value = fifteenMinutesInMillis - elapsed;
+    }
+  }
+  setModalLoading(false);
+}
+defineExpose({ open });
+function handleFinish() {
+  open(String(orderInfo.value?.orderNumber));
+  emit('finish');
+}
+const isRefund = computed(() => {
+  const goodsData = orderInfo.value?.orderItems?.find(it => it.refundIngCount == 1);
+  return Boolean(goodsData);
+});
+function handleShipment() {
+  if (isRefund.value) {
+    window.$message?.error('当前订单正在申请退款中');
+    return;
+  }
+  ShipmentRef.value?.handleOpenOrder(String(orderInfo.value?.orderNumber));
+}
+
+const currentSteps = computed(() => {
+  switch (orderInfo.value?.hbOrderStatus) {
+    case orderStatusEnum.WAIT_PAY:
+      return 1;
+    case orderStatusEnum.ORDER_ACCEPT:
+      return 2;
+    case orderStatusEnum.ORDER_WAIT_DELIVERY:
+      return 2;
+    case orderStatusEnum.WAIT_DELIVERY:
+      return 2;
+    case orderStatusEnum.ORDER_DELIVERY:
+      return 3;
+    case orderStatusEnum.ORDER_ARRIVE:
+      return 3;
+    case orderStatusEnum.ORDER_COMPLETE:
+      return 4;
+    default:
+      return 1;
+  }
+});
+function handleCopy(value: string | number | undefined) {
+  copyTextToClipboard(String(value));
+  // copyTextToClipboard(String(orderInfo.value?.orderNumber));
+}
+</script>
+
+<template>
+  <div>
+    <BasicModal @register="registerModal" @after-leave="orderInfo = undefined">
+      <div v-if="orderInfo">
+        <NFlex justify="space-between" align="center">
+          <NFlex>
+            <NTag v-if="orderInfo.parentOrderNumber">
+              <div class="flex items-center">
+                父订单编号: {{ orderInfo?.parentOrderNumber }}
+                <div @click="handleCopy(orderInfo?.parentOrderNumber)">
+                  <SvgIcon icon="bxs:copy" class="mx-3 cursor-pointer text-[#f97316]"></SvgIcon>
+                </div>
+              </div>
+            </NTag>
+            <NTag>
+              <div class="flex items-center">
+                {{ orderInfo.orderLevel === 0 ? '订单编号' : '子订单编号' }}: {{ orderInfo?.orderNumber }}
+                <div @click="handleCopy(orderInfo?.orderNumber)">
+                  <SvgIcon icon="bxs:copy" class="mx-3 cursor-pointer text-[#f97316]"></SvgIcon>
+                </div>
+              </div>
+            </NTag>
+            <NTag>下单时间: {{ orderInfo?.createTime }}</NTag>
+          </NFlex>
+          <NFlex vertical>
+            <template v-if="orderInfo.hbOrderStatus == orderStatusEnum.WAIT_PAY">
+              <div class="text-16px font-semibold">商品已拍下,等待买家付款</div>
+              <div class="text-gray">
+                如买家未在
+                <NTag :type="TimeDown > 300094 ? 'success' : 'error'">
+                  <NCountdown :duration="TimeDown" @finish="handleFinish" />
+                </NTag>
+                内付款,订单将 自动关闭。
+              </div>
+            </template>
+            <template v-if="!orderInfo.dvyFlowId">
+              <template v-if="ShippingButton.includes(orderInfo.hbOrderStatus)">
+                <div class="text-16px font-semibold">等待商家发货</div>
+                <NButton size="small" type="primary" @click="handleShipment">发货</NButton>
+              </template>
+            </template>
+            <template v-if="orderInfo.hbOrderStatus == orderStatusEnum.ORDER_ARRIVE">
+              <div class="text-16px font-semibold">等待买家收货</div>
+              <div>商家已发货,等待确认收货</div>
+            </template>
+            <template v-if="orderInfo.hbOrderStatus == orderStatusEnum.ORDER_CANCEL">
+              <div class="text-16px font-semibold">已取消</div>
+              <div>取消原因:{{ orderInfo.cancelReason || '未知取消原因' }}</div>
+            </template>
+            <template v-if="orderInfo.hbOrderStatus == orderStatusEnum.ORDER_COMPLETE">
+              <div class="text-16px font-semibold">交易成功</div>
+              <div>买家已收货</div>
+            </template>
+          </NFlex>
+        </NFlex>
+        <NDivider />
+        <template v-if="orderInfo.hbOrderStatus != orderStatusEnum.ORDER_CANCEL">
+          <div class="p3">
+            <NSteps :current="currentSteps" :vertical="appStore.isMobile">
+              <NStep title="用户下单" :description="orderInfo.createTime" />
+              <NStep title="买家已付款" :description="orderInfo.payTime" />
+              <NStep title="卖家已发货" :description="orderInfo.dvyTime" />
+              <NStep title="买家已收货" :description="orderInfo.finallyTime" />
+            </NSteps>
+          </div>
+          <NDivider />
+        </template>
+        <NDescriptions bordered :column="appStore.isMobile ? 1 : 4">
+          <NDescriptionsItem label="收货人信息">
+            <div>收货人姓名:{{ orderInfo?.userAddrOrder?.receiver || '---' }}</div>
+            <div>收货人手机号:{{ orderInfo?.userAddrOrder?.mobile || '---' }}</div>
+            <div>收货地址:{{ orderInfo?.userAddrOrder?.address || '---' }}</div>
+          </NDescriptionsItem>
+          <NDescriptionsItem label="配送信息">
+            <div>配送方式: {{ dvyStatus[orderInfo.dvyType as keyof typeof dvyStatus] || '暂无' }}</div>
+          </NDescriptionsItem>
+          <NDescriptionsItem label="父订单付款信息">
+            <div>实付金额:{{ orderInfo.actualTotal }}元</div>
+            <div>
+              付款方式:{{
+                orderInfo.hbOrderStatus == orderStatusEnum.WAIT_PAY ||
+                orderInfo.hbOrderStatus == orderStatusEnum.ORDER_CANCEL
+                  ? '暂无'
+                  : '微信'
+              }}
+            </div>
+            <div>付款时间:{{ orderInfo.payTime || '暂无' }}</div>
+          </NDescriptionsItem>
+          <NDescriptionsItem label="买家信息">
+            <div>买家昵称:{{ orderInfo?.nickName || '---' }}</div>
+            <div>买家电话:{{ orderInfo?.userMobile || '---' }}</div>
+            <div>买家留言:{{ orderInfo?.remarks || '暂无' }}</div>
+          </NDescriptionsItem>
+        </NDescriptions>
+        <NDivider />
+        <NCard title="子订单信息" :bordered="false">
+          <NDataTable :columns="orderColumns" :data="orderInfo.orderItems" :bordered="false" />
+        </NCard>
+        <NCard title="子费用信息" :bordered="false">
+          <NTable :single-line="false">
+            <NThead>
+              <NTr>
+                <NTh>费用类型</NTh>
+                <NTh>金额/元</NTh>
+              </NTr>
+            </NThead>
+            <NTbody>
+              <NTr>
+                <NTd>商品总额</NTd>
+                <NTd>{{ orderInfo.total }}</NTd>
+              </NTr>
+              <NTr>
+                <NTd>配送费(快递)</NTd>
+                <NTd>{{ orderInfo.freightAmount }}</NTd>
+              </NTr>
+              <NTr>
+                <NTd>积分</NTd>
+                <NTd>-{{ (Number(orderInfo.offsetPoints) / 100).toFixed(2) || 0 }}</NTd>
+              </NTr>
+              <NTr>
+                <NTd v-if="orderInfo.hbOrderStatus == orderStatusEnum.WAIT_PAY">需付款</NTd>
+                <NTd
+                  v-if="
+                    orderInfo.hbOrderStatus != orderStatusEnum.WAIT_PAY &&
+                    orderInfo.hbOrderStatus != orderStatusEnum.ORDER_CANCEL
+                  "
+                >
+                  实际付款
+                </NTd>
+                <NTd v-if="orderInfo.hbOrderStatus == orderStatusEnum.ORDER_CANCEL">应付款</NTd>
+                <NTd>{{ orderInfo.actualTotal }}</NTd>
+              </NTr>
+            </NTbody>
+          </NTable>
+        </NCard>
+      </div>
+    </BasicModal>
+    <DeliveryModal ref="Shipment" @finish="emit('finish')"></DeliveryModal>
+  </div>
+</template>
+
+<style scoped></style>

+ 509 - 0
src/views/order-manage/normal-order/index.vue

@@ -0,0 +1,509 @@
+<script setup lang="tsx">
+import { onMounted, reactive, ref, unref, useTemplateRef, watch } from 'vue';
+import { useRouter } from 'vue-router';
+import { NTag, useDialog } from 'naive-ui';
+import type { InternalRowData } from 'naive-ui/es/data-table/src/interface';
+import {
+  fetchBreakDownload,
+  fetchExportList,
+  fetchExportOrderList,
+  fetchGetDeliveryOrderList,
+  fetchGetDeliveryStatusNum
+} from '@/service/api/order-manage/normal-order';
+// import { fetchGetLoginUserList } from '@/service/api/common';
+import { useAppStore } from '@/store/modules/app';
+import { defaultTransform, useNaivePaginatedTable } from '@/hooks/common/table';
+import { useAuth } from '@/hooks/business/auth';
+// import { copyTextToClipboard } from '@/utils/zt';
+import { commonExport } from '@/utils/common';
+import { $t } from '@/locales';
+import { useForm } from '@/components/zt/Form/hooks/useForm';
+import { useModal } from '@/components/zt/Modal/hooks/useModal';
+import { useTable } from '@/components/zt/Table/hooks/useTable';
+// import { type } from '../../../../packages/axios/src/index';
+import { SearchForm, orderStatus } from './normal-order';
+import DeliveryModal from './component/delivery-modal.vue';
+import NormalMoadl from './component/normal-modal.vue';
+const router = useRouter();
+const appStore = useAppStore();
+const checkedRowKeys = ref([]);
+const activeTab = ref('all');
+const statusList = ref<{ label: string; value: string; num?: number }[]>([]);
+const orderMoadl = useTemplateRef('orderMoadl');
+// const ShipmentModal = useTemplateRef('Shipment');
+const channelIdList = ref([]);
+const searchForm = ref();
+const searchParams = reactive({
+  pageNum: 1,
+  pageSize: 10
+});
+const [registerSearchForm, { getFieldsValue, setFieldsValue }] = useForm({
+  schemas: [
+    // {
+    //   field: 'channelIdList',
+    //   label: '所属企业',
+    //   component: 'ApiSelect',
+    //   componentProps: {
+    //     api: () => fetchGetLoginUserList(),
+    //     labelFeild: 'channelName',
+    //     valueFeild: 'id',
+    //     multiple: true,
+    //     onUpdateValue: () => {
+    //       nextTick(() => {
+    //         handleSearch();
+    //       });
+    //     },
+    //     getOptions: async (options: any) => {
+    //       await setFieldsValue({ channelIdList: [options[0].id] });
+    //       handleSearch();
+    //     }
+    //   }
+    // },
+    ...SearchForm
+  ],
+  showAdvancedButton: false,
+  labelWidth: 120,
+  layout: 'horizontal',
+  size: 'small',
+  gridProps: {
+    cols: '1 xl:4 s:1 l:3',
+    itemResponsive: true
+  },
+  collapsedRows: 1
+});
+const { columns, data, loading, getData, mobilePagination } = useNaivePaginatedTable({
+  api: () => fetchGetDeliveryOrderList({ ...searchParams, orderStatus: activeTab.value, ...unref(searchForm) }),
+  transform: response => defaultTransform(response),
+  immediate: false,
+  paginationProps: {
+    pageSizes: import.meta.env.VITE_PAGE_SIZE.split(',').map(Number)
+  },
+  onPaginationParamsChange: params => {
+    searchParams.pageNum = Number(params.page);
+    searchParams.pageSize = Number(params.pageSize);
+  },
+  columns: () => [
+    {
+      key: 'orderNumber',
+      title: '订单编号',
+      align: 'center',
+      width: 220
+    },
+    {
+      key: 'consigneeAddress',
+      title: '业务类型',
+      align: 'center',
+      width: 120,
+      render: row => {
+        return <NTag class={'mt7'}>{row.businessType}</NTag>;
+      }
+    },
+    {
+      key: 'info',
+      title: '客户信息',
+      align: 'center',
+      width: 220,
+      render: row => {
+        return (
+          <div class={'mt7'}>
+            <div>
+              {row.consigneeName}
+              {row.consigneeMobile}
+            </div>
+            <div>{row.consigneeAddress}</div>
+          </div>
+        );
+      }
+    },
+    {
+      key: 'status',
+      title: '订单状态',
+      align: 'center',
+      width: 120,
+      render: row => {
+        const statusKey = row.hbOrderStatus as keyof typeof orderStatus;
+        const statusText = orderStatus[statusKey] || '未知状态';
+        return <NTag class={'mt7'}>{statusText}</NTag>;
+      }
+    },
+    {
+      key: 'createTime',
+      title: '下单时间',
+      align: 'center',
+      width: 180,
+      render: row => {
+        return <div>{row.createTime?.replace('T', '  ')}</div>;
+      }
+    },
+    {
+      key: 'operate',
+      title: $t('common.operate'),
+      align: 'center',
+      width: 150,
+      fixed: 'right',
+      render: row => {
+        return (
+          <div class={'mt7'}>
+            <n-button size="small" type="primary" ghost onClick={() => handleOrderDetail(row)}>
+              订单详情
+            </n-button>
+          </div>
+        );
+      }
+    }
+  ]
+});
+
+const [registerTable, { refresh, setTableLoading }] = useTable({
+  tableConfig: {
+    keyField: 'id',
+    title: '',
+    showAddButton: false,
+    showTableHeaderAction: false,
+    showSearch: false,
+    minHeight: 400
+  }
+});
+
+const exportColumns: NaiveUI.TableColumn<InternalRowData>[] = [
+  {
+    key: 'index',
+    title: '序号',
+    align: 'center',
+    width: 100,
+    render(_, rowIndex) {
+      return rowIndex + 1;
+    }
+  },
+  {
+    key: 'taskName',
+    title: '任务名称',
+    align: 'center',
+    minWidth: 100
+  },
+  {
+    key: 'updateTime',
+    title: '时间',
+    align: 'center',
+    minWidth: 100,
+    render: row => {
+      return (
+        <div>
+          <div>创建时间:{row.createTime}</div>
+          <div>完成时间:{row.updateTime}</div>
+        </div>
+      );
+    }
+  },
+  {
+    key: 'operator',
+    title: '操作人',
+    align: 'center',
+    minWidth: 100
+  },
+  {
+    key: 'exportStatus',
+    title: '状态',
+    align: 'center',
+    minWidth: 100,
+    render: row => {
+      if (row.exportStatus == 0) {
+        return (
+          <div>
+            请耐心等待,正在导出中...
+            <n-button text type="info" onClick={() => handleBreak(row.id as string)}>
+              中断
+            </n-button>
+          </div>
+        );
+      } else if (row.exportStatus == 1) {
+        return (
+          <div>
+            未下载
+            <n-button text type="info" onClick={() => handleDownload(row.id as string)}>
+              下载
+            </n-button>
+          </div>
+        );
+      } else if (row.exportStatus == 2) {
+        return <div class={'text-gray-500'}>生成文件失败</div>;
+      } else if (row.exportStatus == 3) {
+        return (
+          <div>
+            已下载&nbsp;
+            <n-button text type="info" onClick={() => handleDownload(row.id as string)}>
+              下载
+            </n-button>
+          </div>
+        );
+      } else if (row.exportStatus == 4) {
+        return <div>导出失败</div>;
+      }
+      return <div>进行中</div>;
+    }
+  }
+];
+
+async function handleDownload(id: string) {
+  setTableLoading(true);
+  await commonExport('/platform/exportTask/download', { fileId: id }, '正常订单列表.xlsx');
+  refresh();
+}
+async function handleBreak(id: string) {
+  setTableLoading(true);
+  await fetchBreakDownload(id);
+  refresh();
+}
+
+const [registerModalPrice, { openModal }] = useModal({
+  title: '导出记录',
+  width: 1200,
+  height: 600,
+  showFooter: false
+});
+
+const dialog = useDialog();
+
+// async function handleDeivery(row: Api.delivery.deliveryOrder) {
+//   if (!row.orderNumber) {
+//     window.$message?.error('订单异常');
+//     return;
+//   }
+//   ShipmentModal.value?.handleOpenOrder(row.orderNumber);
+// }
+
+function handleOrderDetail(row: Api.delivery.deliveryOrder) {
+  if (!row.orderNumber) {
+    window.$message?.error('订单异常');
+  }
+  router.push({
+    path: '/order-manage/order-detail',
+    query: {
+      orderNumber: row.orderNumber
+    }
+  });
+  // orderMoadl.value?.open(String(row.orderNumber));
+}
+async function getNums() {
+  const form = getFieldsValue();
+  const params = {
+    ...form,
+    channelIdList: channelIdList.value,
+    startTime: form.createTime ? form.createTime[0] : null,
+    endTime: form.createTime ? form.createTime[1] : null,
+    createTime: null
+  };
+  const { data: keyData } = await fetchGetDeliveryStatusNum(params);
+  if (!keyData) return;
+  const orderStatusList = [
+    {
+      label: '全部',
+      value: 'all'
+    },
+    {
+      label: '待支付',
+      value: 'paddingPay'
+    },
+    {
+      label: '进行中',
+      value: 'ing'
+    },
+    {
+      label: '已完成',
+      value: 'completed'
+    },
+    {
+      label: '已取消',
+      value: 'cancel'
+    }
+  ];
+  const updatedOrderStatusList = orderStatusList.map(item => {
+    const key = item.value as keyof typeof keyData;
+    if (Object.hasOwn(keyData, key)) {
+      return {
+        ...item,
+        num: keyData[key]
+      };
+    }
+    return item;
+  });
+  // console.log(updatedOrderStatusList, 'updatedOrderStatusList');
+  statusList.value = updatedOrderStatusList;
+}
+
+watch(
+  () => [activeTab.value],
+  () => {
+    searchParams.pageNum = 1;
+    getData();
+  }
+);
+function handleSearch() {
+  const form = getFieldsValue();
+  if (form.createTime) {
+    form.startTime = form.createTime[0];
+    form.endTime = form.createTime[1];
+    delete form.createTime;
+  }
+  channelIdList.value = form.channelIdList;
+  searchForm.value = form;
+  getData();
+  getNums();
+}
+onMounted(() => {
+  getData();
+  getNums();
+});
+
+function handleReset() {
+  searchForm.value = getFieldsValue();
+  searchForm.value.channelIdList = channelIdList.value;
+  setFieldsValue({ channelIdList: channelIdList.value });
+  getData();
+  getNums();
+}
+// async function handleCopy(row: Api.delivery.deliveryOrder, key: string) {
+//   if (!row[key]) {
+//     window.$message?.error('订单编号不存在');
+//     return;
+//   }
+//   await copyTextToClipboard(row[key]);
+// }
+function handleRefsh() {
+  getData();
+  getNums();
+}
+async function handleExport() {
+  loading.value = true;
+  try {
+    // await commonExport(
+    //   '/platform/order/export',
+    //   { ...getFieldsValue(), orderStatus: activeTab.value },
+    //   '正常订单列表.xlsx'
+    // );
+    const newParams = getFieldsValue();
+    if (newParams.createTime) {
+      newParams.startTime = newParams.createTime[0];
+      newParams.endTime = newParams.createTime[1];
+      delete newParams.createTime;
+    }
+    await fetchExportOrderList({ ...newParams, orderStatus: activeTab.value });
+    dialog.success({
+      title: '提示',
+      content: () => {
+        return (
+          <div>
+            <p>导出操作进行中......</p>
+            <p>是否进入导出记录</p>
+          </div>
+        );
+      },
+      positiveText: '确定',
+      negativeText: '取消',
+      onPositiveClick: () => {
+        openModal();
+      },
+      onNegativeClick: () => {}
+    });
+  } finally {
+    loading.value = false;
+  }
+}
+
+async function handleExportLog() {
+  loading.value = true;
+  try {
+    openModal();
+  } finally {
+    loading.value = false;
+  }
+}
+</script>
+
+<template>
+  <div class="flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
+    <NCard :bordered="false" size="small">
+      <NCollapse display-directive="show" default-expanded-names="search">
+        <NCollapseItem title="搜索" name="search">
+          <BasicForm @register-form="registerSearchForm" @submit="handleSearch" @reset="handleReset" />
+        </NCollapseItem>
+      </NCollapse>
+    </NCard>
+    <NCard :bordered="false" size="small" class="card-wrapper sm:flex-1-hidden">
+      <template #header>
+        <div class="mr3">订单列表</div>
+        <NScrollbar x-scrollable>
+          <div class="flex items-center">
+            <div class="max-w-800px">
+              <NTabs v-model:value="activeTab" type="line" animated display-directive="show">
+                <NTab
+                  v-for="item in statusList"
+                  :key="item.value"
+                  :name="item.value"
+                  :tab="`${item.label}(${item.num})`"
+                ></NTab>
+              </NTabs>
+            </div>
+          </div>
+        </NScrollbar>
+      </template>
+      <template #header-extra>
+        <NButton
+          v-if="useAuth().hasAuth('order:user:export')"
+          size="small"
+          type="primary"
+          class="ml20px mt30px"
+          ghost
+          :loading="loading"
+          :disabled="data.length == 0"
+          @click="handleExport"
+        >
+          <template #icon>
+            <SvgIcon icon="mingcute:file-export-line"></SvgIcon>
+          </template>
+          导出
+        </NButton>
+        <NButton
+          v-if="useAuth().hasAuth('order:user:export')"
+          size="small"
+          type="primary"
+          class="ml20px mt30px"
+          ghost
+          :loading="loading"
+          @click="handleExportLog"
+        >
+          导出记录
+        </NButton>
+      </template>
+
+      <NDataTable
+        v-model:checked-row-keys="checkedRowKeys"
+        :columns="columns"
+        :data="data"
+        size="small"
+        :flex-height="!appStore.isMobile"
+        :scroll-x="1800"
+        :loading="loading"
+        :row-key="row => row.orderId"
+        remote
+        class="sm:h-full"
+        :pagination="mobilePagination"
+      />
+      <NormalMoadl ref="orderMoadl" @finish="handleRefsh"></NormalMoadl>
+      <DeliveryModal ref="Shipment" @finish="handleRefsh"></DeliveryModal>
+    </NCard>
+    <BasicModal @register="registerModalPrice" @after-leave="refresh">
+      <LayoutTable>
+        <ZTable
+          :show-table-action="false"
+          :columns="exportColumns"
+          :api="fetchExportList"
+          :default-params="{ exportType: 1 }"
+          @register="registerTable"
+        ></ZTable>
+      </LayoutTable>
+    </BasicModal>
+  </div>
+</template>
+
+<style scoped></style>

+ 286 - 0
src/views/order-manage/normal-order/normal-order.ts

@@ -0,0 +1,286 @@
+import { h } from 'vue';
+import { NFlex, NImage, NTag } from 'naive-ui';
+// import { fetchGetAllStoreList } from '@/service/api/goods/desk-category';
+import { fetchGetStoreList } from '@/service/api/xsb-manage/store-info';
+import { fetchGetDictDataList } from '@/service/api/system-manage';
+// import { useAuth } from '@/hooks/business/auth';
+import type { FormSchema } from '@/components/zt/Form/types/form';
+
+export const SearchForm: FormSchema[] = [
+  {
+    label: '业务类型',
+    field: 'businessType',
+    component: 'ApiSelect',
+    componentProps: {
+      api: fetchGetDictDataList,
+      labelFeild: 'name',
+      valueFeild: 'value',
+      resultFeild: 'data.list',
+      params: {
+        typeCode: 'sys_business_type'
+      }
+    }
+  },
+  {
+    label: '门店名称',
+    component: 'ApiSelect',
+    field: 'shopId',
+    componentProps: {
+      api: fetchGetStoreList,
+      resultFeild: 'data.list',
+      labelFeild: 'shopName',
+      valueFeild: 'shopId'
+    }
+  },
+
+  // {
+  //   label: '订单类型',
+  //   component: 'NSelect',
+  //   field: 'dvyType',
+  //   componentProps: {
+  //     options: [
+  //       {
+  //         label: '全部',
+  //         value: ''
+  //       },
+  //       {
+  //         label: '快递',
+  //         value: 1
+  //       },
+  //       {
+  //         label: '配送',
+  //         value: 3
+  //       }
+  //     ]
+  //   }
+  // },
+  // {
+  //   label: '父订单编号',
+  //   component: 'NInput',
+  //   field: 'parentOrderNumber'
+  // },
+  {
+    label: '订单编号',
+    component: 'NInput',
+    field: 'orderNumber'
+  },
+  {
+    label: '收货人姓名',
+    component: 'NInput',
+    field: 'consigneeName'
+  },
+  {
+    label: '收货人电话',
+    component: 'NInput',
+    field: 'consigneeMobile'
+  },
+  // {
+  //   label: '售后状态',
+  //   component: 'NSelect',
+  //   field: 'refundStatus',
+  //   componentProps: {
+  //     options: [
+  //       {
+  //         label: '申请退款',
+  //         value: 1
+  //       },
+  //       {
+  //         label: '退款成功',
+  //         value: 2
+  //       },
+  //       {
+  //         label: '部分退款成功',
+  //         value: 3
+  //       },
+  //       {
+  //         label: '退款失败',
+  //         value: 4
+  //       }
+  //     ]
+  //   }
+  // },
+  {
+    label: '下单时间',
+    component: 'NDatePicker',
+    field: 'createTime',
+    componentProps: {
+      type: 'datetimerange',
+      defaultTime: ['00:00:00', '23:59:59']
+    }
+  }
+  // {
+  //   field: 'userAttrType',
+  //   label: '人员属性',
+  //   component: 'dictSelect',
+  //   componentProps: {
+  //     dictCode: 'user_attr_type',
+  //     immediate: true
+  //   },
+  //   show: useAuth().hasAuth('user:attr:type')
+  // }
+];
+
+export enum orderStatusEnum {
+  /**
+   *
+   *  待支付
+   */
+  WAIT_PAY = 0,
+  /**
+   * 待发货
+   */
+  WAIT_DELIVERY = 1,
+  /**
+   * 订单已接单(待拣货)
+   */
+  ORDER_ACCEPT = 20,
+  /**
+   * 订单待配送(拣货完成/自提类订单为待自提)
+   */
+  ORDER_WAIT_DELIVERY = 30,
+  /**
+   * 订单配送中
+   */
+  ORDER_DELIVERY = 40,
+  /**
+   * 订单取消待审核
+   */
+  ORDER_CANCEL_WAIT_AUDIT = 50,
+  /**
+   * 订单已取消
+   */
+  ORDER_CANCEL = 60,
+  /**
+   * 订单已送达
+   */
+  ORDER_ARRIVE = 70,
+  /**
+   * 订单已完成
+   */
+  ORDER_COMPLETE = 80
+}
+/**
+ * 发货按钮显示状态
+ */
+export const ShippingButton = [
+  orderStatusEnum.WAIT_DELIVERY,
+  orderStatusEnum.ORDER_ACCEPT,
+  orderStatusEnum.ORDER_DELIVERY,
+  orderStatusEnum.ORDER_WAIT_DELIVERY
+];
+/**
+ *  // 0-待支付 1-待发货,20-订单已接单(待拣货),30-订单待配送(拣货完成/自提类订单为待自提),40-订单配送中
+        // ,50-订单取消待审核,60-订单已取消,70-订单已送达,80-订单已完成
+ */
+export const orderStatus = {
+  [orderStatusEnum.WAIT_PAY]: '待支付',
+  [orderStatusEnum.WAIT_DELIVERY]: '待发货',
+  [orderStatusEnum.ORDER_ACCEPT]: '订单已接单(待拣货)',
+  [orderStatusEnum.ORDER_WAIT_DELIVERY]: '订单待配送(拣货完成/自提类订单为待自提)',
+  [orderStatusEnum.ORDER_DELIVERY]: '订单配送中',
+  [orderStatusEnum.ORDER_CANCEL_WAIT_AUDIT]: '订单取消待审核',
+  [orderStatusEnum.ORDER_CANCEL]: '订单已取消',
+  [orderStatusEnum.ORDER_ARRIVE]: '订单已送达',
+  [orderStatusEnum.ORDER_COMPLETE]: '订单已完成'
+};
+
+/**
+ // 1:申请退款 2:退款成功 3:部分退款成功 4:退款失败
+ *
+ */
+
+export const refundStatus = {
+  1: '申请退款',
+  2: '退款成功',
+  3: '部分退款成功',
+  4: '退款失败'
+};
+/**
+ *
+ * 配送方式
+ */
+
+export const dvyStatus = {
+  1: '快递',
+  2: '自提',
+  3: '即时配送'
+};
+
+export const orderColumns: NaiveUI.TableColumn<Api.delivery.OrderItemElement>[] = [
+  {
+    title: '商品',
+    key: 'goods',
+    width: 300,
+    render: row => {
+      const goodsNodes = [
+        h(NImage, { src: row.pic, width: 80, height: 80 }),
+        h('div', { class: 'ml-2 ' }, [
+          h('div', { class: 'text-15px font-semibold' }, row.skuName),
+          h('div', { class: 'text-gray' }, `规格:${row.spec || '--'}`)
+        ])
+      ];
+      return h('div', { class: 'flex items-center' }, goodsNodes);
+    }
+  },
+  {
+    title: '单价(元)',
+    key: 'price',
+    width: 100
+  },
+  {
+    title: '数量',
+    key: 'prodCount',
+    width: 250,
+    render: row => {
+      const nodes = [h('div', { class: 'mr-2' }, row.prodCount)];
+      if (row.refundSuccessCount) {
+        nodes.push(h(NTag, { class: 'ml2', type: 'success' }, () => `退款成功:${row.refundSuccessCount}`));
+      }
+      if (row.refundIngCount && !row.refundSuccessCount) {
+        nodes.push(h(NTag, { class: 'ml2', type: 'error' }, () => `售后处理:${row.refundIngCount}`));
+      }
+      return h(NFlex, { align: 'center' }, () => nodes);
+    }
+  },
+  {
+    title: '小计/元',
+    key: 'productTotalAmount',
+    width: 100
+  }
+];
+
+export const deliveryInfo: FormSchema[] = [
+  {
+    label: '配送方式',
+    component: 'NGradientText',
+    field: 'dvyMethod',
+    render() {
+      return h('div', {}, '快递');
+    }
+  },
+  {
+    label: '收货人姓名',
+    component: 'NGradientText',
+    field: 'receiver',
+    render({ model, field }) {
+      return h('div', {}, model[field]);
+    }
+  },
+  {
+    label: '收货人手机号',
+    component: 'NInput',
+    field: 'mobile',
+    render({ model, field }) {
+      return h('div', {}, model[field]);
+    }
+  },
+  {
+    label: '收货地址',
+    component: 'NInput',
+    field: 'address',
+
+    render({ model, field }) {
+      return h('div', {}, model[field]);
+    }
+  }
+];

+ 180 - 0
src/views/order-manage/order-detail/index.vue

@@ -0,0 +1,180 @@
+<script setup lang="ts">
+import { ref } from 'vue';
+import { useRoute } from 'vue-router';
+// import { NFlex } from 'naive-ui';
+import dayjs from 'dayjs';
+import { fetchGetNomalOrderInfo } from '@/service/api/order-manage/normal-order';
+// import { useAppStore } from '@/store/modules/app';
+// import { copyTextToClipboard } from '@/utils/zt';
+import { orderColumns, orderStatus, orderStatusEnum } from '../normal-order/normal-order';
+import DeliveryModal from '../normal-order/component/delivery-modal.vue';
+const orderInfo = ref<Api.delivery.deliveryOrder>();
+// const appStore = useAppStore();
+const TimeDown = ref<number>(0);
+// const ShipmentRef = useTemplateRef('Shipment');
+const emit = defineEmits<{
+  (e: 'finish'): void;
+}>();
+const route = useRoute();
+async function open(orderNumber: string) {
+  const { data, error } = await fetchGetNomalOrderInfo(orderNumber);
+  if (!error) {
+    orderInfo.value = data;
+    if (orderInfo.value.hbLogisticStatus == orderStatusEnum.WAIT_PAY) {
+      const createTime = dayjs(orderInfo.value.createTime);
+      const currentTime = dayjs();
+      const elapsed = currentTime.diff(createTime);
+      const fifteenMinutesInMillis = 15 * 60 * 1000;
+      TimeDown.value = fifteenMinutesInMillis - elapsed;
+    }
+  }
+}
+console.log(route.query.orderNumber);
+
+open(String(route.query.orderNumber));
+defineExpose({ open });
+
+// const isRefund = computed(() => {
+//   const goodsData = orderInfo.value?.orderItems?.find(it => it.refundIngCount == 1);
+//   return Boolean(goodsData);
+// });
+
+// const currentSteps = computed(() => {
+//   switch (orderInfo.value?.hbOrderStatus) {
+//     case orderStatusEnum.WAIT_PAY:
+//       return 1;
+//     case orderStatusEnum.ORDER_ACCEPT:
+//       return 2;
+//     case orderStatusEnum.ORDER_WAIT_DELIVERY:
+//       return 2;
+//     case orderStatusEnum.WAIT_DELIVERY:
+//       return 2;
+//     case orderStatusEnum.ORDER_DELIVERY:
+//       return 3;
+//     case orderStatusEnum.ORDER_ARRIVE:
+//       return 3;
+//     case orderStatusEnum.ORDER_COMPLETE:
+//       return 4;
+//     default:
+//       return 1;
+//   }
+// });
+// function handleCopy(value: string | number | undefined) {
+//   copyTextToClipboard(String(value));
+//   // copyTextToClipboard(String(orderInfo.value?.orderNumber));
+// }
+</script>
+
+<template>
+  <div>
+    <div v-if="orderInfo" class="flex">
+      <div class="mr-20px w-300px">
+        <div class="mb-10px text-16px font-semibold">
+          统一状态:
+          {{ orderStatus[orderInfo.hbOrderStatus as keyof typeof orderStatus] }}
+        </div>
+        <NCard size="small" title="订单概览" :bordered="false">
+          <div>订单编号:{{ orderInfo.orderNumber }}</div>
+          <div>业务类型:{{ orderInfo.businessType }}</div>
+          <div>
+            订单状态:
+            {{
+              orderInfo.hbOrderStatus == 20 ||
+              orderInfo.hbOrderStatus == 30 ||
+              orderInfo.hbOrderStatus == 40 ||
+              orderInfo.hbOrderStatus == 70
+                ? '进行中'
+                : orderStatus[orderInfo.hbOrderStatus as keyof typeof orderStatus]
+            }}
+          </div>
+          <div>订单金额:{{ orderInfo.actualTotal }}</div>
+
+          <div>订单创建:{{ orderInfo?.remarks || '暂无' }}</div>
+          <div>创建人:用户自助下单</div>
+          <div>备注:{{ orderInfo?.remarks || '暂无' }}</div>
+        </NCard>
+        <NCard size="small" class="mt-20px" title="客户信息" :bordered="false">
+          <div>客户姓名:{{ orderInfo?.consigneeName || '---' }}</div>
+          <div>客户手机号:{{ orderInfo?.consigneeMobile || '---' }}</div>
+          <div>客户地址:{{ orderInfo?.consigneeAddress || '---' }}</div>
+          <div>用户昵称:{{ orderInfo.userName || '---' }}</div>
+          <div>用户电话:{{ orderInfo.consigneeMobile }}</div>
+          <div>企业身份:{{ orderInfo.level || '---' }}</div>
+          <div>会员等级:{{ orderInfo.level || '---' }}</div>
+          <div>分销等级:{{ orderInfo.level || '---' }}</div>
+        </NCard>
+        <NCard size="small" class="mt-20px" title="支付信息" :bordered="false">
+          <div>支付状态:{{ orderInfo.isPayed ? '已支付' : '未支付' }}</div>
+          <div>支付金额:{{ orderInfo.actualTotal }}元</div>
+          <div>
+            付款方式:{{
+              orderInfo.hbOrderStatus == orderStatusEnum.WAIT_PAY ||
+              orderInfo.hbOrderStatus == orderStatusEnum.ORDER_CANCEL
+                ? '暂无'
+                : '微信'
+            }}
+          </div>
+          <div>支付时间:{{ orderInfo.payTime || '暂无' }}</div>
+          <div>交易号:{{ orderInfo.outTradeNo || '---' }}</div>
+          <div>退款记录:{{ orderInfo.record || '暂无' }}</div>
+        </NCard>
+      </div>
+      <div class="flex-1">
+        <div class="flex">
+          <div class="mb-10px text-16px font-semibold">
+            业务状态:
+            {{ orderStatus[orderInfo.hbOrderStatus as keyof typeof orderStatus] }}
+          </div>
+          <div class="mb-10px ml-20px text-16px font-semibold">第三方订单编号:{{ orderInfo.orderNumber }}</div>
+        </div>
+        <NCard size="small" title="业务信息" :bordered="false">
+          <div class="pb-20px font-semibold">01 商家信息</div>
+          <div>门店名称:{{ orderInfo.shopName || '暂无' }}</div>
+          <div>门店地址:{{ orderInfo.shopAddress || '暂无' }}</div>
+          <div>联系电话:{{ orderInfo.tel || '暂无' }}</div>
+          <div class="py-20px font-semibold">02 商品&费用</div>
+          <NDataTable :columns="orderColumns" :data="orderInfo.orderItemList" :bordered="false" />
+
+          <NTable :single-line="false">
+            <NThead>
+              <NTr>
+                <NTh>费用类型</NTh>
+                <NTh>金额/元</NTh>
+              </NTr>
+            </NThead>
+            <NTbody>
+              <NTr>
+                <NTd>商品总额</NTd>
+                <NTd>{{ orderInfo.total }}</NTd>
+              </NTr>
+              <NTr>
+                <NTd>配送费(快递)</NTd>
+                <NTd>{{ orderInfo.freightAmount }}</NTd>
+              </NTr>
+              <NTr>
+                <NTd>积分</NTd>
+                <NTd>-{{ (Number(orderInfo.offsetPoints) / 100).toFixed(2) || 0 }}</NTd>
+              </NTr>
+              <NTr>
+                <NTd v-if="orderInfo.hbOrderStatus == orderStatusEnum.WAIT_PAY">需付款</NTd>
+                <NTd
+                  v-if="
+                    orderInfo.hbOrderStatus != orderStatusEnum.WAIT_PAY &&
+                    orderInfo.hbOrderStatus != orderStatusEnum.ORDER_CANCEL
+                  "
+                >
+                  实际付款
+                </NTd>
+                <NTd v-if="orderInfo.hbOrderStatus == orderStatusEnum.ORDER_CANCEL">应付款</NTd>
+                <NTd>{{ orderInfo.actualTotal }}</NTd>
+              </NTr>
+            </NTbody>
+          </NTable>
+        </NCard>
+      </div>
+    </div>
+    <DeliveryModal ref="Shipment" @finish="emit('finish')"></DeliveryModal>
+  </div>
+</template>
+
+<style scoped></style>

+ 0 - 12
src/views/test/index.vue

@@ -1,12 +0,0 @@
-<script setup lang="ts">
-import { ref } from 'vue';
-const a = ref(1);
-</script>
-
-<template>
-  <div>
-    {{ a }}
-  </div>
-</template>
-
-<style scoped></style>

+ 4 - 2
src/views/xsb-manage/fright-config/index.vue

@@ -1,7 +1,7 @@
 <script setup lang="tsx">
 import { ref } from 'vue';
 import { NDynamicInput, NInputNumber, NSelect } from 'naive-ui';
-import { fetchGetAllChannelList } from '@/service/api/goods-center/store-goods';
+import { fetchGetChannelList } from '@/service/api/goods-center/store-goods';
 import { fetchChannelList, fetchGetAddOrEditTransport, fetchGetTransport } from '@/service/api/common';
 import { useTabStore } from '@/store/modules/tab';
 import { useForm } from '@/components/zt/Form/hooks/useForm';
@@ -58,6 +58,8 @@ const [registerForm, { getFieldsValue, validate, setFieldsValue }] = useForm({
   }
 });
 function handleCreatInput(model: any, field: any, row: Options) {
+  console.log(model, field, row);
+
   return (
     <div class={'flex items-center'}>
       <div class={'w-200px'}>
@@ -126,7 +128,7 @@ function close() {
 }
 
 async function getChannelList() {
-  const { data } = await fetchGetAllChannelList();
+  const { data } = await fetchGetChannelList();
   if (!data) return;
   ChannelOptions.value = data;
 }