Browse Source

Merge branch 'cheney' into dev

WanGxC 7 months ago
parent
commit
36a1bd991c
28 changed files with 1045 additions and 2205 deletions
  1. 12 3
      src/stores/countryInfo.ts
  2. 257 0
      src/views/product-manage/Columns.ts
  3. 0 95
      src/views/product-manage/competitor-monitor/ColumnsTsx.tsx
  4. 11 10
      src/views/product-manage/competitor-monitor/component/DataTable.vue
  5. 1 1
      src/views/product-manage/competitor-monitor/component/DataTableSlot.vue
  6. 1 1
      src/views/product-manage/competitor-monitor/component/EditDrawer.vue
  7. 0 76
      src/views/product-manage/product-list/ColumnsTsx.tsx
  8. 14 14
      src/views/product-manage/product-list/component/DataTable.vue
  9. 1 1
      src/views/product-manage/product-list/component/DataTableSlot.vue
  10. 0 1
      src/views/product-manage/product-list/component/NoticeDialog.vue
  11. 0 104
      src/views/product-manage/product-monitor/ColumnsTsx.tsx
  12. 17 23
      src/views/product-manage/product-monitor/component/DataTable.vue
  13. 1 1
      src/views/product-manage/product-monitor/component/DataTableSlot.vue
  14. 1 1
      src/views/product-manage/product-monitor/component/EditDrawer.vue
  15. 0 82
      src/views/shop-information/api.ts
  16. 0 305
      src/views/shop-information/components/EditDrawer.vue
  17. 0 91
      src/views/shop-information/components/InfoCard.vue
  18. 0 147
      src/views/shop-information/components/PlatformDetail.vue
  19. 0 296
      src/views/shop-information/components/ShopDetail.vue
  20. 0 43
      src/views/shop-information/index.vue
  21. 0 683
      src/views/shop-information/useColumns.tsx
  22. 31 0
      src/views/store-manage/Columns.ts
  23. 118 0
      src/views/store-manage/market-store/api.ts
  24. 186 0
      src/views/store-manage/market-store/component/DataTable.vue
  25. 47 0
      src/views/store-manage/market-store/component/DataTableSlot.vue
  26. 110 0
      src/views/store-manage/market-store/index.vue
  27. 228 218
      src/views/system/login/component/account.vue
  28. 9 9
      vite.config.ts

+ 12 - 3
src/stores/countryInfo.ts

@@ -1,6 +1,6 @@
 // 列出国家信息的pinia
 export const useCountryInfoStore = defineStore('countryInfo', () => {
-  const countries = ref([
+  const countries = [
     { name: '美国', code: 'US', color: '#3C3B6E' }, // 深蓝色
     { name: '英国', code: 'UK', color: '#00247D' }, // 深蓝色
     { name: '德国', code: 'DE', color: '#000000' }, // 黑色
@@ -25,7 +25,16 @@ export const useCountryInfoStore = defineStore('countryInfo', () => {
     { name: '葡萄牙', code: 'PT', color: '#006600' }, // 绿色
     { name: '泰国', code: 'TH', color: '#A51931' }, // 红色
     { name: '新加坡', code: 'SG', color: '#ED2939' }, // 红色
-  ]);
+  ];
 
-  return { countries };
+  const Region = [
+    { name: '北美站', code: 'NA', color: '#3C3B6E' }, // 深蓝色
+    { name: '欧洲站', code: 'EU', color: '#00247D' }, // 深蓝色
+    { name: '日本站', code: 'JP', color: '#BC002D' }, // 红色
+    { name: '澳大利亚站', code: 'AU', color: '#002868' }, // 深蓝色
+    { name: '新加坡站', code: 'SG', color: '#ED2939' }, // 红色
+    { name: '中东站', code: 'ME', color: '#006C35' }, // 绿色
+  ]
+
+  return { countries, Region };
 });

+ 257 - 0
src/views/product-manage/Columns.ts

@@ -0,0 +1,257 @@
+export const ProductColumns = [
+  { type: 'checkbox', minWidth: 50, align: 'center', fixed: 'left' },
+  {
+    field: 'is_monitor', title: '监控管理', minWidth: 90, align: 'center', fixed: 'left',
+    slots: { default: 'is_monitor' }
+  },
+  {
+    field: 'product_info', title: '商品信息', minWidth: 240, align: 'center', fixed: 'left',
+    slots: { default: 'product_info' }
+  },
+  {
+    field: 'sku', title: 'SKU', minWidth: 'auto', align: 'center', showOverflow: true,
+    slots: { default: 'sku' }
+  },
+  {
+    field: 'country_code', title: '国 家', width: 'auto', align: 'center',
+    slots: { default: 'country_code' }
+  },
+  {
+    field: 'brand', title: '品 牌', width: 'auto', align: 'center',
+    slots: { default: 'brand' }
+  },
+  {
+    field: 'platform_number', title: '平台编号', width: 'auto', align: 'center',
+    slots: { default: 'platform_number' }
+  },
+  {
+    field: 'shop_name', title: '店 铺', width: 'auto', align: 'center',
+    slots: { default: 'shop_name' }
+  },
+  {
+    field: 'tag', title: '分 组', width: 'auto', align: 'center',
+    slots: { default: 'tag' }
+  },
+  {
+    field: 'price_info', title: '价 格', width: 'auto', align: 'left',
+    slots: { default: 'price_info' }
+  },
+  {
+    field: 'show_price', title: '指导价格', width: 'auto', align: 'left',
+    slots: { default: 'show_price' }
+  },
+  {
+    field: 'launch_date', title: '上架日期', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'launch_date' }
+  },
+  {
+    field: 'category', title: '类 目', width: 'auto', align: 'center', showOverflow: true,
+    slots: { default: 'category' }
+  },
+  {
+    field: 'status', title: '状 态', width: 'auto', align: 'center',
+    slots: { default: 'status' }
+  },
+  {
+    field: 'update_datetime', title: '更新时间', minWidth: 'auto', align: 'center', showOverflow: true,
+    slots: { default: 'update_datetime' }
+  },
+  {
+    field: 'create_datetime', title: '创建时间', minWidth: 'auto', align: 'center', showOverflow: true,
+    slots: { default: 'create_datetime' }
+  },
+  {
+    field: 'operate', title: '操 作', minWidth: 100, align: 'center', fixed: 'right',
+    slots: { default: 'operate' }
+  }
+];
+
+export const ProductMonitorColumns = [
+  { type: 'checkbox', minWidth: 50, align: 'center', fixed: 'left' },
+  {
+    field: 'product_info', title: '商品信息', minWidth: 240, align: 'center', fixed: 'left',
+    slots: { default: 'product_info' }
+  },
+  {
+    field: 'sku', title: 'SKU', width: 'auto', align: 'center', showOverflow: true,
+    slots: { default: 'sku' }
+  },
+  {
+    field: 'country_code', title: '国 家', width: 'auto', align: 'center',
+    slots: { default: 'country_code' }
+  },
+  {
+    field: 'brand', title: '品 牌', width: 'auto', align: 'center',
+    slots: { default: 'brand' }
+  },
+  {
+    field: 'platform_number', title: '平台编号', width: 'auto', align: 'center',
+    slots: { default: 'platform_number' }
+  },
+  {
+    field: 'shop_name', title: '店 铺', width: 'auto', align: 'center',
+    slots: { default: 'shop_name' }
+  },
+  {
+    field: 'tag', title: '分 组', width: 'auto', align: 'center',
+    slots: { default: 'tag' }
+  },
+  {
+    field: 'price_info', title: '价 格',  width: 'auto', headerAlign: 'center', align: 'left',
+    slots: { default: 'price_info' }
+  },
+  {
+    field: 'show_price', title: '展示价格', width: 'auto', align: 'center',
+    slots: { default: 'show_price' }
+  },
+  {
+    field: 'activity_price', title: '平时活动售价', width: 'auto', align: 'center',
+    slots: { default: 'activity_price' }
+  },
+  {
+    field: 'minimum_price', title: '最低活动售价', width: 'auto', align: 'center',
+    slots: { default: 'minimum_price' }
+  },
+  {
+    field: 'ratings', title: '子ASIN评分人数', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'ratings' }
+  },
+  {
+    field: 'all_ratings', title: '亚马逊显示评分人数', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'all_ratings' }
+  },
+  {
+    field: 'reviews', title: '子ASIN评论人数', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'reviews' }
+  },
+  {
+    field: 'all_reviews', title: '亚马逊显示评论人数', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'all_reviews' }
+  },
+  {
+    field: 'score', title: '子ASIN计算评分', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'score' }
+  },
+  {
+    field: 'all_score', title: '亚马逊显示评分', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'all_score' }
+  },
+  {
+    field: 'stars', title: '子ASIN星级分布', width: 'auto', headerAlign: 'center', align: 'center',
+    slots: { default: 'stars' }
+  },
+  {
+    field: 'all_stars', title: '亚马逊星级分布', width: 'auto', headerAlign: 'center', align: 'center',
+    slots: { default: 'all_stars' }
+  },
+  {
+    field: 'launch_date', title: '上架日期', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'launch_date' }
+  },
+  {
+    field: 'category', title: '类 目', width: 'auto', align: 'center',
+    slots: { default: 'category' }
+  },
+  {
+    field: 'status', title: '状 态', width: 'auto', align: 'center',
+    slots: { default: 'status' }
+  },
+  {
+    field: 'update_datetime', title: '更新时间', width: 'auto', align: 'center', showOverflow: true,
+    slots: { default: 'update_datetime' }
+  },
+  {
+    field: 'create_datetime', title: '创建时间', width: 'auto', align: 'center', showOverflow: true,
+    slots: { default: 'create_datetime' }
+  },
+  {
+    field: 'operate', title: '操 作', minWidth: 100, align: 'center', fixed: 'right',
+    slots: { default: 'operate' }
+  }
+];
+
+export const CompetitorMonitorColumns = [
+  { type: 'checkbox', minWidth: 50, align: 'center', fixed: 'left' },
+  {
+    field: 'product_info', title: '商品信息', minWidth: 240, align: 'center', fixed: 'left',
+    slots: { default: 'product_info' }
+  },
+  {
+    field: 'country_code', title: '国 家', width: 'auto', align: 'center',
+    slots: { default: 'country_code' }
+  },
+  {
+    field: 'brand', title: '品 牌', width: 'auto', align: 'center',
+    slots: { default: 'brand' }
+  },
+  {
+    field: 'shop_name', title: '店 铺', width: 'auto', align: 'center',
+    slots: { default: 'shop_name' }
+  },
+  {
+    field: 'tag', title: '分 组', width: 'auto', align: 'center',
+    slots: { default: 'tag' }
+  },
+  {
+    field: 'price_info', title: '价 格',  width: 'auto', headerAlign: 'center', align: 'left',
+    slots: { default: 'price_info' }
+  },
+  {
+    field: 'ratings', title: '子ASIN评分人数', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'ratings' }
+  },
+  {
+    field: 'all_ratings', title: '亚马逊显示评分人数', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'all_ratings' }
+  },
+  {
+    field: 'reviews', title: '子ASIN评论人数', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'reviews' }
+  },
+  {
+    field: 'all_reviews', title: '亚马逊显示评论人数', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'all_reviews' }
+  },
+  {
+    field: 'score', title: '子ASIN计算评分', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'score' }
+  },
+  {
+    field: 'all_score', title: '亚马逊显示评分', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'all_score' }
+  },
+  {
+    field: 'stars', title: '子ASIN星级分布', width: 'auto', headerAlign: 'center', align: 'center',
+    slots: { default: 'stars' }
+  },
+  {
+    field: 'all_stars', title: '亚马逊星级分布', width: 'auto', headerAlign: 'center', align: 'center',
+    slots: { default: 'all_stars' }
+  },
+  {
+    field: 'launch_date', title: '上架日期', width: 'auto', align: 'center', sortable: true,
+    slots: { default: 'launch_date' }
+  },
+  {
+    field: 'category', title: '类 目', width: 'auto', align: 'center',
+    slots: { default: 'category' }
+  },
+  {
+    field: 'status', title: '状 态', width: 'auto', align: 'center',
+    slots: { default: 'status' }
+  },
+  {
+    field: 'update_datetime', title: '更新时间', width: 'auto', align: 'center', showOverflow: true,
+    slots: { default: 'update_datetime' }
+  },
+  {
+    field: 'create_datetime', title: '创建时间', width: 'auto', align: 'center', showOverflow: true,
+    slots: { default: 'create_datetime' }
+  },
+  {
+    field: 'operate', title: '操 作', minWidth: 100, align: 'center', fixed: 'right',
+    slots: { default: 'operate' }
+  }
+];
+
+

+ 0 - 95
src/views/product-manage/competitor-monitor/ColumnsTsx.tsx

@@ -1,95 +0,0 @@
-export const productColumns = [
-  { type: 'checkbox', minWidth: 50, align: 'center', fixed: 'left' },
-  {
-    field: 'product_info', title: '商品信息', minWidth: 240, align: 'center', fixed: 'left',
-    slots: { default: 'product_info' }
-  },
-  {
-    field: 'country_code', title: '国 家', width: 'auto', align: 'center',
-    slots: { default: 'country_code' }
-  },
-  {
-    field: 'brand', title: '品 牌', width: 'auto', align: 'center',
-    slots: { default: 'brand' }
-  },
-  {
-    field: 'shop_name', title: '店 铺', width: 'auto', align: 'center',
-    slots: { default: 'shop_name' }
-  },
-  {
-    field: 'tag', title: '分 组', width: 'auto', align: 'center',
-    slots: { default: 'tag' }
-  },
-  {
-    field: 'price_info', title: '价 格',  width: 'auto', headerAlign: 'center', align: 'left',
-    slots: { default: 'price_info' }
-  },
-  {
-    field: 'show_price', title: '展示价格', width: 'auto', align: 'center',
-    slots: { default: 'show_price' }
-  },
-  {
-    field: 'activity_price', title: '平时活动售价', width: 'auto', align: 'center',
-    slots: { default: 'activity_price' }
-  },
-  {
-    field: 'minimum_price', title: '最低活动售价', width: 'auto', align: 'center',
-    slots: { default: 'minimum_price' }
-  },
-  {
-    field: 'ratings', title: '子ASIN评分人数', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'ratings' }
-  },
-  {
-    field: 'all_ratings', title: '亚马逊显示评分人数', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'all_ratings' }
-  },
-  {
-    field: 'reviews', title: '子ASIN评论人数', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'reviews' }
-  },
-  {
-    field: 'all_reviews', title: '亚马逊显示评论人数', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'all_reviews' }
-  },
-  {
-    field: 'score', title: '子ASIN计算评分', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'score' }
-  },
-  {
-    field: 'all_score', title: '亚马逊显示评分', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'all_score' }
-  },
-  {
-    field: 'stars', title: '子ASIN星级分布', width: 'auto', headerAlign: 'center', align: 'center',
-    slots: { default: 'stars' }
-  },
-  {
-    field: 'all_stars', title: '亚马逊星级分布', width: 'auto', headerAlign: 'center', align: 'center',
-    slots: { default: 'all_stars' }
-  },
-  {
-    field: 'launch_date', title: '上架日期', width: 'auto', align: 'center', sortable: true, 
-    slots: { default: 'launch_date' }
-  },
-  {
-    field: 'category', title: '类 目', width: 'auto', align: 'center',
-    slots: { default: 'category' }
-  },
-  {
-    field: 'status', title: '状 态', width: 'auto', align: 'center',
-    slots: { default: 'status' }
-  },
-  {
-    field: 'update_datetime', title: '更新时间', width: 'auto', align: 'center', showOverflow: true,
-    slots: { default: 'update_datetime' }
-  },
-  {
-    field: 'create_datetime', title: '创建时间', width: 'auto', align: 'center', showOverflow: true,
-    slots: { default: 'create_datetime' }
-  },
-  {
-    field: 'operate', title: '操 作', minWidth: 100, align: 'center', fixed: 'right',
-    slots: { default: 'operate' }
-  }
-];

+ 11 - 10
src/views/product-manage/competitor-monitor/component/DataTable.vue

@@ -6,16 +6,17 @@
  */
 
 import { Delete, Download, InfoFilled, Plus, Refresh, Upload } from '@element-plus/icons-vue';
-import * as api from '../api';
+import { ElMessage } from 'element-plus';
+import { usePagination } from '/@/utils/usePagination';
+import { useTableData } from '/@/utils/useTableData';
+import { CompetitorMonitorColumns } from '/@/views/product-manage/Columns';
+import DataTableSlot from './DataTableSlot.vue';
 import PermissionButton from '/src/components/PermissionButton/index.vue';
-import EditDrawer from './EditDrawer.vue';
 import ImportButton from '/src/components/ImportButton/index.vue';
 import VerticalDivider from '/src/components/VerticalDivider/index.vue';
-import { productColumns } from '../ColumnsTsx';
-import DataTableSlot from './DataTableSlot.vue';
+import EditDrawer from './EditDrawer.vue';
 import CreateDialog from '/@/views/product-manage/product-monitor/component/createDialog.vue';
-import { ElMessage } from 'element-plus';
-import { batchDeleteRow } from '../api';
+import * as api from '../api';
 
 
 interface Parameter {
@@ -106,7 +107,7 @@ async function fetchList() {
   };
 
   await useTableData(api.getTableData, query, gridOptions);
-  await gridRef.value.loadColumn(productColumns);
+  await gridRef.value.loadColumn(CompetitorMonitorColumns);
   gridOptions.showHeader = Boolean(gridOptions.data?.length);
 
 }
@@ -248,8 +249,8 @@ defineExpose({ fetchList });
           <el-select v-model="templateType" placeholder="Select" style="width: 190px">
             <template #prefix>
               <div class="flex items-center">
-                <el-button bg size="small" style="margin-left: -7px; font-size: 14px; border-radius: 29px;" text
-                           type="success"
+                <el-button bg size="small" text type="success"
+                           style="margin-left: -7px; font-size: 14px; border-radius: 29px;"
                            @click.stop="downloadTemplate">下载
                 </el-button>
                 <VerticalDivider style="margin-left: 7px" />
@@ -289,7 +290,7 @@ defineExpose({ fetchList });
       />
     </template>
     <!-- 自定义列插槽 -->
-    <template v-for="col in productColumns" #[`${col.field}`]="{ row }">
+    <template v-for="col in CompetitorMonitorColumns" #[`${col.field}`]="{ row }">
       <DataTableSlot :key="row.id" :field="col.field" :row="row" @edit-row="handleEdit" @handle-delete="singleDelete" />
     </template>
   </vxe-grid>

+ 1 - 1
src/views/product-manage/competitor-monitor/component/DataTableSlot.vue

@@ -7,9 +7,9 @@
 
 import { useCountryInfoStore } from '/@/stores/countryInfo';
 import { Delete, InfoFilled, Operation } from '@element-plus/icons-vue';
+import { getTagType } from '/@/utils/useTagColor';
 import PermissionButton from '/@/components/PermissionButton/index.vue';
 import ProductInfo from '/@/views/product-manage/product-list/component/ProductInfo.vue';
-import { getTagType } from '/@/utils/useTagColor';
 import ProgressBar from '/@/views/product-manage/product-monitor/component/ProgressBar.vue';
 
 

+ 1 - 1
src/views/product-manage/competitor-monitor/component/EditDrawer.vue

@@ -85,7 +85,7 @@ function closeDrawer() {
                v-model="editOpen"
                :close-on-click-modal="false"
                :close-on-press-escape="false"
-               :title="`商品监控 - 编辑 `"
+               :title="`竞品监控- 编辑 `"
                size="25%">
       <el-form
           ref="ruleFormRef"

+ 0 - 76
src/views/product-manage/product-list/ColumnsTsx.tsx

@@ -1,76 +0,0 @@
-export const productColumns = [
-  { type: 'checkbox', minWidth: 50, align: 'center', fixed: 'left' },
-  // { type: 'seq', title: 'No.', minWidth: 60, align: 'center' },
-  {
-    field: 'is_monitor', title: '监控管理', minWidth: 90, align: 'center', fixed: 'left',
-    slots: { default: 'is_monitor' }
-  },
-  {
-    field: 'product_info', title: '商品信息', minWidth: 240, align: 'center', fixed: 'left',
-    slots: { default: 'product_info' }
-  },
-  {
-    field: 'sku', title: 'SKU', minWidth: 'auto', align: 'center', showOverflow: true,
-    slots: { default: 'sku' }
-  },
-  {
-    field: 'country_code', title: '国 家', width: 'auto', align: 'center',
-    slots: { default: 'country_code' }
-  },
-  {
-    field: 'brand', title: '品 牌', width: 'auto', align: 'center',
-    slots: { default: 'brand' }
-  },
-  {
-    field: 'platform_number', title: '平台编号', width: 'auto', align: 'center',
-    slots: { default: 'platform_number' }
-  },
-  {
-    field: 'shop_name', title: '店 铺', width: 'auto', align: 'center',
-    slots: { default: 'shop_name' }
-  },
-  {
-    field: 'tag', title: '分 组', width: 'auto', align: 'center',
-    slots: { default: 'tag' }
-  },
-  {
-    field: 'price_info', title: '价 格', width: 'auto', align: 'left',
-    slots: { default: 'price_info' }
-  },
-  {
-    field: 'show_price', title: '指导价格', width: 'auto', align: 'left',
-    slots: { default: 'show_price' }
-  },
-  // {
-  //   field: 'activity_price', title: '平时活动售价', width: 'auto', align: 'center',
-  //   slots: { default: 'activity_price' }
-  // },
-  // {
-  //   field: 'minimum_price', title: '最低活动售价', width: 'auto', align: 'center',
-  //   slots: { default: 'minimum_price' }
-  // },
-  {
-    field: 'launch_date', title: '上架日期', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'launch_date' }
-  },
-  {
-    field: 'category', title: '类 目', width: 'auto', align: 'center', showOverflow: true,
-    slots: { default: 'category' }
-  },
-  {
-    field: 'status', title: '状 态', width: 'auto', align: 'center',
-    slots: { default: 'status' }
-  },
-  {
-    field: 'update_datetime', title: '更新时间', minWidth: 'auto', align: 'center', showOverflow: true,
-    slots: { default: 'update_datetime' }
-  },
-  {
-    field: 'create_datetime', title: '创建时间', minWidth: 'auto', align: 'center', showOverflow: true,
-    slots: { default: 'create_datetime' }
-  },
-  {
-    field: 'operate', title: '操 作', minWidth: 100, align: 'center', fixed: 'right',
-    slots: { default: 'operate' }
-  }
-];

+ 14 - 14
src/views/product-manage/product-list/component/DataTable.vue

@@ -5,17 +5,19 @@
  * @Author: Cheney
  */
 
-import { Download, Message, Money, Open, Operation, Refresh } from '@element-plus/icons-vue';
-import * as api from '../api';
+import { Download, Message, Money, Open, Refresh } from '@element-plus/icons-vue';
+import { ElMessage } from 'element-plus';
+import { usePagination } from '/@/utils/usePagination';
+import { useTableData } from '/@/utils/useTableData';
+import { ProductColumns } from '/@/views/product-manage/Columns';
+import DataTableSlot from './DataTableSlot.vue';
+import { downloadFile } from '/@/utils/service';
 import PermissionButton from '/src/components/PermissionButton/index.vue';
-import EditDrawer from '/src/views/product-manage/product-list/component/EditDrawer.vue';
-import NoticeDialog from '/src/views/product-manage/product-list/component/NoticeDialog.vue';
 import ImportButton from '/src/components/ImportButton/index.vue';
 import VerticalDivider from '/src/components/VerticalDivider/index.vue';
-import { productColumns } from '../ColumnsTsx';
-import { downloadFile } from '/@/utils/service';
-import DataTableSlot from './DataTableSlot.vue';
-import { ElMessage } from 'element-plus';
+import EditDrawer from '/src/views/product-manage/product-list/component/EditDrawer.vue';
+import NoticeDialog from '/src/views/product-manage/product-list/component/NoticeDialog.vue';
+import * as api from '../api';
 
 
 interface Parameter {
@@ -52,7 +54,6 @@ const gridOptions: any = reactive({
   },
   columnConfig: {
     resizable: true,
-    useVirtual: true
   },
   pagerConfig: {
     total: tableOptions.value.total,
@@ -97,7 +98,7 @@ async function fetchList() {
   };
 
   await useTableData(api.getTableData, query, gridOptions);
-  await gridRef.value.loadColumn(productColumns);
+  await gridRef.value.loadColumn(ProductColumns);
   gridOptions.showHeader = Boolean(gridOptions.data?.length);
 }
 
@@ -222,9 +223,8 @@ defineExpose({ fetchList });
           <el-select v-model="templateType" style="width: 190px">
             <template #prefix>
               <div class="flex items-center">
-                <el-button bg
-                           size="small" style="margin-left: -7px; font-size: 14px; border-radius: 29px;" text
-                           type="success"
+                <el-button size="small" text type="success"
+                           style="margin-left: -7px; font-size: 14px; border-radius: 29px;"
                            @click.stop="downloadTemplate">下载
                 </el-button>
                 <VerticalDivider style="margin-left: 7px" />
@@ -293,7 +293,7 @@ defineExpose({ fetchList });
       />
     </template>
     <!-- 自定义列插槽 -->
-    <template v-for="col in productColumns" #[`${col.field}`]="{ row }">
+    <template v-for="col in ProductColumns" #[`${col.field}`]="{ row }">
       <DataTableSlot :key="row.id" :field="col.field" :row="row" @edit-row="handleEdit" @handle-notice="handleNotice"
                      @handle-monitor="switchMonitor" />
     </template>

+ 1 - 1
src/views/product-manage/product-list/component/DataTableSlot.vue

@@ -7,9 +7,9 @@
 
 import { useCountryInfoStore } from '/@/stores/countryInfo';
 import { Message, Operation } from '@element-plus/icons-vue';
+import { getTagType } from '/@/utils/useTagColor';
 import PermissionButton from '/@/components/PermissionButton/index.vue';
 import ProductInfo from '/@/views/product-manage/product-list/component/ProductInfo.vue';
-import { getTagType } from '/@/utils/useTagColor';
 
 
 const props = defineProps<{

+ 0 - 1
src/views/product-manage/product-list/component/NoticeDialog.vue

@@ -51,7 +51,6 @@ function isOptionDisabled(id: any) {
 }
 
 function removeTag(tag: any) {
-  console.log('tag=> ', tag);
   staffTags.value = staffTags.value.filter((t: any) => t.id !== tag.id);
   staffSelect.value = '';
 }

+ 0 - 104
src/views/product-manage/product-monitor/ColumnsTsx.tsx

@@ -1,104 +0,0 @@
-export const productColumns = [
-  { type: 'checkbox', minWidth: 50, align: 'center', fixed: 'left' },
-  // { type: 'seq', title: 'No.', minWidth: 60, align: 'center', fixed: 'left' },
-  {
-    field: 'product_info', title: '商品信息', minWidth: 240, align: 'center', fixed: 'left',
-    slots: { default: 'product_info' }
-  },
-  {
-    field: 'sku', title: 'SKU', width: 'auto', align: 'center', showOverflow: true,
-    slots: { default: 'sku' }
-  },
-  {
-    field: 'country_code', title: '国 家', width: 'auto', align: 'center',
-    slots: { default: 'country_code' }
-  },
-  {
-    field: 'brand', title: '品 牌', width: 'auto', align: 'center',
-    slots: { default: 'brand' }
-  },
-  {
-    field: 'platform_number', title: '平台编号', width: 'auto', align: 'center',
-    slots: { default: 'platform_number' }
-  },
-  {
-    field: 'shop_name', title: '店 铺', width: 'auto', align: 'center',
-    slots: { default: 'shop_name' }
-  },
-  {
-    field: 'tag', title: '分 组', width: 'auto', align: 'center',
-    slots: { default: 'tag' }
-  },
-  {
-    field: 'price_info', title: '价 格',  width: 'auto', headerAlign: 'center', align: 'left',
-    slots: { default: 'price_info' }
-  },
-  {
-    field: 'show_price', title: '展示价格', width: 'auto', align: 'center',
-    slots: { default: 'show_price' }
-  },
-  {
-    field: 'activity_price', title: '平时活动售价', width: 'auto', align: 'center',
-    slots: { default: 'activity_price' }
-  },
-  {
-    field: 'minimum_price', title: '最低活动售价', width: 'auto', align: 'center',
-    slots: { default: 'minimum_price' }
-  },
-  {
-    field: 'ratings', title: '子ASIN评分人数', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'ratings' }
-  },
-  {
-    field: 'all_ratings', title: '亚马逊显示评分人数', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'all_ratings' }
-  },
-  {
-    field: 'reviews', title: '子ASIN评论人数', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'reviews' }
-  },
-  {
-    field: 'all_reviews', title: '亚马逊显示评论人数', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'all_reviews' }
-  },
-  {
-    field: 'score', title: '子ASIN计算评分', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'score' }
-  },
-  {
-    field: 'all_score', title: '亚马逊显示评分', width: 'auto', align: 'center', sortable: true,
-    slots: { default: 'all_score' }
-  },
-  {
-    field: 'stars', title: '子ASIN星级分布', width: 'auto', headerAlign: 'center', align: 'center',
-    slots: { default: 'stars' }
-  },
-  {
-    field: 'all_stars', title: '亚马逊星级分布', width: 'auto', headerAlign: 'center', align: 'center',
-    slots: { default: 'all_stars' }
-  },
-  {
-    field: 'launch_date', title: '上架日期', width: 'auto', align: 'center', sortable: true, 
-    slots: { default: 'launch_date' }
-  },
-  {
-    field: 'category', title: '类 目', width: 'auto', align: 'center',
-    slots: { default: 'category' }
-  },
-  {
-    field: 'status', title: '状 态', width: 'auto', align: 'center',
-    slots: { default: 'status' }
-  },
-  {
-    field: 'update_datetime', title: '更新时间', width: 'auto', align: 'center', showOverflow: true,
-    slots: { default: 'update_datetime' }
-  },
-  {
-    field: 'create_datetime', title: '创建时间', width: 'auto', align: 'center', showOverflow: true,
-    slots: { default: 'create_datetime' }
-  },
-  {
-    field: 'operate', title: '操 作', minWidth: 100, align: 'center', fixed: 'right',
-    slots: { default: 'operate' }
-  }
-];

+ 17 - 23
src/views/product-manage/product-monitor/component/DataTable.vue

@@ -6,15 +6,17 @@
  */
 
 import { Delete, Download, InfoFilled, Plus, Refresh, Upload } from '@element-plus/icons-vue';
-import * as api from '../api';
+import { ElMessage } from 'element-plus';
+import { usePagination } from '/@/utils/usePagination';
+import { useTableData } from '/@/utils/useTableData';
+import { ProductMonitorColumns } from '/@/views/product-manage/Columns';
+import DataTableSlot from '/@/views/product-manage/product-monitor/component/DataTableSlot.vue';
 import PermissionButton from '/src/components/PermissionButton/index.vue';
-import EditDrawer from './EditDrawer.vue';
-import ImportButton from '/src/components/ImportButton/index.vue';
 import VerticalDivider from '/src/components/VerticalDivider/index.vue';
-import { productColumns } from '../ColumnsTsx';
-import DataTableSlot from '/@/views/product-manage/product-monitor/component/DataTableSlot.vue';
+import ImportButton from '/src/components/ImportButton/index.vue';
+import EditDrawer from './EditDrawer.vue';
 import CreateDialog from '/@/views/product-manage/product-monitor/component/createDialog.vue';
-import { ElMessage } from 'element-plus';
+import * as api from '../api';
 
 
 interface Parameter {
@@ -77,9 +79,7 @@ const editOpen = ref(false);
 const createOpen = ref(false);
 const rowData = ref({});
 
-const dialogVisible = ref(false);
-
-const templateType = ref();
+const templateType = ref('item1');
 
 onMounted(() => {
   fetchList();
@@ -105,9 +105,8 @@ async function fetchList() {
   };
 
   await useTableData(api.getTableData, query, gridOptions);
-  await gridRef.value.loadColumn(productColumns);
+  await gridRef.value.loadColumn(ProductMonitorColumns);
   gridOptions.showHeader = Boolean(gridOptions.data?.length);
-
 }
 
 function handleRefresh() {
@@ -227,25 +226,20 @@ defineExpose({ fetchList });
           </template>
           <template #actions="{ confirm, cancel }">
             <el-button size="small" @click="cancel">No!</el-button>
-            <el-button
-                size="small"
-                type="danger"
-                @click="confirm"
-            >
-              Yes?
-            </el-button>
+            <el-button size="small" type="danger" @click="confirm">Yes?</el-button>
           </template>
         </el-popconfirm>
         <PermissionButton :icon="Plus" plain round type="primary" @click="handleCreate">
           新 增
         </PermissionButton>
         <div class="custom-el-input">
-          <el-select v-model="templateType" placeholder="Select" style="width: 190px">
+          <el-select v-model="templateType" style="width: 190px">
             <template #prefix>
               <div class="flex items-center">
-                <el-button bg size="small" style="margin-left: -7px; font-size: 14px; border-radius: 29px;" text
-                           type="success"
-                           @click.stop="downloadTemplate">下载
+                <el-button size="small" type="success" text
+                           style="margin-left: -7px; font-size: 14px; border-radius: 29px;"
+                           @click.stop="downloadTemplate">
+                  下载
                 </el-button>
                 <VerticalDivider style="margin-left: 7px" />
               </div>
@@ -305,7 +299,7 @@ defineExpose({ fetchList });
       />
     </template>
     <!-- 自定义列插槽 -->
-    <template v-for="col in productColumns" #[`${col.field}`]="{ row }">
+    <template v-for="col in ProductMonitorColumns" #[`${col.field}`]="{ row }">
       <DataTableSlot :key="row.id" :field="col.field" :row="row" @edit-row="handleEdit" @handle-delete="singleDelete" />
     </template>
   </vxe-grid>

+ 1 - 1
src/views/product-manage/product-monitor/component/DataTableSlot.vue

@@ -7,9 +7,9 @@
 
 import { useCountryInfoStore } from '/@/stores/countryInfo';
 import { Delete, InfoFilled, Operation } from '@element-plus/icons-vue';
+import { getTagType } from '/@/utils/useTagColor';
 import PermissionButton from '/@/components/PermissionButton/index.vue';
 import ProductInfo from '/@/views/product-manage/product-list/component/ProductInfo.vue';
-import { getTagType } from '/@/utils/useTagColor';
 import ProgressBar from '/@/views/product-manage/product-monitor/component/ProgressBar.vue';
 
 

+ 1 - 1
src/views/product-manage/product-monitor/component/EditDrawer.vue

@@ -91,7 +91,7 @@ function closeDrawer() {
                v-model="editOpen"
                :close-on-click-modal="false"
                :close-on-press-escape="false"
-               :title="`商品监控 - 编辑 `"
+               :title="`商品监控- 编辑 `"
                size="25%">
       <el-form
           ref="ruleFormRef"

+ 0 - 82
src/views/shop-information/api.ts

@@ -1,82 +0,0 @@
-import { request } from '/@/utils/service';
-
-
-const apiPrefix = '/api/assets/shop/';
-
-export function getCardData(query: any) {
-  return request({
-    url: apiPrefix + 'card/',
-    method: 'GET',
-    params: query,
-  });
-}
-
-export function getTableData(query: any) {
-  return request({
-    url: apiPrefix,
-    method: 'GET',
-    params: query,
-  });
-}
-
-export function getPlatformDetailOverview(query: any) {
-  return request({
-    url: apiPrefix + 'platform/',
-    method: 'GET',
-    params: query,
-  });
-}
-
-export function getShopDetailOverview(query: any) {
-  return request({
-    url: apiPrefix + 'detail/',
-    method: 'GET',
-    params: query,
-  });
-}
-
-export function getCurrentInfo(query: any) {
-  return request({
-    url: apiPrefix + 'current/',
-    method: 'GET',
-    params: query,
-  });
-}
-
-export function getHistoryInfo(query: any) {
-  return request({
-    url: apiPrefix + 'past/',
-    method: 'GET',
-    params: query,
-  });
-}
-
-export function getComputerInfo(query: any) {
-  return request({
-    url: apiPrefix + 'computer/',
-    method: 'GET',
-    params: query,
-  });
-}
-
-export function getShopSelect() {
-  return request({
-    url: apiPrefix + 'box/',
-    method: 'GET',
-  });
-}
-export function getCompanySelect() {
-  return request({
-    url: '/api/assets/company/box/',
-    method: 'GET',
-  });
-}
-
-export function updateShopDetail(body: any) {
-  return request({
-    url: apiPrefix + `${body.id}/`,
-    method: 'POST',
-    params: { partial: body.partial },
-    data: body.formData,
-  });
-}

+ 0 - 305
src/views/shop-information/components/EditDrawer.vue

@@ -1,305 +0,0 @@
-<script lang="ts" setup>
-/**
- * @Name: EditDrawer.vue
- * @Description: 店铺编辑
- * @Author: Cheney
- */
-
-import { ElMessage, FormInstance, FormRules } from 'element-plus';
-import { useResponse } from '/@/utils/useResponse';
-import * as api from '/@/views/shop-information/api';
-
-
-const loading = ref(false);
-const isOpen = defineModel({ default: false });
-const { gridOptions, platformNumber, formSelect, companySelect } = defineProps<{
-  gridOptions: any;
-  platformNumber: any;
-  formSelect: any;
-  companySelect: any;
-}>();
-
-const emit = defineEmits([ 'refresh' ]);
-
-onBeforeMount(() => {
-  replaceCol();
-});
-
-interface RuleForm {
-  operatorName: string;
-  platformNumber: string;
-  platformName: string;
-  country: string;
-  brandName: string;
-  currencyCode: string;
-  status: number;
-  platform: string;
-  line: string[];
-  ipaddress: string;
-  company: string;
-  belongsCompany: string;
-  companyEnglishName: string;
-  address: string; // 新增
-  juridicalPerson: string; // 新增
-  juridicalPersonCreditCard: string; // 新增
-  juridicalPersonCreditCardAddress: string; // 新增
-  receivablesAccount: string; // 新增
-  receivablesAccountCompany: string; // 新增
-  vatNumber: string; // 新增
-  vatCompany: string; // 新增
-  shopPhoneAndName: string | null; // 新增
-  shopEmail: string | null; // 新增
-  subShopPhoneAndName: string | null; // 新增
-  subShopEmail: string | null; // 新增
-}
-
-const ruleFormRef = ref<FormInstance>();
-const ruleForm = reactive<RuleForm>({
-  operatorName: '',
-  platformNumber: '',
-  platformName: '',
-  country: '',
-  brandName: '',
-  currencyCode: '',
-  status: 0,
-  platform: '',
-  line: [],
-  ipaddress: '',
-  company: '',
-  belongsCompany: '',
-  companyEnglishName: '',
-  address: '',
-  juridicalPerson: '',
-  juridicalPersonCreditCard: '',
-  juridicalPersonCreditCardAddress: '',
-  receivablesAccount: '',
-  receivablesAccountCompany: '',
-  vatNumber: '',
-  vatCompany: '',
-  shopPhoneAndName: '',
-  shopEmail: '',
-  subShopPhoneAndName: '',
-  subShopEmail: ''
-});
-
-const rules = reactive<FormRules<RuleForm>>({
-  operatorName: [
-    { message: 'Please input operator name', trigger: 'blur' }
-  ],
-  platformNumber: [
-    { required: true, message: 'Please input platform name', trigger: 'blur' }
-  ],
-  platformName: [
-    { required: true, message: 'Please input platform name', trigger: 'blur' }
-  ],
-  country: [
-    { required: true, message: 'Please input country name', trigger: 'blur' }
-  ],
-  brandName: [
-    { message: 'Please input brand name', trigger: 'blur' }
-  ],
-  currencyCode: [
-    { required: true, message: 'Please select currency code', trigger: 'change' }
-  ],
-  platform: [
-    { required: true, message: 'Please input platform name', trigger: 'blur' }
-  ],
-  line: [
-    { required: true, message: 'Please select line', trigger: 'change' }
-  ],
-  ipaddress: [
-    { message: 'Please input ip address', trigger: 'blur' }
-  ],
-  company: [
-    { message: 'Please input activity form', trigger: 'blur' }
-  ],
-  belongsCompany: [ { required: true, message: 'Please Select belongsCompany', trigger: 'change' } ],
-  companyEnglishName: [
-    { message: 'Please input Company English Name', trigger: 'blur' }
-  ],
-  address: [
-    { message: 'Please input Address', trigger: 'blur' }
-  ],
-  juridicalPerson: [
-    { message: 'Please input Juridical Person', trigger: 'blur' }
-  ],
-  juridicalPersonCreditCard: [
-    { message: 'Please input Juridical Person Credit Card', trigger: 'blur' }
-  ],
-  juridicalPersonCreditCardAddress: [
-    { message: 'Please input Juridical Person Credit Card Address', trigger: 'blur' }
-  ],
-  receivablesAccount: [
-    { message: 'Please input Receivables Account', trigger: 'blur' }
-  ],
-  receivablesAccountCompany: [
-    { message: 'Please input Receivables Account Company', trigger: 'blur' }
-  ],
-  vatNumber: [
-    { message: 'Please input VAT Number', trigger: 'blur' }
-  ],
-  vatCompany: [
-    { message: 'Please input VAT Company', trigger: 'blur' }
-  ],
-  shopPhoneAndName: [
-    { message: 'Please input Shop Email', trigger: 'blur' }
-  ],
-  shopEmail: [
-    { message: 'Please input Shop Email', trigger: 'blur' }
-  ],
-  subShopPhoneAndName: [
-    { message: 'Please input Shop Email', trigger: 'blur' }
-  ],
-  subShopEmail: [
-    { message: 'Please input Sub Shop Email', trigger: 'blur' }
-  ]
-});
-
-const submitForm = async (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  await formEl.validate(async (valid, fields) => {
-    if (valid) {
-      await useResponse({ id: gridOptions.data[0].id, partial: 1, formData: ruleForm }, api.updateShopDetail, loading);
-      isOpen.value = false;
-      ElMessage.success('编辑成功');
-      emit('refresh');
-    } else {
-      console.log('error submit!', fields);
-    }
-  });
-};
-
-const resetForm = (formEl: FormInstance | undefined) => {
-  if (!formEl) return;
-  formEl.resetFields();
-};
-
-function replaceCol() {
-  const result = Object.keys(ruleForm).reduce((acc, key) => {
-    if (key in gridOptions.data[0]) {
-      acc[key] = gridOptions.data[0][key];
-    }
-    return acc;
-  }, {} as { [key: string]: any });
-  Object.assign(ruleForm, result);
-}
-</script>
-
-<template>
-  <el-drawer v-model="isOpen" :title="`店铺编辑 - ${platformNumber}`" size="30%">
-    <el-form
-        ref="ruleFormRef"
-        :model="ruleForm"
-        :rules="rules"
-        class="mx-2.5 mt-2.5"
-        label-width="auto"
-        status-icon>
-      <el-form-item label="运营" prop="operatorName">
-        <el-input v-model="ruleForm.operatorName"/>
-      </el-form-item>
-      <el-form-item label="平台编号" prop="platformNumber">
-        <el-input v-model="ruleForm.platformNumber"/>
-      </el-form-item>
-      <el-form-item label="平台名称" prop="platformName">
-        <el-input v-model="ruleForm.platformName"/>
-      </el-form-item>
-      <el-form-item label="国家" prop="country">
-        <el-select v-model="ruleForm.country" placeholder="请选择线路">
-          <el-option
-              v-for="item in formSelect.country"
-              :key="item"
-              :label="item"
-              :value="item">
-          </el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item label="品牌名称" prop="brandName">
-        <el-input v-model="ruleForm.brandName"/>
-      </el-form-item>
-      <el-form-item label="货币代码" prop="currencyCode">
-        <el-input v-model="ruleForm.currencyCode"/>
-      </el-form-item>
-      <el-form-item label="状态" prop="status">
-        <el-switch v-model="ruleForm.status" :active-value="1" :inactive-value="0"/>
-      </el-form-item>
-      <el-form-item label="平台" prop="platform">
-        <el-input v-model="ruleForm.platform"/>
-      </el-form-item>
-      <el-form-item label="线路" prop="line">
-        <el-select v-model="ruleForm.line" placeholder="请选择线路">
-          <el-option
-              v-for="item in formSelect.line"
-              :key="item"
-              :label="item"
-              :value="item">
-          </el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item label="IP 地址" prop="ipaddress">
-        <el-input v-model="ruleForm.ipaddress"/>
-      </el-form-item>
-      <el-form-item label="公司" prop="company">
-        <el-input v-model="ruleForm.company"/>
-      </el-form-item>
-      <el-form-item label="关联公司" prop="belongsCompany">
-        <el-select v-model="ruleForm.belongsCompany" placeholder="请选择所属公司">
-          <el-option
-              v-for="item in companySelect"
-              :key="item.id"
-              :label="item.company"
-              :value="item.id">
-          </el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item label="公司英文名称" prop="companyEnglishName">
-        <el-input v-model="ruleForm.companyEnglishName"/>
-      </el-form-item>
-      <el-form-item label="地址" prop="address">
-        <el-input v-model="ruleForm.address"/>
-      </el-form-item>
-      <el-form-item label="法人代表" prop="juridicalPerson">
-        <el-input v-model="ruleForm.juridicalPerson"/>
-      </el-form-item>
-      <el-form-item label="法人信用卡" prop="juridicalPersonCreditCard">
-        <el-input v-model="ruleForm.juridicalPersonCreditCard"/>
-      </el-form-item>
-      <el-form-item label="法人信用卡地址" prop="juridicalPersonCreditCardAddress">
-        <el-input v-model="ruleForm.juridicalPersonCreditCardAddress"/>
-      </el-form-item>
-      <el-form-item label="应收账款账户" prop="receivablesAccount">
-        <el-input v-model="ruleForm.receivablesAccount"/>
-      </el-form-item>
-      <el-form-item label="应收账款公司" prop="receivablesAccountCompany">
-        <el-input v-model="ruleForm.receivablesAccountCompany"/>
-      </el-form-item>
-      <el-form-item label="VAT税号" prop="vatNumber">
-        <el-input v-model="ruleForm.vatNumber"/>
-      </el-form-item>
-      <el-form-item label="VAT公司" prop="vatCompany">
-        <el-input v-model="ruleForm.vatCompany"/>
-      </el-form-item>
-      <el-form-item label="主账户电话" prop="shopPhoneAndName">
-        <el-input v-model="ruleForm.shopPhoneAndName"/>
-      </el-form-item>
-      <el-form-item label="主账户邮箱" prop="shopEmail">
-        <el-input v-model="ruleForm.shopEmail"/>
-      </el-form-item>
-      <el-form-item label="子账户电话" prop="subShopPhoneAndName">
-        <el-input v-model="ruleForm.subShopPhoneAndName"/>
-      </el-form-item>
-      <el-form-item label="子账户邮箱" prop="subShopEmail">
-        <el-input v-model="ruleForm.subShopEmail"/>
-      </el-form-item>
-      <el-form-item>
-        <div class="flex flex-1 justify-center">
-          <el-button :loading="loading" type="primary" @click="submitForm(ruleFormRef)">确 定</el-button>
-          <el-button @click="resetForm(ruleFormRef)">重 置</el-button>
-        </div>
-      </el-form-item>
-    </el-form>
-  </el-drawer>
-</template>
-
-<style scoped>
-
-</style>

+ 0 - 91
src/views/shop-information/components/InfoCard.vue

@@ -1,91 +0,0 @@
-<script lang="ts" setup>
-/**
- * @Name: InfoCard.vue
- * @Description: 店铺信息卡片
- * @Author: Cheney
- */
-
-import { useRouter } from 'vue-router';
-import { ElCard, ElCol, ElDescriptions, ElIcon, ElRow } from 'element-plus';
-import { GoodsFilled, Picture as IconPicture, Search, Shop } from '@element-plus/icons-vue';
-
-
-const router = useRouter();
-const cardData = inject<Ref>('cardData', ref({}));
-
-function handleNavigate(item: any) {
-  router.push({
-    path: '/shop/platform/detail',
-    query: { platform: item.platform }
-  });
-}
-
-function getImageSrc(platform: string) {
-  return new URL(`/src/assets/platformImg/${ platform }.png`, import.meta.url).href;
-}
-
-</script>
-
-<template>
-  <el-row :gutter="20">
-    <el-col v-for="(item, index) in cardData" :key="index" :lg="6" :md="8" :sm="8" :xl="4" :xs="12" class="my-2.5">
-      <el-card body-style="padding: 0px 10px 0px 10px" shadow="hover">
-        <el-descriptions>
-          <template #title>
-            <el-image :src="getImageSrc(item.platform)" class="my-2.5 rounded-2xl" fit="contain"
-                      style="width: 60px; height: 60px">
-              <template #error>
-                <div class="flex justify-center items-center" style="width: 60px; height: 60px; font-size: 4rem">
-                  <el-icon>
-                    <icon-picture/>
-                  </el-icon>
-                </div>
-              </template>
-            </el-image>
-            <div class="text-xl mb-2" style="color: #606266;">{{ item.platform }}</div>
-            <hr style="box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);">
-          </template>
-        </el-descriptions>
-        <div class="flex justify-evenly mb-2.5">
-          <div>
-            <el-icon style="top: 2px; margin-right: 6px; font-size: 1.2rem">
-              <Shop/>
-            </el-icon>
-            <span class="font-medium text-lg mr-2">店铺</span>
-            <span class="font-medium text-xl italic">
-              {{ item.countShop }}
-            </span>
-          </div>
-          <div>
-            <el-icon style="top: 2px; margin-right: 5px; font-size: 1.2rem">
-              <GoodsFilled/>
-            </el-icon>
-            <span class="font-medium text-lg mr-2">公司</span>
-            <span class="font-medium text-xl italic">
-              {{ item.countCompany }}
-            </span>
-          </div>
-        </div>
-        <template #footer>
-          <div style="text-align: center; padding: 0 10px">
-            <el-button :icon="Search" plain round style="width: 100%" type="primary" @click="handleNavigate(item)">
-              查看详情
-            </el-button>
-          </div>
-        </template>
-      </el-card>
-    </el-col>
-  </el-row>
-</template>
-
-<style scoped>
-:deep(.el-descriptions__header .el-descriptions__title) {
-  flex: 1;
-  text-align: center;
-}
-
-:deep(.el-card__footer) {
-  border-top: none;
-  padding: 0 0 10px 0;
-}
-</style>

+ 0 - 147
src/views/shop-information/components/PlatformDetail.vue

@@ -1,147 +0,0 @@
-<script lang="ts" setup>
-/**
- * @Name: PlatformDetail.vue
- * @Description: 平台详情页
- * @Author: Cheney
- */
-
-import { useResponse } from '/@/utils/useResponse';
-import * as api from '../api';
-import { Link, Picture as IconPicture } from '@element-plus/icons-vue';
-import { platformColumns } from '../useColumns';
-import router from '/@/router';
-import { useTableData } from '/@/utils/useTableData';
-import { usePagination } from '/@/utils/usePagination';
-
-
-const route = useRoute();
-const platform = route.query.platform;
-const platformOverview: any = ref([]);
-const overviewLoading = ref();
-const { tableOptions, handlePageChange } = usePagination(fetchPlatformDetail);
-const platformTableData = ref([]);
-const gridOptions: any = reactive({
-  border: false,
-  round: true,
-  stripe: true,
-  currentRowHighLight: true,
-  height: 870,
-  toolbarConfig: {
-    custom: true,
-  },
-  rowConfig: {
-    isHover: true
-  },
-  columnConfig: {
-    resizable: true
-  },
-  pagerConfig: {
-    total: tableOptions.value.total,
-    page: tableOptions.value.page,
-    limit: tableOptions.value.limit
-  },
-  loading: false,
-  loadingConfig: {
-    icon: 'vxe-icon-indicator roll',
-    text: '正在拼命加载中...'
-  },
-  columns: platformColumns,
-  data: platformTableData
-});
-
-onBeforeMount(() => {
-  fetchPlatformDetailOverview();
-  fetchPlatformDetail();
-});
-
-async function fetchPlatformDetail() {
-  const query = {
-    platform,
-    page: gridOptions.pagerConfig.page,
-    limit: gridOptions.pagerConfig.limit
-  };
-  await useTableData(api.getTableData, query, gridOptions)
-}
-
-async function fetchPlatformDetailOverview() {
-  const res = await useResponse({ platform }, api.getPlatformDetailOverview, overviewLoading);
-  platformOverview.value = res.data;
-}
-
-function handleNavigate(item: any) {
-  router.push({
-    path: '/shop/detail',
-    query: { platformNumber: item.platformNumber }
-  });
-}
-
-</script>
-
-<template>
-  <div class="p-2.5">
-    <!-- overview-card -->
-    <el-card v-loading="overviewLoading" body-class="flex items-center" shadow="hover" style="border: none">
-      <el-image :src="`/src/assets/platformImg/${ platform }.png`" class="mr-7 rounded-2xl" fit="contain"
-                style="height: 120px; width: 120px;">
-        <template #error>
-          <div class="mr-3.5 flex items-center justify-center text-5xl"
-               style="height: 100%; width: 100%; background-color: #f5f5f5">
-            <el-icon>
-              <icon-picture/>
-            </el-icon>
-          </div>
-        </template>
-      </el-image>
-      <div class="text-lg">
-        <div class="font-semibold">
-          平台名称:
-          <span class="font-medium italic ml-1.5" style="color: #64748b"> 
-            {{ platformOverview[0]?.platform ? platformOverview[0]?.platform : '--' }} 
-          </span>
-        </div>
-        <div class="font-semibold">
-          公司:
-          <span class="font-medium italic ml-1.5" style="color: #64748b">
-            {{ platformOverview[0]?.countCompany ? platformOverview[0]?.countCompany : '--' }} 
-          </span>
-        </div>
-        <div class="font-semibold">
-          店铺:
-          <span class="font-medium italic ml-1.5" style="color: #64748b">
-            {{ platformOverview[0]?.countShop ? platformOverview[0]?.countShop : '--' }}
-          </span>
-        </div>
-        <div class="font-semibold">
-          电脑:
-          <span class="font-medium italic ml-1.5" style="color: #64748b"> 
-            {{ platformOverview[0]?.countComputer ? platformOverview[0]?.countComputer : '--' }}
-          </span>
-        </div>
-      </div>
-    </el-card>
-    <!-- table-card -->
-    <el-card body-style="padding-top: 10px" class="mt-2.5" shadow="hover" style="border: none">
-      <vxe-grid v-bind="gridOptions">
-        <template #platformNumber="{ row }">
-          <el-button link style="font-weight: 700" type="primary" @click="handleNavigate(row)">
-            <el-icon>
-              <Link/>
-            </el-icon>
-            {{ row.platformNumber ? row.platformNumber : '--' }}
-          </el-button>
-        </template>
-        <template #pager>
-          <vxe-pager
-              v-model:currentPage="gridOptions.pagerConfig.page"
-              v-model:pageSize="gridOptions.pagerConfig.limit"
-              :total="gridOptions.pagerConfig.total"
-              @page-change="handlePageChange"
-          >
-          </vxe-pager>
-        </template>
-      </vxe-grid>
-    </el-card>
-  </div>
-</template>
-
-<style scoped></style>

+ 0 - 296
src/views/shop-information/components/ShopDetail.vue

@@ -1,296 +0,0 @@
-<script lang="ts" setup>
-/**
- * @Name: ShopDetail.vue
- * @Description: 店铺详情
- * @Author: Cheney
- */
-
-import { Edit, Monitor, Picture as IconPicture, RefreshLeft, Timer } from '@element-plus/icons-vue';
-import { useResponse } from '/@/utils/useResponse';
-import * as api from '/@/views/shop-information/api';
-import { computerColumns, historyColumns, shopCurrentColumns, companySelect } from '/@/views/shop-information/useColumns';
-import { useTableData } from '/@/utils/useTableData';
-import { usePagination } from '/@/utils/usePagination';
-import EditDrawer from './EditDrawer.vue';
-
-
-const route = useRoute();
-const platformNumber = route.query.platformNumber;
-const shopOverview: any = ref([]);
-const overviewLoading = ref(false);
-const selectedTab = ref('1');
-const { tableOptions, handlePageChange } = usePagination(handleTabChange);
-const gridOptions: any = reactive({
-  border: false,
-  round: true,
-  stripe: true,
-  currentRowHighLight: true,
-  height: 870,
-  toolbarConfig: {
-    custom: true,
-    slots: {
-      buttons: 'toolbar_buttons',
-      tools: 'toolbar_tools'
-    }
-  },
-  rowConfig: {
-    isHover: true
-  },
-  columnConfig: {
-    resizable: true
-  },
-  pagerConfig: {
-    total: tableOptions.value.total,
-    page: tableOptions.value.page,
-    limit: tableOptions.value.limit
-  },
-  loading: false,
-  loadingConfig: {
-    icon: 'vxe-icon-indicator roll',
-    text: '正在拼命加载中...'
-  },
-  columns: '',
-  data: ''
-});
-
-const isOpen = ref(false);
-const formSelect = ref<{ country: string[], line: string[] }>({
-  country: [],
-  line: []
-});
-
-// const companySelect = ref<{ id: string, company: string }>({
-//   id: '',
-//   company: ''
-// });
-
-onBeforeMount(() => {
-  fetchShopDetailOverview();
-  handleTabChange(selectedTab.value);
-  fetchSelect();
-});
-
-async function fetchSelect() {
-  const res = await useResponse({}, api.getShopSelect);
-  formSelect.value = res.data;
-  // const ret = await useResponse({}, api.getCompanySelect);
-  // companySelect.value = ret.data;
-}
-
-async function fetchShopDetailOverview() {
-  const res = await useResponse({ platformNumber }, api.getShopDetailOverview, overviewLoading);
-  shopOverview.value = res.data;
-}
-
-async function handleTabChange(tabValue: any) {
-  gridOptions.pagerConfig.page = 1;
-  gridOptions.pagerConfig.limit = 10;
-  const query = {
-    platformNumber,
-    page: gridOptions.pagerConfig.page,
-    limit: gridOptions.pagerConfig.limit
-  };
-  switch (tabValue) {
-    case '1':
-      gridOptions.columns = shopCurrentColumns;
-      await useTableData(api.getCurrentInfo, query, gridOptions);
-      break;
-    case '2':
-      gridOptions.columns = historyColumns;
-      await useTableData(api.getHistoryInfo, query, gridOptions);
-      break;
-    case '3':
-      gridOptions.columns = computerColumns;
-      await useTableData(api.getComputerInfo, query, gridOptions);
-      break;
-  }
-}
-
-function drawerOpen() {
-  isOpen.value = true;
-}
-
-function handleRefresh() {
-  handleTabChange(selectedTab.value);
-}
-
-</script>
-
-<template>
-  <div class="p-2.5">
-    <el-card v-loading="overviewLoading" body-class="flex items-center gap-10" shadow="hover" style="border: none">
-      <div v-if="platformNumber" class="artistic-text-container mr-7 ">
-        <div class="artistic-text">
-          {{ platformNumber }}
-        </div>
-      </div>
-      <el-image v-else class="mr-7 rounded-2xl" src="" style="height: 120px; width: 120px; object-fit: contain">
-        <template #error>
-          <div class="mr-3.5 flex items-center justify-center text-5xl"
-               style="height: 100%; width: 100%; background-color: #f5f5f5">
-            <el-icon>
-              <icon-picture/>
-            </el-icon>
-          </div>
-        </template>
-      </el-image>
-      <div class="text-lg">
-        <div class="font-semibold">
-          平台编号:
-          <span class="font-medium italic ml-1.5" style="color: #64748b"> 
-            {{ shopOverview[0]?.platformNumber ? shopOverview[0]?.platformNumber : '--' }} 
-          </span>
-        </div>
-        <div class="font-semibold">
-          所属公司:
-          <span class="font-medium italic ml-1.5" style="color: #64748b">
-            {{ shopOverview[0]?.company ? shopOverview[0]?.company : '--' }} 
-          </span>
-        </div>
-        <div class="font-semibold">
-          所属平台:
-          <span class="font-medium italic ml-1.5" style="color: #64748b">
-            {{ shopOverview[0]?.platform ? shopOverview[0]?.platform : '--' }}
-          </span>
-        </div>
-        <div class="font-semibold">
-          运营:
-          <span class="font-medium italic ml-1.5" style="color: #64748b"> 
-            {{ shopOverview[0]?.operatorName ? shopOverview[0]?.operatorName : '--' }}
-          </span>
-        </div>
-        <div class="font-semibold">
-          电脑:
-          <span class="font-medium italic ml-1.5" style="color: #64748b"> 
-            {{ shopOverview[0]?.countComputer === 0 ? '0' : shopOverview[0]?.countComputer || '--' }}
-          </span>
-        </div>
-      </div>
-      <div class="text-lg">
-        <div class="font-semibold">
-          主账户手机号及归属人:
-          <span class="font-medium italic ml-1.5" style="color: #64748b"> 
-            {{ shopOverview[0]?.shopPhoneAndNameStr ? shopOverview[0]?.shopPhoneAndNameStr : '--' }} 
-          </span>
-        </div>
-        <div class="font-semibold">
-          主账户Email:
-          <span class="font-medium italic ml-1.5" style="color: #64748b">
-            {{ shopOverview[0]?.shopEmail ? shopOverview[0]?.shopEmail : '--' }} 
-          </span>
-        </div>
-        <div class="font-semibold">
-          子账户手机号及归属人:
-          <span class="font-medium italic ml-1.5" style="color: #64748b">
-            {{ shopOverview[0]?.subShopPhoneAndNameStr ? shopOverview[0]?.subShopPhoneAndNameStr : '--' }}
-          </span>
-        </div>
-        <div class="font-semibold">
-          子账户Email:
-          <span class="font-medium italic ml-1.5" style="color: #64748b"> 
-            {{ shopOverview[0]?.subShopEmail ? shopOverview[0]?.subShopEmail : '--' }}
-          </span>
-        </div>
-      </div>
-    </el-card>
-    <el-card body-style="padding-top: 10px" class="mt-2.5" shadow="hover" style="border: none">
-      <vxe-grid v-bind="gridOptions">
-        <template #toolbar_buttons>
-          <el-radio-group v-model="selectedTab" @change="handleTabChange(selectedTab)">
-            <el-radio-button label="当前信息" value="1">
-              <template #default>
-                <el-icon style="top: 2px;">
-                  <Timer/>
-                </el-icon>
-                当前信息
-              </template>
-            </el-radio-button>
-            <el-radio-button label="历史记录" value="2">
-              <template #default>
-                <el-icon style="top: 2px;">
-                  <RefreshLeft/>
-                </el-icon>
-                历史记录
-              </template>
-            </el-radio-button>
-            <el-radio-button label="电脑信息" value="3">
-              <template #default>
-                <el-icon style="top: 2px;">
-                  <Monitor/>
-                </el-icon>
-                电脑信息
-              </template>
-            </el-radio-button>
-          </el-radio-group>
-        </template>
-        <template #toolbar_tools>
-          <div class="mr-2.5">
-            <el-button :icon="Edit" plain circle type="warning" @click="drawerOpen" :disabled="selectedTab != '1'"></el-button>
-          </div>
-        </template>
-        <template #pager>
-          <vxe-pager
-              v-model:currentPage="gridOptions.pagerConfig.page"
-              v-model:pageSize="gridOptions.pagerConfig.limit"
-              :total="gridOptions.pagerConfig.total"
-              @page-change="handlePageChange"
-          >
-          </vxe-pager>
-        </template>
-      </vxe-grid>
-    </el-card>
-    <EditDrawer
-        v-if="isOpen"
-        v-model="isOpen"
-        :formSelect
-        :companySelect
-        :gridOptions="gridOptions"
-        :platformNumber
-        @refresh="handleRefresh"
-    />
-  </div>
-</template>
-
-<style scoped>
-.artistic-text-container {
-  height: 120px; /* 高度与要求一致 */
-  width: 120px; /* 宽度与要求一致 */
-  display: flex;
-  align-items: center; /* 垂直居中 */
-  justify-content: center; /* 水平居中 */
-  background-color: #f5f5f5; /* 背景色 */
-  border-radius: 12px; /* 圆角 */
-  overflow: hidden; /* 隐藏溢出部分 */
-  position: relative; /* 为绝对定位提供参考 */
-}
-
-.artistic-text {
-  font-size: 1rem; /* 初始字体大小 */
-  font-weight: bold; /* 加粗字体 */
-  text-align: center; /* 居中对齐 */
-  background: linear-gradient(90deg, #c86fc9, #3023ae);
-  -webkit-background-clip: text; /* 背景裁剪 */
-  -webkit-text-fill-color: transparent; /* 字体颜色透明 */
-  white-space: nowrap; /* 防止换行 */
-  overflow: hidden; /* 隐藏溢出部分 */
-  text-overflow: ellipsis; /* 溢出部分用省略号表示 */
-  transform: scale(1); /* 默认缩放为 1 */
-  transition: transform 0.2s ease; /* 动画过渡效果 */
-  max-width: 100%; /* 最大宽度为 100% */
-}
-
-/* 当文本溢出时,缩小文本以适应容器 */
-.artistic-text-container:has(.artistic-text) {
-  /* 计算并缩放文本 */
-  animation: scale-text 0.2s forwards;
-}
-
-/* @keyframes scale-text {
-  0% {
-    transform: scale(1);
-  }
-  100% {
-    transform: scale(calc(120px / var(--text-width))); !* 根据文本宽度缩放 *!
-  }
-} */
-</style>

+ 0 - 43
src/views/shop-information/index.vue

@@ -1,43 +0,0 @@
-<script lang="ts" setup>
-/**
- * @Name: index.vue
- * @Description: 店铺信息页面
- * @Author: Cheney
- */
-
-import InfoCard from '/@/views/shop-information/components/InfoCard.vue';
-import * as api from '/@/views/shop-information/api';
-import { useResponse } from '/@/utils/useResponse';
-
-
-const cardData = ref();
-provide('cardData', cardData);
-
-const loading = ref(false);
-
-onBeforeMount(() => {
-  initData();
-});
-
-async function initData() {
-  const res = await useResponse({}, api.getCardData, loading);
-  cardData.value = res.data;
-}
-</script>
-
-<template>
-  <div class="px-2.5">
-    <el-divider content-position="left">
-      <div class="font-bold text-xl">店铺信息概览</div>
-    </el-divider>
-    <el-card v-loading="loading" shadow="never" style="border: none; min-height: 692px;">
-      <InfoCard></InfoCard>
-    </el-card>
-  </div>
-</template>
-
-<style scoped>
-:deep(.el-divider__text.is-left) {
-  background-color: #F5F5F5;
-}
-</style>

+ 0 - 683
src/views/shop-information/useColumns.tsx

@@ -1,683 +0,0 @@
-import { useCountryInfoStore } from '/@/stores/countryInfo';
-import * as api from '/@/views/shop-information/api';
-
-
-const countryInfoStore = useCountryInfoStore();
-
-export const companySelect: Ref<any[]> = ref([]);
-
-async function main() {
-  const result = await api.getCompanySelect();
-  companySelect.value = result.data;
-}
-
-main();
-
-export const platformColumns = [
-  { type: 'seq', width: 50, align: 'center', fixed: 'left' },
-  {
-    field: 'operatorName', title: '运营', minWidth: 'auto', align: 'center', fixed: 'left',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.operatorName ? row.operatorName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'platformNumber', title: '平台编号', minWidth: 'auto', align: 'center', slots: { default: 'platformNumber' }
-  },
-  {
-    field: 'platformName', title: '平台名称', minWidth: 'auto', align: 'center', slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }
-                     style={ { color: '#303133' } }>{ row.platformName ? row.platformName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'country', title: '国家', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        const country = countryInfoStore.countries.find(c => c.name === row.country);
-        const color = country ? country.color : '#3875F6';
-        return <el-tag effect="plain" round
-                       style={ { color: color, borderColor: color } }>{ row.country ? row.country : '--' }</el-tag>;
-      }
-    }
-  },
-  {
-    field: 'brandName', title: '品牌名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.brandName ? row.brandName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'currencyCode', title: '货币代码', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.currencyCode ? row.currencyCode : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'status', title: '状态', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.status ? row.status : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'platform', title: '平台', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.platform ? row.platform : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'line', title: '线路', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.line ? row.line : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'ipaddress', title: 'IP地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.ipaddress ? row.ipaddress : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'company', title: '公司名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.company ? row.company : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'companyEnglishName', title: '公司英文名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.companyEnglishName ? row.companyEnglishName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'address', title: '公司地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.address ? row.address : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'juridicalPerson', title: '法人', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.juridicalPerson ? row.juridicalPerson : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'juridicalPersonCreditCard', title: '法人信用卡', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span
-            class={ 'font-medium' }>{ row.juridicalPersonCreditCard ? row.juridicalPersonCreditCard : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'juridicalPersonCreditCardAddress', title: '法人信用卡地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span
-            class={ 'font-medium' }>{ row.juridicalPersonCreditCardAddress ? row.juridicalPersonCreditCardAddress : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'receivablesAccount', title: '收款账户', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.receivablesAccount ? row.receivablesAccount : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'receivablesAccountCompany', title: '收款账户公司', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span
-            class={ 'font-medium' }>{ row.receivablesAccountCompany ? row.receivablesAccountCompany : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'vatNumber', title: 'VAT税号', minWidth: 200, align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.vatNumber ? row.vatNumber : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'vatCompany', title: 'VAT公司', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.vatCompany ? row.vatCompany : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'shopPhoneEmail', title: '店铺电话与邮箱', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.shopPhoneEmail ? row.shopPhoneEmail : '--' }</span>;
-      }
-    }
-  }
-];
-
-export const shopCurrentColumns = [
-  { type: 'seq', width: 50, align: 'center', fixed: 'left' },
-  {
-    field: 'operatorName', title: '运营', minWidth: 'auto', align: 'center', fixed: 'left',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.operatorName ? row.operatorName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'platformNumber', title: '平台编号', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.platformNumber ? row.platformNumber : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'platformName', title: '平台名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.platformName ? row.platformName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'country', title: '国家', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        const country = countryInfoStore.countries.find(c => c.name === row.country);
-        const color = country ? country.color : '#3875F6';
-        return <el-tag effect="plain" round
-                       style={ { color: color, borderColor: color } }>{ row.country ? row.country : '--' }</el-tag>;
-      }
-    }
-  },
-  {
-    field: 'brandName', title: '品牌名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.brandName ? row.brandName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'currencyCode', title: '货币代码', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.currencyCode ? row.currencyCode : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'status', title: '状态', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return (
-            <el-tag
-                class="font-medium"
-                type={ row.status === 1 ? 'success' : 'danger' }   // 动态绑定 type
-            >
-              { row.status === 1 ? '启用' : '暂停' }
-            </el-tag>
-        );
-      }
-    }
-  },
-  {
-    field: 'platform', title: '平台', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.platform ? row.platform : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'line', title: '线路', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.line ? row.line : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'ipaddress', title: 'IP地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.ipaddress ? row.ipaddress : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'belongsCompany', title: '关联公司', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        const company = companySelect.value.find(c => c.id === row.belongsCompany);
-        return <span class="font-medium">{ company ? company.company : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'company', title: '公司名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.company ? row.company : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'companyEnglishName', title: '公司英文名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.companyEnglishName ? row.companyEnglishName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'address', title: '公司地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.address ? row.address : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'juridicalPerson', title: '法人', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.juridicalPerson ? row.juridicalPerson : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'juridicalPersonCreditCard', title: '法人信用卡', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span
-            class={ 'font-medium' }>{ row.juridicalPersonCreditCard ? row.juridicalPersonCreditCard : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'juridicalPersonCreditCardAddress', title: '法人信用卡地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span
-            class={ 'font-medium' }>{ row.juridicalPersonCreditCardAddress ? row.juridicalPersonCreditCardAddress : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'receivablesAccount', title: '收款账户', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.receivablesAccount ? row.receivablesAccount : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'receivablesAccountCompany', title: '收款账户公司', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span
-            class={ 'font-medium' }>{ row.receivablesAccountCompany ? row.receivablesAccountCompany : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'vatNumber', title: 'VAT税号', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.vatNumber ? row.vatNumber : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'vatCompany', title: 'VAT公司', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.vatCompany ? row.vatCompany : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'shopPhoneAndName', title: '主账户电话', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.shopPhoneAndName !== null ? row.shopPhoneAndName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'shopEmail', title: '主账户邮箱', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.shopEmail ? row.shopEmail : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'subShopPhoneAndName', title: '子账户电话', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.subShopPhoneAndName ? row.subShopPhoneAndName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'subShopEmail', title: '子账户邮箱', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.subShopEmail ? row.subShopEmail : '--' }</span>;
-      }
-    }
-  }
-];
-
-export const historyColumns: any = [
-  { type: 'seq', width: 50, align: 'center', fixed: 'left' },
-  {
-    field: 'operatorName', title: '运营', minWidth: 'auto', align: 'center', fixed: 'left',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.operatorName ? row.operatorName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'platformNumber', title: '平台编号', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.platformNumber ? row.platformNumber : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'platformName', title: '平台名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.platformName ? row.platformName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'country', title: '国家', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        const country = countryInfoStore.countries.find(c => c.name === row.country);
-        const color = country ? country.color : '#3875F6';
-        return <el-tag effect="plain" round
-                       style={ { color: color, borderColor: color } }>{ row.country ? row.country : '--' }</el-tag>;
-      }
-    }
-  },
-  {
-    field: 'brandName', title: '品牌名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.brandName ? row.brandName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'currencyCode', title: '货币代码', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.currencyCode ? row.currencyCode : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'status', title: '状态', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return (
-            <el-tag
-                class="font-medium"
-                type={ row.status === 1 ? 'success' : 'danger' }   // 动态绑定 type
-            >
-              { row.status === 1 ? '启用' : '暂停' }
-            </el-tag>
-        );
-      }
-    }
-  },
-  {
-    field: 'platform', title: '平台', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.platform ? row.platform : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'line', title: '线路', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.line ? row.line : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'ipaddress', title: 'IP地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.ipaddress ? row.ipaddress : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'company', title: '公司名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.company ? row.company : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'companyEnglishName', title: '公司英文名称', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.companyEnglishName ? row.companyEnglishName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'address', title: '公司地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.address ? row.address : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'juridicalPerson', title: '法人', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.juridicalPerson ? row.juridicalPerson : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'juridicalPersonCreditCard', title: '法人信用卡', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span
-            class={ 'font-medium' }>{ row.juridicalPersonCreditCard ? row.juridicalPersonCreditCard : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'juridicalPersonCreditCardAddress', title: '法人信用卡地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span
-            class={ 'font-medium' }>{ row.juridicalPersonCreditCardAddress ? row.juridicalPersonCreditCardAddress : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'receivablesAccount', title: '收款账户', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.receivablesAccount ? row.receivablesAccount : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'receivablesAccountCompany', title: '收款账户公司', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span
-            class={ 'font-medium' }>{ row.receivablesAccountCompany ? row.receivablesAccountCompany : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'vatNumber', title: 'VAT税号', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.vatNumber ? row.vatNumber : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'vatCompany', title: 'VAT公司', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.vatCompany ? row.vatCompany : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'create_datetime', title: '创建时间', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.create_datetime ? row.create_datetime : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'approveNum', title: '审批数量', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.approveNum ? row.approveNum : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'shopPhoneAndName', title: '主账户电话', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.shopPhoneAndName !== null ? row.shopPhoneAndName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'shopEmail', title: '主账户邮箱', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.shopEmail ? row.shopEmail : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'subShopPhoneAndName', title: '子账户电话', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.subShopPhoneAndName ? row.subShopPhoneAndName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'subShopEmail', title: '子账户邮箱', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.subShopEmail ? row.subShopEmail : '--' }</span>;
-      }
-    }
-  }
-];
-
-export const computerColumns: any = [
-  { type: 'seq', width: 50, align: 'center', fixed: 'left' },
-  {
-    field: 'operatorName', title: '使用人', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.operatorName ? row.operatorName : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'computerNumber', title: '电脑编号', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.computerNumber ? row.computerNumber : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'computerType', title: '计算机类型', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.computerType ? row.computerType : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'station', title: '位置', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.station ? row.station : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'ipaddress', title: 'IP地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.ipaddress ? row.ipaddress : '--' }</span>;
-      }
-    }
-  },
-  {
-    field: 'macaddress', title: 'MAC地址', minWidth: 'auto', align: 'center',
-    slots: {
-      default({ row }: any) {
-        return <span class={ 'font-medium' }>{ row.macaddress ? row.macaddress : '--' }</span>;
-      }
-    }
-  }
-];
-

+ 31 - 0
src/views/store-manage/Columns.ts

@@ -0,0 +1,31 @@
+export const MarketStoreColumns = [
+  { type: 'seq', title: 'No.', minWidth: 60, align: 'center' },
+  {
+    field: 'platform_number', title: '平台编号', minWidth: 'auto', align: 'center',
+    slots: { default: 'platform_number' }
+  },
+  {
+    field: 'name', title: '店 铺', minWidth: 'auto', align: 'center',
+    slots: { default: 'name' }
+  },
+  {
+    field: 'seller', title: '卖家ID', minWidth: 'auto', align: 'center',
+    slots: { default: 'seller' }
+  },
+  {
+    field: 'region', title: '站 点', minWidth: 'auto', align: 'center',
+    slots: { default: 'region' }
+  },
+  {
+    field: 'country_code', title: '国 家', minWidth: 'auto', align: 'center',
+    slots: { default: 'country_code' }
+  },
+  {
+    field: 'marketplace_id', title: '市场ID', minWidth: 'auto', align: 'center',
+    slots: { default: 'marketplace_id' }
+  },
+  {
+    field: 'create_datetime', title: '创建时间', minWidth: 'auto', align: 'center',
+    slots: { default: 'create_datetime' }
+  }
+];

+ 118 - 0
src/views/store-manage/market-store/api.ts

@@ -0,0 +1,118 @@
+import { request } from '/@/utils/service';
+
+
+const apiPrefix = '/api/choice/marketplace_shops/';
+
+export function getTableData(query: any) {
+  return request({
+    url: apiPrefix,
+    method: 'GET',
+    params: query
+  });
+}
+
+export function updateRow(body: any) {
+  return request({
+    url: apiPrefix + body.id + '/',
+    method: 'PUT',
+    data: body
+  });
+}
+
+export function getRegionOptions() {
+  return request({
+    url: apiPrefix + 'tags/',
+    method: 'GET'
+  });
+}
+
+export function getBrandsOptions() {
+  return request({
+    url: apiPrefix + 'brands/',
+  });
+}
+
+export function getShopOptions() {
+  return request({
+    url: '/api/choice/marketplace_shops/select/',
+    method: 'GET',
+  });
+}
+
+export function getStaffsOptions(query: any) {
+  return request({
+    url: '/api/system/user/select/',
+    params: query,
+    method: 'GET'
+  })
+}
+
+export function getExistingStaffs(query: any) {
+  return request({
+    url: apiPrefix + 'alarm-manage/',
+    params: query,
+    method: 'GET'
+  })
+}
+
+export function postMonitor(body: any) {
+  return request({
+    url: apiPrefix + 'monitor/',
+    data: body,
+    method: 'POST'
+  })
+}
+
+export function postStaffs(body: any) {
+  return request({
+    url: apiPrefix + 'alarm-manage/',
+    data: body,
+    method: 'post'
+  })
+}
+
+export function uploadFile(body: any){
+  return request({
+    url: 'api/system/file/',
+    method: 'POST',
+    data: body,
+    headers: { 'Content-Type':'multipart/form-data' },
+  });
+}
+
+// 商品变更通知导入
+export function uploadChangeNotice(body: any){
+  return request({
+    url: '/api/choice/goods/alarm/import_data/',
+    method: 'POST',
+    data: body,
+  });
+}
+
+// 商品导入
+export function uploadProducts(body: any){
+  return request({
+    url: '/api/choice/goods/import_data/',
+    method: 'POST',
+    data: body,
+  });
+}
+
+// 指导价格导入
+export function uploadPrice(body: any){
+  return request({
+    url: '/api/choice/goods/GuidancePrice/import_data/',
+    method: 'POST',
+    data: body,
+  });
+}
+
+// 导出
+export function exportData(query: any) {
+  return request({
+    url: '/api/choice/goods/export_data/',
+    method: 'GET',
+    params: query,
+    responseType: 'blob'
+  });
+}

+ 186 - 0
src/views/store-manage/market-store/component/DataTable.vue

@@ -0,0 +1,186 @@
+<script lang="ts" setup>
+/**
+ * @Name: Table.vue
+ * @Description: 商品列表表格
+ * @Author: Cheney
+ */
+
+import { Refresh } from '@element-plus/icons-vue';
+import { ElMessage } from 'element-plus';
+import { usePagination } from '/@/utils/usePagination';
+import { useTableData } from '/@/utils/useTableData';
+import { MarketStoreColumns } from '/@/views/store-manage/Columns';
+import DataTableSlot from './DataTableSlot.vue';
+import EditDrawer from '/src/views/product-manage/product-list/component/EditDrawer.vue';
+import NoticeDialog from '/src/views/product-manage/product-list/component/NoticeDialog.vue';
+import * as api from '../api';
+
+
+interface Parameter {
+  country: string,
+  shop: string,
+  region: string,
+}
+
+const queryParameter: Parameter | undefined = inject('query-parameter');
+const { tableOptions, handlePageChange } = usePagination(fetchList);
+
+const gridRef = ref();
+const gridOptions: any = reactive({
+  size: 'small',
+  border: false,
+  round: true,
+  stripe: true,
+  currentRowHighLight: true,
+  height: '100%',
+  toolbarConfig: {
+    size: 'large',
+    custom: true,
+    slots: {
+      tools: 'toolbar_tools'
+    }
+  },
+  rowConfig: {
+    isHover: true
+  },
+  columnConfig: {
+    resizable: true,
+  },
+  pagerConfig: {
+    total: tableOptions.value.total,
+    page: tableOptions.value.page,
+    limit: tableOptions.value.limit
+  },
+  loading: false,
+  loadingConfig: {
+    icon: 'vxe-icon-indicator roll',
+    text: '正在拼命加载中...'
+  },
+  columns: '',
+  data: ''
+});
+
+const checkedList = ref<Set<number>>(new Set());
+
+const editOpen = ref(false);
+const rowData = ref({});
+
+const dialogVisible = ref(false);
+
+onMounted(() => {
+  fetchList();
+});
+
+async function fetchList() {
+  gridOptions.data = [];
+  gridOptions.columns = [];
+
+  const query = {
+    country_code: queryParameter?.country,
+    region: queryParameter?.region,
+    name__icontains: queryParameter?.shop
+  };
+
+  await useTableData(api.getTableData, query, gridOptions);
+  await gridRef.value.loadColumn(MarketStoreColumns);
+  gridOptions.showHeader = Boolean(gridOptions.data?.length);
+}
+
+function handleRefresh() {
+  fetchList();
+}
+
+function selectChangeEvent({ checked, row }: any) {
+  if (checked) {
+    checkedList.value.add(row.id); // 获取单个数据
+  } else {
+    checkedList.value.delete(row.id);
+  }
+}
+
+function selectAllChangeEvent({ checked }: any) {
+  const $grid = gridRef.value;
+  if ($grid) {
+    const records = $grid.getData(); // 获取所有数据
+    if (checked) {
+      records.forEach((item: any) => {
+        checkedList.value.add(item.id);
+      });
+    } else {
+      checkedList.value.clear();
+    }
+  }
+}
+
+function handleEdit(row: any) {
+  editOpen.value = true;
+  rowData.value = row;
+}
+
+function handleNotice(row: any) {
+  dialogVisible.value = true;
+  rowData.value = row;
+}
+
+async function switchMonitor(row: any) {
+  const res = await useResponse(api.postMonitor, { ids: [ row.id ], status: row.is_monitor ? 1 : 0 });
+  if (res && res.code === 2000) {
+    ElMessage.success('操作成功!');
+  } else {
+    row.is_monitor = !row.is_monitor;
+    ElMessage.error('操作失败!');
+  }
+}
+
+defineExpose({ fetchList });
+</script>
+
+<template>
+  <vxe-grid ref="gridRef"
+            v-bind="gridOptions">
+    <!-- 工具栏右侧 -->
+    <template #toolbar_tools>
+      <el-button circle class="mr-3 toolbar-btn" @click="handleRefresh">
+        <el-icon>
+          <Refresh />
+        </el-icon>
+      </el-button>
+      <!--<el-button circle class="mr-3 toolbar-btn" @click="handleDownload">-->
+      <!--  <el-icon>-->
+      <!--    <Download />-->
+      <!--  </el-icon>-->
+      <!--</el-button>-->
+    </template>
+    <!--<template #top>-->
+    <!--  <div class="mb-2"></div>-->
+    <!--</template>-->
+    <!-- 分页 -->
+    <template #pager>
+      <vxe-pager
+          v-model:currentPage="gridOptions.pagerConfig.page"
+          v-model:pageSize="gridOptions.pagerConfig.limit"
+          :total="gridOptions.pagerConfig.total"
+          class="mt-1.5"
+          @page-change="handlePageChange"
+      />
+    </template>
+    <!-- 自定义列插槽 -->
+    <template v-for="col in MarketStoreColumns" #[`${col.field}`]="{ row }">
+      <DataTableSlot :key="row.id" :field="col.field" :row="row" />
+    </template>
+  </vxe-grid>
+  <EditDrawer v-if="editOpen" v-model="editOpen" :row-data="rowData" @refresh="handleRefresh" />
+  <NoticeDialog v-if="dialogVisible" v-model="dialogVisible" :row-data="rowData" />
+</template>
+
+<style scoped>
+.toolbar-btn {
+  width: 34px;
+  height: 34px;
+  font-size: 18px
+}
+
+:deep(.custom-el-input .el-select__wrapper) {
+  border-radius: 20px;
+}
+</style>

+ 47 - 0
src/views/store-manage/market-store/component/DataTableSlot.vue

@@ -0,0 +1,47 @@
+<script lang="ts" setup>
+/**
+ * @Name: DataTableSlot.vue
+ * @Description: 商品列表-单元格插槽
+ * @Author: Cheney
+ */
+
+import { useCountryInfoStore } from '/@/stores/countryInfo';
+import { Message, Operation } from '@element-plus/icons-vue';
+import { getTagType } from '/@/utils/useTagColor';
+import PermissionButton from '/@/components/PermissionButton/index.vue';
+import ProductInfo from '/@/views/product-manage/product-list/component/ProductInfo.vue';
+
+
+const props = defineProps<{
+  row: any,
+  field: any
+}>();
+const { row, field } = props;
+
+const countryInfoStore = useCountryInfoStore();
+const country = countryInfoStore.countries.find(c => c.code == row.country_code);
+const color = country ? country.color : '#3875F6';
+const region = countryInfoStore.Region.find(r => r.code == row.region);
+</script>
+
+<template>
+  <div class="font-medium">
+    <div v-if="field === 'region'">
+      <el-tag :disable-transitions="true" :type=getTagType(row.region)  >
+        {{ region ? region.name : '-' }}
+      </el-tag>
+    </div>
+    <div v-else-if="field === 'country_code'">
+      <el-tag :disable-transitions="true" :style="{ color: color, borderColor: color }" effect="plain" round>
+        {{ country ? country.name : '-' }}
+      </el-tag>
+    </div>
+    <div v-else>
+      {{ row[field] }}
+    </div>
+  </div>
+</template>
+
+<style scoped>
+
+</style>

+ 110 - 0
src/views/store-manage/market-store/index.vue

@@ -0,0 +1,110 @@
+<script setup lang="ts">
+/**
+ * @Name: index.vue
+ * @Description: 市场店铺
+ * @Author: Cheney
+ */
+
+import VerticalDivider from '/src/components/VerticalDivider/index.vue';
+import { RefreshRight, Search } from '@element-plus/icons-vue';
+import { useTableHeight } from '/@/utils/useTableHeight';
+import DataTable from './component/DataTable.vue';
+import { DictionaryStore } from '/@/stores/dictionary';
+import { useResponse } from '/@/utils/useResponse';
+import * as api from './api';
+import { useTemplateRef } from 'vue';
+import { useCountryInfoStore } from '/@/stores/countryInfo';
+
+
+const { data: staticData } = DictionaryStore();
+const countryInfoStore = useCountryInfoStore();
+
+const titleContainer: Ref<HTMLElement | null> = useTemplateRef('titleContainer');
+const queryContainer: Ref<HTMLElement | null> = useTemplateRef('queryContainer');
+const { tableHeight } = useTableHeight(titleContainer, queryContainer);
+
+const tableRef: Ref<any> = useTemplateRef('table');
+
+const btnLoading = ref(false);
+
+const formInline = reactive<any>({
+  country: '',
+  region: '',
+  shop: '',
+});
+provide('query-parameter', formInline);
+
+onBeforeMount(() => {
+  
+});
+
+
+async function handleQuery() {
+  btnLoading.value = true;
+  await tableRef.value?.fetchList();
+  btnLoading.value = false;
+}
+
+function resetParameter() {
+  for (const key in formInline) {
+    formInline[key] = '';
+  }
+}
+</script>
+
+<template>
+  <div class="p-5 flex-grow">
+    <el-card class="h-full" style="color: rgba(0, 0, 0, 0.88);">
+      <div ref="titleContainer" class="text-xl font-semibold pb-5">市场店铺</div>
+      <!-- 查询条件 -->
+      <div ref="queryContainer" class="flex justify-between">
+        <div class="flex flex-1">
+          <div class="w-full whitespace-nowrap">
+            <el-row :gutter="20" style="margin-bottom: 16px;">
+              <el-col :span="6">
+                <div class="flex items-center">
+                  <span class="mr-2">国 家</span>
+                  <el-select v-model="formInline.country" clearable placeholder="请选择国家">
+                    <el-option v-for="item in staticData.country_code" :key="item.value" :label="item.label"
+                               :value="item.value" />
+                  </el-select>
+                </div>
+              </el-col>
+              <el-col :span="6">
+                <div class="flex items-center">
+                  <span class="mr-2">站 点</span>
+                  <el-select v-model="formInline.region" clearable placeholder="请选择品牌">
+                    <el-option v-for="item in countryInfoStore.Region" :label="item.name" :value="item.code" />
+                  </el-select>
+                </div>
+              </el-col>
+              <el-col :span="6">
+                <div class="flex items-center">
+                  <span class="mr-2">店 铺</span>
+                  <el-input v-model="formInline.shop" clearable placeholder="请输入店铺名称" />
+                </div>
+              </el-col>
+            </el-row>
+          </div>
+        </div>
+        <VerticalDivider />
+        <div class="flex flex-col gap-1.5 items-end">
+          <el-button :icon="Search" :loading="btnLoading" class="mb-4" type="primary" @click="handleQuery">
+            查 询
+          </el-button>
+          <el-button :icon="RefreshRight" color="#ECECF1C9" style="width: 88px; color: #3c3c3c;" @click="resetParameter">
+            重 置
+          </el-button>
+        </div>
+      </div>
+      <el-divider ref="dividerContainer" style="margin: 20px 0 12px 0;" />
+      <div :style="{ height: tableHeight + 'px' }">
+        <DataTable ref="table" />
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<style scoped>
+
+</style>

+ 228 - 218
src/views/system/login/component/account.vue

@@ -1,56 +1,63 @@
 <template>
-	<el-form ref="formRef" size="large" class="login-content-form" :model="state.ruleForm" :rules="rules" @keyup.enter="loginClick">
-		<el-form-item class="login-animation1" prop="username">
-			<el-input type="text" :placeholder="$t('message.account.accountPlaceholder1')" v-model="ruleForm.username"
-				clearable autocomplete="off">
-				<template #prefix>
-					<el-icon class="el-input__icon"><ele-User /></el-icon>
-				</template>
-			</el-input>
-		</el-form-item>
-		<el-form-item class="login-animation2" prop="password">
-			<el-input :type="isShowPassword ? 'text' : 'password'" :placeholder="$t('message.account.accountPlaceholder2')"
-				v-model="ruleForm.password">
-				<template #prefix>
-					<el-icon class="el-input__icon"><ele-Unlock /></el-icon>
-				</template>
-				<template #suffix>
-					<i class="iconfont el-input__icon login-content-password"
-						:class="isShowPassword ? 'icon-yincangmima' : 'icon-xianshimima'"
-						@click="isShowPassword = !isShowPassword">
-					</i>
-				</template>
-			</el-input>
-		</el-form-item>
-		<el-form-item class="login-animation3" v-if="isShowCaptcha" prop="captcha">
-			<el-col :span="15">
-				<el-input type="text" maxlength="4" :placeholder="$t('message.account.accountPlaceholder3')"
-					v-model="ruleForm.captcha" clearable autocomplete="off">
-					<template #prefix>
-						<el-icon class="el-input__icon"><ele-Position /></el-icon>
-					</template>
-				</el-input>
-			</el-col>
-			<el-col :span="1"></el-col>
-			<el-col :span="8">
-				<el-button class="login-content-captcha">
-					<el-image :src="ruleForm.captchaImgBase" @click="refreshCaptcha" />
-				</el-button>
-			</el-col>
-		</el-form-item>
-		<el-form-item class="login-animation4">
-			<el-button type="primary" class="login-content-submit" round @click="loginClick"
-				:loading="loading.signIn">
-				<span>{{ $t('message.account.accountBtnText') }}</span>
-			</el-button>
-		</el-form-item>
-	</el-form>
+  <el-form ref="formRef" :model="state.ruleForm" :rules="rules" class="login-content-form" size="large"
+           @keyup.enter="loginClick">
+    <el-form-item class="login-animation1" prop="username">
+      <el-input v-model="ruleForm.username" :placeholder="$t('message.account.accountPlaceholder1')" autocomplete="off"
+                clearable type="text">
+        <template #prefix>
+          <el-icon class="el-input__icon">
+            <ele-User />
+          </el-icon>
+        </template>
+      </el-input>
+    </el-form-item>
+    <el-form-item class="login-animation2" prop="password">
+      <el-input v-model="ruleForm.password" :placeholder="$t('message.account.accountPlaceholder2')"
+                :type="isShowPassword ? 'text' : 'password'">
+        <template #prefix>
+          <el-icon class="el-input__icon">
+            <ele-Unlock />
+          </el-icon>
+        </template>
+        <template #suffix>
+          <i :class="isShowPassword ? 'icon-yincangmima' : 'icon-xianshimima'"
+             class="iconfont el-input__icon login-content-password"
+             @click="isShowPassword = !isShowPassword">
+          </i>
+        </template>
+      </el-input>
+    </el-form-item>
+    <el-form-item v-if="isShowCaptcha" class="login-animation3" prop="captcha">
+      <el-col :span="15">
+        <el-input v-model="ruleForm.captcha" :placeholder="$t('message.account.accountPlaceholder3')" autocomplete="off"
+                  clearable maxlength="4" type="text">
+          <template #prefix>
+            <el-icon class="el-input__icon">
+              <ele-Position />
+            </el-icon>
+          </template>
+        </el-input>
+      </el-col>
+      <el-col :span="1"></el-col>
+      <el-col :span="8">
+        <el-button class="login-content-captcha">
+          <el-image :src="ruleForm.captchaImgBase" @click="refreshCaptcha" />
+        </el-button>
+      </el-col>
+    </el-form-item>
+    <el-form-item class="login-animation4">
+      <el-button :loading="loginLoading" class="login-content-submit" round type="primary"
+                 @click="loginClick">
+        <span>{{ $t('message.account.accountBtnText') }}</span>
+      </el-button>
+    </el-form-item>
+  </el-form>
 </template>
 
 <script lang="ts">
-import { toRefs, reactive, defineComponent, computed, onMounted, onUnmounted, ref } from 'vue';
+import { computed, defineComponent, onMounted, reactive, ref, toRefs } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
-import { ElMessage, FormInstance, FormRules } from 'element-plus';
+import { ElMessage, FormRules } from 'element-plus';
 import { useI18n } from 'vue-i18n';
 import Cookies from 'js-cookie';
 import { storeToRefs } from 'pinia';
@@ -64,193 +71,196 @@ import * as loginApi from '/@/views/system/login/api';
 import { useUserInfo } from '/@/stores/userInfo';
 import { DictionaryStore } from '/@/stores/dictionary';
 import { SystemConfigStore } from '/@/stores/systemConfig';
-import { BtnPermissionStore } from '/@/plugin/permission/store.permission';
 import { Md5 } from 'ts-md5';
 import { errorMessage } from '/@/utils/message';
 
-export default defineComponent({
-	name: 'loginAccount',
-	setup() {
-		const { t } = useI18n();
-		const storesThemeConfig = useThemeConfig();
-		const { themeConfig } = storeToRefs(storesThemeConfig);
-		const { userInfos } = storeToRefs(useUserInfo());
-		const route = useRoute();
-		const router = useRouter();
-		const state = reactive({
-			isShowPassword: false,
-			ruleForm: {
-				username: '',
-				password: '',
-				captcha: '',
-				captchaKey: '',
-				captchaImgBase: '',
-			},
-			loading: {
-				signIn: false,
-			},
-		});
-		const rules = reactive<FormRules>({
-			username: [
-				{ required: true, message: '请填写账号', trigger: 'blur' },
-			],
-			password: [
-				{
-					required: true,
-					message: '请填写密码',
-					trigger: 'blur',
-				},
-			],
-			captcha: [
-				{
-					required: true,
-					message: '请填写验证码',
-					trigger: 'blur',
-				},
-			],
-		})
-		const formRef = ref();
-		// 时间获取
-		const currentTime = computed(() => {
-			return formatAxis(new Date());
-		});
-		// 是否关闭验证码
-		const isShowCaptcha = computed(() => {
-			return SystemConfigStore().systemConfig['base.captcha_state'];
-		});
-
-		const getCaptcha = async () => {
-			loginApi.getCaptcha().then((ret: any) => {
-				state.ruleForm.captchaImgBase = ret.data.image_base;
-				state.ruleForm.captchaKey = ret.data.key;
-			});
-		};
-		const refreshCaptcha = async () => {
-			state.ruleForm.captcha=''
-			loginApi.getCaptcha().then((ret: any) => {
-				state.ruleForm.captchaImgBase = ret.data.image_base;
-				state.ruleForm.captchaKey = ret.data.key;
-			});
-		};
-		const loginClick = async () => {
-			if (!formRef.value) return
-			await formRef.value.validate((valid: any) => {
-				if (valid) {
-					loginApi.login({ ...state.ruleForm, password: Md5.hashStr(state.ruleForm.password) }).then((res: any) => {
-						if (res.code === 2000) {
-							Session.set('token', res.data.access);
-							Cookies.set('username', res.data.name);
-							if (!themeConfig.value.isRequestRoutes) {
-								// 前端控制路由,2、请注意执行顺序
-								initFrontEndControlRoutes();
-								loginSuccess();
-							} else {
-								// 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
-								// 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
-								initBackEndControlRoutes();
-								// 执行完 initBackEndControlRoutes,再执行 signInSuccess
-								loginSuccess();
-							}
-						}
-					}).catch((err: any) => {
-						// 登录错误之后,刷新验证码
-						refreshCaptcha();
-					});
-				} else {
-					errorMessage("请填写登录信息")
-				}
-			})
 
-		};
-		const getUserInfo = () => {
-			useUserInfo().setUserInfos();
-		};
+export default defineComponent({
+  name: 'loginAccount',
+  setup() {
+    const loginLoading = ref(false);
+    const { t } = useI18n();
+    const storesThemeConfig = useThemeConfig();
+    const { themeConfig } = storeToRefs(storesThemeConfig);
+    const { userInfos } = storeToRefs(useUserInfo());
+    const route = useRoute();
+    const router = useRouter();
+    const state = reactive({
+      isShowPassword: false,
+      ruleForm: {
+        username: '',
+        password: '',
+        captcha: '',
+        captchaKey: '',
+        captchaImgBase: ''
+      },
+      loading: {
+        signIn: false
+      }
+    });
+    const rules = reactive<FormRules>({
+      username: [
+        { required: true, message: '请填写账号', trigger: 'blur' }
+      ],
+      password: [
+        {
+          required: true,
+          message: '请填写密码',
+          trigger: 'blur'
+        }
+      ],
+      captcha: [
+        {
+          required: true,
+          message: '请填写验证码',
+          trigger: 'blur'
+        }
+      ]
+    });
+    const formRef = ref();
+    // 时间获取
+    const currentTime = computed(() => {
+      return formatAxis(new Date());
+    });
+    // 是否关闭验证码
+    const isShowCaptcha = computed(() => {
+      return SystemConfigStore().systemConfig['base.captcha_state'];
+    });
 
+    const getCaptcha = async () => {
+      loginApi.getCaptcha().then((ret: any) => {
+        state.ruleForm.captchaImgBase = ret.data.image_base;
+        state.ruleForm.captchaKey = ret.data.key;
+      });
+    };
+    const refreshCaptcha = async () => {
+      state.ruleForm.captcha = '';
+      loginApi.getCaptcha().then((ret: any) => {
+        state.ruleForm.captchaImgBase = ret.data.image_base;
+        state.ruleForm.captchaKey = ret.data.key;
+      });
+    };
+    const loginClick = async () => {
+      if (!formRef.value) return;
+      await formRef.value.validate((valid: any) => {
+        if (valid) {
+          loginLoading.value = true;
+          loginApi.login({ ...state.ruleForm, password: Md5.hashStr(state.ruleForm.password) }).then((res: any) => {
+            if (res.code === 2000) {
+              Session.set('token', res.data.access);
+              Cookies.set('username', res.data.name);
+              if (!themeConfig.value.isRequestRoutes) {
+                // 前端控制路由,2、请注意执行顺序
+                initFrontEndControlRoutes();
+                loginSuccess();
+              } else {
+                // 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
+                // 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
+                initBackEndControlRoutes();
+                // 执行完 initBackEndControlRoutes,再执行 signInSuccess
+                loginSuccess();
+              }
+            }
+          }).catch((err: any) => {
+            // 登录错误之后,刷新验证码
+            refreshCaptcha();
+          }).finally(() => {
+            loginLoading.value = false;
+          });
+        } else {
+          errorMessage('请填写登录信息');
+        }
+      });
 
-		// 登录成功后的跳转
-		const loginSuccess = () => {
-			//登录成功获取用户信息,获取系统字典数据
-			getUserInfo();
-			//获取所有字典
-			DictionaryStore().getSystemDictionarys();
+    };
+    const getUserInfo = () => {
+      useUserInfo().setUserInfos();
+    };
 
-			// 初始化登录成功时间问候语
-			let currentTimeInfo = currentTime.value;
-			// 登录成功,跳到转首页
-			// 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
-			if (route.query?.redirect) {
-				router.push({
-					path: <string>route.query?.redirect,
-					query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : '',
-				});
-			} else {
-				router.push('/');
-			}
-			// 登录成功提示
-			// 关闭 loading
-			state.loading.signIn = true;
-			const signInText = t('message.signInText');
-			ElMessage.success(`${currentTimeInfo},${signInText}`);
-			// 添加 loading,防止第一次进入界面时出现短暂空白
-			NextLoading.start();
-		};
-		onMounted(() => {
-			getCaptcha();
-			//获取系统配置
-			SystemConfigStore().getSystemConfigs();
-		});
+    // 登录成功后的跳转
+    const loginSuccess = () => {
+      //登录成功获取用户信息,获取系统字典数据
+      getUserInfo();
+      //获取所有字典
+      DictionaryStore().getSystemDictionarys();
 
+      // 初始化登录成功时间问候语
+      let currentTimeInfo = currentTime.value;
+      // 登录成功,跳到转首页
+      // 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
+      if (route.query?.redirect) {
+        router.push({
+          path: <string>route.query?.redirect,
+          query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : ''
+        });
+      } else {
+        router.push('/');
+      }
+      // 登录成功提示
+      // 关闭 loading
+      state.loading.signIn = true;
+      const signInText = t('message.signInText');
+      ElMessage.success(`${ currentTimeInfo },${ signInText }`);
+      // 添加 loading,防止第一次进入界面时出现短暂空白
+      NextLoading.start();
+    };
+    onMounted(() => {
+      getCaptcha();
+      //获取系统配置
+      SystemConfigStore().getSystemConfigs();
+    });
 
-		return {
-			refreshCaptcha,
-			loginClick,
-			loginSuccess,
-			isShowCaptcha,
-			state,
-			formRef,
-			rules,
-			...toRefs(state),
-		};
-	},
+    return {
+      loginLoading,
+      refreshCaptcha,
+      loginClick,
+      loginSuccess,
+      isShowCaptcha,
+      state,
+      formRef,
+      rules,
+      ...toRefs(state)
+    };
+  }
 });
 </script>
 
-<style scoped lang="scss">
+<style lang="scss" scoped>
 .login-content-form {
-	margin-top: 20px;
+  margin-top: 20px;
 
-	@for $i from 1 through 4 {
-		.login-animation#{$i} {
-			opacity: 0;
-			animation-name: error-num;
-			animation-duration: 0.5s;
-			animation-fill-mode: forwards;
-			animation-delay: calc($i/10) + s;
-		}
-	}
+  @for $i from 1 through 4 {
+    .login-animation#{$i} {
+      opacity: 0;
+      animation-name: error-num;
+      animation-duration: 0.5s;
+      animation-fill-mode: forwards;
+      animation-delay: calc($i/10) + s;
+    }
+  }
 
-	.login-content-password {
-		display: inline-block;
-		width: 20px;
-		cursor: pointer;
+  .login-content-password {
+    display: inline-block;
+    width: 20px;
+    cursor: pointer;
 
-		&:hover {
-			color: #909399;
-		}
-	}
+    &:hover {
+      color: #909399;
+    }
+  }
 
-	.login-content-captcha {
-		width: 100%;
-		padding: 0;
-		font-weight: bold;
-		letter-spacing: 5px;
-	}
+  .login-content-captcha {
+    width: 100%;
+    padding: 0;
+    font-weight: bold;
+    letter-spacing: 5px;
+  }
 
-	.login-content-submit {
-		width: 100%;
-		letter-spacing: 2px;
-		font-weight: 300;
-		margin-top: 15px;
-	}
+  .login-content-submit {
+    width: 100%;
+    letter-spacing: 2px;
+    font-weight: 300;
+    margin-top: 15px;
+  }
 }
 </style>

+ 9 - 9
vite.config.ts

@@ -37,15 +37,15 @@ const viteConfig = defineConfig((mode: ConfigEnv) => {
               // 默认导入
               ['default', 'dayjs']
             ],
-            '/@/utils/useTableData': [
-              'useTableData'
-            ],
-            '/@/utils/usePagination': [
-              'usePagination'
-            ],
-            '/@/utils/useResponse': [
-              'useResponse'
-            ]
+            // '/@/utils/useTableData': [
+            //   'useTableData'
+            // ],
+            // '/@/utils/usePagination': [
+            //   'usePagination'
+            // ],
+            // '/@/utils/useResponse': [
+            //   'useResponse'
+            // ]
           },
         ],
         resolvers: [ElementPlusResolver()],