Sfoglia il codice sorgente

✨ feat<reportManage>: 普通展示表格切换,数据录入表格切换及创建

根据日,周,月的值实现页面切换
xinyan 1 anno fa
parent
commit
50d0949dbd

+ 130 - 60
src/views/reportManage/dataCenter/api.ts

@@ -1,82 +1,152 @@
-import { request } from '/@/utils/service'
-import {UserPageQuery} from "@fast-crud/fast-crud";
+import { request } from '/@/utils/service';
+import { UserPageQuery } from '@fast-crud/fast-crud';
 
-export const apiPrefix = '/api/sellers/product/trend/daily/'
+export const apiPrefix = '/api/sellers/product/trend/daily/';
 
 export function getCardData(query: UserPageQuery) {
-    return request({
-        url: '/api/sellers/home/total/',//需要修改
-        method: 'GET',
-        params: query,
-    })
+  return request({
+    url: '/api/sellers/home/total/',//需要修改
+    method: 'GET',
+    params: query,
+  });
 }
+
 export function getLineData(query: UserPageQuery) {
-    query['dateRangeType'] = 'D'
-    return request({
-        url: apiPrefix,
-        method: 'GET',
-        params: query,
-    })
+  query['dateRangeType'] = 'D';
+  return request({
+    url: apiPrefix,
+    method: 'GET',
+    params: query,
+  });
 }
 
 export function getLineWeekData(query: UserPageQuery) {
-    query['dateRangeType'] = 'W'
-    return request({
-        url: apiPrefix,
-        method: 'GET',
-        params: query,
-    })
+  query['dateRangeType'] = 'W';
+  return request({
+    url: apiPrefix,
+    method: 'GET',
+    params: query,
+  });
 }
+
 export function getLineMonthData(query: UserPageQuery) {
-    query['dateRangeType'] = 'M'
-    return request({
-        url: apiPrefix,
-        method: 'GET',
-        params: query,
-    })
+  query['dateRangeType'] = 'M';
+  return request({
+    url: apiPrefix,
+    method: 'GET',
+    params: query,
+  });
 }
+
 export function postCreateTask(body) {
-    return request({
-        url: '/api/report_manage/summary-tasks/',
-        method: 'POST',
-        data: body,
-    })
+  return request({
+    url: '/api/report_manage/summary-tasks/',
+    method: 'POST',
+    data: body,
+  });
 }
 
 export function getTasks(query) {
-    return request({
-        url: '/api/report_manage/summary-tasks/',
-        method: 'GET',
-        params: query,
-    })
+  return request({
+    url: '/api/report_manage/summary-tasks/',
+    method: 'GET',
+    params: query,
+  });
 }
 
-export  function postDeleteProductLine(body) {
-    return request({
-        url: '/api/report_manage/summary-tasks/8/delete/',
-        method: 'POST',
-        data: body,
-    })
+export function postDeleteTask(body) {
+  return request({
+    url: `/api/report_manage/summary-tasks/delete/`,
+    method: 'POST',
+    data: body,
+  });
 }
 
 export function getOperationSelect(query) {
-    return request({
-        url: '/api/system/user-select/',
-        method: 'GET',
-        params: query,
-    })
-}
-// export function getQuantitySelect(query) {
-//     return request({
-//         url: '',
-//         method: 'get',
-//         params: query,
-//     })
-// }
+  return request({
+    url: '/api/system/user-select/',
+    method: 'GET',
+    params: query,
+  });
+}
+
 export function postUpdateTask(body) {
-    return request({
-        url: `/api/report_manage/summary-tasks/${body.id}/`,
-        method: 'POST',
-        data: body,
-    });
+  return request({
+    url: `/api/report_manage/summary-tasks/${body.id}/`,
+    method: 'POST',
+    data: body,
+  });
+}
+
+// 日数据列表展示
+export function getDayData(query) {
+  return request({
+    url: `/api/report_manage/data-day/`,
+    method: 'GET',
+    params: query,
+  });
+}
+
+export function getWeekData(query) {
+  return request({
+    url: `/api/report_manage/data-week/`,
+    method: 'GET',
+    params: query,
+  });
+}
+export function getMonthData(query) {
+  return request({
+    url: `/api/report_manage/data-month/`,
+    method: 'GET',
+    params: query,
+  });
+}
+
+//日数据插入
+export function postCreateDayData(body) {
+  return request({
+    url: `/api/report_manage/data-day/`,
+    method: 'POST',
+    data: body,
+  });
+}
+
+export function postCreateWeekData(body) {
+  return request({
+    url: `/api/report_manage/data-week/`,
+    method: 'POST',
+    data: body,
+  });
+}
+export function postCreateMonthData(body) {
+  return request({
+    url: `/api/report_manage/data-month/`,
+    method: 'POST',
+    data: body,
+  });
+}
+
+// 日数据更新页面的数据展示
+export function getDayTaskData(query) {
+  return request({
+    url: '/api/report_manage/summary-tasks/data/day/',
+    method: 'GET',
+    params: query,
+  });
+}
+
+export function getWeekTaskData(query) {
+  return request({
+    url: '/api/report_manage/summary-tasks/data/week/',
+    method: 'GET',
+    params: query,
+  });
+}
+
+export function getMonthTaskData(query) {
+  return request({
+    url: '/api/report_manage/summary-tasks/data/month/',
+    method: 'GET',
+    params: query,
+  });
 }

+ 48 - 6
src/views/reportManage/dataCenter/components/TableBrowsing.vue → src/views/reportManage/dataCenter/components/CombinedDisplay.vue

@@ -23,6 +23,7 @@ const queryParams = ref({
   // childAsin,
   // sku,
 })
+//表格
 const tableColumns = [
   { type: 'seq', title: '平台编号' },
   { field: 'Name', title: '平台名称' },
@@ -45,8 +46,8 @@ const tableColumns = [
   { field: 'SalesCompletion', title: '销售额完成情况' },
   { field: 'MonthOnMonthGrowthRate', title: '环比上周增长率' },
 ]
+const tableData = ref([])
 
-//表格
 const gridOptions = reactive({
   border: true,
   height: 300,
@@ -87,15 +88,50 @@ const gridOptions = reactive({
     },
   ],
 })
+// 模拟从后端获取列名数据
+async function fetchColumnNames() {
+  // 这里替换成实际的后端数据请求
+  const response = await fetch('/api/columns'); // 假设后端接口为 /api/columns
+  const data = await response.json();
+  return data;
+}
+
+// 根据后端数据生成表格列配置
+async function generateColumns() {
+  const columnNames = await fetchColumnNames();
+  columns.value = columnNames.map(columnName => ({
+    field: columnName,
+    title: columnName,
+  }));
+}
+
+// 模拟从后端获取表格数据
+async function fetchTableData() {
+  // 这里替换成实际的后端数据请求
+  const response = await fetch('/api/data'); // 假设后端接口为 /api/data
+  const data = await response.json();
+  return data;
+}
+
+// 加载表格数据
+async function loadData() {
+  tableData.value = await fetchTableData();
+}
+
+// 组件挂载时生成表格列配置并加载数据
+onMounted(async () => {
+  await generateColumns();
+  await loadData();
+});
+
 </script>
 
 <template>
   <div>
-    <div class="flex gap-1.5 justify-between">
+    <div class="custom-card-style flex gap-1.5 justify-between my-1.5 mx-2">
       <Selector></Selector>
       <DateRangePicker v-model="dateRange"></DateRangePicker>
     </div>
-
     <el-card class="mb-1.5">
       <DataTendencyChart
         :metricEnum="dataCenterMetricsEnum"
@@ -111,12 +147,18 @@ const gridOptions = reactive({
       <vxe-grid v-bind="gridOptions">
         <template #toolbar_buttons>
           <!--TODO: 主数据-->
-          <vxe-button @click="">主数据</vxe-button>
-          <vxe-button @click="">月对比数据</vxe-button>
+          <vxe-button @click="mainData">主数据</vxe-button>
+          <vxe-button @click="monthlyComparativeData">月对比数据</vxe-button>
         </template>
       </vxe-grid>
     </el-card>
   </div>
 </template>
 
-<style scoped></style>
+<style scoped>
+.custom-card-style {
+  z-index: 999;
+  position: sticky;
+  top: 0;
+}
+</style>

+ 140 - 222
src/views/reportManage/dataCenter/components/DataExport.vue

@@ -1,243 +1,161 @@
 <template>
   <div>
-    <vxe-toolbar>
-      <template #buttons>
-        <vxe-button icon="vxe-icon-square-plus" @click="insertEvent()">新增</vxe-button>
-      </template>
-    </vxe-toolbar>
-    <vxe-table
-        border
-        show-overflow
-        ref="tableRef"
-        height="300"
-        :column-config="{resizable: true}"
-        :row-config="{isHover: true}"
-        :data="tableData"
-        @cell-dblclick="cellDBLClickEvent">
-      <vxe-column type="seq" width="60"></vxe-column>
-      <vxe-column field="name" title="Name"></vxe-column>
-      <vxe-column field="sex" title="Sex" :formatter="formatterSex"></vxe-column>
-      <vxe-column field="age" title="Age"></vxe-column>
-      <vxe-column field="address" title="Address" show-overflow></vxe-column>
-      <vxe-column title="操作" width="100" show-overflow>
-        <template #default="{ row }">
-          <vxe-button mode="text" icon="vxe-icon-edit" @click="editEvent(row)"></vxe-button>
-          <vxe-button mode="text" icon="vxe-icon-delete" @click="removeEvent(row)"></vxe-button>
+    <vxe-grid ref="xGrid" v-bind="gridOptions" v-on="gridEvents">
+      <template #operate="{ row }">
+        <template v-if="hasActiveEditRow(row)">
+          <vxe-button content="取消" @click="clearRowEvent"></vxe-button>
+          <vxe-button status="primary" content="保存" @click="saveRowEvent(row)"></vxe-button>
+        </template>
+        <template v-else>
+          <vxe-button content="编辑" @click="editRowEvent(row)"></vxe-button>
         </template>
-      </vxe-column>
-    </vxe-table>
+        <vxe-button status="danger" content="删除" @click="removeRowEvent(row)"></vxe-button>
+      </template>
 
-    <vxe-modal v-model="showEdit" :title="selectRow ? '编辑&保存' : '新增&保存'" width="800" min-width="600" min-height="300" :loading="submitLoading" resize destroy-on-close>
-      <template #default>
-        <vxe-form :data="formData" :rules="formRules" title-align="right" title-width="100" @submit="submitEvent">
-          <vxe-form-item title="Basic information" title-align="left" :title-width="200" :span="24" :title-prefix="{icon: 'vxe-icon-comment'}"></vxe-form-item>
-          <vxe-form-item field="name" title="Name" :span="12" :item-render="{}">
-            <template #default="{ data }">
-              <vxe-input v-model="data.name" placeholder="请输入名称"></vxe-input>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item field="nickname" title="Nickname" :span="12" :item-render="{}">
-            <template #default="{ data }">
-              <vxe-input v-model="data.name" placeholder="请输入名称"></vxe-input>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item field="role" title="Role" :span="12" :item-render="{}">
-            <template #default="{ data }">
-              <vxe-input v-model="data.name" placeholder="请输入角色"></vxe-input>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item field="sex" title="Sex" :span="12" :item-render="{}">
-            <template #default="{ data }">
-              <vxe-select v-model="data.sex" transfer>
-                <vxe-option v-for="item in sexList" :key="item.value" :value="item.value" :label="item.label"></vxe-option>
-              </vxe-select>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item field="age" title="Age" :span="12" :item-render="{}">
-            <template #default="{ data }">
-              <vxe-input v-model="data.age" type="number" placeholder="请输入年龄"></vxe-input>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item field="flag1" title="是否单身" :span="12" :item-render="{}">
-            <template #default="{ data }">
-              <vxe-radio-group v-model="data.flag1">
-                <vxe-radio label="Y" content="是"></vxe-radio>
-                <vxe-radio label="N" content="否"></vxe-radio>
-              </vxe-radio-group>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item field="checkedList" title="可选信息" :visible-method="visibleMethod" :span="24" :item-render="{}">
-            <template #default="{ data }">
-              <vxe-checkbox-group v-model="data.checkedList">
-                <vxe-checkbox label="1" content="运动、跑步"></vxe-checkbox>
-                <vxe-checkbox label="2" content="听音乐"></vxe-checkbox>
-                <vxe-checkbox label="3" content="爬山"></vxe-checkbox>
-                <vxe-checkbox label="4" content="吃美食"></vxe-checkbox>
-              </vxe-checkbox-group>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item title="Other information" title-align="left" :title-width="200" :span="24" :title-prefix="{message: '请填写必填项', icon: 'vxe-icon-info-circle-fill'}"></vxe-form-item>
-          <vxe-form-item field="num" title="Number" :span="12" :item-render="{}">
-            <template #default="{ data }">
-              <vxe-input v-model="data.num" type="number" placeholder="请输入数值"></vxe-input>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item field="date3" title="Date" :span="12" :item-render="{}">
-            <template #default="{ data }">
-              <vxe-input v-model="data.date3" type="date" placeholder="请选择日期" transfer></vxe-input>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item field="address" title="Date" :span="24" :item-render="{}" :title-suffix="{message: '提示信息!!', icon: 'vxe-icon-question-circle-fill'}">
-            <template #default="{ data }">
-              <vxe-textarea v-model="data.address" :autosize="{minRows: 2, maxRows: 4}"></vxe-textarea>
-            </template>
-          </vxe-form-item>
-          <vxe-form-item align="center" title-align="left" :span="24">
-            <template #default>
-              <vxe-button type="submit">提交</vxe-button>
-              <vxe-button type="reset">重置</vxe-button>
-            </template>
-          </vxe-form-item>
-        </vxe-form>
+      <template #name_edit="{ row }">
+        <vxe-input v-model="row.name"></vxe-input>
+      </template>
+      <template #nickname_edit="{ row }">
+        <vxe-input v-model="row.nickname"></vxe-input>
+      </template>
+      <template #sex_default="{ row }">
+        <span>{{ formatSex(row.sex) }}</span>
+      </template>
+      <template #sex_edit="{ row }">
+        <vxe-select v-model="row.sex" transfer>
+          <vxe-option v-for="item in sexList1" :key="item.value" :value="item.value" :label="item.label"></vxe-option>
+        </vxe-select>
       </template>
-    </vxe-modal>
+      <template #role_edit="{ row }">
+        <vxe-input v-model="row.role"></vxe-input>
+      </template>
+      <template #describe_edit="{ row }">
+        <vxe-input v-model="row.describe"></vxe-input>
+      </template>
+    </vxe-grid>
   </div>
 </template>
 
-<script lang="ts" setup>
-import { reactive, ref } from 'vue'
-import { VXETable, VxeTableInstance, VxeColumnPropTypes, VxeFormPropTypes, VxeFormItemPropTypes, VxeTableEvents } from 'vxe-table'
-
-interface RowVO {
-  id: number
-  name: string
-  nickname: string
-  role: string
-  sex: string
-  sex2: string[]
-  num: number
-  num1: number
-  age: number
-  flag1: boolean
-  address: string
-  date12: string
-  date13: string
-  date3: string
-  checkedList: any[]
-}
-
-const tableRef = ref<VxeTableInstance<RowVO>>()
-
-const formData = reactive({
-  name: '',
-  nickname: '',
-  role: '',
-  sex: '',
-  age: 0,
-  num: 0,
-  checkedList: [] as any[],
-  flag1: false,
-  date3: '',
-  address: ''
-})
-
-const submitLoading = ref(false)
-const showEdit = ref(false)
-const selectRow = ref<RowVO | null>()
-const tableData = ref<RowVO[]>([])
-
-const sexList = ref([
-  { label: '女', value: '0' },
-  { label: '男', value: '1' }
-])
-
-const formRules = reactive<VxeFormPropTypes.Rules>({
-  name: [
-    { required: true, message: '请输入名称' },
-    { min: 3, max: 5, message: '长度在 3 到 5 个字符' }
-  ],
-  nickname: [
-    { required: true, message: '请输入昵称' }
+<script setup>
+import { ref, reactive } from 'vue'
+import { VXETable } from 'vxe-table'
+const xGrid = ref()
+const gridOptions = reactive({
+  border: true,
+  keepSource: true,
+  showOverflow: true,
+  height: 530,
+  loading: false,
+  columnConfig: {
+    resizable: true
+  },
+  pagerConfig: {
+    enabled: true,
+    total: 0,
+    currentPage: 1,
+    pageSize: 10,
+    pageSizes: [10, 20, 50, 100, 200, 500]
+  },
+  editConfig: {
+    trigger: 'manual',
+    mode: 'row',
+    showStatus: true
+  },
+  columns: [
+    { type: 'seq', width: 60 },
+    { type: 'checkbox', width: 50 },
+    { field: 'name', title: 'Name', editRender: { autofocus: '.vxe-input--inner' }, slots: { edit: 'name_edit' } },
+    { field: 'nickname', title: 'Nickname', editRender: { autofocus: '.vxe-input--inner' }, slots: { edit: 'nickname_edit' } },
+    { field: 'sex', title: 'Sex', editRender: {}, slots: { default: 'sex_default', edit: 'sex_edit' } },
+    { field: 'role', title: 'Role', editRender: {}, slots: { edit: 'role_edit' } },
+    { field: 'describe', title: 'Describe', showOverflow: true, editRender: {}, slots: { edit: 'describe_edit' } },
+    { title: '操作', width: 300, slots: { default: 'operate' } }
   ],
-  sex: [
-    { required: true, message: '请选择性别' }
-  ]
+  data: []
 })
-
-const formatterSex: VxeColumnPropTypes.Formatter<RowVO> = ({ cellValue }) => {
-  const item = sexList.value.find(item => item.value === cellValue)
-  return item ? item.label : ''
+const sexList1 = ref([
+  { value: '1', label: '男' },
+  { value: '0', label: '女' }
+])
+const findList = () => {
+  gridOptions.loading = true
+  setTimeout(() => {
+    gridOptions.loading = false
+    if (gridOptions.pagerConfig) {
+      gridOptions.pagerConfig.total = 10
+    }
+    gridOptions.data = [
+      { id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: '1', age: 28, address: 'Shenzhen' },
+      { id: 10002, name: 'Test2', nickname: 'T2', role: 'Test', sex: '0', age: 22, address: 'Guangzhou' },
+      { id: 10003, name: 'Test3', nickname: 'T3', role: 'PM', sex: '1', age: 32, address: 'Shanghai' },
+      { id: 10004, name: 'Test4', nickname: 'T4', role: 'Designer', sex: '0', age: 23, address: 'Shenzhen' },
+      { id: 10005, name: 'Test5', nickname: 'T5', role: 'Develop', sex: '0', age: 30, address: 'Shanghai' },
+      { id: 10006, name: 'Test6', nickname: 'T6', role: 'Develop', sex: '0', age: 27, address: 'Shanghai' },
+      { id: 10007, name: 'Test7', nickname: 'T7', role: 'Develop', sex: '1', age: 29, address: 'Shenzhen' },
+      { id: 10008, name: 'Test8', nickname: 'T8', role: 'Develop', sex: '0', age: 32, address: 'Shanghai' },
+      { id: 10009, name: 'Test9', nickname: 'T9', role: 'Develop', sex: '1', age: 30, address: 'Shenzhen' },
+      { id: 10010, name: 'Test10', nickname: 'T10', role: 'Develop', sex: '0', age: 34, address: 'Shanghai' }
+    ]
+  }, 300)
 }
-
-const visibleMethod: VxeFormItemPropTypes.VisibleMethod = ({ data }) => {
-  return data.flag1 === 'Y'
+const gridEvents = {
+  pageChange ({ currentPage, pageSize }) {
+    if (gridOptions.pagerConfig) {
+      gridOptions.pagerConfig.currentPage = currentPage
+      gridOptions.pagerConfig.pageSize = pageSize
+    }
+    findList()
+  }
 }
-
-const insertEvent = () => {
-  Object.assign(formData, {
-    name: '',
-    nickname: '',
-    role: '',
-    sex: '',
-    age: 0,
-    num: 0,
-    checkedList: [],
-    flag1: false,
-    date3: '',
-    address: ''
-  })
-  selectRow.value = null
-  showEdit.value = true
+const formatSex = (value) => {
+  if (value === '1') {
+    return '男'
+  }
+  if (value === '0') {
+    return '女'
+  }
+  return ''
 }
-
-const editEvent = (row: RowVO) => {
-  Object.assign(formData, row)
-  selectRow.value = row
-  showEdit.value = true
+const hasActiveEditRow = (row) => {
+  const $grid = xGrid.value
+  if ($grid) {
+    return $grid.isEditByRow(row)
+  }
+  return false
 }
-
-const cellDBLClickEvent: VxeTableEvents.CellDblclick<RowVO> = ({ row }) => {
-  editEvent(row)
+const editRowEvent = (row) => {
+  const $grid = xGrid.value
+  if ($grid) {
+    $grid.setEditRow(row)
+  }
 }
 
-const removeEvent = async (row: RowVO) => {
-  const type = await VXETable.modal.confirm('您确定要删除该数据?')
-  if (type === 'confirm') {
-    const $table = tableRef.value
-    if ($table) {
-      $table.remove(row)
-    }
+const clearRowEvent = () => {
+  const $grid = xGrid.value
+  if ($grid) {
+    $grid.clearEdit()
   }
 }
-
-const submitEvent = () => {
-  submitLoading.value = true
-  setTimeout(() => {
-    const $table = tableRef.value
-    if ($table) {
-      submitLoading.value = false
-      showEdit.value = false
-      if (selectRow.value) {
-        VXETable.modal.message({ content: '保存成功', status: 'success' })
-        Object.assign(selectRow.value, formData)
-      } else {
-        VXETable.modal.message({ content: '新增成功', status: 'success' })
-        $table.insert({ ...formData })
-      }
+const saveRowEvent = async (row) => {
+  const $grid = xGrid.value
+  if ($grid) {
+    await $grid.clearEdit()
+    gridOptions.loading = true
+    // 模拟异步保存
+    setTimeout(() => {
+      gridOptions.loading = false
+      VXETable.modal.message({ content: `${JSON.stringify(row)}`, status: 'success' })
+    }, 300)
+  }
+}
+const removeRowEvent = async (row) => {
+  const type = await VXETable.modal.confirm('您确定要删除该数据?')
+  const $grid = xGrid.value
+  if ($grid) {
+    if (type === 'confirm') {
+      await $grid.remove(row)
     }
-  }, 500)
+  }
 }
-
-setTimeout(() => {
-  const list: RowVO[] = [
-    { id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: '0', sex2: ['0'], num: 40, num1: 40, age: 28, flag1: false, address: 'Shenzhen', date3: '', date12: '', date13: '', checkedList: [] },
-    { id: 10002, name: 'Test2', nickname: 'T2', role: 'Designer', sex: '1', sex2: ['0', '1'], num: 40, num1: 20, age: 22, flag1: false, address: 'Guangzhou', date3: '', date12: '', date13: '2020-08-20', checkedList: [] },
-    { id: 10003, name: 'Test3', nickname: 'T3', role: 'Test', sex: '0', sex2: ['1'], num: 4, num1: 200, age: 32, flag1: true, address: 'Shanghai', date3: '', date12: '2020-09-10', date13: '', checkedList: [] },
-    { id: 10004, name: 'Test4', nickname: 'T4', role: 'Designer', sex: '1', sex2: ['0'], num: 3, num1: 30, age: 23, flag1: false, address: 'Shenzhen', date3: '', date12: '', date13: '2020-12-04', checkedList: [] },
-    { id: 10004, name: 'Test5', nickname: 'T5', role: 'Designer', sex: '1', sex2: ['1'], num: 40, num1: 30, age: 26, flag1: true, address: 'Shenzhen', date3: '', date12: '', date13: '', checkedList: [] },
-    { id: 10004, name: 'Test6', nickname: 'T6', role: 'Designer', sex: '1', sex2: ['1'], num: 5, num1: 30, age: 28, flag1: false, address: 'BeiJing', date3: '', date12: '', date13: '2020-09-04', checkedList: [] },
-    { id: 10004, name: 'Test7', nickname: 'T7', role: 'Designer', sex: '1', sex2: ['1'], num: 40, num1: 30, age: 30, flag1: false, address: 'BeiJing', date3: '', date12: '', date13: '2020-04-10', checkedList: [] }
-  ]
-  tableData.value = list
-}, 100)
+findList()
 </script>

+ 180 - 0
src/views/reportManage/dataCenter/components/DatePicker/index.vue

@@ -0,0 +1,180 @@
+<script setup lang="ts">
+import { computed, ref, watch } from 'vue';
+import dayjs from 'dayjs';
+
+
+
+const dailyEntryTime = ref(dayjs().format("YYYY-MM-DD"));
+const dailyTime = ref(dayjs().subtract(1, "day").format("YYYY-MM-DD"));
+
+const weeklyEntryTime = ref<string | null>(null);
+const weeklySalesTime = ref<string | null>(null);
+const weeklyAdTime = ref<string | null>(null);
+
+
+const entryStartDate = ref<string>("");
+const entryEndDate = ref<string>("");
+const salesStartDate = ref<string>("");
+const salesEndDate = ref<string>("");
+const adStartDate = ref<string>("");
+const adEndDate = ref<string>("");
+
+const monthlyEntryTime = ref(null);
+const startDate = ref(null);
+const endDate = ref(null);
+
+const shortcuts = [
+  {
+    text: "今天",
+    value: new Date(),
+  },
+  {
+    text: "昨天",
+    value: () => {
+      const date = new Date();
+      date.setTime(date.getTime() - 3600 * 1000 * 24);
+      return date;
+    },
+  },
+  {
+    text: "最近七天",
+    value: () => {
+      const date = new Date();
+      date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
+      return date;
+    },
+  },
+];
+
+function handleDayChange(event) {
+  const $dailyEntryTime = dailyEntryTime.value;
+  if ($dailyEntryTime) {
+    const dailyTimeValue = new Date($dailyEntryTime);
+    dailyTimeValue.setDate(dailyTimeValue.getDate());
+    dailyTime.value = dailyTimeValue.toISOString().split("T")[0];
+  } else {
+    dailyTime.value = "";
+  }
+}
+
+const handleWeekChange
+    = () => {
+  if (weeklyEntryTime.value) {
+    entryStartDate.value = dayjs(weeklyEntryTime.value).startOf("isoWeek").format("YYYY-MM-DD");
+    entryEndDate.value = dayjs(weeklyEntryTime.value).endOf("isoWeek").format("YYYY-MM-DD");
+
+    weeklySalesTime.value = weeklyEntryTime.value;
+    salesStartDate.value = entryStartDate.value;
+    salesEndDate.value = entryEndDate.value;
+
+    const adDate = dayjs(weeklyEntryTime.value).subtract(7, "day");
+    weeklyAdTime.value = adDate.format("YYYY-WW");
+    adStartDate.value = adDate.startOf("isoWeek").format("YYYY-MM-DD");
+    adEndDate.value = adDate.endOf("isoWeek").format("YYYY-MM-DD");
+  }
+};
+
+const entryFormat = computed(() => `${entryStartDate.value} to ${entryEndDate.value}`);
+const salesFormat = computed(() => `${salesStartDate.value} to ${salesEndDate.value}`);
+const adFormat = computed(() => `${adStartDate.value} to ${adEndDate.value}`);
+
+watch(weeklyEntryTime, handleWeekChange
+);
+
+const handleMonthChange = (value) => {
+  if (value) {
+    const date = new Date(value);
+    const year = date.getFullYear();
+    const month = date.getMonth() + 1; // getMonth() 返回值为 0-11,需要加 1
+    const lastDay = new Date(year, month, 0).getDate();
+    startDate.value = `${year}-${String(month).padStart(2, "0")}-01`;
+    endDate.value = `${year}-${String(month).padStart(2, "0")}-${lastDay}`;
+  } else {
+    startDate.value = null;
+    endDate.value = null;
+  }
+};
+const monthlyEntryFormat = computed(() => `${startDate.value} to ${endDate.value}`);
+
+const disabledDate = (time: Date) => {
+  return time.getTime() > Date.now();
+};
+
+</script>
+
+<template>
+  <div>
+    <div class="demo-date-picker" v-if="dateType === 'day'">
+      <div class="block">
+        <span class="demonstration">日录入数据时间:</span>
+        <el-date-picker
+            v-model="dailyEntryTime"
+            type="Date"
+            :disabled-date="disabledDate"
+            :shortcuts="shortcuts"
+            @change="handleDayChange"
+        />
+      </div>
+      <div class="block">
+        <span class="demonstration">日数据时间:</span>
+        <el-date-picker
+            v-model="dailyTime"
+            type="Date"
+            :shortcuts="shortcuts"
+            disabled
+        />
+      </div>
+    </div>
+    <div class="demo-date-picker" v-if="dateType === 'week'">
+      <div class="block">
+        <span class="demonstration">周录入数据时间:</span>
+        <el-date-picker
+            v-model="weeklyEntryTime"
+            type="week"
+            :format="entryFormat"
+            placeholder="选择一周"
+            :disabled-date="disabledDate"
+            @change="handleWeekChange
+"
+        />
+      </div>
+      <div class="block">
+        <span class="demonstration">周销售数据时间:</span>
+        <el-date-picker
+            v-model="weeklySalesTime"
+            type="week"
+            :format="salesFormat"
+            placeholder="选择一周"
+            disabled
+        />
+      </div>
+      <div class="block">
+        <span class="demonstration">周广告数据时间:</span>
+        <el-date-picker
+            v-model="weeklyAdTime"
+            type="week"
+            :format="adFormat"
+            placeholder="选择一周"
+            disabled
+        />
+      </div>
+    </div>
+    <div class="demo-date-picker" v-if="dateType === 'month'">
+      <div class="block">
+        <span class="demonstration">月录入数据时间:</span>
+        <el-date-picker
+            v-model="monthlyEntryTime"
+            type="month"
+            :format="monthlyEntryFormat"
+            placeholder="选择月份"
+            @change="handleMonthChange"
+            :disabled-date="disabledDate"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+
+</style>

+ 2 - 1
src/views/reportManage/dataCenter/components/DateTendency/index.vue

@@ -280,7 +280,8 @@ const changeMetric = () => {
 
 const emit = defineEmits(['changeStatDim'])
 const changeStatDim = async () => {
-  emitter.emit('DateTendency-changeStatDim') // 触发DataTable的loading
+  // emitter.emit('DateTendency-changeStatDim') // 触发DataTable的loading
+  emitter.emit('DateTendency-dateChange', statDim.value)
   loading.value = true
   let source = await getDataset()
   if (source.length > 0) {

+ 0 - 248
src/views/reportManage/dataCenter/components/EntryDetail.vue

@@ -1,248 +0,0 @@
-<script setup lang="ts">
-import { reactive,ref} from 'vue'
-import { VXETable, VxeGridInstance, VxeGridProps, VxeGridListeners} from 'vxe-table'
-import dayjs from 'dayjs';
-import { useRouter } from 'vue-router'
-const router = useRouter()
-
-const DailyEntryTime = ref(dayjs().format('YYYY-MM-DD'));
-const DailyTime = ref(dayjs().format('YYYY-MM-DD'));
-
-const shortcuts = [
-  {
-    text: 'Today',
-    value: new Date(),
-  },
-  {
-    text: 'Yesterday',
-    value: () => {
-      const date = new Date()
-      date.setTime(date.getTime() - 3600 * 1000 * 24)
-      return date
-    },
-  },
-  {
-    text: 'A week ago',
-    value: () => {
-      const date = new Date()
-      date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
-      return date
-    },
-  },
-];
-
-//表格
-interface RowVO {
-  id: number
-  name: string
-  country: string
-  brand: string
-  sales: string
-  totalAdSales: number
-  adSpend: string
-}
-
-const xGrid = ref<VxeGridInstance<RowVO>>()
-const tableColumns = [
-  { type: 'seq', title: 'ID', width: 50 },
-  { field: 'name', title: '平台名称', },
-  { field: 'country', title: '国家',},
-  { field: 'brand', title: '品牌',  },
-
-  { field: 'sales', title: '销售额', editRender: { autofocus: '.vxe-input--inner' }, slots: { edit: 'sales_edit' }},
-  { field: 'totalAdSales', title: '广告销售额', editRender: { autofocus: '.vxe-input--inner' }, slots: { edit: 'totalAdSales_edit' }},
-  { field: 'adSpend', title: '广告花费', editRender: { autofocus: '.vxe-input--inner' }, slots: { edit: 'adSpend_edit' }},
-  { title: '操作', width: 300, slots: { default: 'operate' } }
-]
-
-const gridOptions = reactive<VxeGridProps<RowVO>>({
-  border: true,
-  keepSource: true,
-  showOverflow: true,
-  height: 530,
-  loading: false,
-  columnConfig: {
-    resizable: true
-  },
-  pagerConfig: {
-    enabled: true,
-    total: 0,
-    currentPage: 1,
-    pageSize: 10,
-    pageSizes: [10, 20, 50, 100, 200, 500]
-  },
-  editConfig: {
-    trigger: 'manual',
-    mode: 'row',
-    showStatus: true,
-  },
-  columns: tableColumns,
-  toolbarConfig: {
-    slots: {
-      buttons: 'toolbar_buttons',
-    },
-  },
-  data: []
-})
-const findList = () => {
-  gridOptions.loading = true
-  setTimeout(() => {
-    gridOptions.loading = false
-    if (gridOptions.pagerConfig) {
-      gridOptions.pagerConfig.total = 10
-    }
-    gridOptions.data = [
-      { name: 'Test1', country: 'T1', brand: 'B1', sales: 'Develop', totalAdSales: '1', adSpend: 28},
-      { name: 'Test2', country: 'T2', brand: 'B2', sales: 'Test', totalAdSales: '2', adSpend: 28},
-      { name: 'Test3', country: 'T3', brand: 'B3', sales: 'Test', totalAdSales: '3', adSpend: 28},
-      { name: 'Test4', country: 'T4', brand: 'B4', sales: 'Test', totalAdSales: '4', adSpend: 28},
-    ]
-  }, 300)
-}
-
-const gridEvents: VxeGridListeners<RowVO> = {
-  pageChange ({ currentPage, pageSize }) {
-    if (gridOptions.pagerConfig) {
-      gridOptions.pagerConfig.currentPage = currentPage
-      gridOptions.pagerConfig.pageSize = pageSize
-    }
-    findList()
-  }
-}
-
-const hasActiveEditRow = (row: RowVO) => {
-  const $grid = xGrid.value
-  if ($grid) {
-    return $grid.isEditByRow(row)
-  }
-  return false
-}
-
-const editRowEvent = (row: RowVO) => {
-  const $grid = xGrid.value
-  if ($grid) {
-    $grid.setEditRow(row)
-  }
-}
-
-const clearRowEvent = () => {
-  const $grid = xGrid.value
-  if ($grid) {
-    $grid.clearEdit()
-  }
-}
-
-const saveRowEvent = async (row: RowVO) => {
-  const $grid = xGrid.value
-  if ($grid) {
-    await $grid.clearEdit()
-    gridOptions.loading = true
-    // 模拟异步保存
-    setTimeout(() => {
-      gridOptions.loading = false
-      VXETable.modal.message({ content: `${JSON.stringify(row)}`, status: 'success' })
-    }, 300)
-  }
-}
-
-const removeRowEvent = async (row: RowVO) => {
-  const type = await VXETable.modal.confirm('您确定要删除该数据?')
-  const $grid = xGrid.value
-  if ($grid) {
-    if (type === 'confirm') {
-      await $grid.remove(row)
-    }
-  }
-}
-
-// const editDisabledEvent: VxeGridEvents.EditDisabled = () => {
-//   console.log('禁止编辑')
-// }
-// @edit-disabled="editDisabledEvent"
-
-findList()
-const returnHome = (row: any) => {
-  router.push({
-    name:'DataCenter'
-  })
-}
-</script>
-
-<template>
-  <div>
-    <div class="demo-date-picker">
-      <div class="block">
-        <span class="demonstration">日录入数据时间:</span>
-        <el-date-picker
-            v-model="DailyEntryTime"
-            type="Date"
-            :size="size"
-        />
-      </div>
-      <div class="block">
-        <span class="demonstration">日数据时间:</span>
-        <el-date-picker
-            v-model="DailyTime"
-            type="Date"
-            :size="size"
-        />
-      </div>
-    </div>
-  </div>
-    <el-card>
-        <div>
-          <vxe-grid ref="xGrid" v-bind="gridOptions" v-on="gridEvents" >
-            <template #operate="{ row }">
-              <template v-if="hasActiveEditRow(row)">
-                <vxe-button content="取消" @click="clearRowEvent"></vxe-button>
-                <vxe-button status="primary" content="保存" @click="saveRowEvent(row)"></vxe-button>
-              </template>
-              <template v-else>
-                <vxe-button content="编辑" @click="editRowEvent(row)"></vxe-button>
-              </template>
-              <vxe-button status="danger" content="删除" @click="removeRowEvent(row)"></vxe-button>
-            </template>
-            <!--<template #name_edit="{ row }">-->
-            <!--  <vxe-input v-model="row.name"></vxe-input>-->
-            <!--</template>-->
-            <!--<template #country_edit="{ row }">-->
-            <!--  <vxe-input v-model="row.country"></vxe-input>-->
-            <!--</template>-->
-            <!--<template #brand_edit="{ row }">-->
-            <!--  <vxe-input v-model="row.brand"></vxe-input>-->
-            <!--</template>-->
-            <template #sales_edit="{ row }">
-              <vxe-input v-model="row.sales"></vxe-input>
-            </template>
-            <template #totalAdSales_edit="{ row }">
-              <vxe-input v-model="row.totalAdSales"></vxe-input>
-            </template>
-            <template #adSpend_edit="{ row }">
-              <vxe-input v-model="row.adSpend"></vxe-input>
-            </template>
-          </vxe-grid>
-        </div>
-      <!--<vxe-button @click="returnHome">确认</vxe-button>-->
-    </el-card>
-</template>
-
-<style scoped>
-.demo-date-picker {
-  display: flex;
-  width: 100%;
-  padding: 0;
-  flex-wrap: wrap;
-}
-.demo-date-picker .block:last-child {
-  border-right: none;
-}
-.demo-date-picker .demonstration {
-  color: var(--el-text-color-secondary);
-  font-size: 14px;
-  margin:10px;
-}
-.vxe-grid {
-  border-radius: 10px;
-  margin-bottom: 10px;
-}
-</style>

+ 18 - 76
src/views/reportManage/dataCenter/components/NormalDisplay.vue

@@ -2,14 +2,14 @@
 import { dataCenterMetricsEnum } from '/@/views/reportManage/dataCenter/utils/enum'
 import { getCardData, getLineData, getLineMonthData, getLineWeekData } from '/@/views/reportManage/dataCenter/api'
 import DataTendencyChart from '/@/views/reportManage/dataCenter/components/DateTendency/index.vue'
-import { reactive, ref } from 'vue'
+import {onBeforeUnmount, provide, reactive, ref} from 'vue'
 import DateRangePicker from '/@/components/DateRangePicker/index.vue'
 import { storeToRefs } from 'pinia'
 import { useShopInfo } from '/@/stores/shopInfo'
 import { usePublicData } from '/@/stores/publicData'
-import { useRouter } from 'vue-router'
 import Selector from "/@/views/reportManage/dataCenter/components/Selector/index.vue";
-const router = useRouter()
+import TableSelect from "/src/views/reportManage/dataCenter/components/TableDataDisplay.vue"
+import emitter from "/@/utils/emitter";
 // 店铺信息
 const shopInfo = useShopInfo()
 const { profile } = storeToRefs(shopInfo)
@@ -25,74 +25,21 @@ const queryParams = ref({
   // sku,
 })
 
-const tableColumns = [
-  { type: 'seq', title: '平台编号' },
-  { field: 'Name', title: '平台名称' },
-  { field: 'Operation', title: '运营' },
-  { field: 'Country', title: '国家' },
-  { field: 'Brand', title: '品牌' },
-  { field: 'Sales', title: '销售额' },
-  { field: 'YearOnYear', title: '期末同比变化' },
-  { field: 'MonthOnMonth', title: '期末环比变化' },
-  { field: 'AdSpend', title: '广告花费' },
-  { field: 'TotalAdSales', title: '广告销售额' },
-  { field: 'ROI', title: '广告ROI' },
-  { field: 'ACOS', title: '广告ACOS' },
-  { field: 'ROAS', title: '广告ROAS' },
-  { field: 'MonthSalesCompletionRate', title: '月销售额完成占比' },
-]
-
-//表格
-const gridOptions = reactive({
-  border: true,
-  height: 600,
-  align: null,
-  round: true,
-  columnConfig: {
-    resizable: true,
-  },
-  columns: tableColumns,
-  toolbarConfig: {
-    slots: {
-      buttons: 'toolbar_buttons',
-    },
-  },
-  data: [
-    {
-      id: 10001,
-      Name: 'Test1',
-      Operation: 'T1',
-      Country: 'Develop',
-      Brand: 'Man',
-      Sales: 28,
-      YearOnYear: 11,
-      MonthOnMonth: 22,
-      AdSpend: 33,
-      TotalAdSales: 100,
-      ROI: 11,
-      ACOS: 11,
-      ROAS: 11,
-      MonthSalesCompletionRate: 11,
-    },
-  ],
+const dateDimension = ref('day')
+provide('dateDimension', dateDimension)
+emitter.on('DateTendency-dateChange', (value: string)=>{
+  dateDimension.value = value
+  console.log(1, dateDimension.value)
 })
 
-//数据导入
-const handleImport = (row: any) => {
-  router.push({
-    name: 'EntryDetail',
-  })
-}
-const QueryTask = (row: any) => {
-  router.push({
-    name: 'TaskManage',
-  })
-}
+onBeforeUnmount(()=>{
+  emitter.all.clear();
+})
 </script>
 
 <template>
   <div>
-    <div class="flex gap-1.5 justify-between">
+    <div class="custom-card-style flex gap-1.5 justify-between my-1.5 mx-2">
       <Selector></Selector>
       <DateRangePicker v-model="dateRange"></DateRangePicker>
     </div>
@@ -104,22 +51,17 @@ const QueryTask = (row: any) => {
         :fetchLine="getLineData"
         :fetch-line-month="getLineMonthData"
         :fetch-line-week="getLineWeekData"
-        >np
+        >
       </DataTendencyChart>
     </el-card>
   </div>
-    <el-card>
-      <vxe-grid v-bind="gridOptions">
-        <template #toolbar_buttons>
-          <vxe-button @click="handleImport">数据录入</vxe-button>
-          <vxe-button @click="QueryTask">任务列表</vxe-button>
-        </template>
-      </vxe-grid>
-    </el-card>
+  <el-card><TableSelect></TableSelect></el-card>
 </template>
 
 <style scoped>
-.vxe-grid {
-  border-radius: 10px;
+.custom-card-style {
+  z-index: 999;
+  position: sticky;
+  top: 0;
 }
 </style>

+ 572 - 0
src/views/reportManage/dataCenter/components/TableDataEntry.vue

@@ -0,0 +1,572 @@
+<script setup lang="ts">
+import { reactive, ref, computed, inject, watch, onMounted } from 'vue';
+import { VXETable, VxeGridInstance, VxeGridProps, VxeGridEvents } from 'vxe-table';
+import dayjs from 'dayjs';
+import isoWeek from 'dayjs/plugin/isoWeek';
+import { useRouter, useRoute } from 'vue-router';
+import {
+  getDayTaskData,
+  postCreateDayData,
+  postCreateWeekData,
+  postCreateMonthData, getMonthTaskData ,getWeekTaskData
+} from '/@/views/reportManage/dataCenter/api';
+
+dayjs.extend(isoWeek);
+
+const router = useRouter();
+const route = useRoute();
+const dateType = <string>route.query.dateType;
+
+//日期选择
+const dailyEntryTime = ref(dayjs().format('YYYY-MM-DD'));
+const dailyTime = ref(dayjs().subtract(1, 'day').format('YYYY-MM-DD'));
+
+const weeklyEntryTime = ref<string | null>(null);
+const weeklySalesTime = ref<string | null>(null);
+const weeklyAdTime = ref<string | null>(null);
+
+
+const entryStartDate = ref<string>('');
+const entryEndDate = ref<string>('');
+const salesStartDate = ref<string>('');
+const salesEndDate = ref<string>('');
+const adStartDate = ref<string>('');
+const adEndDate = ref<string>('');
+
+const monthlyEntryTime = ref(null);
+const startDate = ref(null);
+const endDate = ref(null);
+
+const shortcuts = [
+  {
+    text: '今天',
+    value: new Date(),
+  },
+  {
+    text: '昨天',
+    value: () => {
+      const date = new Date();
+      date.setTime(date.getTime() - 3600 * 1000 * 24);
+      return date;
+    },
+  },
+  {
+    text: '最近七天',
+    value: () => {
+      const date = new Date();
+      date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
+      return date;
+    },
+  },
+];
+
+function handleDayChange(event) {
+  const $dailyEntryTime = dailyEntryTime.value;
+  if ($dailyEntryTime) {
+    const dailyTimeValue = new Date($dailyEntryTime);
+    dailyTimeValue.setDate(dailyTimeValue.getDate());
+    dailyTime.value = dailyTimeValue.toISOString().split('T')[0];
+  } else {
+    dailyTime.value = '';
+  }
+}
+
+const handleWeekChange
+    = () => {
+  if (weeklyEntryTime.value) {
+    entryStartDate.value = dayjs(weeklyEntryTime.value).startOf('isoWeek').format('YYYY-MM-DD');
+    entryEndDate.value = dayjs(weeklyEntryTime.value).endOf('isoWeek').format('YYYY-MM-DD');
+
+    weeklySalesTime.value = weeklyEntryTime.value;
+    salesStartDate.value = entryStartDate.value;
+    salesEndDate.value = entryEndDate.value;
+
+    const adDate = dayjs(weeklyEntryTime.value).subtract(7, 'day');
+    weeklyAdTime.value = adDate.format('YYYY-WW');
+    adStartDate.value = adDate.startOf('isoWeek').format('YYYY-MM-DD');
+    adEndDate.value = adDate.endOf('isoWeek').format('YYYY-MM-DD');
+  }
+};
+
+const entryFormat = computed(() => `${entryStartDate.value} to ${entryEndDate.value}`);
+const salesFormat = computed(() => `${salesStartDate.value} to ${salesEndDate.value}`);
+const adFormat = computed(() => `${adStartDate.value} to ${adEndDate.value}`);
+
+watch(weeklyEntryTime, handleWeekChange
+);
+
+const handleMonthChange = (value) => {
+  if (value) {
+    const date = new Date(value);
+    const year = date.getFullYear();
+    const month = date.getMonth() + 1; // getMonth() 返回值为 0-11,需要加 1
+    const lastDay = new Date(year, month, 0).getDate();
+    startDate.value = `${year}-${String(month).padStart(2, '0')}-01`;
+    endDate.value = `${year}-${String(month).padStart(2, '0')}-${lastDay}`;
+  } else {
+    startDate.value = null;
+    endDate.value = null;
+  }
+};
+const monthlyEntryFormat = computed(() => `${startDate.value} to ${endDate.value}`);
+
+const disabledDate = (time: Date) => {
+  return time.getTime() > Date.now();
+};
+
+//表格
+const dayColumns = [
+  {field: 'task', title: 'ID', width: 50},
+  {field: 'platformNumber', title: '平台编号'},
+  {field: 'platformName', title: '平台名称'},
+  {field: 'country', title: '国家'},
+  {field: 'brandName', title: '品牌'},
+
+  {field: 'sales', title: '销售额', editRender: {}, slots: {edit: 'sales_edit'}},
+  {field: 'ad_sales', title: '广告销售额', editRender: {}, slots: {edit: 'ad_sales_edit'}},
+  {field: 'ad_cost', title: '广告花费', editRender: {}, slots: {edit: 'ad_cost_edit'}},
+  {title: '操作', width: 300, slots: {default: 'operate'}},
+];
+const weekColumns = [
+  {field: 'task', title: 'ID', width: 50},
+  {field: 'platformNumber', title: '平台编号',},
+  {field: 'platformName', title: '平台名称'},
+  {field: 'country', title: '国家'},
+  {field: 'brandName', title: '品牌'},
+
+  {field: 'sales', title: '销售额',editRender: {}, slots: {edit: 'sales_edit'}},
+  {field: 'total_sales_current_monthly', title: '当月累计销售额',editRender: {}, slots: {edit: 'total_sales_current_monthly_edit'}},
+  {field: 'ad_sales', title: '广告销售额',editRender: {},slots: {edit: 'ad_sales_edit'}},
+  { field: 'ad_cost', title: '广告花费', editRender: {}, slots: { edit: 'ad_cost_edit' } },
+  { field: 'impression', title: '广告曝光', editRender: {}, slots: { edit: 'impression_edit' } },
+  { field: 'ad_click', title: '广告点击', editRender: {}, slots: { edit: 'ad_click_edit' } },
+  { field: 'ad_order', title: '广告订单', editRender: {}, slots: { edit: 'ad_order_edit' } },
+  { field: 'money_by_amazon', title: 'Amazon回款金额', editRender: {}, slots: { edit: 'money_by_amazon_edit' } },
+  { field: 'money_by_other', title: 'Other回款金额', editRender: {}, slots: { edit: 'money_by_other_edit' } },
+  { field: 'session', title: '流量', editRender: {}, slots: { edit: 'session_edit' } },
+  { field: 'order', title: '转化', editRender: {}, slots: { edit: 'order_edit' } },
+  { field: 'availableSalesDay', title: '当前存货可售天', editRender: {}, slots: { edit: 'availableSalesDay_edit' } },
+  { field: 'intransitInventory', title: '当前在途库存', editRender: {}, slots: { edit: 'intransitInventory_edit' } },
+  { field: 'overseasStorage', title: '当前海外仓库存', editRender: {}, slots: { edit: 'overseasStorage_edit' } },
+  { field: 'refundRate', title: '最近90天平台退货率', editRender: {}, slots: { edit: 'refundRate_edit' } },
+  {title: '操作', width: 150, slots: {default: 'operate'}},
+];
+const monthColumns = [
+  {type: 'seq', title: 'ID', width: 50},
+  {field: 'platformName', title: '平台名称'},
+  {field: 'country', title: '国家'},
+  {field: 'brandName', title: '品牌'},
+
+  {field: 'sales', title: '销售额',editRender: {}, slots: {edit: 'sales_edit'}},
+  {field: 'ad_sales', title: '广告销售额',editRender: {},slots: {edit: 'ad_sales_edit'}},
+  { field: 'ad_cost', title: '广告花费', editRender: {}, slots: { edit: 'ad_cost_edit' } },
+  { field: 'impression', title: '广告曝光', editRender: {}, slots: { edit: 'impression_edit' } },
+  { field: 'ad_click', title: '广告点击', editRender: {}, slots: { edit: 'ad_click_edit' } },
+  { field: 'ad_order', title: '广告订单', editRender: {}, slots: { edit: 'ad_order_edit' } },
+  {title: '操作', width: 300, slots: {default: 'operate'}},
+];
+
+const dayData = [];
+const weekData = [];
+const monthData = [];
+
+interface RowVO {
+  task: number;
+  sales: number;
+  ad_sales: number;
+  ad_cost: number;
+
+  total_sales_current_monthly: number;
+  impression: number;
+  ad_click: number;
+  ad_order: number;
+  money_by_amazon: number;
+  money_by_other: number;
+  session: string;
+  order: string;
+  availableSalesDay: number;
+  intransitInventory: number;
+  overseasStorage: number;
+  refundRate: number;
+}
+
+const xGrid = ref<VxeGridInstance<RowVO>>();
+const gridOptions = reactive({
+  border: false,
+  height: 600,
+  align: null,
+  round: true,
+  loading: false,
+  columnConfig: {
+    resizable: true
+  },
+  pagerConfig: {
+    enabled: true,
+    total: 20,
+    currentPage: 1,
+    pageSize: 10,
+    pageSizes: [10, 20, 30],
+  },
+  editConfig: {
+    trigger: 'click',
+    mode: 'row',
+    showStatus: true,
+  },
+  day: {
+    columns: dayColumns,
+    data: dayData
+  },
+  week: {
+    columns: weekColumns,
+    data: weekData
+  },
+  month: {
+    columns: monthColumns,
+    data: monthData
+  }
+});
+
+const gridEvents = {
+  pageChange({currentPage, pageSize}) {
+    console.log(currentPage, pageSize);
+    if (gridOptions.pagerConfig) {
+      gridOptions.pagerConfig.currentPage = currentPage;
+      gridOptions.pagerConfig.pageSize = pageSize;
+    }
+    if (dateType === 'day') {
+      fetchDayTaskData();
+    } else if (dateType === 'week') {
+      fetchWeekTaskData();
+    } else if (dateType === 'month') {
+      fetchMonthTaskData();
+    }
+  }
+};
+
+// 获取表格数据
+async function fetchTaskData(apiFunction) {
+  try {
+    const resp = await apiFunction({
+      page: gridOptions.pagerConfig.currentPage,
+      limit: gridOptions.pagerConfig.pageSize,
+    });
+    gridOptions[dateType].data = resp.data;
+    gridOptions.pagerConfig.total = resp.total;
+  } catch (error) {
+    console.error('Error fetching task data:', error);
+  }
+}
+async function fetchDayTaskData() {
+  await fetchTaskData(getDayTaskData);
+}
+
+async function fetchWeekTaskData() {
+  await fetchTaskData(getWeekTaskData);
+}
+
+async function fetchMonthTaskData() {
+  await fetchTaskData(getMonthTaskData);
+}
+//创建日数据
+async function createDayData(row: RowVO) {
+  const body = {
+    sales: row.sales,
+    ad_sales: row.ad_sales,
+    ad_cost: row.ad_cost,
+    enter_datetime: dailyEntryTime.value,
+    data_datetime: dailyTime.value,
+    task: row.task,
+  };
+  try {
+    const resp = await postCreateDayData(body);
+    if (resp.code === 2000) {
+      await fetchDayTaskData();
+      await VXETable.modal.message({
+        content: '创建成功',
+        status: 'success',
+      });
+    }
+  } catch (e) {
+    await VXETable.modal.message({content: '创建失败',});
+  }
+}
+//创建周数据
+async function createWeekData(row: RowVO) {
+  const body = {
+    sales:row.sales,
+    total_sales_current_monthly:row.total_sales_current_monthly,
+    ad_sales:row.ad_sales,
+    ad_cost:row.ad_cost,
+    impression:row.impression,
+    ad_click:row.ad_click,
+    ad_order:row.ad_order,
+    money_by_amazon:row.money_by_amazon,
+    money_by_other:row.money_by_other,
+    session:row.session,
+    order:row.order,
+    availableSalesDay:row.availableSalesDay,
+    intransitInventory:row.intransitInventory,
+    overseasStorage:row.overseasStorage,
+    refundRate:row.refundRate,
+    sales_start_time:salesStartDate.value,
+    sales_end_time:salesEndDate.value,
+    ad_start_time:adStartDate.value,
+    ad_end_time:adEndDate.value,
+    enter_start_datetime:entryStartDate.value,
+    enter_end_datetime:entryEndDate.value,
+    task:row.task,
+  };
+  try {
+    const resp = await postCreateWeekData(body);
+    console.log(body);
+    if (resp.code === 2000) {
+      await fetchWeekTaskData();
+      await VXETable.modal.message({
+        content: '创建成功',
+        status: 'success',
+      });
+    }
+  } catch (e) {
+    await VXETable.modal.message({content: '创建失败',});
+  }
+}
+//创建月数据
+async function createMonthData(row: RowVO) {
+  const body = {
+    sales:row.sales,
+    ad_sales:row.ad_sales,
+    ad_cost:row.ad_cost,
+    impression:row.impression,
+    ad_click:row.ad_click,
+    ad_order:row.ad_order,
+    data_start_time:startDate.value,
+    data_end_time:endDate.value,
+    enter_start_time:startDate.value,
+    enter_end_time:endDate.value,
+    task:row.task,
+  };
+  try {
+    const resp = await postCreateMonthData(body);
+    console.log(body);
+    if (resp.code === 2000) {
+      await fetchMonthTaskData();
+      await VXETable.modal.message({
+        content: '创建成功',
+        status: 'success',
+      });
+    }
+  } catch (e) {
+    await VXETable.modal.message({content: '创建失败',});
+  }
+}
+
+const saveRowEvent = async (row: RowVO) => {
+  const $grid = xGrid.value;
+  if ($grid) {
+    await $grid.clearEdit();
+    gridOptions.loading = true;
+    if (dateType === 'day') {
+      await createDayData(row);
+    } else if (dateType === 'week') {
+      await createWeekData(row);
+    } else if (dateType === 'month') {
+      await createMonthData(row);
+    }
+    // 模拟异步保存
+    setTimeout(() => {
+      gridOptions.loading = false;
+    }, 300);
+  }
+};
+
+const editRowEvent = async (row: any) => {
+  const $grid = xGrid.value;
+  if ($grid) {
+    await $grid.clearEdit();
+    gridOptions.loading = true;
+    // 模拟异步保存
+    setTimeout(() => {
+      gridOptions.loading = false;
+    }, 300);
+  }
+};
+
+const SubmitData = (row: any) => {
+  router.push({
+    name: 'DataCenter',
+  });
+};
+
+const currentGridOptions = computed(() => {
+  const selectedGridOptions = gridOptions[dateType] || gridOptions['day'];
+  return {
+    ...gridOptions,
+    ...selectedGridOptions
+  };
+});
+
+onMounted(() => {
+  if (dateType === 'day') {
+    fetchDayTaskData();
+  } else if (dateType === 'week') {
+    fetchWeekTaskData();
+  } else if (dateType === 'month') {
+    fetchMonthTaskData();
+  }
+});
+</script>
+
+<template>
+  <div>
+    <el-card class="custom-card-style flex gap-1.5 justify-between my-1.5 mx-2">
+      <div class="demo-date-picker" v-if="dateType === 'day'">
+        <div class="block">
+          <span class="demonstration">日录入数据时间:</span>
+          <el-date-picker
+              v-model="dailyEntryTime"
+              type="Date"
+              :disabled-date="disabledDate"
+              :shortcuts="shortcuts"
+              @change="handleDayChange"
+          />
+        </div>
+        <div class="block">
+          <span class="demonstration">日数据时间:</span>
+          <el-date-picker
+              v-model="dailyTime"
+              type="Date"
+              :shortcuts="shortcuts"
+              disabled
+          />
+        </div>
+      </div>
+      <div class="demo-date-picker" v-if="dateType === 'week'">
+        <div class="block">
+          <span class="demonstration">周录入数据时间:</span>
+          <el-date-picker
+              v-model="weeklyEntryTime"
+              type="week"
+              :format="entryFormat"
+              placeholder="选择一周"
+              :disabled-date="disabledDate"
+              @change="handleWeekChange
+"
+          />
+        </div>
+        <div class="block">
+          <span class="demonstration">周销售数据时间:</span>
+          <el-date-picker
+              v-model="weeklySalesTime"
+              type="week"
+              :format="salesFormat"
+              placeholder="选择一周"
+              disabled
+          />
+        </div>
+        <div class="block">
+          <span class="demonstration">周广告数据时间:</span>
+          <el-date-picker
+              v-model="weeklyAdTime"
+              type="week"
+              :format="adFormat"
+              placeholder="选择一周"
+              disabled
+          />
+        </div>
+      </div>
+      <div class="demo-date-picker" v-if="dateType === 'month'">
+        <div class="block">
+          <span class="demonstration">月录入数据时间:</span>
+          <el-date-picker
+              v-model="monthlyEntryTime"
+              type="month"
+              :format="monthlyEntryFormat"
+              placeholder="选择月份"
+              @change="handleMonthChange"
+              :disabled-date="disabledDate"
+          />
+        </div>
+      </div>
+    </el-card>
+  </div>
+  <el-card class="mx-2">
+    <div style="position: relative">
+      <vxe-grid ref="xGrid" v-bind="currentGridOptions" v-on="gridEvents">
+        <template #operate="{ row }">
+          <vxe-button content="创建" @click="saveRowEvent(row)"></vxe-button>
+          <vxe-button content="更新" @click="editRowEvent(row)"></vxe-button>
+        </template>
+        <template #sales_edit="{ row }">
+          <vxe-input v-model="row.sales"></vxe-input>
+        </template>
+        <template #ad_sales_edit="{ row }">
+          <vxe-input v-model="row.ad_sales"></vxe-input>
+        </template>
+        <template #ad_cost_edit="{ row }">
+          <vxe-input v-model="row.ad_cost"></vxe-input>
+        </template>
+        <template #total_sales_current_monthly_edit="{ row }">
+          <vxe-input v-model="row.total_sales_current_monthly"></vxe-input>
+        </template>
+        <template #impression_edit="{ row }">
+          <vxe-input v-model="row.impression"></vxe-input>
+        </template>
+        <template #ad_click_edit="{ row }">
+          <vxe-input v-model="row.ad_click"></vxe-input>
+        </template>
+        <template #ad_order_edit="{ row }">
+          <vxe-input v-model="row.ad_order"></vxe-input>
+        </template>
+        <template #money_by_amazon_edit="{ row }">
+          <vxe-input v-model="row.money_by_amazon"></vxe-input>
+        </template>
+        <template #money_by_other_edit="{ row }">
+          <vxe-input v-model="row.money_by_other"></vxe-input>
+        </template>
+        <template #session_edit="{ row }">
+          <vxe-input v-model="row.session"></vxe-input>
+        </template>
+        <template #order_edit="{ row }">
+          <vxe-input v-model="row.order"></vxe-input>
+        </template>
+        <template #availableSalesDay_edit="{ row }">
+          <vxe-input v-model="row.availableSalesDay"></vxe-input>
+        </template>
+        <template #intransitInventory_edit="{ row }">
+          <vxe-input v-model="row.intransitInventory"></vxe-input>
+        </template>
+        <template #overseasStorage_edit="{ row }">
+          <vxe-input v-model="row.overseasStorage"></vxe-input>
+        </template>
+        <template #refundRate_edit="{ row }">
+          <vxe-input v-model="row.refundRate"></vxe-input>
+        </template>
+
+      </vxe-grid>
+    </div>
+  </el-card>
+</template>
+
+<style scoped>
+.demo-date-picker {
+  display: flex;
+  width: 100%;
+  padding: 0;
+  flex-wrap: wrap;
+}
+
+.demo-date-picker .block:last-child {
+  border-right: none;
+}
+
+.demo-date-picker .demonstration {
+  color: var(--el-text-color-secondary);
+  font-size: 14px;
+  margin: 10px;
+}
+
+.vxe-grid {
+  border-radius: 10px;
+  margin-bottom: 10px;
+}
+</style>

+ 171 - 153
src/views/reportManage/dataCenter/components/TaskManage.vue

@@ -1,23 +1,24 @@
 <script setup lang="ts">
-import Selector from '/@/views/reportManage/dataCenter/components/Selector/index.vue'
-import {ref, reactive, onMounted, nextTick } from 'vue'
-import {VXETable, VxeGridInstance, VxeGridProps, VxeGridListeners} from 'vxe-table'
-import {getTasks, postCreateTask, getOperationSelect ,postUpdateTask } from '../api'
-import {ComponentSize, ElMessage, FormInstance, FormRules} from 'element-plus'
+import Selector from '/@/views/reportManage/dataCenter/components/Selector/index.vue';
+import { ref, reactive, onMounted, nextTick } from 'vue';
+import { VXETable, VxeGridInstance, VxeGridProps, VxeGridListeners } from 'vxe-table';
+import { getTasks, postCreateTask, getOperationSelect, postUpdateTask, postDeleteTask } from '../api';
+import { ComponentSize, ElMessage, FormInstance, FormRules } from 'element-plus';
+import { length } from 'sortablejs';
 
 //表单
 interface taskRuleForm {
-  number: string
-  name: string
-  country: string
-  brand: string
-  operation: string[]
-  currency: string
+  number: string;
+  name: string;
+  country: string;
+  brand: string;
+  operation: string[];
+  currency: string;
 }
 
-const formSize = ref<ComponentSize>('default')
-const dialogFormVisible = ref(false)
-const taskRuleFormRef = ref<FormInstance>()
+const formSize = ref<ComponentSize>('default');
+const dialogFormVisible = ref(false);
+const taskRuleFormRef = ref<FormInstance>();
 const taskRuleForm = reactive({
   number: '',
   name: '',
@@ -25,11 +26,11 @@ const taskRuleForm = reactive({
   brand: '',
   operation: '',
   currency: '',
-})
+});
 const resetForm = (formEl: FormInstance | undefined) => {
-  if (!formEl) return
-  formEl.resetFields()
-}
+  if (!formEl) return;
+  formEl.resetFields();
+};
 const rules = reactive<FormRules>({
   number: [{required: true, message: '请输入平台编号', trigger: 'blur'},],
   name: [{required: true, message: '请输入平台名称', trigger: 'blur'}],
@@ -37,30 +38,32 @@ const rules = reactive<FormRules>({
   brand: [{required: true, message: '请输入品牌', trigger: 'blur'}],
   operation: [{required: true, message: '请选择运营', trigger: 'change'}],
   currency: [{required: true, message: '请输入货币', trigger: 'blur'}],
-})
+});
 
 //表格
-let page = 1
-let limit = 10
-const  loading = ref(false)
+let page = 1;
+let limit = 10;
+
+// const  loading = ref(false)
 
 interface RowVO {
-  platformNumber: string
-  platformName: string
-  country: string
-  brandName: string
-  operation: string
-  currencyCode: string
-  quantity: number
+  platformNumber: string;
+  platformName: string;
+  country: string;
+  brandName: string;
+  user_name: string;
+  currencyCode: string;
+  child_user_number: number;
+  user: [];
 }
 
-const xGrid = ref<VxeGridInstance<RowVO>>()
+const xGrid = ref<VxeGridInstance<RowVO>>();
 
 const gridOptions = reactive<VxeGridProps<RowVO>>({
   border: false,
   keepSource: true,
   showOverflow: true,
-  height: 500,
+  height: 1000,
   loading: false,
   round: true,
   toolbarConfig: {
@@ -69,7 +72,6 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
     },
     refresh: true,
   },
-
   rowConfig: {
     isHover: true,
   },
@@ -84,7 +86,7 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
     pageSizes: [10, 20, 30],
   },
   editConfig: {
-    trigger: 'auto',
+    trigger: 'click',
     mode: 'row',
     showStatus: true,
   },
@@ -95,7 +97,7 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
   },
   columns: [
     {type: 'checkbox', width: 50},
-    {type: 'seq', title: 'ID', width: 120},
+    // {type: 'seq', title: 'ID', width: 120},
     {
       field: 'platformNumber',
       title: '平台编号',
@@ -117,36 +119,30 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
     {title: '操作', width: 300, slots: {default: 'operate'}},
   ],
   data: [],
-})
+});
 
-const operationList = ref([
-  {value: '1', label: 'option1'},
-  {value: '2', label: 'option2'},
-])
-const quantityList = ref([
-  {value: '1', label: 'per1'},
-  {value: '2', label: 'per2'},
-])
+const operationList = ref([]);
+const quantityList = ref([]);
 
 // 分页
 const gridEvents: VxeGridListeners<RowVO> = {
   pageChange({currentPage, pageSize}) {
     // console.log(currentPage, pageSize)
     if (gridOptions.pagerConfig) {
-      gridOptions.pagerConfig.currentPage = currentPage
-      gridOptions.pagerConfig.pageSize = pageSize
-      getTaskList()
+      gridOptions.pagerConfig.currentPage = currentPage;
+      gridOptions.pagerConfig.pageSize = pageSize;
+      getTaskList();
     }
   },
-}
+};
 
 async function getTaskList() {
   const resp = await getTasks({
     page: gridOptions.pagerConfig.currentPage,
     limit: gridOptions.pagerConfig.pageSize
-  })
-  gridOptions.data = resp.data
-  gridOptions.pagerConfig.total = resp.total
+  });
+  gridOptions.data = resp.data;
+  gridOptions.pagerConfig.total = resp.total;
 }
 
 /**
@@ -155,94 +151,130 @@ async function getTaskList() {
  * @return {boolean}
  */
 const hasActiveEditRow = (row: RowVO) => {
-  const $grid = xGrid.value
+  const $grid = xGrid.value;
   if ($grid) {
-    return $grid.isEditByRow(row)
+    return $grid.isEditByRow(row);
   }
-  return false
-}
+  return false;
+};
 
 const editRowEvent = (row: RowVO) => {
-  const $grid = xGrid.value
+  const $grid = xGrid.value;
   if ($grid) {
-    $grid.setEditRow(row)
-    console.log(row.id)
+    $grid.setEditRow(row);
+    // console.log(row)
   }
-}
+};
 
 //清除编辑状态
 const clearRowEvent = () => {
-  const $grid = xGrid.value
+  const $grid = xGrid.value;
   if ($grid) {
-    $grid.clearEdit()
+    $grid.clearEdit();
   }
-}
+};
+
+async function deleteTask() {
+  const $grid = xGrid.value;
+  if ($grid) {
+  const selectRecords = $grid.getCheckboxRecords();
+  const selectedIds = selectRecords.map(record => record.id);
+    console.log(selectedIds);
+  const obj = {keys: selectedIds};
+  try {
+    const resp = await postDeleteTask(obj);
+    if (resp.code === 2000) {
+      ElMessage({
+        message: '删除成功',
+        type: 'success',
+      });
+      await getTaskList();
+    }
+  } catch (e) {
+    ElMessage({
+      message: '删除失败',
+      type: 'error',
+    });
+  }
+}}
 
 // 删除选中行
 const removeEvent = async () => {
-  const $grid = xGrid.value
+  const $grid = xGrid.value;
   if ($grid) {
-    const selectRecords = $grid.getCheckboxRecords()
+    const selectRecords = $grid.getCheckboxRecords();
     if (selectRecords.length > 0) {
-      const type = await VXETable.modal.confirm('您确定要删除选中的数据?')
+      const type = await VXETable.modal.confirm('您确定要删除选中的数据?');
       if (type === 'confirm') {
-        await $grid.removeCheckboxRow()
+        await deleteTask(selectRecords);
+        await $grid.removeCheckboxRow();
       }
     } else {
-      await VXETable.modal.message({content: '请选择要删除的数据', status: 'error'})
+      await VXETable.modal.message({content: '请选择要删除的数据', status: 'error'});
     }
   }
-}
+};
 
-// let n = setEditRow(row.id)
-async function updateRow() {
-  const body = {
-    country:gridOptions.data[0].country,
-    platformNumber:gridOptions.data[0].platformNumber,
-    platformName:gridOptions.data[0].platformName,
-    brandName:gridOptions.data[0].brandName,
-    user:gridOptions.data[0].operation,
-    currencyCode:gridOptions.data[0].currencyCode,
-  }
-  try {
-    const response = await postUpdateTask(body)
-    console.log(response.data)
-    if (response.data.code === 'success') {
-      ElMessage.success('更新成功')
-    } else if (response.data.code === 'error') {
-      ElMessage.warning(`${response.data.description}`)
-    } else {
-      ElMessage.error('更新失败')
+async function updateRow(row: RowVO) {
+  const $grid = xGrid.value;
+  const transUser = ref('');
+  operationList.value.find((item) => {
+    if (item.label === row.user_name) {
+      transUser.value = item.value;
+    } else if (row.user_name === item.value) {
+      row.user_name = item.label;
+      transUser.value = item.value;
+    }
+  });
+  if ($grid) {
+    const updatedRowData = {
+      id: row.id,
+      platformNumber: row.platformNumber,
+      platformName: row.platformName,
+      country: row.country,
+      brandName: row.brandName,
+      user: [transUser.value],
+      currencyCode: row.currencyCode,
+    };
+    try {
+      const response = await postUpdateTask(updatedRowData);
+      if (response.code === 2000) {
+        ElMessage.success('更新成功');
+      } else if (response.code == 400) {
+        ElMessage.warning(`${response.data.description}`);
+      } else {
+        ElMessage.error('更新失败');
+      }
+    } catch (error) {
+      console.log('error:', error);
     }
-  } catch (error) {
-    console.error('error:', error)
   }
 }
+
 // 保存表格行数据
 const saveRowEvent = async (row: RowVO) => {
-  const $grid = xGrid.value
+  const $grid = xGrid.value;
   if ($grid) {
-    // await updateRow()
-    console.log(gridOptions.data[0].id)
-    await $grid.clearEdit()
-    gridOptions.loading = true
+    await $grid.clearEdit();
+    await updateRow(row);
+    gridOptions.loading = true;
     setTimeout(() => {
-      gridOptions.loading = false
-    }, 300)
+      gridOptions.loading = false;
+    }, 300);
   }
-}
+};
 
 // 保存全部数据
 const saveEvent = async () => {
-  const $grid = xGrid.value
+  const $grid = xGrid.value;
   if ($grid) {
-    const {insertRecords, removeRecords, updateRecords} = $grid.getRecordset()
+    const {insertRecords, removeRecords, updateRecords} = $grid.getRecordset();
     await VXETable.modal.message({
       content: `新增 ${insertRecords.length} 条,删除 ${removeRecords.length} 条,更新 ${updateRecords.length} 条`,
       status: 'success',
-    })
+    });
   }
-}
+};
 
 async function createTask() {
   const body = {
@@ -252,12 +284,12 @@ async function createTask() {
     brandName: taskRuleForm.brand,
     currencyCode: taskRuleForm.currency,
     user: [taskRuleForm.operation],
-  }
+  };
   try {
-    const resp = await postCreateTask(body) // await VXETable.modal.message({ content: '创建成功', status: 'success' })
+    const resp = await postCreateTask(body);
   } catch (error) {
-    console.error('error:', error)
-    await VXETable.modal.message({content: '创建失败,请重试', status: 'error'})
+    console.error('error:', error);
+    await VXETable.modal.message({content: '创建失败,请重试', status: 'error'});
   }
 }
 
@@ -273,69 +305,52 @@ const submitEvent = async () => {
     user_name: taskRuleForm.operation,
     currencyCode: taskRuleForm.currency,
     child_user_number: '',
-  }
+  };
   // 将新行添加到表格数据中
-  gridOptions.data.push(newRow)
+  gridOptions.data.push(newRow);
   try {
-    await createTask()
-    dialogFormVisible.value = false
+    await createTask();
+    dialogFormVisible.value = false;
     //获取更新表格数据
-    await saveEvent()
-    await getTaskList()
-    await nextTick(() => {
-      loading.value = true
-      setTimeout(() => {
-        loading.value = false
-      }, 500)
-    })
+    await getTaskList();
+    gridOptions.loading = true;
+    setTimeout(() => {
+      gridOptions.loading = false;
+    }, 300);
   } catch (error) {
-    console.error('Failed to save task:', error)
+    console.error('Failed to save task:', error);
   }
-}
+};
 
 // 提交表单
 const submitForm = async (formEl: FormInstance | undefined) => {
-  if (!formEl) return
+  if (!formEl) return;
   await formEl.validate(async (valid, fields) => {
     if (valid) {
       await submitEvent();
       await nextTick();
       taskRuleFormRef.value.resetFields();
     } else {
-      console.log('error submit!', fields)
+      console.log('error submit!', fields);
     }
   });
 };
 
-
 async function fetchOperationSelect() {
   try {
-    const resp = await getOperationSelect()
-    // console.log("resp", resp.data)
+    const resp = await getOperationSelect();
     operationList.value = resp.data.map((item: any) => {
-      return {value: item.id, label: item.name}
-    })
-    // console.log(operationList.value)
+      return {value: item.id, label: item.name};
+    });
   } catch (e) {
-    console.error("Failed to fetch operation select:", e)
+    console.error('Failed to fetch operation select:', e);
   }
 }
 
-// async function fetchQuantitySelect() {
-//   try {
-//     const resp = await getQuantitySelect()
-//     quantityList.value = resp.data.map((item: any) => {
-//       return {value: item.id, label: item.name}
-//     })
-//   } catch (e) {
-//     console.error("Failed to fetch operation select:", e)
-//   }
-// }
-
 onMounted(() => {
-  getTaskList()
-  fetchOperationSelect()
-})
+  getTaskList();
+  fetchOperationSelect();
+});
 </script>
 
 <template>
@@ -344,7 +359,7 @@ onMounted(() => {
   </el-card>
   <el-card class="mx-2">
     <div style="position: relative">
-      <vxe-grid ref="xGrid" v-bind="gridOptions" v-on="gridEvents" v-loading="loading">
+      <vxe-grid ref="xGrid" v-bind="gridOptions" v-on="gridEvents">
         <template #toolbar_buttons>
           <vxe-button icon="vxe-icon-add" plain @click="dialogFormVisible = true"> 添加任务</vxe-button>
           <vxe-button icon="vxe-icon-delete" @click="removeEvent">删除</vxe-button>
@@ -374,7 +389,8 @@ onMounted(() => {
         </template>
         <template #operation_edit="{ row }">
           <vxe-select v-model="row.user_name" transfer>
-            <vxe-option v-for="item in operationList" :key="item.value" :value="item.value" :label="item.label"></vxe-option>
+            <vxe-option v-for="item in operationList" :key="item.value" :value="item.value"
+                        :label="item.label"></vxe-option>
           </vxe-select>
         </template>
         <template #currency_edit="{ row }">
@@ -382,7 +398,8 @@ onMounted(() => {
         </template>
         <template #quantity_edit="{ row }">
           <vxe-select v-model="row.child_user_number" transfer>
-            <vxe-option v-for="item in quantityList" :key="item.value" :value="item.value" :label="item.label"></vxe-option>
+            <vxe-option v-for="item in quantityList" :key="item.value" :value="item.value"
+                        :label="item.label"></vxe-option>
           </vxe-select>
         </template>
       </vxe-grid>
@@ -390,14 +407,14 @@ onMounted(() => {
   </el-card>
   <el-dialog v-model="dialogFormVisible" title="新建任务" width="500">
     <el-form
-      ref="taskRuleFormRef"
-      style="max-width: 600px"
-      :model="taskRuleForm"
-      :rules="rules"
-      label-width="auto"
-      class="demo-taskRuleForm"
-      :size="formSize"
-      status-icon>
+        ref="taskRuleFormRef"
+        style="max-width: 600px"
+        :model="taskRuleForm"
+        :rules="rules"
+        label-width="auto"
+        class="demo-taskRuleForm"
+        :size="formSize"
+        status-icon>
       <el-form-item label="平台编号" prop="number">
         <el-input v-model="taskRuleForm.number" placeholder="请输入平台编号" />
       </el-form-item>
@@ -412,7 +429,8 @@ onMounted(() => {
       </el-form-item>
       <el-form-item label="运营" prop="operation">
         <el-select v-model="taskRuleForm.operation" placeholder="请选择运营">
-          <el-option v-for="item in operationList" :key="item.value" :value="item.value" :label="item.label"></el-option>
+          <el-option v-for="item in operationList" :key="item.value" :value="item.value"
+                     :label="item.label"></el-option>
         </el-select>
       </el-form-item>
       <el-form-item label="回款币种" prop="currency">

+ 3 - 3
src/views/reportManage/dataCenter/index.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import { ref } from 'vue'
 import type { TabsPaneContext } from 'element-plus'
-import TableBrowsing from '/@/views/reportManage/dataCenter/components/TableBrowsing.vue'
+import CombinedDisplay from '/src/views/reportManage/dataCenter/components/CombinedDisplay.vue'
 import DataExport from '/@/views/reportManage/dataCenter/components/DataExport.vue'
 import CompareData from '/@/views/reportManage/dataCenter/components/CompareData.vue'
 import NormalDisplay from '/@/views/reportManage/dataCenter/components/NormalDisplay.vue'
@@ -9,13 +9,13 @@ import NormalDisplay from '/@/views/reportManage/dataCenter/components/NormalDis
 const activeName = ref('NormalDisplay')
 const tabsComponents: any = {
   NormalDisplay,
-  TableBrowsing,
+  CombinedDisplay,
   // CompareData,
   DataExport,
 }
 const panes = [
   { label: '普通展示', name: 'NormalDisplay' },
-  { label: '表格浏览', name: 'TableBrowsing' },
+  { label: '合并展示', name: 'CombinedDisplay' },
   // { label: '对比数据', name: 'CompareData' },
   { label: '数据导出', name: 'DataExport' },
 ]