瀏覽代碼

Merge branch 'cheney' into dev

WanGxC 7 月之前
父節點
當前提交
fc56a2fa37

文件差異過大導致無法顯示
+ 295 - 294
package-lock.json


+ 2 - 2
package.json

@@ -71,11 +71,11 @@
 		"eslint": "^8.54.0",
 		"eslint-plugin-vue": "^9.8.0",
 		"prettier": "^2.8.1",
-		"sass": "^1.80.1",
+		"sass": "1.56.2",
 		"typescript": "^5.6.2",
 		"unplugin-auto-import": "^0.18.3",
 		"unplugin-vue-components": "^0.27.4",
-		"vite": "^5.4.9",
+		"vite": "^4.5.3",
 		"vite-plugin-lazy-import": "^1.0.7",
 		"vite-plugin-vue-setup-extend": "^0.4.0",
 		"vue-eslint-parser": "^9.1.0"

+ 2 - 2
src/stores/countryInfo.ts

@@ -1,6 +1,6 @@
 // 列出国家信息的pinia
 export const useCountryInfoStore = defineStore('countryInfo', () => {
-  const countries = [
+  const Countries = [
     { name: '美国', code: 'US', color: '#3C3B6E' }, // 深蓝色
     { name: '英国', code: 'UK', color: '#00247D' }, // 深蓝色
     { name: '德国', code: 'DE', color: '#000000' }, // 黑色
@@ -36,5 +36,5 @@ export const useCountryInfoStore = defineStore('countryInfo', () => {
     { name: '中东站', code: 'ME', color: '#006C35' }, // 绿色
   ]
 
-  return { countries, Region };
+  return { Countries, Region };
 });

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

@@ -22,7 +22,7 @@ const { row, field } = props;
 const emit = defineEmits([ 'edit-row', 'handle-delete' ]);
 
 const countryInfoStore = useCountryInfoStore();
-const country = countryInfoStore.countries.find(c => c.code == row.country_code);
+const country = countryInfoStore.Countries.find(c => c.code == row.country_code);
 const color = country ? country.color : '#3875F6';
 
 const statusText = row.status === 1 ? '在售' : '停售';
@@ -198,7 +198,7 @@ function starsPercent(goods: any) {
       </div>
     </div>
     <div v-else>
-      {{ row.goods[field] }}
+      {{ row.goods[field] || '-' }}
     </div>
   </div>
 </template>

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

@@ -5,7 +5,7 @@
  * @Author: Cheney
  */
 
-import { Download, Message, Money, Open, Refresh } from '@element-plus/icons-vue';
+import { Download, InfoFilled, Message, Money, Open, Refresh } from '@element-plus/icons-vue';
 import { ElMessage } from 'element-plus';
 import { usePagination } from '/@/utils/usePagination';
 import { useTableData } from '/@/utils/useTableData';
@@ -257,7 +257,6 @@ defineExpose({ fetchList });
 				:icon="InfoFilled"
 				icon-color="#626AEF"
 				title="是否确认导出当前时间内所有数据项?"
-				@cancel="onCancel"
 				@confirm="handleDownload"
 			>
 				<template #reference>

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

@@ -21,7 +21,7 @@ const { row, field } = props;
 const emit = defineEmits([ 'edit-row', 'handle-notice', 'handle-monitor' ]);
 
 const countryInfoStore = useCountryInfoStore();
-const country = countryInfoStore.countries.find(c => c.code == row.country_code);
+const country = countryInfoStore.Countries.find(c => c.code == row.country_code);
 const color = country ? country.color : '#3875F6';
 
 const statusText = row.status === 1 ? '在售' : '停售';
@@ -105,7 +105,7 @@ function handleMonitor() {
       </div>
     </div>
     <div v-else>
-      {{ row[field] }}
+      {{ row[field] || '-' }}
     </div>
   </div>
 </template>

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

@@ -22,7 +22,7 @@ const { row, field } = props;
 const emit = defineEmits([ 'edit-row', 'handle-delete' ]);
 
 const countryInfoStore = useCountryInfoStore();
-const country = countryInfoStore.countries.find(c => c.code == row.country_code);
+const country = countryInfoStore.Countries.find(c => c.code == row.country_code);
 const color = country ? country.color : '#3875F6';
 
 const statusText = row.status === 1 ? '在售' : '停售';
@@ -165,7 +165,7 @@ function onConfirm() {
       </div>
     </div>
     <div v-else>
-      {{ row.goods[field] }}
+      {{ row.goods[field] || '-' }}
     </div>
   </div>
 </template>

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

@@ -29,3 +29,48 @@ export const MarketStoreColumns = [
     slots: { default: 'create_datetime' }
   }
 ];
+
+export const OnlineMerchandiseColumns = [
+  { type: 'seq', title: 'No.', width: 60, align: 'center' },
+  { field: 'asin', title: 'ASIN', minWidth: 'auto', align: 'center', slots: { default: 'asin' } },
+  { field: 'sku', title: 'SKU', minWidth: 'auto', align: 'center', slots: { default: 'sku' } },
+  { field: 'platform_number', title: '平台编号', minWidth: 'auto', align: 'center',
+    slots: { default: 'platform_number' }
+  },
+  {
+    field: 'shop_name', title: '店 铺', minWidth: 'auto', align: 'center',
+    slots: { default: 'shop_name' }
+  },
+  {
+    field: 'country_code', title: '国 家', minWidth: 'auto', align: 'center',
+    slots: { default: 'country_code' }
+  },
+  {
+    field: 'region', title: '站 点', minWidth: 'auto', align: 'center',
+    slots: { default: 'region' }
+  },
+  {
+    field: 'quantity', title: '可售数量', width: 'auto', align: 'center',
+    slots: { default: 'quantity' }
+  },
+  {
+    field: 'fulfillment_channel', title: '配送方式', width: 'auto', align: 'center',
+    slots: { default: 'fulfillment_channel' }
+  },
+  {
+    field: 'raw_launch_datetime', title: '上架时间', minWidth: 'auto', align: 'center',
+    slots: { default: 'raw_launch_datetime' }
+  },
+  {
+    field: 'price', title: '价 格', minWidth: 'auto', align: 'center',
+    slots: { default: 'price' }
+  },
+  {
+    field: 'status', title: '状 态', width: 80, align: 'center',
+    slots: { default: 'status' }
+  },
+  {
+    field: 'create_datetime', title: '创建时间', minWidth: 'auto', align: 'center',
+    slots: { default: 'create_datetime' }
+  }
+];

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

@@ -11,102 +11,6 @@ export function getTableData(query: any) {
   });
 }
 
-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({

+ 2 - 56
src/views/store-manage/market-store/component/DataTable.vue

@@ -1,12 +1,11 @@
 <script lang="ts" setup>
 /**
  * @Name: Table.vue
- * @Description: 商品列表表格
+ * @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';
@@ -44,7 +43,7 @@ const gridOptions: any = reactive({
     isHover: true
   },
   columnConfig: {
-    resizable: true,
+    resizable: true
   },
   pagerConfig: {
     total: tableOptions.value.total,
@@ -60,8 +59,6 @@ const gridOptions: any = reactive({
   data: ''
 });
 
-const checkedList = ref<Set<number>>(new Set());
-
 const editOpen = ref(false);
 const rowData = ref({});
 
@@ -90,48 +87,6 @@ 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>
 
@@ -145,16 +100,7 @@ defineExpose({ fetchList });
           <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"

+ 3 - 5
src/views/store-manage/market-store/component/DataTableSlot.vue

@@ -6,10 +6,7 @@
  */
 
 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<{
@@ -19,7 +16,7 @@ const props = defineProps<{
 const { row, field } = props;
 
 const countryInfoStore = useCountryInfoStore();
-const country = countryInfoStore.countries.find(c => c.code == row.country_code);
+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>
@@ -27,7 +24,7 @@ const region = countryInfoStore.Region.find(r => r.code == row.region);
 <template>
   <div class="font-medium">
     <div v-if="field === 'region'">
-      <el-tag :disable-transitions="true" :type=getTagType(row.region)  >
+      <el-tag :disable-transitions="true" :type=getTagType(row.region)>
         {{ region ? region.name : '-' }}
       </el-tag>
     </div>
@@ -36,6 +33,7 @@ const region = countryInfoStore.Region.find(r => r.code == row.region);
         {{ country ? country.name : '-' }}
       </el-tag>
     </div>
+    <!-- 动态获取 -->
     <div v-else>
       {{ row[field] }}
     </div>

+ 4 - 10
src/views/store-manage/market-store/index.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<script lang="ts" setup>
 /**
  * @Name: index.vue
  * @Description: 市场店铺
@@ -10,8 +10,6 @@ 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';
 
@@ -30,15 +28,10 @@ const btnLoading = ref(false);
 const formInline = reactive<any>({
   country: '',
   region: '',
-  shop: '',
+  shop: ''
 });
 provide('query-parameter', formInline);
 
-onBeforeMount(() => {
-  
-});
-
-
 async function handleQuery() {
   btnLoading.value = true;
   await tableRef.value?.fetchList();
@@ -92,7 +85,8 @@ function resetParameter() {
           <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 :icon="RefreshRight" color="#ECECF1C9" style="width: 88px; color: #3c3c3c;"
+                     @click="resetParameter">
             重 置
           </el-button>
         </div>

+ 29 - 0
src/views/store-manage/online-merchandise/api.ts

@@ -0,0 +1,29 @@
+import { request } from '/@/utils/service';
+
+
+const apiPrefix = '/api/choice/listings/';
+
+export function getTableData(query: any) {
+  return request({
+    url: apiPrefix,
+    method: 'GET',
+    params: query
+  });
+}
+
+export function getShopOptions() {
+  return request({
+    url: '/api/choice/marketplace_shops/',
+    method: 'GET',
+  });
+}
+
+// 导出
+export function exportData(query: any) {
+  return request({
+    url: '/api/choice/goods/export_data/',
+    method: 'GET',
+    params: query,
+    responseType: 'blob'
+  });
+}

+ 168 - 0
src/views/store-manage/online-merchandise/component/DataTable.vue

@@ -0,0 +1,168 @@
+<script lang="ts" setup>
+/**
+ * @Name: Table.vue
+ * @Description: 市场店铺表格
+ * @Author: Cheney
+ */
+
+import { Download, InfoFilled, Refresh } from '@element-plus/icons-vue';
+import { usePagination } from '/@/utils/usePagination';
+import { useTableData } from '/@/utils/useTableData';
+import { OnlineMerchandiseColumns } 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,
+  delivery: string,
+  status: string,
+  asin: string,
+  sku: 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 editOpen = ref(false);
+const rowData = ref({});
+
+const dialogVisible = ref(false);
+
+onMounted(() => {
+  fetchList();
+});
+
+async function fetchList() {
+  gridOptions.data = [];
+  gridOptions.columns = [];
+
+  const query = {
+    asin: queryParameter?.asin,
+    sku__startswith: queryParameter?.sku,
+    country_code: queryParameter?.country,
+    shop_id: queryParameter?.shop,
+    shop__region: queryParameter?.region,
+    fulfillment_channel: queryParameter?.delivery,
+    status: queryParameter?.status,
+  };
+
+  await useTableData(api.getTableData, query, gridOptions);
+  await gridRef.value.loadColumn(OnlineMerchandiseColumns);
+  gridOptions.showHeader = Boolean(gridOptions.data?.length);
+}
+
+function handleRefresh() {
+  fetchList();
+}
+
+async function handleDownload() {
+}
+
+defineExpose({ fetchList });
+</script>
+
+<template>
+  <vxe-grid ref="gridRef" v-bind="gridOptions">
+    
+    <!-- 工具栏右侧 -->
+    <template #toolbar_tools>
+      <el-button circle class="toolbar-btn" @click="handleRefresh">
+        <el-icon>
+          <Refresh />
+        </el-icon>
+      </el-button>
+      <el-popconfirm
+          width="220"
+          :icon="InfoFilled"
+          icon-color="#626AEF"
+          title="是否确认导出当前时间内所有数据项?"
+          @confirm="handleDownload"
+      >
+        <template #reference>
+          <el-button circle class="mr-3 toolbar-btn">
+            <el-icon>
+              <Download />
+            </el-icon>
+          </el-button>
+        </template>
+        <template #actions="{ confirm, cancel }">
+          <el-button size="small" @click="cancel">No!</el-button>
+          <el-button
+              type="danger"
+              size="small"
+              @click="confirm"
+          >
+            Yes?
+          </el-button>
+        </template>
+      </el-popconfirm>
+    </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 OnlineMerchandiseColumns" #[`${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>

+ 62 - 0
src/views/store-manage/online-merchandise/component/DataTableSlot.vue

@@ -0,0 +1,62 @@
+<script lang="ts" setup>
+/**
+ * @Name: DataTableSlot.vue
+ * @Description: 商品列表-单元格插槽
+ * @Author: Cheney
+ */
+
+import { useCountryInfoStore } from '/@/stores/countryInfo';
+import { getTagType } from '/@/utils/useTagColor';
+
+
+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.shop.region);
+</script>
+
+<template>
+  <div class="font-medium">
+    <div v-if="field === 'region'">
+      <el-tag :disable-transitions="true" :type=getTagType(row.shop.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-if="field === 'platform_number'">
+      {{ row.shop.platform_number }}
+    </div>
+    <div v-else-if="field === 'shop_name'">
+      {{ row.shop.name }}
+    </div>
+    <div v-else-if="field === 'fulfillment_channel'">
+      <el-tag :disable-transitions="true" :type="row.fulfillment_channel === 'FBM' ? 'primary' : 'warning'">
+        {{ row.fulfillment_channel }}
+      </el-tag>
+    </div>
+    <div v-else-if="field === 'status'">
+      <el-tag :disable-transitions="true"
+              :type="row.status === 'Active' ? 'success' : row.status === 'Inactive' ? 'warning' : 'danger'">
+        {{ row.status === 'Active' ? '在售' : row.status === 'Inactive' ? '不在售' : '不完整' }}
+      </el-tag>
+    </div>
+    <!-- 动态获取 -->
+    <div v-else>
+      {{ row[field] }}
+    </div>
+  </div>
+</template>
+
+<style scoped>
+
+</style>

+ 157 - 0
src/views/store-manage/online-merchandise/index.vue

@@ -0,0 +1,157 @@
+<script lang="ts" setup>
+/**
+ * @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 { useTemplateRef } from 'vue';
+import { useCountryInfoStore } from '/@/stores/countryInfo';
+import { useResponse } from '/@/utils/useResponse';
+import * as api from './api';
+
+
+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: '',
+  shop: '',
+  region: '',
+  delivery: '',
+  status: '',
+  asin: '',
+  sku: '',
+});
+provide('query-parameter', formInline);
+
+const shopOptions = ref<any>([]);
+
+onBeforeMount(() => {
+  fetchShopOptions();
+})
+
+async function fetchShopOptions() {
+  const res = await useResponse(api.getShopOptions)
+  shopOptions.value = res.data
+}
+
+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="4">
+                <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="5">
+                <div class="flex items-center">
+                  <span class="mr-2">店 铺</span>
+                  <el-select v-model="formInline.shop" clearable placeholder="请选择店铺">
+                    <el-option v-for="item in shopOptions" :key="item.id" :label="item.name"
+                               :value="item.id" />
+                  </el-select>
+                </div>
+              </el-col>
+              <el-col :span="5">
+                <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="5">
+                <div class="flex items-center">
+                  <span class="mr-2">配送方式</span>
+                  <el-select v-model="formInline.delivery" clearable placeholder="请选择配送方式">
+                    <el-option label="FBM" value="FBM" />
+                    <el-option label="FBA" value="FBA" />
+                  </el-select>
+                </div>
+              </el-col>
+              <el-col :span="4">
+                <div class="flex items-center">
+                  <span class="mr-2">状 态</span>
+                  <el-select v-model="formInline.status" clearable placeholder="请选择状态">
+                    <el-option label="在售" value="Active" />
+                    <el-option label="不在售" value="Inactive" />
+                    <el-option label="不完整" value="Incomplete" />
+                  </el-select>
+                </div>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20" style="margin-bottom: 16px;">
+              <el-col :span="6">
+                <div class="flex items-center">
+                  <span class="mr-2">ASIN</span>
+                  <el-input v-model="formInline.asin" clearable placeholder="请输入ASIN" />
+                </div>
+              </el-col>
+              <el-col :span="6">
+                <div class="flex items-center">
+                  <span class="mr-2">SKU</span>
+                  <el-input v-model="formInline.sku" clearable placeholder="请输入SKU" />
+                </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>

部分文件因文件數量過多而無法顯示