Pārlūkot izejas kodu

✨ feat: 新增搜索词-导入页; layout-main背景颜色修改为'#f7f7f7';

WanGxC 10 mēneši atpakaļ
vecāks
revīzija
4afcbc694c

+ 2 - 1
src/theme/app.scss

@@ -82,7 +82,8 @@ body,
     padding: 0 !important;
     overflow: hidden;
     width: 100%;
-    background-color: var(--next-bg-main-color);
+    //background-color: var(--next-bg-main-color);
+    background-color: #f7f7f7;
     display: flex;
     flex-direction: column;
     // 内层 el-scrollbar样式,用于界面高度自适应(main.vue)

+ 24 - 0
src/views/searchTerm/importPage/api.ts

@@ -0,0 +1,24 @@
+import { request } from '/@/utils/service';
+
+const apiPrefix = '/api/searchterm/'
+
+export function uploadFile(file: any) {
+  const formData = new FormData();
+  formData.append('file', file);
+  return request({
+    url: apiPrefix + 'upload_file/',
+    method: 'POST',
+    data: formData,
+    headers: {
+      'Content-Type': 'multipart/form-data',
+    },
+  });
+}
+
+export function confirmUploadFile(query: any) {
+  return request({
+    url: apiPrefix + 'upload_file/',
+    method: 'POST',
+    params: query,
+  });
+}

+ 200 - 0
src/views/searchTerm/importPage/index.vue

@@ -0,0 +1,200 @@
+<script setup lang="ts">
+/**
+ * @Name: index.vue
+ * @Description: 导入页
+ * @Author: Cheney
+ */
+import { Plus, Upload, View } from '@element-plus/icons-vue';
+import { reactive, ref } from 'vue';
+import { ElMessage, genFileId, UploadInstance, UploadRawFile } from 'element-plus';
+import { SUCCESS_CODE, WARNING_CODE } from '/@/utils/requestCode';
+import * as api from './api';
+import { VxeGridProps } from 'vxe-table';
+
+const upload = ref<UploadInstance>();
+const upBtnLoading = ref(false);
+const filter = reactive({
+  reportFilter: '',
+  reportDateFilter: '',
+  typeFilter: '',
+  variableFilter: '',
+});
+const defaultLabel = ref('ASIN');
+
+const gridOptions = reactive<VxeGridProps>({
+  loading: upBtnLoading,
+  round: true,
+  // border: 'inner',
+  stripe: true,
+  resizable: true,
+  height: 900,
+  toolbarConfig: {
+    custom: true,
+  },
+  columns: [
+    // { type: 'seq', width: 70 },
+    // { field: 'name', title: 'Name' },
+  ],
+  data: [],
+});
+
+/**
+ * @description 替换文件并上传
+ * @param files 文件列表
+ */
+function handleExceed(files: any) {
+  upload.value!.clearFiles();
+  const file = files[0] as UploadRawFile;
+  file.uid = genFileId();
+  upload.value!.handleStart(file);
+  upload.value!.submit();
+}
+
+/**
+ * 统一处理响应
+ * @param response 后端返回的响应
+ */
+function handleResponse(response: any) {
+  if (response.code === SUCCESS_CODE) {
+    ElMessage.success({ message: response.msg, plain: true });
+  } else if (response.code === WARNING_CODE) {
+    ElMessage.warning({ message: response.msg, plain: true });
+  } else {
+    ElMessage.error({ message: response.msg, plain: true });
+  }
+}
+
+/**
+ * 上传文件
+ * @param uploadRequest 上传请求
+ */
+async function handleCustomUpload(uploadRequest: any) {
+  upBtnLoading.value = true;
+  try {
+    const { file } = uploadRequest;
+    const response = await api.uploadFile(file);
+    handleResponse(response);
+    processResponseData(response.data);
+    uploadRequest.onSuccess(response); // 通知 el-upload 上传成功
+  } catch (error) {
+    console.log('==Error==', error);
+    uploadRequest.onError(error);
+  } finally {
+    upBtnLoading.value = false;
+  }
+}
+
+/**
+ * 处理响应数据,更新 gridOptions
+ * @param data 响应数据
+ */
+function processResponseData(data: any) {
+  const limitedData = data.length > 15 ? data.slice(0, 15) : data;
+
+  if (data.length > 0) {
+    filter.reportFilter = data[0].Reporting_Range || '';
+    filter.reportDateFilter = data[0].Reporting_Date || '';
+    filter.typeFilter = data[0].ASIN ? 'ASIN View' : 'Brand View';
+    filter.variableFilter = data[0].ASIN ? data[0].ASIN : data[0].brand || '';
+  } else {
+    filter.reportFilter = '';
+    filter.reportDateFilter = '';
+    filter.typeFilter = '';
+    filter.variableFilter = '';
+  }
+
+  // 动态生成 columns 配置
+  gridOptions.columns = Object.keys(limitedData[0] || {}).map((key) => {
+    const title = key.replace(/_/g, ' '); // 将下划线替换成空格
+    let minWidth = title.length * 10;
+    if (key === 'ASIN' || key === 'brand') {
+      minWidth = 130;
+    }
+    return {
+      field: key,
+      title,
+      minWidth,
+    };
+  });
+
+  gridOptions.data = limitedData;
+
+  // 更新默认标签
+  if (limitedData[0].brand) {
+    defaultLabel.value = 'Brand';
+  } else {
+    defaultLabel.value = 'ASIN';
+  }
+}
+
+/**
+ * 确认导入
+ */
+async function confirmUpload() {
+  try {
+    const response = await api.confirmUploadFile({ upload: true });
+    handleResponse(response);
+    if (response.code === SUCCESS_CODE) {
+      gridOptions.data = [];
+      gridOptions.columns = [];
+      filter.reportFilter = '';
+      filter.reportDateFilter = '';
+      filter.typeFilter = '';
+      filter.variableFilter = '';
+    }
+  } catch (error) {
+    console.error('==Error==', error);
+  }
+}
+</script>
+
+<template>
+  <div class="py-2 px-2.5" style="background-color: #f7f7f7">
+    <el-card body-class="flex justify-between gap-3.5" shadow="hover" style="border: none; margin-bottom: 10px">
+      <div class="flex gap-7">
+        <div>
+          <span class="font-bold mr-2" style="color: #303133">报告类型:</span>
+          <el-input v-model="filter.reportFilter" :disabled="true" style="width: 200px"></el-input>
+        </div>
+        <div>
+          <span class="font-bold mr-2" style="color: #303133">报告日期:</span>
+          <el-input v-model="filter.reportDateFilter" :disabled="true" style="width: 200px"></el-input>
+        </div>
+        <div>
+          <span class="font-bold mr-2" style="color: #303133">类型:</span>
+          <el-input v-model="filter.typeFilter" :disabled="true" style="width: 200px"></el-input>
+        </div>
+        <div>
+          <span class="font-bold mr-2" style="color: #303133">{{ defaultLabel }}:</span>
+          <el-input v-model="filter.variableFilter" :disabled="true" style="width: 240px"></el-input>
+        </div>
+      </div>
+      <div class="flex gap-3.5">
+        <!-- 想要不页面不跳动可以加72的高度 -->
+        <div>
+          <el-upload
+            ref="upload"
+            action="#"
+            :limit="1"
+            :show-file-list="false"
+            :auto-upload="true"
+            :on-exceed="handleExceed"
+            :http-request="handleCustomUpload">
+            <template #trigger>
+              <el-button :loading="upBtnLoading" plain color="#6366f1" :icon="View">导入预览</el-button>
+            </template>
+          </el-upload>
+        </div>
+        <el-button plain round type="warning" :icon="Upload" @click="confirmUpload">
+          确认导入
+        </el-button>
+      </div>
+    </el-card>
+    <el-card shadow="hover" style="border: none">
+      <div class="text-xl font-bold text-center font-sans subpixel-antialiased">导入预览</div>
+      <vxe-grid v-bind="gridOptions"></vxe-grid>
+    </el-card>
+  </div>
+</template>
+
+<style scoped></style>