提交 73a98b11 authored 作者: lidongxu's avatar lidongxu

refactor(promotion/display_schedule): 修复:店内执行上报_重构框架和架构,梳理数据层和视图层关系,增加输入数字超出计划标红提示等细节(暂时完成常规陈列部分)

上级 54734e9e
...@@ -34,14 +34,14 @@ ...@@ -34,14 +34,14 @@
"lib-flexible": "^0.3.2", "lib-flexible": "^0.3.2",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"nprogress": "0.2.0", "nprogress": "0.2.0",
"pinia": "2.1.7", "pinia": "^3.0.4",
"splitpanes": "3.1.5", "splitpanes": "3.1.5",
"uuid": "^11.0.5", "uuid": "^11.0.5",
"vant": "^4.9.18", "vant": "^4.9.18",
"vue": "^3.5.13", "vue": "^3.5.25",
"vue-count-to": "^1.0.13", "vue-count-to": "^1.0.13",
"vue-cropper": "1.1.1", "vue-cropper": "1.1.1",
"vue-router": "4.4.0", "vue-router": "^4.6.3",
"vue3-count-to": "^1.1.2", "vue3-count-to": "^1.1.2",
"vuedraggable": "^4.1.0" "vuedraggable": "^4.1.0"
}, },
......
<template> <template>
<div class="search" v-show="showSearch"> <div class="search"
v-show="showSearch">
<el-form :inline="true" <el-form :inline="true"
:model="queryParams" :model="queryParams"
class="demo-form-inline"> class="demo-form-inline">
...@@ -28,7 +29,8 @@ ...@@ -28,7 +29,8 @@
@input="handleChange" @input="handleChange"
clearable /> clearable />
</el-form-item> </el-form-item>
<el-form-item label="门店编码/名称" v-if="showStoreSearch"> <el-form-item label="门店编码/名称"
v-if="showStoreSearch">
<el-input v-model="queryParams.storeCN" <el-input v-model="queryParams.storeCN"
placeholder="请输入门店编码/名称" placeholder="请输入门店编码/名称"
@input="handleChange" @input="handleChange"
...@@ -47,20 +49,17 @@ const props = defineProps({ ...@@ -47,20 +49,17 @@ const props = defineProps({
showStoreSearch: { showStoreSearch: {
type: Boolean, type: Boolean,
default: true default: true
},
queryParams: {
type: Object,
default: () => ({})
} }
}) })
const queryParams = reactive({
// 当月
salesMonth: new Date(),
deptName: '',
dealerCN: '',
lineNameLike: '',
storeCN: ''
})
const emits = defineEmits(['change']) const emits = defineEmits(['change'])
const handleChange = () => { const handleChange = () => {
emits('change', queryParams) emits('change')
} }
</script> </script>
......
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
<!-- 操作类型 --> <!-- 操作类型 -->
<el-row> <el-row>
<el-form-item> <el-form-item>
<el-radio-group v-model="operation" <el-radio-group v-model="operation">
@change="checkTableColumns">
<el-radio-button label="展示模式" <el-radio-button label="展示模式"
value="展示模式" /> value="展示模式" />
<el-radio-button label="填报模式" <el-radio-button label="填报模式"
...@@ -77,13 +76,11 @@ ...@@ -77,13 +76,11 @@
</div> </div>
<!-- 公式计算 --> <!-- 公式计算 -->
<div v-else-if="col.type === 'formula'"> <div v-else-if="col.type === 'formula'">
{{ col.func(row) }} {{ row[col.prop] || '-' }}
</div> </div>
<!-- 其他类型内容 --> <!-- 其他类型内容(正常显示文字) -->
<div cllass="fill-span-wrap" <div class="fill-span-wrap"
v-else> v-else>{{ row[col.prop] || '-' }}
<!-- 正常显示 -->
<span class="fill-span">{{ row[col.prop] || '-' }}</span>
</div> </div>
</div> </div>
<!-- 展示模式 --> <!-- 展示模式 -->
...@@ -97,10 +94,10 @@ ...@@ -97,10 +94,10 @@
<pagination :total="total" <pagination :total="total"
v-model:page="params.pageNum" v-model:page="params.pageNum"
v-model:limit="params.pageSize" v-model:limit="params.pageSize"
:pageSizes="[10, 20, 50, 100]"
@pagination="getTableList" /> @pagination="getTableList" />
</div> </div>
</div> </div>
<!-- 表格弹窗 - 使用DOM移动而非复制 --> <!-- 表格弹窗 - 使用DOM移动而非复制 -->
<el-dialog v-model="showTableInDialog" <el-dialog v-model="showTableInDialog"
title="表格详情" title="表格详情"
...@@ -115,27 +112,16 @@ ...@@ -115,27 +112,16 @@
<script setup> <script setup>
import { h } from 'vue' import { h } from 'vue'
import userStore from '@/store/modules/user'
const props = defineProps({ const props = defineProps({
tableColumns: { // 表格列 tableData: { // 数据源
type: Array,
default: () => []
},
chooseColumns: { // 显隐列数据结构
type: Array,
default: () => []
},
visibleProps: { // 显隐列数据,默认勾选的列
type: Array, type: Array,
default: () => [] default: () => []
}, },
tableData: { // 数据源 baseColumns: { // 表格列
type: Array, type: Array,
default: () => [] default: () => []
}, },
isLoading: { // 表格加载状态
type: Boolean,
default: false
},
total: { // 总条数 total: { // 总条数
type: Number, type: Number,
default: 0 default: 0
...@@ -147,7 +133,7 @@ const props = defineProps({ ...@@ -147,7 +133,7 @@ const props = defineProps({
pageSize: 10, pageSize: 10,
}) })
}, },
showFill: { // 是否显示填报模式 isLoading: { // 表格加载状态
type: Boolean, type: Boolean,
default: false default: false
}, },
...@@ -156,27 +142,60 @@ const props = defineProps({ ...@@ -156,27 +142,60 @@ const props = defineProps({
default: (row, col, cellValue) => cellValue default: (row, col, cellValue) => cellValue
} }
}) })
const emit = defineEmits(['updateColumns', 'getTableList', 'updateShowSearch']) const emit = defineEmits(['getTableList', 'updateShowSearch'])
/*************** 工具栏 ***************/ /*************** 工具栏 ***************/
// 切换平铺/填报模式 const showFill = userStore().hasQcMarketEmpInfo // 是否启用填报模式
const operation = ref('展示模式'); // const operation = ref('展示模式'); // 切换平铺/填报模式
// const operation = ref('填报模式'); const operation = ref('填报模式'); // 切换平铺/填报模式
const tableRef = ref(null) const tableRef = ref(null)
const checkTableColumns = async () => { const chooseColumns = ref([]) // 右上角工具显隐列选择
// 通知外面传入 tableColumns / chooseColumns 数据源
await emit('updateColumns', operation.value) // 使用computed缓存展示列,避免重复创建
const displayModeColumns = computed(() => {
return props.baseColumns.flatMap(item => {
if (item.children) {
return item.children.filter(child => !child.onlyFill);
}
return [];
});
});
// 使用computed缓存填报列,避免重复创建
const fillModeColumns = computed(() => {
return props.baseColumns.flatMap(item => {
if (item.children) {
return item.children.filter(child => child.fill === true)
}
return [];
});
});
// 使用computed动态返回当前模式的列
const tableColumns = computed(() => {
return operation.value === '展示模式' ? displayModeColumns.value : fillModeColumns.value;
});
// 强制表格立即应用所有宽度设置,避免先自适应再调整 // 监听operation变化,更新chooseColumns并触发布局调整
watch(operation, () => {
chooseColumns.value = operation.value === '展示模式' ? props.baseColumns : fillModeColumns.value;
// 强制表格立即应用所有宽度设置
nextTick(() => { nextTick(() => {
if (tableRef.value) { if (tableRef.value) {
tableRef.value.doLayout() tableRef.value.doLayout()
} }
}) });
} }, { immediate: true });
onMounted(() => {
checkTableColumns() const visibleProps = computed(() => {
}) return props.baseColumns.flatMap(item => {
if (item.children) {
return item.children.filter(child => child.visible).map(child => child.prop);
}
return item.prop;
});
});
// 控制搜索框显隐 // 控制搜索框显隐
const showSearch = ref(true) const showSearch = ref(true)
...@@ -285,9 +304,8 @@ const handleDialogClose = () => { ...@@ -285,9 +304,8 @@ const handleDialogClose = () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 0; min-height: 0;
/* 解决flex子项内容溢出问题 */
/* overflow-y: scroll; */ /* 解决flex子项内容溢出问题 */
.auto-fit-header-table { .auto-fit-header-table {
flex: 1; flex: 1;
...@@ -326,6 +344,7 @@ const handleDialogClose = () => { ...@@ -326,6 +344,7 @@ const handleDialogClose = () => {
white-space: nowrap; white-space: nowrap;
} }
/* 自定义单元格样式(仅填充模式生效) */
.cell-style { .cell-style {
>div { >div {
display: flex; display: flex;
...@@ -383,17 +402,12 @@ const handleDialogClose = () => { ...@@ -383,17 +402,12 @@ const handleDialogClose = () => {
} }
} }
/* 填充模式下的普通战士文字 */ /* 普通文字单元格(仅填充模式生效) */
.fill-span-wrap { .fill-span-wrap {
/* line-height: 1; */ /* 超出省略号 */
.fill-span { overflow: hidden;
display: inline-block; text-overflow: ellipsis;
width: 80% !important; white-space: nowrap;
/* 超出省略号 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
} }
} }
...@@ -404,7 +418,8 @@ const handleDialogClose = () => { ...@@ -404,7 +418,8 @@ const handleDialogClose = () => {
/* 无上下内边距 */ /* 无上下内边距 */
::v-deep(.el-table__row) { ::v-deep(.el-table__row) {
.el-table__cell { .el-table__cell {
padding: 0; padding-top: 0;
padding-bottom: 0;
.cell { .cell {
padding: 0 !important; padding: 0 !important;
...@@ -419,6 +434,8 @@ const handleDialogClose = () => { ...@@ -419,6 +434,8 @@ const handleDialogClose = () => {
margin: 10px; margin: 10px;
} }
} }
</style> </style>
<style lang="scss"> <style lang="scss">
...@@ -440,6 +457,7 @@ const handleDialogClose = () => { ...@@ -440,6 +457,7 @@ const handleDialogClose = () => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden !important; overflow: hidden !important;
padding-bottom: 5px;
.dialog-table-container { .dialog-table-container {
flex: 1; flex: 1;
...@@ -457,8 +475,24 @@ const handleDialogClose = () => { ...@@ -457,8 +475,24 @@ const handleDialogClose = () => {
} }
} }
} }
}
}
// 不显示数字输入框的 spinner
.no-spinner input::-webkit-inner-spin-button,
.no-spinner input::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
.no-spinner {
-moz-appearance: textfield;
}
// 填入数字超过计划值时,红色文字提示
.red-text {
input {
color: red !important;
} }
} }
</style> </style>
\ No newline at end of file
...@@ -42,10 +42,10 @@ import ThreeTwoSeconds from './tabs/three_two_seconds.vue' ...@@ -42,10 +42,10 @@ import ThreeTwoSeconds from './tabs/three_two_seconds.vue'
import SixLittleDiamonds from './tabs/six_little_diamonds.vue' import SixLittleDiamonds from './tabs/six_little_diamonds.vue'
const activeName = ref('常规陈列'); const activeName = ref('常规陈列');
// const activeName = ref('档期计划');
const handleClickTabs = (tab) => { const handleClickTabs = (tab) => {
activeName.value = tab.name; activeName.value = tab.name;
} }
</script> </script>
<style scoped <style scoped
...@@ -71,24 +71,8 @@ const handleClickTabs = (tab) => { ...@@ -71,24 +71,8 @@ const handleClickTabs = (tab) => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.formula-column {
display: flex;
justify-content: center;
align-items: center;
.el-icon {
margin-left: 2px;
}
}
} }
} }
.el-form-item {
align-items: center;
}
} }
} }
</style> </style>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论