Browse Source

✨ feat<数据中心>: 任务列表更改字段;更改搜索框

xinyan 10 months ago
parent
commit
449de7eacb

+ 15 - 5
src/views/reportManage/TaskManage/index.vue

@@ -164,11 +164,19 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
     },
     {
       field: 'user_name',
-      title: '运营',
+      title: '填写人',
       editRender: {},
       slots: { edit: 'operation_edit' },
       align: 'center',
-      minWidth: 89
+      minWidth: 104
+    },
+    {
+      field: 'operater',
+      title: '运营',
+      editRender: {},
+      slots: { edit: 'operater_name_edit' },
+      align: 'center',
+      minWidth: 104
     },
     {
       field: 'currencyCode',
@@ -336,7 +344,7 @@ const requiredFields = [
   { field: 'platformName', title: '平台名称' },
   { field: 'country', title: '国家' },
   { field: 'brandName', title: '品牌' },
-  { field: 'user', title: '运营' },
+  { field: 'user', title: '填写人' },
   { field: 'currencyCode', title: '平台币种' },
   { field: 'currencyCodePlatform', title: '回款/余额币种' },
   { field: 'line', title: '线路' },
@@ -404,7 +412,6 @@ async function handleStatusChange(row) {
       status: row.status,
     };
     const query = { partial: 1, };
-    console.log('updatedData', updatedData);
     try {
       const response = await postUpdateTaskStatus(query, updatedData);
       if (response.code === 2000) {
@@ -590,7 +597,7 @@ onMounted(() => {
 
 <template>
   <el-card class="custom-card-style flex gap-1.5 justify-between mx-8">
-    <Selector ref="selectorRef" @update:filteredData="filteredDataChange" />
+    <Selector ref="selectorRef" @update:filteredData="filteredDataChange" :showOperationSearch="true" />
   </el-card>
   <el-card class="mx-8 my-3">
     <div style="position: relative">
@@ -664,6 +671,9 @@ onMounted(() => {
                         :value="item.value"></vxe-option>
           </vxe-select>
         </template>
+        <template #operater_name_edit="{ row }">
+          <vxe-input v-model="row.operater"></vxe-input>
+        </template>
         <template #currency_edit="{ row }">
           <!--<vxe-input v-model="row.currencyCode"></vxe-input>-->
           <el-autocomplete

+ 8 - 6
src/views/reportManage/dataCenter/combinedDisplay/components/tableData/mainData.vue

@@ -35,7 +35,7 @@ const gridOptions = reactive({
   id: 'mainDataCustomStorage',
   columnConfig: {
     resizable: true,
-    isCurrent: true,
+    //isCurrent: true,
   },
   rowConfig: {
     isHover: true,
@@ -51,7 +51,9 @@ const gridOptions = reactive({
     remote: true
   },
   customConfig: {
-    storage: true
+    storage: {
+      visible:true,
+    }
   },
   toolbarConfig: {
     custom: true,
@@ -144,7 +146,7 @@ async function fetchMainData(taskIds, resetPage = false) {
         const column = {
           field: key,
           title: key, // 使用字段名作为列标题
-          minWidth: key.includes('~') ? 90 : key.includes('截止') ? 90 : regex2.test(key) ? 91 : 72,
+          minWidth: key.includes('~') ? 94 : key.includes('截止') ? 94 : regex2.test(key) ? 95 : 76,
           align: 'center',
           formatter: formatEmptyCell,
           sortable: isSortable,
@@ -354,8 +356,8 @@ onMounted(() => {
     <template #platformName_default="{ row }">
       <div class="font-semibold" style="color: #0097f8">{{ row.platformName }}</div>
     </template>
-    <template #currencyCode_default="{ row }">
-      <el-tag color="#fef9c3" style="color: #f59e0b; border-color: #fbbf24;">{{ row.currencyCode }}</el-tag>
+    <template #brandName_default="{ row }">
+      <el-tag effect="plain" type="success" round>{{ row.brandName }}</el-tag>
     </template>
   </vxe-grid>
 </template>
@@ -369,7 +371,7 @@ onMounted(() => {
 
 :deep(.vxe-table--header .vxe-header--row th .vxe-cell,
 .vxe-table--body .vxe-body--row td .vxe-cell) {
-  padding-right: 0 !important;
+  padding-right: 4px !important;
   padding-left: 0 !important;
 }
 </style>

+ 13 - 11
src/views/reportManage/dataCenter/combinedDisplay/components/tableData/monthlyComparativeData.vue

@@ -23,7 +23,9 @@ const gridOptions = reactive({
   loading: false,
   id: 'monthlyCustomStorage',
   customConfig: {
-    storage: true
+    storage: {
+      visible:true,
+    }
   },
   columnConfig: {
     resizable: true,
@@ -97,7 +99,7 @@ async function fetchMonthlyData(taskIds, resetPage = false) {
       const dynamicColumns = Array.from(allColumns).map(key => ({
         field: key,
         title: key,
-        minWidth: 97,
+        minWidth: 120,
         align: 'center',
         formatter: formatEmptyCell,
       }));
@@ -128,8 +130,8 @@ function formatEmptyCell({cellValue}) {
   }
   if (typeof cellValue === 'number') {
     const formatter = new Intl.NumberFormat('en-US', {
-      minimumFractionDigits: 2,
-      maximumFractionDigits: 2,
+      minimumFractionDigits: 0,
+      //maximumFractionDigits: 2,
     });
     return formatter.format(cellValue);
   }
@@ -159,16 +161,16 @@ const headerCellStyle = () => {
     <template #platformName_default="{ row }">
       <div class="font-semibold" style="color: #0097f8">{{ row.platformName }}</div>
     </template>
-    <template #currencyCode_default="{ row }">
-      <el-tag color="#fef9c3" style="color: #f59e0b; border-color: #fbbf24;">{{ row.currencyCode }}</el-tag>
+    <template #brandName_default="{ row }">
+      <el-tag effect="plain" type="success" round>{{ row.brandName }}</el-tag>
     </template>
   </vxe-grid>
 </template>
 
 <style scoped>
-/* :deep(.vxe-table--header .vxe-header--row th .vxe-cell, */
-/* .vxe-table--body .vxe-body--row td .vxe-cell) { */
-/*   padding-left: 0 !important; */
-/*   padding-right: 0 !important; */
-/* } */
+:deep(.vxe-table--header .vxe-header--row th .vxe-cell,
+.vxe-table--body .vxe-body--row td .vxe-cell) {
+  padding-left: 5px !important;
+  padding-right: 0 !important;
+}
 </style>

+ 21 - 10
src/views/reportManage/dataCenter/normalDisplay/components/Selector/index.vue

@@ -2,15 +2,24 @@
 import { onMounted, ref, watch } from 'vue';
 import { getOperationSelect, getTasks, getTasksId } from '/@/views/reportManage/TaskManage/api';
 
+const props = defineProps({
+  showOperationSearch: {
+    type: Boolean,
+    default: false
+  }
+});
+
 const emit = defineEmits();
 const platformNumberList = ref('');
 const platformNameList = ref('');
-const operationList = ref([]);
+const operationList = ref('');
+const usersList = ref([]);
 const countryList = ref([]);
 const brandNameList = ref([]);
 
 const platformNumberOptions = ref([]);
 const platformNameOptions = ref([]);
+const usersOptions = ref([]);
 const operationOptions = ref([]);
 const countryOptions = ref([]);
 const brandNameOptions = ref([]);
@@ -40,14 +49,15 @@ async function fetchAllTasks() {
 
   platformNumberOptions.value = [...new Set(allData.map(item => item.platformNumber))];
   platformNameOptions.value = [...new Set(allData.map(item => item.platformName))];
+  operationOptions.value = [...new Set(allData.map(item => item.operater))];
   countryOptions.value = sortCountriesByInitial([...new Set(allData.map(item => item.country))]);
   brandNameOptions.value = [...new Set(allData.map(item => item.brandName))];
 }
 
-async function fetchOperationSelect() {
+async function fetchUsersSelect() {
   try {
     const resp = await getOperationSelect();
-    operationOptions.value = resp.data.map((item: any) => {
+    usersOptions.value = resp.data.map((item: any) => {
       return { value: item.id, label: item.name };
     });
   } catch (e) {
@@ -76,11 +86,12 @@ async function fetchFilteredData() {
 
   processFilterSingle(platformNumberList.value, 'platformNumber');
   processFilterSingle(platformNameList.value, 'platformName');
+  processFilterSingle(operationList.value, 'operater');
   processFilterMultiple(countryList, 'country', 'countries');
   processFilterMultiple(brandNameList, 'brandName', 'brandNames');
 
-  if (operationList.value.length > 0) {
-    filters.users = operationList.value.join(',');
+  if (usersList.value.length > 0) {
+    filters.users = usersList.value.join(',');
   }
 
   filteredData.value = filters;
@@ -94,18 +105,17 @@ async function fetchFilteredData() {
 
 async function emitChange() {
   await fetchFilteredData();
-  // await fetchFilteredDataId();
   emit('update:filteredData', filteredData);
   emit('update:updateData', updateData);
 }
 
-watch([countryList, brandNameList, operationList], () => {
+watch([countryList, brandNameList, usersList], () => {
   emitChange();
 });
 
 onMounted(() => {
   fetchAllTasks();
-  fetchOperationSelect();
+  fetchUsersSelect();
 });
 
 defineExpose({ fetchFilteredData, filteredData, updateData });
@@ -115,8 +125,9 @@ defineExpose({ fetchFilteredData, filteredData, updateData });
   <div class="flex-container">
     <el-input v-model="platformNumberList" @change="emitChange" placeholder="平台编号" class="flex-item"></el-input>
     <el-input v-model="platformNameList" @change="emitChange" placeholder="平台名称" class="flex-item"></el-input>
-    <el-select v-model="operationList" multiple collapse-tags collapse-tags-tooltip placeholder="运营" class="flex-item">
-      <el-option v-for="item in operationOptions" :key="item.value" :label="item.label" :value="item.value" />
+    <el-input v-model="operationList" @change="emitChange" placeholder="运营" class="flex-item"></el-input>
+    <el-select v-if="props.showOperationSearch" v-model="usersList" multiple collapse-tags collapse-tags-tooltip placeholder="填写人" class="flex-item">
+      <el-option v-for="item in usersOptions" :key="item.value" :label="item.label" :value="item.value" />
     </el-select>
     <el-select v-model="countryList" multiple collapse-tags collapse-tags-tooltip placeholder="国家" class="flex-item">
       <el-option v-for="item in countryOptions" :key="item" :label="item" :value="item" />

+ 23 - 23
src/views/reportManage/dataCenter/normalDisplay/components/TableDataDisplay.vue

@@ -27,7 +27,9 @@ const monthData = [];
 // 排序
 const order_date = ref('');
 const sortOrder = ref('');
-
+const salesOrder = ref(null);
+const salesField = ref(null);
+const tableKey = ref(Math.random());
 const gridOptions = reactive({
   border: 'inner',
   height: 900,
@@ -36,7 +38,9 @@ const gridOptions = reactive({
   loading: false,
   id: 'normalCustomStorage',
   customConfig: {
-    storage: true
+    storage: {
+      visible:true,
+    }
   },
   columnConfig: {
     resizable: true,
@@ -146,7 +150,7 @@ async function fetchData(taskIds, apiFunc, startDate, endDate, dataColumns, date
       const allColumns = new Set();
       const salesColumns = [];
       const otherColumns = [];
-
+      //清空列名
       dataColumns.value = dataColumns.value.filter(column => !/\d{2}-\d{2}/.test(column.field) && !column.field.includes('余额币种') && !column.field.includes('退货率'));
 
       resp.data.forEach(row => {
@@ -160,18 +164,18 @@ async function fetchData(taskIds, apiFunc, startDate, endDate, dataColumns, date
       //"的销售额"字段可以排序
       allColumns.forEach(key => {
         let isSortable = false;
-        if (key.includes('的销售额')&& !key.includes('增长率')) {
+        if (key.includes('的销售额') && !key.includes('增长率')) {
           isSortable = true;
         }
         const column = {
           field: key,
           title: key,
-          minWidth: key.includes('~') ? 95 : /\d{4}-\d{2}-\d{2}的/.test(key) ? 88 : key.includes('截止')? 90 :79,
+          minWidth: key.includes('~') ? 95 : /\d{4}-\d{2}-\d{2}的/.test(key) ? 93 : key.includes('截止') ? 90 : 79,
           align: 'center',
           formatter: formatEmptyCell,
           sortable: isSortable,
         };
-        if (key.includes('的销售额')&& !key.includes('增长率')) {
+        if (key.includes('的销售额') && !key.includes('增长率')) {
           salesColumns.push(column);
         } else {
           otherColumns.push(column);
@@ -185,15 +189,14 @@ async function fetchData(taskIds, apiFunc, startDate, endDate, dataColumns, date
           const dateB = b.field.match(/\d{4}-\d{2}-\d{2}/)[0];
           return new Date(dateA) - new Date(dateB);
         });
-      }
-      else if (dateType.value=='week'){
+      } else if (dateType.value == 'week') {
         salesColumns.sort((a, b) => {
           const dateA = a.field.match(/\d{4}-\d{2}-\d{2}~\d{4}-\d{2}-\d{2}/)[0].split('~')[0];
           const dateB = b.field.match(/\d{4}-\d{2}-\d{2}~\d{4}-\d{2}-\d{2}/)[0].split('~')[0];
-          console.log(dateA,dateB);
+          console.log(dateA, dateB);
           return new Date(dateA) - new Date(dateB);
         });
-      }else if (dateType.value=='month'){
+      } else if (dateType.value == 'month') {
         salesColumns.sort((a, b) => {
           const dateA = a.field.match(/\d{4}-\d{2}/)[0];
           const dateB = b.field.match(/\d{4}-\d{2}/)[0];
@@ -242,16 +245,12 @@ function fetchCurrentData(taskIds, resetPage = false) {
   }
 }
 
-const salesOrder = ref(null);
-const salesField = ref(null);
 
-function handleSortChange({ column, order }) {
-  salesOrder.value = order;
-  salesField.value = column.field;
-  //console.log('salesOrder', salesOrder.value);
-  //console.log('salesField', salesField.value);
+function handleSortChange({ field, order }) {
+  //salesOrder.value = order;
+  //salesField.value = field;
   sortOrder.value = order === 'asc' ? 'smallfirst' : 'bigfirst';
-  const sortField = column.field;
+  const sortField = field;
   if (sortField) {
     const match = sortField.match(/(\d{4}-\d{2}-\d{2})的销售额/);
     const matchRange = sortField.match(/(\d{4}-\d{2}-\d{2})~(\d{4}-\d{2}-\d{2})的销售额/);
@@ -265,7 +264,8 @@ function handleSortChange({ column, order }) {
     }
   }
   saveSortState(); // 保存排序状态
-  fetchCurrentData(props.taskIds, true); // 获取数据
+  fetchCurrentData(props.taskIds, true);
+  tableKey.value = Math.random();
 }
 
 watch(() => props.taskIds, (newTaskIds) => {
@@ -321,8 +321,8 @@ onMounted(() => {
 
 <template>
   <div>
-    <vxe-grid :cell-style="cellStyle" :header-cell-style="headerCellStyle" stripe v-bind="currentGridOptions"
-              v-on="gridEvents" @sort-change="handleSortChange">
+    <vxe-grid :key="tableKey" :cell-style="cellStyle" :header-cell-style="headerCellStyle" :sort-config="sortConfig" stripe
+              v-bind="currentGridOptions" v-on="gridEvents" @sort-change="handleSortChange">
       <template #toolbar_buttons>
         <el-button icon="plus" target="_blank" type="primary" @click="handleImport">数据录入</el-button>
       </template>
@@ -332,8 +332,8 @@ onMounted(() => {
       <template #platformName_default="{ row }">
         <div class="font-semibold" style="color: #0097f8">{{ row.platformName }}</div>
       </template>
-      <template #currencyCode_default="{ row }">
-        <el-tag color="#fef9c3" style="color: #f59e0b; border-color: #fbbf24;">{{ row.currencyCode }}</el-tag>
+      <template #brandName_default="{ row }">
+        <el-tag effect="plain" type="success" round>{{ row.brandName }}</el-tag>
       </template>
     </vxe-grid>
   </div>

+ 15 - 2
src/views/reportManage/dataCenter/normalDisplay/components/TableDataEntry.vue

@@ -424,6 +424,18 @@ const validateNumericFields = (fields: Record<string, any>, fieldsToValidate: st
   return true;
 };
 
+//表单规则
+
+function createDayDataRules() {
+  if (dateType === 'day') {
+    rules.ad_sales_original[0].required = false;
+    rules.ad_cost_original[0].required = false;
+  } else {
+    rules.ad_sales_original[0].required = true;
+    rules.ad_cost_original[0].required = true;
+  }
+}
+
 //创建日数据
 async function createDayData() {
   const body = {
@@ -530,7 +542,7 @@ const submitForm = async (formEl: FormInstance | undefined) => {
   await formEl.validate(async (valid, fields) => {
     if (valid) {
       if (dateType === 'day') {
-        const fieldsToValidate = ['sales_original', 'ad_sales_original', 'ad_cost_original'];
+        const fieldsToValidate = ['sales_original'];
         if (!validateNumericFields(taskDataForm, fieldsToValidate)) return; // 验证字段
         await createDayData();
       }
@@ -658,7 +670,7 @@ const editRowEvent = async (row: any) => {
   const $grid = xGrid.value;
   if ($grid) {
     if (dateType === 'day') {
-      const fieldsToValidate = ['sales_original', 'ad_sales_original', 'ad_cost_original'];
+      const fieldsToValidate = ['sales_original'];
       if (!validateNumericFields(row, fieldsToValidate)) return; // 验证字段
       await updateDayData(row);
     } else if (dateType === 'week') {
@@ -730,6 +742,7 @@ const headerCellStyle = () => {
 onMounted(() => {
   setDefaultDate();
   fetchCurrentTaskData();
+  createDayDataRules();
 });
 </script>
 

+ 14 - 13
src/views/reportManage/dataCenter/utils/columns.ts

@@ -5,7 +5,7 @@ export const dayColumns = ref([
   { field: 'platformName', title: '平台名称', align: 'center', width: 142, },
   { field: 'country', title: '国家', align: 'center', width: 90, },
   { field: 'brandName', title: '品牌', align: 'center', width: 90, },
-  { field: 'user_name', title: '运营', align: 'center', width: 100 },
+  { field: 'operater', title: '运营', align: 'center', width: 100 },
   { field: 'currencyCode', title: '平台币种', align: 'center', width: 100 },
   {
     title: '销售额', align: 'center', children: [
@@ -55,7 +55,7 @@ export const weekColumns = ref([
   { field: 'platformName', title: '平台名称', fixed: 'left', width: 142, align: 'center' },
   { field: 'country', title: '国家', fixed: 'left', width: 80, align: 'center' },
   { field: 'brandName', title: '品牌', fixed: 'left', width: 60 },
-  { field: 'user_name', title: '运营', fixed: 'left', width: 80, align: 'center' },
+  { field: 'operater', title: '运营', fixed: 'left', width: 80, align: 'center' },
   { field: 'currencyCode', title: '平台币种', fixed: 'left', width: 80, align: 'center' },
 
   {
@@ -189,7 +189,7 @@ export const monthColumns = ref([
   { field: 'platformName', title: '平台名称', fixed: 'left', width: 142, align: 'center' },
   { field: 'country', title: '国家', fixed: 'left', width: 80, align: 'center' },
   { field: 'brandName', title: '品牌', fixed: 'left', width: 60 },
-  { field: 'user_name', title: '运营', fixed: 'left', width: 80, align: 'center' },
+  { field: 'operater', title: '运营', fixed: 'left', width: 80, align: 'center' },
   { field: 'currencyCode', title: '平台币种', fixed: 'left', width: 80, align: 'center' },
 
   {
@@ -254,7 +254,7 @@ export const universal = [
     titlePrefix: { icon: 'vxe-icon-goods-fill' },
   },
   {
-    field: 'user_name',
+    field: 'operater',
     title: '运营',
     fixed: 'left',
     minWidth: 75,
@@ -273,18 +273,19 @@ export const universal = [
     field: 'brandName',
     title: '品牌',
     fixed: 'left',
-    minWidth: 75,
+    minWidth: 89,
     align: 'center',
     titlePrefix: { icon: 'vxe-icon-brand' },
+    slots:{default: 'brandName_default'}
   },
-  {
-    field: 'currencyCode',
-    title: '平台币种',
-    fixed: 'left',
-    minWidth: 75,
-    align: 'center',
-    slots: { default: 'currencyCode_default' }
-  },
+  //{
+  //  field: 'currencyCode',
+  //  title: '平台币种',
+  //  fixed: 'left',
+  //  minWidth: 75,
+  //  align: 'center',
+  //  slots: { default: 'currencyCode_default' }
+  //},
 ];
 
 // 表格展示