|
@@ -5,8 +5,11 @@ import dayjs from 'dayjs';
|
|
|
import isoWeek from 'dayjs/plugin/isoWeek';
|
|
|
import { useRoute } from 'vue-router';
|
|
|
import {
|
|
|
+ getDayBeforeData,
|
|
|
getDayTaskData,
|
|
|
+ getMonthBeforeData,
|
|
|
getMonthTaskData,
|
|
|
+ getWeekBeforeData,
|
|
|
getWeekTaskData,
|
|
|
postCreateDayData,
|
|
|
postCreateMonthData,
|
|
@@ -19,6 +22,8 @@ import { dayColumns, monthColumns, weekColumns } from '../../utils/columns';
|
|
|
import { ComponentSize, ElMessage, FormInstance, FormRules } from 'element-plus';
|
|
|
import enLocale from 'element-plus/es/locale/lang/en';
|
|
|
import Selector from '/@/views/reportManage/dataCenter/normalDisplay/components/Selector/index.vue';
|
|
|
+import { Warning } from '@element-plus/icons-vue';
|
|
|
+
|
|
|
|
|
|
dayjs.extend(isoWeek);
|
|
|
|
|
@@ -67,8 +72,13 @@ const shortcuts = [
|
|
|
},
|
|
|
];
|
|
|
|
|
|
+const yDayDate = ref(null);
|
|
|
+const yWeekDay = ref(null);
|
|
|
+const yMonthDay = ref(null);
|
|
|
+
|
|
|
function handleDayChange(value) {
|
|
|
dailySalesTime.value = dayjs(value).format('YYYY-MM-DD');
|
|
|
+ yDayDate.value = dayjs(dailySalesTime.value).subtract(1, 'day').format('YYYY-MM-DD');
|
|
|
fetchCurrentTaskData();
|
|
|
}
|
|
|
|
|
@@ -80,6 +90,7 @@ const handleWeekChange = () => {
|
|
|
weeklyAdTime.value = adDate.format('YYYY-WW');
|
|
|
adStartDate.value = adDate.startOf('week').format('YYYY-MM-DD');
|
|
|
adEndDate.value = adDate.endOf('week').format('YYYY-MM-DD');
|
|
|
+ yWeekDay.value = dayjs(entryEndDate.value).locale('en').endOf('week').subtract(1, 'week').format('YYYY-MM-DD');
|
|
|
}
|
|
|
if (initialLoad) {
|
|
|
initialLoad = false; // 只在初次加载时避免多次调用
|
|
@@ -96,6 +107,7 @@ const handleMonthChange = (value) => {
|
|
|
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 }`;
|
|
|
+ yMonthDay.value = dayjs(endDate.value).subtract(1, 'month').endOf('month').format('YYYY-MM-DD');
|
|
|
fetchCurrentTaskData();
|
|
|
} else {
|
|
|
startDate.value = null;
|
|
@@ -115,6 +127,7 @@ function setDefaultDate() {
|
|
|
switch (dateType) {
|
|
|
case 'day':
|
|
|
dailySalesTime.value = dayjs().subtract(1, 'day').format('YYYY-MM-DD');
|
|
|
+ yDayDate.value = dayjs(dailySalesTime.value).subtract(1, 'day').format('YYYY-MM-DD');
|
|
|
break;
|
|
|
case 'week':
|
|
|
weeklyEntryTime.value = dayjs().locale('en').subtract(1, 'week').startOf('week').format('YYYY-MM-DD');
|
|
@@ -124,6 +137,7 @@ function setDefaultDate() {
|
|
|
monthlyEntryTime.value = dayjs().subtract(1, 'month').format('YYYY-MM-DD');
|
|
|
startDate.value = dayjs(monthlyEntryTime.value).startOf('month').format('YYYY-MM-DD');
|
|
|
endDate.value = dayjs(monthlyEntryTime.value).endOf('month').format('YYYY-MM-DD');
|
|
|
+ yMonthDay.value = dayjs(endDate.value).subtract(1, 'month').endOf('month').format('YYYY-MM-DD');
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -150,6 +164,8 @@ interface taskDataForm {
|
|
|
const formSize = ref<ComponentSize>('default');
|
|
|
const isSubmitting = ref(false);
|
|
|
const dayFormVisible = ref(false);
|
|
|
+const dialogVisible = ref(false);
|
|
|
+const dialogMessage = ref('');
|
|
|
const taskDataFormRef = ref<FormInstance>();
|
|
|
const taskDataForm = reactive({
|
|
|
sales_original: null,
|
|
@@ -159,7 +175,6 @@ const taskDataForm = reactive({
|
|
|
impression: null,
|
|
|
ad_click: null,
|
|
|
ad_order: null,
|
|
|
- // money_by_other: null,
|
|
|
session: null,
|
|
|
order: null,
|
|
|
availableSalesDay: null,
|
|
@@ -195,6 +210,11 @@ const rules = reactive<FormRules>({
|
|
|
const flatDayColumns = ref(flattenColumns(dayColumns.value));
|
|
|
const flatWeekColumns = ref(flattenColumns(weekColumns.value));
|
|
|
const flatMonthColumns = ref(flattenColumns(monthColumns.value));
|
|
|
+
|
|
|
+const ySalesData = ref({
|
|
|
+ sales_original: '',
|
|
|
+ total_sales_current_monthly_original: '',
|
|
|
+});
|
|
|
//表格
|
|
|
let taskId = 0;
|
|
|
let currentId = 0;
|
|
@@ -315,7 +335,6 @@ const handelEditRow = (row: RowVO) => {
|
|
|
// 强制恢复滚动条位置
|
|
|
setTimeout(() => {
|
|
|
bodyWrapper.scrollLeft = currentScrollLeft.value;
|
|
|
- console.log('After setTimeout, scrollLeft:', bodyWrapper.scrollLeft);
|
|
|
}, 0);
|
|
|
}
|
|
|
};
|
|
@@ -387,9 +406,9 @@ function fetchCurrentTaskData() {
|
|
|
|
|
|
const editEvent = async (row: RowVO) => {
|
|
|
taskId = row.task;
|
|
|
- // console.log('row', taskId);
|
|
|
currentId = row.id;
|
|
|
Object.assign(taskDataForm, row);
|
|
|
+ await currentSalesTip();
|
|
|
dayFormVisible.value = true;
|
|
|
};
|
|
|
|
|
@@ -543,31 +562,43 @@ async function createMonthData() {
|
|
|
|
|
|
//创建任务
|
|
|
const submitForm = async (formEl: FormInstance | undefined) => {
|
|
|
- if (!formEl || isSubmitting.value) return; // 防止重复提交
|
|
|
- await formEl.validate(async (valid, fields) => {
|
|
|
- if (valid) {
|
|
|
- isSubmitting.value = true; // 表单开始提交,禁用按钮
|
|
|
- try {
|
|
|
- if (dateType === 'day') {
|
|
|
- const fieldsToValidate = ['sales_original'];
|
|
|
- if (!validateNumericFields(taskDataForm, fieldsToValidate)) return; // 验证字段
|
|
|
- await createDayData();
|
|
|
- }
|
|
|
- if (dateType === 'week') {
|
|
|
- const fieldsToValidate = ['sales_original', 'ad_sales_original', 'ad_cost_original', 'total_sales_current_monthly_original', 'impression', 'ad_click', 'ad_order', 'money_by_amazon', 'money_by_other', 'session', 'order', 'availableSalesDay', 'intransitInventory', 'overseasStorage', 'refundRate'];
|
|
|
- if (!validateNumericFields(taskDataForm, fieldsToValidate)) return; // 验证字段
|
|
|
- await createWeekData();
|
|
|
- }
|
|
|
- if (dateType === 'month') {
|
|
|
- const fieldsToValidate = ['sales_original'];
|
|
|
- if (!validateNumericFields(taskDataForm, fieldsToValidate)) return; // 验证字段
|
|
|
- await createMonthData();
|
|
|
+ const fieldsToWarn = validateForm();
|
|
|
+ if (fieldsToWarn.length > 0) {
|
|
|
+ dialogVisible.value = true;
|
|
|
+ dialogMessage.value = `${ fieldsToWarn.join(', ') }`;
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ if (!formEl || isSubmitting.value) return; // 防止重复提交
|
|
|
+ await formEl.validate(async (valid, fields) => {
|
|
|
+ if (valid) {
|
|
|
+ isSubmitting.value = true; // 表单开始提交,禁用按钮
|
|
|
+ try {
|
|
|
+ await submit(formEl);
|
|
|
+ } finally {
|
|
|
+ isSubmitting.value = false; // 无论成功或失败,恢复按钮
|
|
|
}
|
|
|
- } finally {
|
|
|
- isSubmitting.value = false; // 无论成功或失败,恢复按钮
|
|
|
}
|
|
|
- }
|
|
|
- });
|
|
|
+ });
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const submit = async () => {
|
|
|
+ dialogVisible.value = false;
|
|
|
+ if (dateType === 'day') {
|
|
|
+ const fieldsToValidate = ['sales_original'];
|
|
|
+ if (!validateNumericFields(taskDataForm, fieldsToValidate)) return; // 验证字段
|
|
|
+ await createDayData();
|
|
|
+ }
|
|
|
+ if (dateType === 'week') {
|
|
|
+ const fieldsToValidate = ['sales_original', 'ad_sales_original', 'ad_cost_original', 'total_sales_current_monthly_original', 'impression', 'ad_click', 'ad_order', 'money_by_amazon', 'money_by_other', 'session', 'order', 'availableSalesDay', 'intransitInventory', 'overseasStorage', 'refundRate'];
|
|
|
+ if (!validateNumericFields(taskDataForm, fieldsToValidate)) return; // 验证字段
|
|
|
+ await createWeekData();
|
|
|
+ }
|
|
|
+ if (dateType === 'month') {
|
|
|
+ const fieldsToValidate = ['sales_original'];
|
|
|
+ if (!validateNumericFields(taskDataForm, fieldsToValidate)) return; // 验证字段
|
|
|
+ await createMonthData();
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
// 更新日数据
|
|
@@ -696,6 +727,47 @@ const editRowEvent = async (row: any) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+// 日数据提示
|
|
|
+async function salesTip(apiFunction, dateTypeKey) {
|
|
|
+ const dateMap = {
|
|
|
+ day: yDayDate.value,
|
|
|
+ week: yWeekDay.value,
|
|
|
+ month: yMonthDay.value,
|
|
|
+ };
|
|
|
+ const resp = await apiFunction({
|
|
|
+ task: taskId,
|
|
|
+ [`${ dateTypeKey }_end_date`]: dateMap[dateTypeKey],
|
|
|
+ });
|
|
|
+ if (dateType === 'week') {
|
|
|
+ ySalesData.value = resp.data;
|
|
|
+ } else {
|
|
|
+ ySalesData.value = resp.data[0];
|
|
|
+ }
|
|
|
+ return ySalesData.value;
|
|
|
+}
|
|
|
+
|
|
|
+async function daySalesTip() {
|
|
|
+ await salesTip(getDayBeforeData, 'day');
|
|
|
+}
|
|
|
+
|
|
|
+async function weekSalesTip() {
|
|
|
+ await salesTip(getWeekBeforeData, 'week');
|
|
|
+}
|
|
|
+
|
|
|
+async function monthSalesTip() {
|
|
|
+ await salesTip(getMonthBeforeData, 'month');
|
|
|
+}
|
|
|
+
|
|
|
+async function currentSalesTip() {
|
|
|
+ if (dateType === 'week') {
|
|
|
+ await weekSalesTip();
|
|
|
+ } else if (dateType === 'month') {
|
|
|
+ await monthSalesTip();
|
|
|
+ } else {
|
|
|
+ await daySalesTip();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
const currentGridOptions = computed(() => {
|
|
|
const selectedGridOptions = gridOptions[dateType] || gridOptions['day'];
|
|
|
return {
|
|
@@ -749,6 +821,27 @@ const headerCellStyle = () => {
|
|
|
};
|
|
|
};
|
|
|
|
|
|
+const validateForm = () => {
|
|
|
+ const fieldsToWarn = [];
|
|
|
+ const fieldsToValidate = ['sales_original', 'total_sales_current_monthly_original'];
|
|
|
+ if (ySalesData.value) {
|
|
|
+ for (const key of fieldsToValidate) {
|
|
|
+ const newValue = taskDataForm[key];
|
|
|
+ const yDayValue = ySalesData.value[key];
|
|
|
+ const column = flatWeekColumns.value.find(col => col.field === key);
|
|
|
+ const title = column ? column.title : key;
|
|
|
+
|
|
|
+ if (newValue != null && yDayValue !== null && yDayValue !== undefined) {
|
|
|
+ const diffPercentage = Math.abs((newValue - yDayValue) / yDayValue) * 100;
|
|
|
+ if (diffPercentage > 50) {
|
|
|
+ fieldsToWarn.push(title);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return fieldsToWarn;
|
|
|
+};
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
setDefaultDate();
|
|
|
//fetchCurrentTaskData();
|
|
@@ -769,9 +862,9 @@ onMounted(() => {
|
|
|
:clearable="false"
|
|
|
:disabled-date="disabledDate"
|
|
|
:shortcuts="shortcuts"
|
|
|
+ style="width: 170px"
|
|
|
type="Date"
|
|
|
@change="handleDayChange"
|
|
|
- style="width: 170px"
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -838,6 +931,9 @@ onMounted(() => {
|
|
|
@click="editEvent(row)">创建
|
|
|
</el-button>
|
|
|
</template>
|
|
|
+ <template #total_header="{ row }">
|
|
|
+ <span>当月截止{{ entryEndDate }}销售额</span>
|
|
|
+ </template>
|
|
|
<template #sales_original_edit="{ row }">
|
|
|
<vxe-input v-model="row.sales_original"></vxe-input>
|
|
|
</template>
|
|
@@ -925,8 +1021,8 @@ onMounted(() => {
|
|
|
<div class="dialog-footer">
|
|
|
<el-button @click="dayFormVisible = false ;resetForm(taskDataFormRef)">取消</el-button>
|
|
|
<el-button
|
|
|
- type="primary"
|
|
|
:disabled="isSubmitting"
|
|
|
+ type="primary"
|
|
|
@click="submitForm(taskDataFormRef)"
|
|
|
>
|
|
|
{{ isSubmitting ? '提交中...' : '确认' }}
|
|
@@ -934,6 +1030,31 @@ onMounted(() => {
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-dialog>
|
|
|
+ <el-dialog
|
|
|
+ v-model="dialogVisible"
|
|
|
+ align-center
|
|
|
+ style="border-radius: 10px;"
|
|
|
+ title="重要提示"
|
|
|
+ width="30%"
|
|
|
+ >
|
|
|
+ <template #title>
|
|
|
+ <el-button link style="font-size: 18px" type="warning">
|
|
|
+ <el-icon size="22px">
|
|
|
+ <warning />
|
|
|
+ </el-icon>
|
|
|
+ 重要提示
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ <span>您输入的 </span>
|
|
|
+ <span style="color: #f1a055;">{{ dialogMessage }}</span>
|
|
|
+ <span> 相较于上次填入的数据偏离值超过 50% ,是否仍要提交?</span>
|
|
|
+ <template #footer>
|
|
|
+ <span class="dialog-footer">
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="submit(formEl)">确认</el-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
</template>
|
|
|
|
|
|
<style lang="scss" scoped>
|