提交 77b36d9a authored 作者: lidongxu's avatar lidongxu

refactor(promotion/display_schedule): 修改:链路中心PC_AP 执行上报:把计划信息放在实际填报信息上面辅助参考

上级 8a4a00d6
...@@ -238,7 +238,9 @@ function initTreeData() { ...@@ -238,7 +238,9 @@ function initTreeData() {
} }
} }
watch(() => props.columns, () => { watch(() => props.columns, () => {
initTreeData(); if (props.showColumnsType === 'tree') {
initTreeData();
}
}) })
// 再添加一个watcher来监听showColumnsType变化 // 再添加一个watcher来监听showColumnsType变化
watch( watch(
......
...@@ -69,7 +69,7 @@ import VConsole from 'vconsole' ...@@ -69,7 +69,7 @@ import VConsole from 'vconsole'
// 创建vConsole实例 // 创建vConsole实例
// 生产环境不加载 // 生产环境不加载
if (import.meta.env.VITE_APP_ENV !== 'production') { if (import.meta.env.VITE_APP_ENV === 'staging') {
new VConsole() new VConsole()
} }
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
<div class="app-container"> <div class="app-container">
<div class="container"> <div class="container">
<el-tabs v-model="activeName" <el-tabs v-model="activeName"
type="card"
class="demo-tabs" class="demo-tabs"
@tab-click="handleClickTabs"> @tab-click="handleClickTabs">
<el-tab-pane label="陈列计划" <el-tab-pane label="陈列计划"
...@@ -21,7 +20,7 @@ ...@@ -21,7 +20,7 @@
<script setup> <script setup>
import Display from './tabs/display.vue' import Display from './tabs/display.vue'
import Schedule from './tabs/schedule.vue' import Schedule from './tabs/schedule.vue'
const activeName = ref('陈列计划'); const activeName = ref('档期计划');
const handleClickTabs = (tab) => { const handleClickTabs = (tab) => {
activeName.value = tab.name; activeName.value = tab.name;
} }
......
...@@ -18,73 +18,79 @@ ...@@ -18,73 +18,79 @@
</el-row> </el-row>
<!-- 筛选列组的按钮 --> <!-- 筛选列组的按钮 -->
<el-table :data="tableData" <el-table :data="tableData"
height="100%"
border border
:scroll-x="'max-content'" ref="tableRef"
class="auto-fit-header-table" class="auto-fit-header-table"
fit
v-loading="isLoading"> v-loading="isLoading">
<el-table-column v-for="col in tableColumns" <template v-for="col in tableColumns">
:label="col.label" <el-table-column v-if="col.visible"
align="center" :label="col.label"
:min-width="getColumnMinWidth(col)" :key="col.prop"
show-overflow-tooltip> align="center"
<template #header="{ column }"> :show-overflow-tooltip="col.type === 'string'"
<!-- 只为特定列添加问号图标 --> class-name="column-style"
<span class="formula-column"> :width="getColumnMinWidth(col)">
{{ column.label }} <template #header="{ column }">
<el-tooltip v-if="col.type === 'formula'" <!-- 只为特定列添加问号图标 -->
:content="col.formulaStr" <span class="formula-column">
placement="top"> {{ column.label }}
<el-icon><question-filled /></el-icon> <el-tooltip v-if="col.type === 'formula'"
</el-tooltip> :content="col.formulaStr"
</span> placement="top">
</template> <el-icon><question-filled /></el-icon>
<template #default="{ row }"> </el-tooltip>
<div v-if="col.type === 'select'"> </span>
<!-- 实际主货架-数量(要根据实际主货架-形式不为空时才可以选择否则为 0) --> </template>
<div v-if="col.prop === 'actualMainShelfQty'"> <template #default="{ row }">
<el-select :disabled="!row.actualMainShelfType" <div v-if="col.type === 'select'"
v-model="row[col.prop]" class="cell-style">
placeholder="请选择" <!-- 实际主货架-数量(要根据实际主货架-形式不为空时才可以选择否则为 0) -->
clearable <div v-if="col.prop === 'actualMainShelfQty'">
@change="submitChange(row, col)"> <span>{{ row[col.referenceKey] }}</span>
<el-option v-for="item in col.options" <el-select :disabled="!row.actualMainShelfType"
:key="item.value" v-model="row[col.prop]"
:label="item.label" placeholder="请选择"
:value="item.value" /> clearable
</el-select> @change="submitChange(row, col)">
<el-option v-for="item in col.options"
:key="item.value"
:label="item.label"
:value="item.value" />
</el-select>
</div>
<div v-else>
<span>{{ row[col.referenceKey] }}</span>
<el-select v-model="row[col.prop]"
placeholder="请选择"
clearable
@change="submitChange(row, col)">
<el-option v-for="item in col.options"
:key="item.value"
:label="item.label"
:value="item.value" />
</el-select>
</div>
</div> </div>
<el-select v-else <!-- 公式计算 -->
v-model="row[col.prop]" <div v-else-if="col.type === 'formula'">
placeholder="请选择" {{ col.func(row) }}
clearable
@change="submitChange(row, col)">
<el-option v-for="item in col.options"
:key="item.value"
:label="item.label"
:value="item.value" />
</el-select>
</div>
<!-- 公式计算 -->
<div v-else-if="col.type === 'formula'">
{{ col.func(row) }}
</div>
<!-- 输入框 -->
<div v-else-if="col.type === 'input'">
<el-input v-model="row[col.prop]"
placeholder="请输入"
@input="submitChange(row, col)" />
</div>
<!-- 为其他类型或未定义类型提供默认显示 -->
<div v-else>
<div class="ellipsis-text"
style="max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
{{ formatterTableData(row, col) }}
</div> </div>
</div> <!-- 输入框 -->
</template> <div v-else-if="col.type === 'input'">
</el-table-column> <el-input v-model="row[col.prop]"
placeholder="请输入"
@input="submitChange(row, col)" />
</div>
<!-- 为其他类型或未定义类型提供默认显示 -->
<div v-else>
<div class="ellipsis-text"
style="max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
{{ formatterTableData(row, col) }}
</div>
</div>
</template>
</el-table-column>
</template>
</el-table> </el-table>
<!-- 分页 --> <!-- 分页 -->
<pagination :total="total" <pagination :total="total"
...@@ -96,46 +102,42 @@ ...@@ -96,46 +102,42 @@
<script setup> <script setup>
import { getDisplayList, submitDisplayPlan } from '@/api' import { getDisplayList, submitDisplayPlan } from '@/api'
import { parseTime } from '@/utils' import { parseTime } from '@/utils'
import { onMounted } from 'vue';
const activeName = ref('陈列计划');
const handleClickTabs = (tab) => {
activeName.value = tab.name;
}
/*************** 操作类型 ***************/ /*************** 操作类型 ***************/
const operation = ref('全部列'); const operation = ref('全部列');
const tableRef = ref(null)
// 全部列 // 全部列
const baseColumns = ref([ const baseColumns = ref([
{ {
label: "基础信息", label: "基础信息",
children: [ children: [
{ label: "销售大区", prop: "regionName", visible: true, type: 'string' }, { label: "销售大区", prop: "regionName", visible: true, type: 'string', fill: false },
{ label: "销售战区", prop: "districtName", visible: true, type: 'string' }, { label: "销售战区", prop: "districtName", visible: true, type: 'string', fill: false },
{ label: "经销商-省份", prop: "dealerProvince", visible: true, type: 'string' }, { label: "经销商-省份", prop: "dealerProvince", visible: true, type: 'string', fill: false },
{ label: "经销商-城市", prop: "dealerCity", visible: true, type: 'string' }, { label: "经销商-城市", prop: "dealerCity", visible: true, type: 'string', fill: false },
{ label: "经销商-代码", prop: "dealerCode", visible: true, type: 'string' }, { label: "经销商-代码", prop: "dealerCode", visible: true, type: 'string', fill: false },
{ label: "经销商名称", prop: "dealerName", visible: true, type: 'string' }, { label: "经销商名称", prop: "dealerName", visible: true, type: 'string', fill: false },
{ label: "经销商-类型", prop: "dealerType", visible: true, type: 'string' }, { label: "经销商-类型", prop: "dealerType", visible: true, type: 'string', fill: false },
{ label: "开户日期", prop: "openingDate", visible: true, type: 'string' }, { label: "开户日期", prop: "openingDate", visible: true, type: 'string', fill: false },
{ label: "闭户日期", prop: "closingDate", visible: true, type: 'string' }, { label: "闭户日期", prop: "closingDate", visible: true, type: 'string', fill: false },
{ label: "大区总监", prop: "regionManager", visible: true, type: 'string' }, { label: "大区总监", prop: "regionManager", visible: true, type: 'string', fill: false },
{ label: "战区经理", prop: "districtManager", visible: true, type: 'string' }, { label: "战区经理", prop: "districtManager", visible: true, type: 'string', fill: false },
{ label: "城市经理", prop: "cityManager", visible: true, type: 'string' }, { label: "城市经理", prop: "cityManager", visible: true, type: 'string', fill: false },
{ label: "门店编码", prop: "storeCode", visible: true, type: 'string' }, { label: "门店编码", prop: "storeCode", visible: true, type: 'string', fill: true },
{ label: "门店名称", prop: "storeName", visible: true, type: 'string' }, { label: "门店名称", prop: "storeName", visible: true, type: 'string', fill: true },
{ label: "门店-省份", prop: "storeProvince", visible: true, type: 'string' }, { label: "门店-省份", prop: "storeProvince", visible: true, type: 'string', fill: false },
{ label: "门店-城市", prop: "storeCity", visible: true, type: 'string' }, { label: "门店-城市", prop: "storeCity", visible: true, type: 'string', fill: false },
{ label: "系统名称", prop: "lineName", visible: true, type: 'string' }, { label: "系统名称", prop: "lineName", visible: true, type: 'string', fill: true },
{ label: "系统类型", prop: "lineType", visible: true, type: 'string' }, { label: "系统类型", prop: "lineType", visible: true, type: 'string', fill: false },
{ label: "渠道大类", prop: "channelDl", visible: true, type: 'string' }, { label: "渠道大类", prop: "channelDl", visible: true, type: 'string', fill: false },
{ label: "渠道小类", prop: "channelXl", visible: true, type: 'string' }, { label: "渠道小类", prop: "channelXl", visible: true, type: 'string', fill: false },
{ label: "门店类型", prop: "storeType", visible: true, type: 'string' }, { label: "门店类型", prop: "storeType", visible: true, type: 'string', fill: false },
{ label: "系统业态", prop: "systemFormat", visible: true, type: 'string' }, { label: "系统业态", prop: "systemFormat", visible: true, type: 'string', fill: false },
{ label: "门店面积", prop: "storeArea", visible: true, type: 'string' }, { label: "门店面积", prop: "storeArea", visible: true, type: 'string', fill: false },
{ label: "门店分级(销量坎级)", prop: "storeLevel", visible: true, type: 'string' }, { label: "门店分级(销量坎级)", prop: "storeLevel", visible: true, type: 'string', fill: false },
{ label: "门店地址", prop: "storeAddress", visible: true, type: 'string' }, { label: "门店地址", prop: "storeAddress", visible: true, type: 'string', fill: false },
{ label: "品项数", prop: "productCount", visible: true, type: 'string' } { label: "品项数", prop: "productCount", visible: true, type: 'string', fill: false }
], ],
prop: 'baseColumns', prop: 'baseColumns',
visible: true visible: true
...@@ -143,8 +145,8 @@ const baseColumns = ref([ ...@@ -143,8 +145,8 @@ const baseColumns = ref([
{ {
label: "大业态测试", label: "大业态测试",
children: [ children: [
{ label: "大业态测试-动销模型", prop: "lfSalesModel", visible: true, type: 'string' }, { label: "大业态测试-动销模型", prop: "lfSalesModel", visible: true, type: 'string', fill: false },
{ label: "大业态测试-月均POS", prop: "lfMonthlyPos", visible: true, type: 'string' }, { label: "大业态测试-月均POS", prop: "lfMonthlyPos", visible: true, type: 'string', fill: false },
], ],
prop: 'lfColumns', prop: 'lfColumns',
visible: true visible: true
...@@ -153,10 +155,10 @@ const baseColumns = ref([ ...@@ -153,10 +155,10 @@ const baseColumns = ref([
label: "费用计划", label: "费用计划",
prop: 'fpColumns', prop: 'fpColumns',
children: [ children: [
{ label: "计划主货架-形式", prop: "plannedMainShelfType", visible: true, type: 'string' }, // { label: "计划主货架-形式", prop: "plannedMainShelfType", visible: true, type: 'string' },
{ label: "计划主货架-数量", prop: "plannedMainShelfQty", visible: true, type: 'string' }, // { label: "计划主货架-数量", prop: "plannedMainShelfQty", visible: true, type: 'string' },
{ label: "计划主货架-单个费用", prop: "plannedMainShelfUnitCost", visible: true, type: 'string' }, { label: "计划主货架-单个费用", prop: "plannedMainShelfUnitCost", visible: true, type: 'string', fill: false },
{ label: "计划主货架-总费用", prop: "plannedMainShelfTotalCost", visible: true, type: 'string' }, { label: "计划主货架-总费用", prop: "plannedMainShelfTotalCost", visible: true, type: 'string', fill: false },
{ {
label: "实际主货架-形式", label: "实际主货架-形式",
prop: "actualMainShelfType", prop: "actualMainShelfType",
...@@ -168,7 +170,9 @@ const baseColumns = ref([ ...@@ -168,7 +170,9 @@ const baseColumns = ref([
{ label: '6纵', value: '6纵' }, { label: '6纵', value: '6纵' },
{ label: '7纵', value: '7纵' }, { label: '7纵', value: '7纵' },
{ label: '8纵及以上', value: '8纵及以上' } { label: '8纵及以上', value: '8纵及以上' }
] ],
referenceKey: "plannedMainShelfType",
fill: true
}, },
{ {
label: "实际主货架-数量", label: "实际主货架-数量",
...@@ -178,7 +182,9 @@ const baseColumns = ref([ ...@@ -178,7 +182,9 @@ const baseColumns = ref([
options: [ options: [
{ label: '1', value: 1 }, { label: '1', value: 1 },
{ label: '2', value: 2 } { label: '2', value: 2 }
] ],
referenceKey: "plannedMainShelfQty",
fill: true
}, },
{ {
label: "实际主货架-是否执行", label: "实际主货架-是否执行",
...@@ -190,10 +196,20 @@ const baseColumns = ref([ ...@@ -190,10 +196,20 @@ const baseColumns = ref([
return row.actualMainShelfExecuted; return row.actualMainShelfExecuted;
}, },
formulaStr: '公式:(实际主货架形式 >= 计划主货架形式)并且(实际主货架数量 >= 计划主货架数量)', formulaStr: '公式:(实际主货架形式 >= 计划主货架形式)并且(实际主货架数量 >= 计划主货架数量)',
fill: true
},
// {
// label: "计划端架-数量", prop: "plannedEndCapQty", visible: true, type: 'string',
// fill: true
// },
{
label: "计划端架-总费用", prop: "plannedEndCapTotalCost", visible: true, type: 'string',
fill: false
},
{
label: "计划端架-单个费用", prop: "plannedEndCapUnitCost", visible: true, type: 'string',
fill: false
}, },
{ label: "计划端架-数量", prop: "plannedEndCapQty", visible: true },
{ label: "计划端架-总费用", prop: "plannedEndCapTotalCost", visible: true },
{ label: "计划端架-单个费用", prop: "plannedEndCapUnitCost", visible: true },
{ {
label: "实际端架-数量", label: "实际端架-数量",
prop: "actualEndCapQty", prop: "actualEndCapQty",
...@@ -204,7 +220,9 @@ const baseColumns = ref([ ...@@ -204,7 +220,9 @@ const baseColumns = ref([
{ label: '0.5', value: 0.5 }, { label: '0.5', value: 0.5 },
{ label: '1', value: 1 }, { label: '1', value: 1 },
{ label: '2', value: 2 } { label: '2', value: 2 }
] ],
referenceKey: "plannedEndCapQty",
fill: true
}, },
{ {
label: "实际端架-是否执行", label: "实际端架-是否执行",
...@@ -216,16 +234,31 @@ const baseColumns = ref([ ...@@ -216,16 +234,31 @@ const baseColumns = ref([
return row.actualEndCapExecuted; return row.actualEndCapExecuted;
}, },
formulaStr: '公式:(实际端架数量 >= 计划端架数量)', formulaStr: '公式:(实际端架数量 >= 计划端架数量)',
fill: true
}, },
{ {
label: "计划地堆-平米数(㎡)", label: "计划地堆-平米数(㎡)",
prop: "plannedFloorStackArea", prop: "plannedFloorStackArea",
visible: true visible: true,
type: 'string',
fill: true
},
{
label: "计划地堆-数量", prop: "plannedFloorStackQty", visible: true, type: 'string',
fill: true
},
{
label: "计划主题地堆-是否", prop: "plannedThemedFloorStack", visible: true, type: 'string',
fill: true
},
{
label: "计划地堆-总费用", prop: "plannedFloorStackTotalCost", visible: true, type: 'string',
fill: false
},
{
label: "计划折算1㎡-单个费用", prop: "plannedFloorStackUnitCostPerSqm", visible: true, type: 'string',
fill: false
}, },
{ label: "计划地堆-数量", prop: "plannedFloorStackQty", visible: true },
{ label: "计划主题地堆-是否", prop: "plannedThemedFloorStack", visible: true },
{ label: "计划地堆-总费用", prop: "plannedFloorStackTotalCost", visible: true },
{ label: "计划折算1㎡-单个费用", prop: "plannedFloorStackUnitCostPerSqm", visible: true },
{ {
label: "实际地堆-平米数(㎡)", label: "实际地堆-平米数(㎡)",
prop: "actualFloorStackArea", prop: "actualFloorStackArea",
...@@ -239,7 +272,9 @@ const baseColumns = ref([ ...@@ -239,7 +272,9 @@ const baseColumns = ref([
{ label: '2', value: 2 }, { label: '2', value: 2 },
{ label: '3', value: 3 }, { label: '3', value: 3 },
{ label: '4', value: 4 }, { label: '4', value: 4 },
] ],
referenceKey: "plannedFloorStackArea",
fill: true
}, },
{ {
label: "实际地堆-数量", label: "实际地堆-数量",
...@@ -251,7 +286,9 @@ const baseColumns = ref([ ...@@ -251,7 +286,9 @@ const baseColumns = ref([
{ label: '1', value: 1 }, { label: '1', value: 1 },
{ label: '2', value: 2 }, { label: '2', value: 2 },
{ label: '3', value: 3 } { label: '3', value: 3 }
] ],
referenceKey: "plannedFloorStackQty",
fill: true
}, },
{ {
label: "实际主题地堆-是否", label: "实际主题地堆-是否",
...@@ -261,7 +298,9 @@ const baseColumns = ref([ ...@@ -261,7 +298,9 @@ const baseColumns = ref([
options: [ options: [
{ label: '是', value: '是' }, { label: '是', value: '是' },
{ label: '否', value: '否' }, { label: '否', value: '否' },
] ],
referenceKey: "plannedThemedFloorStack",
fill: true
}, },
{ {
label: "实际地堆是否执行", label: "实际地堆是否执行",
...@@ -273,9 +312,16 @@ const baseColumns = ref([ ...@@ -273,9 +312,16 @@ const baseColumns = ref([
return row.actualFloorStackExecuted; return row.actualFloorStackExecuted;
}, },
formulaStr: '公式:(实际地堆平米数 >= 计划地堆平米数)并且(实际地堆数量 >= 计划地堆数量)', formulaStr: '公式:(实际地堆平米数 >= 计划地堆平米数)并且(实际地堆数量 >= 计划地堆数量)',
fill: true
},
{
label: "计划多点陈列-数量+形式", prop: "plannedMultiDisplay", visible: true, type: 'string',
fill: true
},
{
label: "计划多点陈列-总费用", prop: "plannedMultiDisplayTotalCost", visible: true, type: 'string',
fill: false
}, },
{ label: "计划多点陈列-数量+形式", prop: "plannedMultiDisplay", visible: true },
{ label: "计划多点陈列-总费用", prop: "plannedMultiDisplayTotalCost", visible: true },
{ {
label: "实际多点陈列-数量+形式", label: "实际多点陈列-数量+形式",
prop: "actualMultiDisplay", prop: "actualMultiDisplay",
...@@ -284,7 +330,9 @@ const baseColumns = ref([ ...@@ -284,7 +330,9 @@ const baseColumns = ref([
func: (row) => { func: (row) => {
// 没有输入内容时,则是否执行设置为否 // 没有输入内容时,则是否执行设置为否
row.actualMultiDisplayExecuted = !row.actualMultiDisplay ? '否' : '是' row.actualMultiDisplayExecuted = !row.actualMultiDisplay ? '否' : '是'
} },
referenceKey: "plannedMultiDisplay",
fill: true
}, },
{ {
label: "实际多点陈列-是否执行", label: "实际多点陈列-是否执行",
...@@ -294,10 +342,17 @@ const baseColumns = ref([ ...@@ -294,10 +342,17 @@ const baseColumns = ref([
options: [ options: [
{ label: '是', value: '是' }, { label: '是', value: '是' },
{ label: '否', value: '否' }, { label: '否', value: '否' },
] ],
fill: true
},
{
label: "合计费用-费用", prop: "totalCost", visible: true, type: 'string',
fill: false
},
{
label: "合计费用-费率", prop: "totalCostRate", visible: true, type: 'string',
fill: false
}, },
{ label: "合计费用-费用", prop: "totalCost", visible: true },
{ label: "合计费用-费率", prop: "totalCostRate", visible: true },
{ {
label: "常规陈列是否执行", label: "常规陈列是否执行",
prop: "regularDisplayExecuted", prop: "regularDisplayExecuted",
...@@ -307,178 +362,30 @@ const baseColumns = ref([ ...@@ -307,178 +362,30 @@ const baseColumns = ref([
// 实际主货架-是否执行 && 实际端架-是否执行 && 实际地堆-是否执行 && 实际多点陈列-是否执行 // 实际主货架-是否执行 && 实际端架-是否执行 && 实际地堆-是否执行 && 实际多点陈列-是否执行
row.regularDisplayExecuted = (row.actualMainShelfExecuted === '是' && row.actualEndCapExecuted === '是' && row.actualFloorStackExecuted === '是' && row.actualMultiDisplayExecuted === '是') ? '是' : '否'; row.regularDisplayExecuted = (row.actualMainShelfExecuted === '是' && row.actualEndCapExecuted === '是' && row.actualFloorStackExecuted === '是' && row.actualMultiDisplayExecuted === '是') ? '是' : '否';
return row.regularDisplayExecuted; return row.regularDisplayExecuted;
} },
fill: true
},
{
label: "综合标签-拜访辅助列", prop: "visitAssistTag", visible: true, type: 'string',
fill: false
}, },
{ label: "综合标签-拜访辅助列", prop: "visitAssistTag", visible: true }, {
{ label: "付费陈列- 是否", prop: "paidDisplay", visible: true }, label: "付费陈列- 是否", prop: "paidDisplay", visible: true, type: 'string',
{ label: "当月拜访目标", prop: "monthlyVisitTarget", visible: true }, fill: false
{ label: "当月是否拜访", prop: "monthlyVisited", visible: true } },
{
label: "当月拜访目标", prop: "monthlyVisitTarget", visible: true, type: 'string',
fill: false
},
{
label: "当月是否拜访", prop: "monthlyVisited", visible: true, type: 'string',
fill: false
}
], ],
visible: true visible: true
} }
// ...baseColumns.value,
// ...lfColumns.value,
// ...fpColumns.value
]); ]);
// 填报列 // 表格列
const fillColumns = ref([
{ label: "系统名称", prop: "lineName", visible: true, type: 'string' },
{ label: "门店编码", prop: "storeCode", visible: true },
{ label: "门店名称", prop: "storeName", visible: true },
{ label: "计划主货架-形式", prop: "plannedMainShelfType", visible: true, type: 'string' },
{ label: "计划主货架-数量", prop: "plannedMainShelfQty", visible: true, type: 'string' },
{
label: "实际主货架-形式",
prop: "actualMainShelfType",
visible: true,
type: 'select',
options: [
{ label: '4纵', value: '4纵' },
{ label: '5纵', value: '5纵' },
{ label: '6纵', value: '6纵' },
{ label: '7纵', value: '7纵' },
{ label: '8纵及以上', value: '8纵及以上' }
]
},
{
label: "实际主货架-数量",
prop: "actualMainShelfQty",
visible: true,
type: 'select',
options: [
{ label: '1', value: 1 },
{ label: '2', value: 2 }
]
},
{
label: "实际主货架-是否执行",
prop: "actualMainShelfExecuted",
visible: true,
type: 'formula', // 公式
func: (row) => {
row.actualMainShelfExecuted = ((parseInt(row.actualMainShelfType) >= parseInt(row.plannedMainShelfType)) && (parseInt(row.actualMainShelfQty) >= parseInt(row.plannedMainShelfQty))) ? '是' : '否';
return row.actualMainShelfExecuted;
},
formulaStr: '公式:(实际主货架形式 >= 计划主货架形式)并且(实际主货架数量 >= 计划主货架数量)',
},
{ label: "计划端架-数量", prop: "plannedEndCapQty", visible: true },
{
label: "实际端架-数量",
prop: "actualEndCapQty",
visible: true,
type: 'select',
options: [
{ label: '0', value: 0 },
{ label: '0.5', value: 0.5 },
{ label: '1', value: 1 },
{ label: '2', value: 2 }
]
},
{
label: "实际端架-是否执行",
prop: "actualEndCapExecuted",
visible: true,
type: 'formula', // 公式
func: (row) => {
row.actualEndCapExecuted = ((parseFloat(row.actualEndCapQty) >= parseFloat(row.plannedEndCapQty))) ? '是' : '否';
return row.actualEndCapExecuted;
},
formulaStr: '公式:(实际端架数量 >= 计划端架数量)',
},
{
label: "计划地堆-平米数(㎡)",
prop: "plannedFloorStackArea",
visible: true
},
{ label: "计划地堆-数量", prop: "plannedFloorStackQty", visible: true },
{ label: "计划主题地堆-是否", prop: "plannedThemedFloorStack", visible: true },
{
label: "实际地堆-平米数(㎡)",
prop: "actualFloorStackArea",
visible: true,
type: 'select',
options: [
{ label: '0', value: 0 },
{ label: '0.5', value: 0.5 },
{ label: '0.8', value: 0.8 },
{ label: '1', value: 1 },
{ label: '2', value: 2 },
{ label: '3', value: 3 },
{ label: '4', value: 4 },
]
},
{
label: "实际地堆-数量",
prop: "actualFloorStackQty",
visible: true,
type: 'select',
options: [
{ label: '0', value: 0 },
{ label: '1', value: 1 },
{ label: '2', value: 2 },
{ label: '3', value: 3 }
]
},
{
label: "实际主题地堆-是否",
prop: "actualThemedFloorStack",
visible: true,
type: 'select',
options: [
{ label: '是', value: '是' },
{ label: '否', value: '否' },
]
},
{
label: "实际地堆是否执行",
prop: "actualFloorStackExecuted",
visible: true,
type: 'formula', // 公式
func: (row) => {
row.actualFloorStackExecuted = ((parseFloat(row.actualFloorStackArea) >= parseFloat(row.plannedFloorStackArea)) && (parseInt(row.actualFloorStackQty) >= parseInt(row.plannedFloorStackQty))) ? '是' : '否';
return row.actualFloorStackExecuted;
},
formulaStr: '公式:(实际地堆平米数 >= 计划地堆平米数)并且(实际地堆数量 >= 计划地堆数量)',
},
{ label: "计划多点陈列-数量+形式", prop: "plannedMultiDisplay", visible: true },
{ label: "计划多点陈列-总费用", prop: "plannedMultiDisplayTotalCost", visible: true },
{
label: "实际多点陈列-数量+形式",
prop: "actualMultiDisplay",
visible: true,
type: 'input',
func: (row) => {
// 没有输入内容时,则是否执行设置为否
row.actualMultiDisplayExecuted = !row.actualMultiDisplay ? '否' : '是'
}
},
{
label: "实际多点陈列-是否执行",
prop: "actualMultiDisplayExecuted",
visible: true,
type: 'select',
options: [
{ label: '是', value: '是' },
{ label: '否', value: '否' },
]
},
{ label: "合计费用-费用", prop: "totalCost", visible: true },
{ label: "合计费用-费率", prop: "totalCostRate", visible: true },
{
label: "常规陈列是否执行",
prop: "regularDisplayExecuted",
visible: true,
type: 'formula', // 公式
func: (row) => {
// 实际主货架-是否执行 && 实际端架-是否执行 && 实际地堆-是否执行 && 实际多点陈列-是否执行
row.regularDisplayExecuted = (row.actualMainShelfExecuted === '是' && row.actualEndCapExecuted === '是' && row.actualFloorStackExecuted === '是' && row.actualMultiDisplayExecuted === '是') ? '是' : '否';
return row.regularDisplayExecuted;
},
formulaStr: '公式:(实际主货架是否执行 = 是)并且(实际端架是否执行 = 是)并且(实际地堆是否执行 = 是)并且(实际多点陈列是否执行 = 是)',
}
])
// 表格列数据
const tableColumns = ref([]) const tableColumns = ref([])
// 右上角工具选择列 // 右上角工具选择列
const chooseColumns = ref([]) const chooseColumns = ref([])
...@@ -488,37 +395,42 @@ const checkTableColumns = () => { ...@@ -488,37 +395,42 @@ const checkTableColumns = () => {
chooseColumns.value = baseColumns.value chooseColumns.value = baseColumns.value
tableColumns.value = baseColumns.value.flatMap(item => { tableColumns.value = baseColumns.value.flatMap(item => {
if (item.children) { if (item.children) {
// 在扁平化时就过滤掉 visible 为 false 的列 return item.children.filter(child => child);
return item.children.filter(child => child.visible);
} }
// 如果是没有 children 的单元素,也检查其 visible 属性 return [];
return item.visible ? item : []; });
}).filter(Boolean); // 过滤掉空数组项
} else if (operation.value === '填报列') { } else if (operation.value === '填报列') {
chooseColumns.value = fillColumns.value chooseColumns.value = baseColumns.value.flatMap(item => {
tableColumns.value = fillColumns.value.filter(item => item.visible); if (item.children) {
return item.children
.filter(child => child.fill)
}
return [];
});
tableColumns.value = chooseColumns.value
} }
// 强制表格立即应用所有宽度设置,避免先自适应再调整
nextTick(() => {
if (tableRef.value) {
tableRef.value.doLayout()
}
})
} }
checkTableColumns()
// 选择列默认选中哪些 onMounted(() => {
checkTableColumns()
})
// 树形结构选择列默认有哪些
const visibleProps = computed(() => { const visibleProps = computed(() => {
// 分情况返回 return baseColumns.value.flatMap(item => {
return tableColumns.value.flatMap(item => {
if (item.children) { if (item.children) {
return item.children.map(child => child.prop); return item.children.filter(child => child.visible).map(child => child.prop);
} }
return item.prop; return item.prop;
}); });
}); });
// 监听chooseColumns变化,当列的visible属性改变时重新计算tableColumns
watch(
() => chooseColumns.value,
() => {
// 不需要重新赋值,只需要重新计算tableColumns
checkTableColumns();
},
{ deep: true }
);
// 提交变更 // 提交变更
const submitChange = async (row, col) => { const submitChange = async (row, col) => {
...@@ -598,7 +510,7 @@ const getColumnMinWidth = (column) => { ...@@ -598,7 +510,7 @@ const getColumnMinWidth = (column) => {
'districtManager': 85, 'districtManager': 85,
'cityManager': 85, 'cityManager': 85,
'storeCode': 100, 'storeCode': 100,
'storeName': 120, 'storeName': 170,
'storeProvince': 85, 'storeProvince': 85,
'storeCity': 85, 'storeCity': 85,
'lineName': 85, 'lineName': 85,
...@@ -617,7 +529,7 @@ const getColumnMinWidth = (column) => { ...@@ -617,7 +529,7 @@ const getColumnMinWidth = (column) => {
'plannedMainShelfQty': 125, 'plannedMainShelfQty': 125,
'plannedMainShelfUnitCost': 150, 'plannedMainShelfUnitCost': 150,
'plannedMainShelfTotalCost': 140, 'plannedMainShelfTotalCost': 140,
'actualMainShelfType': 125, 'actualMainShelfType': 135,
'actualMainShelfQty': 125, 'actualMainShelfQty': 125,
'actualMainShelfExecuted': 165, 'actualMainShelfExecuted': 165,
'plannedEndCapQty': 110, 'plannedEndCapQty': 110,
...@@ -647,7 +559,7 @@ const getColumnMinWidth = (column) => { ...@@ -647,7 +559,7 @@ const getColumnMinWidth = (column) => {
'monthlyVisited': 105 'monthlyVisited': 105
}; };
return widthMap[column.prop]; // 默认宽度 return widthMap[column.prop] || 100; // 默认宽度
}; };
// 格式化函数 // 格式化函数
...@@ -700,37 +612,50 @@ const formatterTableData = (row, col) => { ...@@ -700,37 +612,50 @@ const formatterTableData = (row, col) => {
align-items: center; align-items: center;
} }
/* 表格区域 */
.auto-fit-header-table { .auto-fit-header-table {
width: 100%;
--el-table-header-cell-text-color: #333;
--el-table-header-cell-padding: 0 .4267rem;
/* 列头内边距(可调整) */
.el-table__header th.el-table__cell { /* 优化超长文本的显示效果 */
white-space: nowrap; .cell {
/* 禁止列头文本换行 */ /* padding: 0 .2133rem; */
text-overflow: clip;
/* 溢出不隐藏(若想隐藏用 ellipsis,但需配合 overflow: hidden) */
overflow: visible;
/* 允许内容撑满(避免文本被截断) */
} }
/* 保持原有的单元格样式,但优化内容显示 */ ::v-deep(.el-table__row) {
.el-table__body td.el-table__cell { .el-table__cell {
white-space: nowrap; padding: 0;
text-overflow: ellipsis; }
overflow: hidden;
} }
/* 优化超长文本的显示效果 */
.cell {
padding: 0 .2133rem;
}
/* 表格内下拉框 */ ::v-deep(.column-style) {
.el-select {
width: 100% !important; .cell-style {
margin: 0 -12px;
>div {
display: flex;
flex-direction: column;
align-items: flex-start;
>span {
text-align: left;
text-indent: 5px;
display: inline-block;
width: 100%;
background-color: #e1e2e6;
border-bottom: 1px solid #ebeef5;
}
}
/* 表格内下拉框 */
.el-select {
width: 100% !important;
padding: 10px;
}
}
} }
} }
} }
</style> </style>
\ No newline at end of file
...@@ -18,82 +18,101 @@ ...@@ -18,82 +18,101 @@
</el-row> </el-row>
<!-- 筛选列组的按钮 --> <!-- 筛选列组的按钮 -->
<el-table :data="tableData" <el-table :data="tableData"
height="100%"
border border
:scroll-x="'max-content'" ref="tableRef"
class="auto-fit-header-table" class="auto-fit-header-table"
fit
v-loading="isLoading"> v-loading="isLoading">
<el-table-column v-for="col in tableColumns" <template v-for="col in tableColumns">
:label="col.label" <el-table-column v-if="col.visible"
align="center" :label="col.label"
:min-width="getColumnMinWidth(col)" :key="col.prop"
show-overflow-tooltip> align="center"
<template #header="{ column }"> :show-overflow-tooltip="col.type === 'string'"
<!-- 只为特定列添加问号图标 --> class-name="column-style"
<span class="formula-column"> :width="getColumnMinWidth(col)">
{{ column.label }} <template #header="{ column }">
<el-tooltip v-if="col.type === 'formula'" <!-- 只为特定列添加问号图标 -->
:content="col.formulaStr" <span class="formula-column">
placement="top"> {{ column.label }}
<el-icon><question-filled /></el-icon> <el-tooltip v-if="col.type === 'formula'"
</el-tooltip> :content="col.formulaStr"
</span> placement="top">
</template> <el-icon><question-filled /></el-icon>
<template #default="{ row }"> </el-tooltip>
<div v-if="col.type === 'select'"> </span>
<!-- 实际主货架-数量(要根据实际主货架-形式不为空时才可以选择否则为 0) --> </template>
<div v-if="col.prop === 'actualMainShelfQty'"> <template #default="{ row }">
<el-select :disabled="!row.actualMainShelfType" <div v-if="col.type === 'select'"
v-model="row[col.prop]" class="cell-style">
placeholder="请选择" <div>
clearable <el-tooltip effect="dark"
@change="submitChange(row, col)"> :content="row[col.referenceKey]"
<el-option v-for="item in col.options" placement="top-start"
:key="item.value" :disabled="!isContentOverflow(col.referenceKey, row[col.referenceKey])">
:label="item.label" <span class="ellipsis-tooltip">{{ row[col.referenceKey] }}</span>
:value="item.value" /> </el-tooltip>
</el-select> <el-select v-model="row[col.prop]"
placeholder="请选择"
clearable
@change="submitChange(row, col)">
<el-option v-for="item in col.options"
:key="item.value"
:label="item.label"
:value="item.value" />
</el-select>
</div>
</div> </div>
<el-select v-else <!-- 公式计算 -->
v-model="row[col.prop]" <div v-else-if="col.type === 'formula'">
placeholder="请选择" {{ col.func(row) }}
clearable
@change="submitChange(row, col)">
<el-option v-for="item in col.options"
:key="item.value"
:label="item.label"
:value="item.value" />
</el-select>
</div>
<!-- 公式计算 -->
<div v-else-if="col.type === 'formula'">
{{ col.func(row) }}
</div>
<!-- 输入框 -->
<div v-else-if="col.type === 'input'">
<el-input v-model="row[col.prop]"
placeholder="请输入"
:type="col.format === 'number' ? 'number' : 'text'"
@input="submitChange(row, col)" />
</div>
<!-- 日期选择 -->
<div v-else-if="col.type === 'date'">
<el-date-picker v-model="row[col.prop]"
type="date"
:format="col.format"
placeholder="请选择日期"
@change="submitChange(row, col)" />
</div>
<!-- 为其他类型或未定义类型提供默认显示 -->
<div v-else>
<div class="ellipsis-text"
style="max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
{{ formatterTableData(row, col) }}
</div> </div>
</div> <!-- 输入框 -->
</template> <div v-else-if="col.type === 'input'"
</el-table-column> class="cell-style">
<div>
<el-tooltip effect="dark"
:content="row[col.referenceKey]"
placement="top-start"
:disabled="!isContentOverflow(col.referenceKey, row[col.referenceKey])">
<span class="ellipsis-tooltip">{{ row[col.referenceKey] }}</span>
</el-tooltip>
<el-input v-model="row[col.prop]"
placeholder="请输入"
:type="col.format === 'number' ? 'number' : 'text'"
@input="submitChange(row, col)" />
</div>
</div>
<!-- 日期选择 -->
<div v-else-if="col.type === 'date'"
class="cell-style">
<div>
<el-tooltip effect="dark"
:content="row[col.referenceKey]"
placement="top-start"
:disabled="!isContentOverflow(col.referenceKey, row[col.referenceKey])">
<span class="ellipsis-tooltip">{{ row[col.referenceKey] }}</span>
</el-tooltip>
<div class="date-picker">
<el-date-picker v-model="row[col.prop]"
type="date"
:format="col.format"
placeholder="请选择日期"
@change="submitChange(row, col)"
/>
</div>
</div>
</div>
<!-- 为其他类型或未定义类型提供默认显示 -->
<div v-else>
<div class="ellipsis-text"
style="max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
{{ row[col.prop] }}
</div>
</div>
</template>
</el-table-column>
</template>
</el-table> </el-table>
<!-- 分页 --> <!-- 分页 -->
<pagination :total="total" <pagination :total="total"
...@@ -108,30 +127,30 @@ import { parseTime } from '@/utils' ...@@ -108,30 +127,30 @@ import { parseTime } from '@/utils'
/*************** 操作类型 ***************/ /*************** 操作类型 ***************/
const operation = ref('全部列'); const operation = ref('全部列');
const tableRef = ref(null)
// 全部列 // 全部列
const baseColumns = ref([ const baseColumns = ref([
{ {
label: "基础信息", label: "基础信息",
children: [ children: [
{ "label": "销售大区", "prop": "regionName", visible: true }, { "label": "销售大区", "prop": "regionName", visible: true, type: "string", fill: false },
{ "label": "销售战区", "prop": "districtName", visible: true }, { "label": "销售战区", "prop": "districtName", visible: true, type: "string", fill: false },
{ "label": "经销商-省份", "prop": "dealerProvince", visible: true }, { "label": "经销商-省份", "prop": "dealerProvince", visible: true, type: "string", fill: false },
{ "label": "经销商-城市", "prop": "dealerCity", visible: true }, { "label": "经销商-城市", "prop": "dealerCity", visible: true, type: "string", fill: false },
{ "label": "经销商-代码", "prop": "dealerCode", visible: true }, { "label": "经销商-代码", "prop": "dealerCode", visible: true, type: "string", fill: false },
{ "label": "经销商名称", "prop": "dealerName", visible: true }, { "label": "经销商名称", "prop": "dealerName", visible: true, type: "string", fill: false },
{ "label": "经销商类型", "prop": "dealerType", visible: true }, { "label": "经销商类型", "prop": "dealerType", visible: true, type: "string", fill: false },
{ "label": "开户日期", "prop": "openingDate", visible: true }, { "label": "开户日期", "prop": "openingDate", visible: true, type: "string", fill: false },
{ "label": "闭户日期", "prop": "closingDate", visible: true }, { "label": "闭户日期", "prop": "closingDate", visible: true, type: "string", fill: false },
{ "label": "大区总监", "prop": "regionManager", visible: true }, { "label": "大区总监", "prop": "regionManager", visible: true, type: "string", fill: false },
{ "label": "战区经理", "prop": "districtManager", visible: true }, { "label": "战区经理", "prop": "districtManager", visible: true, type: "string", fill: false },
{ "label": "城市经理", "prop": "cityManager", visible: true }, { "label": "城市经理", "prop": "cityManager", visible: true, type: "string", fill: false },
{ "label": "系统名称", "prop": "lineName", visible: true }, { "label": "系统名称", "prop": "lineName", visible: true, type: "string", fill: true },
{ "label": "系统类型", "prop": "lineType", visible: true }, { "label": "系统类型", "prop": "lineType", visible: true, type: "string", fill: false },
{ "label": "渠道大类", "prop": "channelDl", visible: true }, { "label": "渠道大类", "prop": "channelDl", visible: true, type: "string", fill: false },
{ "label": "渠道小类", "prop": "channelXl", visible: true }, { "label": "渠道小类", "prop": "channelXl", visible: true, type: "string", fill: false },
{ "label": "系统业态", "prop": "lineLf", visible: true }, { "label": "系统业态", "prop": "lineLf", visible: true, type: "string", fill: false },
{ "label": "门店数", "prop": "storeCount", visible: true } { "label": "门店数", "prop": "storeCount", visible: true, type: "string", fill: false }
], ],
prop: 'baseColumns', prop: 'baseColumns',
visible: true visible: true
...@@ -139,9 +158,9 @@ const baseColumns = ref([ ...@@ -139,9 +158,9 @@ const baseColumns = ref([
{ {
label: "档期基础信息", label: "档期基础信息",
children: [ children: [
{ "label": "档期执行月份", "prop": "promotionExecutionMonth", visible: true }, { "label": "档期执行月份", "prop": "promotionExecutionMonth", visible: true, type: "string", fill: false },
{ "label": "档期计划-促销规格", "prop": "plannedPromotionSpec", visible: true }, { "label": "档期计划-促销规格", "prop": "plannedPromotionSpec", visible: true, type: "string", fill: false },
{ "label": "档期计划-促销口味", "prop": "plannedPromotionFlavor", visible: true }, { "label": "档期计划-促销口味", "prop": "plannedPromotionFlavor", visible: true, type: "string", fill: false },
{ {
"label": "档期执行-促销规格", "label": "档期执行-促销规格",
"prop": "actualPromotionSpec", "prop": "actualPromotionSpec",
...@@ -156,13 +175,17 @@ const baseColumns = ref([ ...@@ -156,13 +175,17 @@ const baseColumns = ref([
{ label: '老卤95g', value: '老卤95g' }, { label: '老卤95g', value: '老卤95g' },
{ label: '鸡肉豆堡', value: '鸡肉豆堡' }, { label: '鸡肉豆堡', value: '鸡肉豆堡' },
{ label: '牛肉豆堡', value: '牛肉豆堡' }, { label: '牛肉豆堡', value: '牛肉豆堡' },
] ],
referenceKey: "plannedPromotionSpec",
fill: true
}, },
{ {
"label": "档期执行-促销口味", "label": "档期执行-促销口味",
"prop": "actualPromotionFlavor", "prop": "actualPromotionFlavor",
visible: true, visible: true,
type: 'input' type: 'input',
referenceKey: "plannedPromotionFlavor",
fill: true
}, },
{ {
"label": "档期规格是否执行", "label": "档期规格是否执行",
...@@ -174,6 +197,7 @@ const baseColumns = ref([ ...@@ -174,6 +197,7 @@ const baseColumns = ref([
return row.specExecutionStatus; return row.specExecutionStatus;
}, },
formulaStr: '公式:(档期计划促销规格 = 档期执行促销规格)', formulaStr: '公式:(档期计划促销规格 = 档期执行促销规格)',
fill: true
}, },
], ],
prop: 'scheduleInfo', prop: 'scheduleInfo',
...@@ -183,8 +207,8 @@ const baseColumns = ref([ ...@@ -183,8 +207,8 @@ const baseColumns = ref([
label: "合计费用", label: "合计费用",
prop: 'totalCostParent', prop: 'totalCostParent',
children: [ children: [
{ "label": "合计费用", "prop": "totalCost", visible: true }, { "label": "合计费用", "prop": "totalCost", visible: true, type: "string", fill: false },
{ "label": "合计费率", "prop": "totalCostRate", visible: true }, { "label": "合计费率", "prop": "totalCostRate", visible: true, type: "string", fill: false },
], ],
visible: true visible: true
}, },
...@@ -192,30 +216,36 @@ const baseColumns = ref([ ...@@ -192,30 +216,36 @@ const baseColumns = ref([
label: "促销计划", label: "促销计划",
prop: 'promotionPlan', prop: 'promotionPlan',
children: [ children: [
{ "label": "计划-档期形式", "prop": "plannedPromotionFormat", visible: true }, { "label": "计划-档期形式", "prop": "plannedPromotionFormat", visible: true, type: "string", fill: false },
{ "label": "计划-核销方式", "prop": "plannedVerificationMethod", visible: true }, { "label": "计划-核销方式", "prop": "plannedVerificationMethod", visible: true, type: "string", fill: false },
{ "label": "计划-档期规则", "prop": "plannedPromotionRules", visible: true }, { "label": "计划-档期规则", "prop": "plannedPromotionRules", visible: true, type: "string", fill: false },
{ "label": "计划-档期前补差天数", "prop": "plannedPrePromotionAdjustDays", visible: true }, { "label": "计划-档期前补差天数", "prop": "plannedPrePromotionAdjustDays", visible: true, type: "string", fill: false },
{ "label": "计划-档期后补差天数", "prop": "plannedPostPromotionAdjustDays", visible: true }, { "label": "计划-档期后补差天数", "prop": "plannedPostPromotionAdjustDays", visible: true, type: "string", fill: false },
{ {
"label": "计划-档期开始时间", "label": "计划-档期开始时间",
"prop": "plannedPromotionStartDate", "prop": "plannedPromotionStartDate",
visible: true visible: true,
type: "string",
fill: false
}, },
{ {
"label": "实际-档期开始时间", "label": "实际-档期开始时间",
"prop": "actualPromotionStartDate", "prop": "actualPromotionStartDate",
visible: true, visible: true,
type: 'date', type: 'date',
format: 'MM-DD' format: 'MM-DD',
referenceKey: "plannedPromotionStartDate",
fill: true
}, },
{ "label": "计划-档期结束时间", "prop": "plannedPromotionEndDate", visible: true }, { "label": "计划-档期结束时间", "prop": "plannedPromotionEndDate", visible: true, type: "string", fill: false },
{ {
"label": "实际-档期结束时间", "label": "实际-档期结束时间",
"prop": "actualPromotionEndDate", "prop": "actualPromotionEndDate",
visible: true, visible: true,
type: 'date', type: 'date',
format: 'MM-DD' format: 'MM-DD',
fill: true,
referenceKey: "plannedPromotionEndDate",
}, },
{ {
"label": "档期是否开展", "label": "档期是否开展",
...@@ -227,6 +257,7 @@ const baseColumns = ref([ ...@@ -227,6 +257,7 @@ const baseColumns = ref([
return row.promotionImplementationStatus; return row.promotionImplementationStatus;
}, },
formulaStr: '公式:(实际档期开始时间不为空,并且实际档期结束时间不为空)', formulaStr: '公式:(实际档期开始时间不为空,并且实际档期结束时间不为空)',
fill: true
}, },
{ {
"label": "时间是否执行", "label": "时间是否执行",
...@@ -238,15 +269,17 @@ const baseColumns = ref([ ...@@ -238,15 +269,17 @@ const baseColumns = ref([
return row.timeExecutionStatus; return row.timeExecutionStatus;
}, },
formulaStr: '公式:(实际档期开始时间 = 计划档期开始时间,并且实际档期结束时间 = 计划档期结束时间)', formulaStr: '公式:(实际档期开始时间 = 计划档期开始时间,并且实际档期结束时间 = 计划档期结束时间)',
fill: true
}, },
{ "label": "计划-补差开始时间", "prop": "plannedAdjustmentStartDate", visible: true }, { "label": "计划-补差开始时间", "prop": "plannedAdjustmentStartDate", visible: true, type: "string", fill: false },
{ "label": "计划-补差结束时间", "prop": "plannedAdjustmentEndDate", visible: true }, { "label": "计划-补差结束时间", "prop": "plannedAdjustmentEndDate", visible: true, type: "string", fill: false },
{ "label": "计划促销机制", "prop": "plannedPromotionMechanism", visible: true }, { "label": "计划促销机制", "prop": "plannedPromotionMechanism", visible: true, type: "string", fill: false },
{ {
"label": "实际促销机制", "label": "实际促销机制",
"prop": "actualPromotionMechanism", "prop": "actualPromotionMechanism",
visible: true, visible: true,
type: 'input' type: 'input',
fill: true
}, },
{ {
"label": "促销机制是否执行", "label": "促销机制是否执行",
...@@ -256,26 +289,29 @@ const baseColumns = ref([ ...@@ -256,26 +289,29 @@ const baseColumns = ref([
options: [ options: [
{ label: '是', value: '是' }, { label: '是', value: '是' },
{ label: '否', value: '否' }, { label: '否', value: '否' },
] ],
fill: true
}, },
{ "label": "预估袋数", "prop": "estimatedBagCount", visible: true }, { "label": "预估袋数", "prop": "estimatedBagCount", visible: true, type: "string", fill: false },
{ {
"label": "档期备货量(袋)", "label": "档期备货量(袋)",
"prop": "promotionStockQuantity", "prop": "promotionStockQuantity",
visible: true, visible: true,
type: 'input', type: 'input',
format: 'number', format: 'number',
fill: true
}, },
{ "label": "单包厂价(单包)", "prop": "unitFactoryPrice", visible: true }, { "label": "单包厂价(单包)", "prop": "unitFactoryPrice", visible: true, type: "string", fill: false },
{ "label": "正常供价(单包)", "prop": "normalSupplyPrice", visible: true }, { "label": "正常供价(单包)", "prop": "normalSupplyPrice", visible: true, type: "string", fill: false },
{ "label": "日常零售价(单包)", "prop": "regularRetailPrice", visible: true }, { "label": "日常零售价(单包)", "prop": "regularRetailPrice", visible: true, type: "string", fill: false },
{ "label": "计划促销售价(单包)", "prop": "plannedPromotionPrice", visible: true }, { "label": "计划促销售价(单包)", "prop": "plannedPromotionPrice", visible: true, type: "string", fill: false },
{ {
"label": "实际促销售价(单包)", "label": "实际促销售价(单包)",
"prop": "actualPromotionPrice", "prop": "actualPromotionPrice",
visible: true, visible: true,
type: 'input', type: 'input',
format: 'number', format: 'number',
fill: true
}, },
{ {
"label": "促销价是否执行", "label": "促销价是否执行",
...@@ -286,15 +322,16 @@ const baseColumns = ref([ ...@@ -286,15 +322,16 @@ const baseColumns = ref([
return row.promotionPriceExecutionStatus; return row.promotionPriceExecutionStatus;
}, },
formulaStr: '公式:(计划促销售价 = 实际促销售价)', formulaStr: '公式:(计划促销售价 = 实际促销售价)',
fill: true
}, },
{ "label": "正常经销商毛利现状", "prop": "normalDealerMarginStatus", visible: true }, { "label": "正常经销商毛利现状", "prop": "normalDealerMarginStatus", visible: true, type: "string", fill: false },
{ "label": "系统前台毛利保证", "prop": "systemFrontendMarginGuarantee", visible: true }, { "label": "系统前台毛利保证", "prop": "systemFrontendMarginGuarantee", visible: true, type: "string", fill: false },
{ "label": "系统后台毛利保证", "prop": "systemBackendMarginGuarantee", visible: true }, { "label": "系统后台毛利保证", "prop": "systemBackendMarginGuarantee", visible: true, type: "string", fill: false },
{ "label": "系统促销毛利保证", "prop": "systemPromotionMarginGuarantee", visible: true }, { "label": "系统促销毛利保证", "prop": "systemPromotionMarginGuarantee", visible: true, type: "string", fill: false },
{ "label": "经销商毛利保证", "prop": "dealerMarginGuarantee", visible: true }, { "label": "经销商毛利保证", "prop": "dealerMarginGuarantee", visible: true, type: "string", fill: false },
{ "label": "单袋补差金额(费用)", "prop": "unitBagAdjustmentAmount", visible: true }, { "label": "单袋补差金额(费用)", "prop": "unitBagAdjustmentAmount", visible: true, type: "string", fill: false },
{ "label": "补差费比(%)", "prop": "adjustmentCostRatio", visible: true }, { "label": "补差费比(%)", "prop": "adjustmentCostRatio", visible: true, type: "string", fill: false },
{ "label": "整体补差(费用)", "prop": "totalAdjustmentCost", visible: true }, { "label": "整体补差(费用)", "prop": "totalAdjustmentCost", visible: true, type: "string", fill: false },
{ {
"label": "档期是否执行", "label": "档期是否执行",
"prop": "promotionExecutionStatus", "prop": "promotionExecutionStatus",
...@@ -306,6 +343,7 @@ const baseColumns = ref([ ...@@ -306,6 +343,7 @@ const baseColumns = ref([
return row.promotionExecutionStatus; return row.promotionExecutionStatus;
}, },
formulaStr: '公式:(促销价是否执行 = 是,并且促销机制是否执行 = 是,并且促销规格是否执行 = 是,并且档期是否开展 = 是)', formulaStr: '公式:(促销价是否执行 = 是,并且促销机制是否执行 = 是,并且促销规格是否执行 = 是,并且档期是否开展 = 是)',
fill: true
}, },
], ],
visible: true visible: true
...@@ -313,8 +351,8 @@ const baseColumns = ref([ ...@@ -313,8 +351,8 @@ const baseColumns = ref([
label: "海报计划", label: "海报计划",
prop: 'posterPlan', prop: 'posterPlan',
children: [ children: [
{ "label": "计划-海报形式", "prop": "plannedPosterFormat", visible: true }, { "label": "计划-海报形式", "prop": "plannedPosterFormat", visible: true, type: "string", fill: false },
{ "label": "计划-海报费用", "prop": "plannedPosterCost", visible: true }, { "label": "计划-海报费用", "prop": "plannedPosterCost", visible: true, type: "string", fill: false },
{ {
"label": "实际-海报形式", "label": "实际-海报形式",
"prop": "actualPosterFormat", "prop": "actualPosterFormat",
...@@ -323,7 +361,8 @@ const baseColumns = ref([ ...@@ -323,7 +361,8 @@ const baseColumns = ref([
options: [ options: [
{ label: '电子', value: '电子' }, { label: '电子', value: '电子' },
{ label: '纸制', value: '纸制' } { label: '纸制', value: '纸制' }
] ],
fill: true
}, },
{ {
"label": "海报是否执行", "label": "海报是否执行",
...@@ -335,6 +374,7 @@ const baseColumns = ref([ ...@@ -335,6 +374,7 @@ const baseColumns = ref([
return row.posterExecutionStatus; return row.posterExecutionStatus;
}, },
formulaStr: '公式:(计划海报形式 = 实际海报形式)', formulaStr: '公式:(计划海报形式 = 实际海报形式)',
fill: true
}, },
], ],
visible: true visible: true
...@@ -343,165 +383,13 @@ const baseColumns = ref([ ...@@ -343,165 +383,13 @@ const baseColumns = ref([
label: "档期陈列", label: "档期陈列",
prop: 'displayPlan', prop: 'displayPlan',
children: [ children: [
{ "label": "门店数", "prop": "storeCountInt", visible: true }, { "label": "门店数", "prop": "storeCountInt", visible: true, type: "string", fill: false },
{ "label": "店均费用", "prop": "averageStoreCost", visible: true }, { "label": "店均费用", "prop": "averageStoreCost", visible: true, type: "string", fill: false },
{ "label": "费用", "prop": "cost", visible: true }, { "label": "费用", "prop": "cost", visible: true, type: "string", fill: false },
], ],
visible: true visible: true
} }
]); ]);
// 填报列
const fillColumns = ref([
{ "label": "档期计划-促销规格", "prop": "plannedPromotionSpec", visible: true },
{ "label": "档期计划-促销口味", "prop": "plannedPromotionFlavor", visible: true }, {
"label": "档期执行-促销规格",
"prop": "actualPromotionSpec",
visible: true,
type: 'select',
options: [
{ label: '虎皮105g', value: '虎皮105g' },
{ label: '虎皮210g', value: '虎皮210g' },
{ label: '去骨72g', value: '去骨72g' },
{ label: '去骨138g', value: '去骨138g' },
{ label: '小鸡腿80g', value: '小鸡腿80g' },
{ label: '老卤95g', value: '老卤95g' },
{ label: '鸡肉豆堡', value: '鸡肉豆堡' },
{ label: '牛肉豆堡', value: '牛肉豆堡' },
]
},
{
"label": "档期执行-促销口味",
"prop": "actualPromotionFlavor",
visible: true,
type: 'input'
},
{
"label": "档期规格是否执行",
"prop": "specExecutionStatus",
visible: true,
type: 'formula',
func: (row) => {
row.specExecutionStatus = row.plannedPromotionSpec === row.actualPromotionSpec ? '是' : '否';
return row.specExecutionStatus;
},
formulaStr: '公式:(档期计划促销规格 = 档期执行促销规格)',
}, {
"label": "计划-档期开始时间",
"prop": "plannedPromotionStartDate",
visible: true
},
{
"label": "实际-档期开始时间",
"prop": "actualPromotionStartDate",
visible: true,
type: 'date',
format: 'MM-DD'
},
{ "label": "计划-档期结束时间", "prop": "plannedPromotionEndDate", visible: true },
{
"label": "实际-档期结束时间",
"prop": "actualPromotionEndDate",
visible: true,
type: 'date',
format: 'MM-DD'
},
{
"label": "档期是否开展",
"prop": "promotionImplementationStatus",
visible: true,
type: 'formula',
func: (row) => {
row.promotionImplementationStatus = row.actualPromotionStartDate && row.actualPromotionEndDate ? '是' : '否';
return row.promotionImplementationStatus;
},
formulaStr: '公式:(实际档期开始时间不为空,并且实际档期结束时间不为空)',
},
{
"label": "时间是否执行",
"prop": "timeExecutionStatus",
visible: true,
type: 'formula',
func: (row) => {
row.timeExecutionStatus = (row.actualPromotionStartDate === row.plannedPromotionStartDate) && (row.actualPromotionEndDate === row.plannedPromotionEndDate) ? '是' : '否';
return row.timeExecutionStatus;
},
formulaStr: '公式:(实际档期开始时间 = 计划档期开始时间,并且实际档期结束时间 = 计划档期结束时间)',
},
{ "label": "计划促销机制", "prop": "plannedPromotionMechanism", visible: true },
{
"label": "实际促销机制",
"prop": "actualPromotionMechanism",
visible: true,
type: 'input'
},
{
"label": "促销机制是否执行",
"prop": "promotionMechanismExecutionStatus",
visible: true,
type: 'select',
options: [
{ label: '是', value: '是' },
{ label: '否', value: '否' },
]
},
{ "label": "预估袋数", "prop": "estimatedBagCount", visible: true },
{
"label": "档期备货量(袋)",
"prop": "promotionStockQuantity",
visible: true,
type: 'input',
format: 'number',
}, { "label": "计划促销售价(单包)", "prop": "plannedPromotionPrice", visible: true },
{
"label": "实际促销售价(单包)",
"prop": "actualPromotionPrice",
visible: true,
type: 'input',
format: 'number',
},
{
"label": "促销价是否执行",
"prop": "promotionPriceExecutionStatus", visible: true,
type: 'formula',
func: (row) => {
row.promotionPriceExecutionStatus = row.plannedPromotionPrice == row.actualPromotionPrice ? '是' : '否';
return row.promotionPriceExecutionStatus;
},
formulaStr: '公式:(计划促销售价 = 实际促销售价)',
}, {
"label": "档期是否执行",
"prop": "promotionExecutionStatus",
visible: true,
type: 'formula',
func: (row) => {
// 促销价是否执行,促销机制是否执行,促销规格是否执行,档期是否开展
row.promotionExecutionStatus = row.promotionPriceExecutionStatus == '是' && row.promotionMechanismExecutionStatus == '是' && row.specExecutionStatus == '是' && row.promotionImplementationStatus == '是' ? '是' : '否';
return row.promotionExecutionStatus;
},
formulaStr: '公式:(促销价是否执行 = 是,并且促销机制是否执行 = 是,并且促销规格是否执行 = 是,并且档期是否开展 = 是)',
}, { "label": "计划-海报形式", "prop": "plannedPosterFormat", visible: true }, {
"label": "实际-海报形式",
"prop": "actualPosterFormat",
visible: true,
type: 'select',
options: [
{ label: '电子', value: '电子' },
{ label: '纸制', value: '纸制' }
]
},
{
"label": "海报是否执行",
"prop": "posterExecutionStatus",
visible: true,
type: 'formula',
func: (row) => {
row.posterExecutionStatus = row.plannedPosterFormat == row.actualPosterFormat ? '是' : '否';
return row.posterExecutionStatus;
},
formulaStr: '公式:(计划海报形式 = 实际海报形式)',
},
])
// 表格列数据 // 表格列数据
const tableColumns = ref([]) const tableColumns = ref([])
// 右上角工具选择列 // 右上角工具选择列
...@@ -512,18 +400,33 @@ const checkTableColumns = () => { ...@@ -512,18 +400,33 @@ const checkTableColumns = () => {
chooseColumns.value = baseColumns.value chooseColumns.value = baseColumns.value
tableColumns.value = baseColumns.value.flatMap(item => { tableColumns.value = baseColumns.value.flatMap(item => {
if (item.children) { if (item.children) {
// 在扁平化时就过滤掉 visible 为 false 的列 return item.children.filter(child => child);
return item.children.filter(child => child.visible);
} }
// 如果是没有 children 的单元素,也检查其 visible 属性 return [];
return item.visible ? item : []; });
}).filter(Boolean); // 过滤掉空数组项
} else if (operation.value === '填报列') { } else if (operation.value === '填报列') {
chooseColumns.value = fillColumns.value chooseColumns.value = baseColumns.value.flatMap(item => {
tableColumns.value = fillColumns.value.filter(item => item.visible); if (item.children) {
return item.children
.filter(child => child.fill)
}
return [];
});
tableColumns.value = chooseColumns.value
} }
// 强制表格立即应用所有宽度设置,避免先自适应再调整
nextTick(() => {
if (tableRef.value) {
tableRef.value.doLayout()
}
})
} }
checkTableColumns()
onMounted(() => {
checkTableColumns()
})
// 选择列默认选中哪些 // 选择列默认选中哪些
const visibleProps = computed(() => { const visibleProps = computed(() => {
// 分情况返回 // 分情况返回
...@@ -534,15 +437,6 @@ const visibleProps = computed(() => { ...@@ -534,15 +437,6 @@ const visibleProps = computed(() => {
return item.prop; return item.prop;
}); });
}); });
// 监听chooseColumns变化,当列的visible属性改变时重新计算tableColumns
watch(
() => chooseColumns.value,
() => {
// 不需要重新赋值,只需要重新计算tableColumns
checkTableColumns();
},
{ deep: true }
);
// 提交变更 // 提交变更
const submitChange = async (row, col) => { const submitChange = async (row, col) => {
...@@ -614,6 +508,18 @@ const getTableList = async () => { ...@@ -614,6 +508,18 @@ const getTableList = async () => {
const res = await getDisplayScheduleList({ const res = await getDisplayScheduleList({
...params ...params
}) })
// 处理日期格式
res.data.rows.forEach(item => {
item.openingDate = parseTime(item.openingDate, '{y}-{m}-{d}')
item.plannedAdjustmentStartDate = parseTime(item.plannedAdjustmentStartDate, '{y}-{m}-{d}')
item.plannedAdjustmentEndDate = parseTime(item.plannedAdjustmentEndDate, '{y}-{m}-{d}')
item.plannedPromotionStartDate = parseTime(item.plannedPromotionStartDate, '{m}-{d}')
item.actualPromotionStartDate = parseTime(item.actualPromotionStartDate, '{m}-{d}')
item.plannedPromotionEndDate = parseTime(item.plannedPromotionEndDate, '{m}-{d}')
item.actualPromotionEndDate = parseTime(item.actualPromotionEndDate, '{m}-{d}')
item.totalCostRate = item.totalCostRate ? `${(item.totalCostRate).toFixed(2)}%` : '-'
item.adjustmentCostRatio = item.adjustmentCostRatio ? `${(item.adjustmentCostRatio).toFixed(2)}%` : '-'
})
tableData.value = res.data.rows tableData.value = res.data.rows
total.value = res.data.total total.value = res.data.total
isLoading.value = false isLoading.value = false
...@@ -695,17 +601,29 @@ const getColumnMinWidth = (column) => { ...@@ -695,17 +601,29 @@ const getColumnMinWidth = (column) => {
return widthMap[column.prop] || 150; // 默认宽度 return widthMap[column.prop] || 150; // 默认宽度
}; };
// 格式化函数
const formatterTableData = (row, col) => {
if (col.prop === 'openingDate' || col.prop === 'plannedAdjustmentStartDate' || col.prop === 'plannedAdjustmentEndDate') { const isContentOverflow = (key, content) => {
return parseTime(row[col.prop], '{y}-{m}-{d}') // 创建临时元素用于测量
} else if (col.prop === 'plannedPromotionStartDate' || col.prop === 'actualPromotionStartDate' || col.prop === 'plannedPromotionEndDate' || col.prop === 'actualPromotionEndDate') { if (!content) return false;
return parseTime(row[col.prop], '{m}-{d}')
} else if (col.prop === 'totalCostRate' || col.prop === 'adjustmentCostRatio') { const tempSpan = document.createElement('span');
return `${(row[col.prop]).toFixed(2)}%` tempSpan.textContent = content;
} tempSpan.className = 'ellipsis-tooltip';
return row[col.prop] || '-' tempSpan.style.visibility = 'hidden';
} tempSpan.style.position = 'absolute';
document.body.appendChild(tempSpan);
// 获取元素宽度和内容宽度
const { width } = tempSpan.getBoundingClientRect();
const scrollWidth = tempSpan.scrollWidth;
// 移除临时元素
document.body.removeChild(tempSpan);
// 当内容宽度大于元素宽度时,表示内容溢出
return scrollWidth > width;
};
</script> </script>
...@@ -749,37 +667,66 @@ const formatterTableData = (row, col) => { ...@@ -749,37 +667,66 @@ const formatterTableData = (row, col) => {
align-items: center; align-items: center;
} }
/* 表格区域 */
.auto-fit-header-table { .auto-fit-header-table {
width: 100%;
--el-table-header-cell-text-color: #333;
--el-table-header-cell-padding: 0 .4267rem;
/* 列头内边距(可调整) */
.el-table__header th.el-table__cell {
white-space: nowrap;
/* 禁止列头文本换行 */
text-overflow: clip;
/* 溢出不隐藏(若想隐藏用 ellipsis,但需配合 overflow: hidden) */
overflow: visible;
/* 允许内容撑满(避免文本被截断) */
}
/* 保持原有的单元格样式,但优化内容显示 */
.el-table__body td.el-table__cell {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
/* 优化超长文本的显示效果 */ /* 优化超长文本的显示效果 */
.cell { .cell {
padding: 0 .2133rem; /* padding: 0 .2133rem; */
} }
/* 表格内下拉框 */ ::v-deep(.el-table__row) {
.el-select { .el-table__cell {
width: 100% !important; padding: 0;
}
}
::v-deep(.column-style) {
.cell-style {
margin: 0 -12px;
>div {
display: flex;
flex-direction: column;
align-items: flex-start;
>span.ellipsis-tooltip {
text-align: left;
text-indent: 5px;
display: inline-block;
width: 100%;
background-color: #e1e2e6;
border-bottom: 1px solid #ebeef5;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
max-width: 100%;
}
}
/* 表格内下拉框 */
.el-select {
width: 100% !important;
padding: 10px;
}
.el-input {
padding: 10px;
}
.date-picker {
padding: 10px;
.el-input{
padding: 0;
}
}
}
} }
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论