Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
wangxiaolu-sfa-ui
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
sfa
wangxiaolu-sfa-ui
Commits
017cd04d
提交
017cd04d
authored
12月 15, 2025
作者:
lidongxu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor(mobile/pages/storeexecution/report): 新增:勤策App移动端_新增店内执行上报预览功能
上级
8fb7776d
显示空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
1723 行增加
和
2 行删除
+1723
-2
index.vue
src/views/mobile/pages/menu/index.vue
+3
-2
index.vue
...ges/storeExecution/report/components/SearchList/index.vue
+265
-0
index.vue
...le/pages/storeExecution/report/components/Table/index.vue
+433
-0
index.vue
src/views/mobile/pages/storeExecution/report/index.vue
+150
-0
data.jsx
src/views/mobile/pages/storeExecution/report/tabs/data.jsx
+0
-0
display.vue
...views/mobile/pages/storeExecution/report/tabs/display.vue
+156
-0
schedule.vue
...iews/mobile/pages/storeExecution/report/tabs/schedule.vue
+174
-0
schedule_dis.vue
.../mobile/pages/storeExecution/report/tabs/schedule_dis.vue
+121
-0
six_little_diamonds.vue
.../pages/storeExecution/report/tabs/six_little_diamonds.vue
+97
-0
snack.vue
src/views/mobile/pages/storeExecution/report/tabs/snack.vue
+227
-0
three_two_seconds.vue
...le/pages/storeExecution/report/tabs/three_two_seconds.vue
+97
-0
没有找到文件。
src/views/mobile/pages/menu/index.vue
浏览文件 @
017cd04d
...
@@ -89,7 +89,8 @@ const handleIconClick = (icon) => {
...
@@ -89,7 +89,8 @@ const handleIconClick = (icon) => {
.mobile-container
{
.mobile-container
{
background-color
:
#f3f3f3
;
background-color
:
#f3f3f3
;
min-height
:
100vh
;
min-height
:
100vh
;
font-size
:
14px
;
font-size
:
13px
;
// font-size: 12px;
padding
:
20px
;
padding
:
20px
;
p
{
p
{
...
@@ -122,7 +123,7 @@ const handleIconClick = (icon) => {
...
@@ -122,7 +123,7 @@ const handleIconClick = (icon) => {
display
:
grid
;
display
:
grid
;
grid-template-columns
:
repeat
(
4
,
1fr
);
grid-template-columns
:
repeat
(
4
,
1fr
);
/* 创建4列等宽布局 */
/* 创建4列等宽布局 */
gap
:
10
px
;
gap
:
2
px
;
/* 列之间的间距 */
/* 列之间的间距 */
justify-content
:
space-between
;
justify-content
:
space-between
;
/* 两边对齐 */
/* 两边对齐 */
...
...
src/views/mobile/pages/storeExecution/report/components/SearchList/index.vue
0 → 100644
浏览文件 @
017cd04d
<
template
>
<!-- 抽屉搜索组件 -->
<van-popup
v-model:show=
"showDrawer"
position=
"right"
class=
"search-drawer"
:style=
"
{ width: '85%', height: '100%' }"
teleport="body"
@close="handleClose">
<!-- 抽屉头部 -->
<van-nav-bar
title=
"筛选条件"
left-text=
"关闭"
left-arrow
@
click-left=
"handleClose"
/>
<!-- 搜索表单内容 -->
<div
class=
"search-content"
>
<van-cell-group
inset
>
<!-- 计划月份 -->
<van-field
:modelValue=
"parseTime(queryParams.salesMonth, '
{y}-{m}')"
label="计划月份"
placeholder="选择计划月份"
readonly
is-link
@click="showMonthPicker = true">
<template
#
input
>
<span>
{{
queryParams
.
salesMonth
||
'请选择'
}}
</span>
</
template
>
</van-field>
<!-- 大区/战区 -->
<van-field
v-model=
"queryParams.deptName"
label=
"大区/战区"
placeholder=
"请输入大区/战区"
@
update:model-value=
"handleChange"
clearable
/>
<!-- 经销商编码/名称 -->
<van-field
v-model=
"queryParams.dealerCN"
label=
"经销商编码/名称"
placeholder=
"请输入经销商编码/名称"
@
update:model-value=
"handleChange"
clearable
/>
<!-- 系统名称 -->
<van-field
v-model=
"queryParams.lineNameLike"
label=
"系统名称"
placeholder=
"请输入系统名称"
@
update:model-value=
"handleChange"
clearable
/>
<!-- 门店编码/名称 -->
<van-field
v-if=
"showStoreSearch"
v-model=
"queryParams.storeCN"
label=
"门店编码/名称"
placeholder=
"请输入门店编码/名称"
@
update:model-value=
"handleChange"
clearable
/>
<!-- 数据筛选 -->
<van-field
v-model=
"queryParams.rqStatus"
label=
"数据筛选"
placeholder=
"请选择筛选状态"
readonly
is-link
@
click=
"showStatusPicker = true"
>
<
template
#
input
>
<span>
{{
getStatusText
(
queryParams
.
rqStatus
)
}}
</span>
</
template
>
</van-field>
</van-cell-group>
<!-- 月份选择器 -->
<van-popup
v-model:show=
"showMonthPicker"
position=
"bottom"
teleport=
"body"
>
<van-date-picker
v-model=
"currentMonth"
title=
"选择计划月份"
:columns-type=
"['year', 'month']"
:min-date=
"minDate"
:max-date=
"maxDate"
@
confirm=
"confirmMonth"
@
cancel=
"showMonthPicker = false"
/>
</van-popup>
<!-- 状态选择器 -->
<van-popup
v-model:show=
"showStatusPicker"
position=
"bottom"
teleport=
"body"
>
<van-picker
:columns=
"statusOptions"
@
confirm=
"confirmStatus"
@
cancel=
"showStatusPicker = false"
/>
</van-popup>
<!-- 操作按钮 -->
<div
class=
"action-buttons"
>
<van-button
type=
"default"
size=
"large"
@
click=
"handleReset"
class=
"reset-btn"
>
<van-icon
name=
"replay"
/>
重置
</van-button>
<van-button
type=
"primary"
size=
"large"
@
click=
"handleConfirm"
class=
"confirm-btn"
>
<van-icon
name=
"success"
/>
确定
</van-button>
</div>
</div>
</van-popup>
</template>
<
script
setup
>
import
{
ref
,
computed
,
watch
}
from
'vue'
import
{
parseTime
}
from
'@/utils'
const
{
proxy
}
=
getCurrentInstance
()
const
props
=
defineProps
({
showSearch
:
{
type
:
Boolean
,
default
:
false
},
showStoreSearch
:
{
type
:
Boolean
,
default
:
true
},
queryParams
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
const
emits
=
defineEmits
([
'change'
,
'update:showSearch'
])
// 抽屉显示状态
const
showDrawer
=
computed
({
get
:
()
=>
props
.
showSearch
,
set
:
(
value
)
=>
emits
(
'update:showSearch'
,
value
)
})
// 选择器状态
const
showMonthPicker
=
ref
(
false
)
const
showStatusPicker
=
ref
(
false
)
const
currentMonth
=
ref
([])
// 日期范围
const
minDate
=
new
Date
(
2016
,
0
,
1
)
const
maxDate
=
new
Date
(
new
Date
().
getFullYear
(),
new
Date
().
getMonth
()
+
1
,
31
)
// 状态选项
const
statusOptions
=
[
{
text
:
'全部'
,
value
:
''
},
{
text
:
'未执行'
,
value
:
'未执行'
}
]
// 获取状态文本
const
getStatusText
=
(
value
)
=>
{
const
option
=
statusOptions
.
find
(
item
=>
item
.
value
===
value
)
return
option
?
option
.
text
:
'全部'
}
// 确认月份选择
const
confirmMonth
=
({
selectedValues
:
value
})
=>
{
// value 是 [2025, 2] 这种格式
const
year
=
value
[
0
]
const
month
=
String
(
value
[
1
]).
padStart
(
2
,
'0'
)
props
.
queryParams
.
salesMonth
=
`
${
year
}
-
${
month
}
`
showMonthPicker
.
value
=
false
handleChange
()
}
// 确认状态选择
const
confirmStatus
=
(
value
)
=>
{
props
.
queryParams
.
rqStatus
=
value
.
selectedOptions
[
0
]?.
value
||
''
showStatusPicker
.
value
=
false
handleChange
()
}
// 处理变化
const
handleChange
=
()
=>
{
emits
(
'change'
)
}
// 关闭抽屉
const
handleClose
=
()
=>
{
showDrawer
.
value
=
false
}
// 重置表单
const
handleReset
=
()
=>
{
// 重置所有查询参数
Object
.
keys
(
props
.
queryParams
).
forEach
(
key
=>
{
if
(
key
!==
'pageNum'
&&
key
!==
'pageSize'
)
{
props
.
queryParams
[
key
]
=
''
}
})
handleChange
()
}
// 确定搜索
const
handleConfirm
=
()
=>
{
handleChange
()
handleClose
()
}
// 监听外部showSearch变化
watch
(()
=>
props
.
showSearch
,
(
newVal
)
=>
{
if
(
newVal
)
{
// 打开抽屉时初始化当前月份
if
(
props
.
queryParams
.
salesMonth
)
{
// 如果是日期类型转成字符串
if
(
props
.
queryParams
.
salesMonth
instanceof
Date
)
{
props
.
queryParams
.
salesMonth
=
props
.
queryParams
.
salesMonth
.
toISOString
().
split
(
'T'
)[
0
].
substring
(
0
,
7
)
}
const
[
year
,
month
]
=
props
.
queryParams
.
salesMonth
.
split
(
'-'
)
// currentMonth = [2025, 02] 这种格式
currentMonth
.
value
=
[
parseInt
(
year
),
parseInt
(
month
)]
}
else
{
// 当前年月日
currentMonth
.
value
=
[
new
Date
().
getFullYear
(),
new
Date
().
getMonth
()]
}
}
})
</
script
>
<
style
scoped
lang=
"scss"
>
.search-drawer
{
.search-content
{
height
:
calc
(
100%
-
46px
);
// 减去导航栏高度
overflow-y
:
auto
;
padding
:
16px
;
.van-cell-group
{
margin-bottom
:
20px
;
}
.action-buttons
{
position
:
fixed
;
bottom
:
0
;
left
:
0
;
right
:
0
;
background
:
#fff
;
padding
:
16px
;
display
:
flex
;
gap
:
12px
;
border-top
:
1px
solid
#ebedf0
;
.reset-btn
,
.confirm-btn
{
flex
:
1
;
:deep
(
.van-button__content
)
{
display
:
flex
;
align-items
:
center
;
gap
:
4px
;
}
}
}
}
}
</
style
>
\ No newline at end of file
src/views/mobile/pages/storeExecution/report/components/Table/index.vue
0 → 100644
浏览文件 @
017cd04d
<
template
>
<div
class=
"flex-container"
>
<!-- 操作类型 -->
<!-- 表格容器 - 用于DOM移动 -->
<div
ref=
"tableContainer"
class=
"table-container"
>
<!-- 数据表格 -->
<el-table
:data=
"tableData"
border
ref=
"tableRef"
class=
"auto-fit-header-table"
v-loading=
"isLoading"
show-overflow-tooltip
:class=
"
{ 'cell-no-padding': operation === '填报模式' }"
:row-style="tableRowStyle">
<template
v-for=
"col in tableColumns"
>
<el-table-column
v-if=
"col.visible"
:label=
"col.label"
:prop=
"col.prop"
:key=
"col.prop"
align=
"center"
class-name=
"column-style"
:width=
"col.width"
:fixed=
"operation === '填报模式' && col.fixed"
>
<template
#
header=
"
{ column }">
<!-- 只为特定公式列添加问号图标 -->
<span
class=
"formula-column"
>
<div
class=
"column"
>
<p>
{{
column
.
label
}}
</p>
<p
v-if=
"col.subLabel"
>
{{
col
.
subLabel
}}
</p>
</div>
<el-tooltip
v-if=
"col.type === 'formula'"
:content=
"col.formulaStr"
placement=
"top"
>
<el-icon><question-filled
/></el-icon>
</el-tooltip>
</span>
</
template
>
<
template
#
default=
"{ row }"
>
<!-- 填报模式 -->
<div
v-if=
"operation === '填报模式'"
>
<!-- 自定义渲染内容单元格 -->
<div
v-if=
"col.render"
class=
"cell-style"
>
<component
:is=
"col.render(h, row, col, !isCurrentMonth(row.salesMonth))"
/>
</div>
<!-- 公式计算 -->
<div
v-else-if=
"col.type === 'formula'"
>
{{
row
[
col
.
prop
]
||
'-'
}}
</div>
<!-- 其他类型内容(正常显示文字) -->
<div
class=
"fill-span-wrap"
v-else
>
{{
row
[
col
.
prop
]
||
'-'
}}
</div>
</div>
<!-- 展示模式 -->
<div
class=
"show-cell-style"
v-else
>
{{
formatter
(
row
,
col
,
row
[
col
.
prop
]
||
'-'
)
}}
</div>
</
template
>
</el-table-column>
</template>
</el-table>
<!-- 分页 -->
<pagination
:total=
"total"
:layout=
"'prev,pager,next'"
v-model:page=
"params.pageNum"
v-model:limit=
"params.pageSize"
:pageSizes=
"[10, 20, 50, 100]"
@
pagination=
"getTableList"
/>
</div>
</div>
<!-- 表格弹窗 - 使用DOM移动而非复制 -->
<el-dialog
v-model=
"showTableInDialog"
title=
"表格详情"
modal-class=
"table-dialog-modal"
fullscreen
:before-close=
"handleDialogClose"
>
<!-- 弹窗内的表格容器 -->
<div
ref=
"dialogTableContainer"
class=
"dialog-table-container"
></div>
</el-dialog>
</template>
<
script
setup
>
import
{
h
}
from
'vue'
import
userStore
from
'@/store/modules/user'
const
props
=
defineProps
({
tableData
:
{
// 数据源
type
:
Array
,
default
:
()
=>
[]
},
baseColumns
:
{
// 表格列
type
:
Array
,
default
:
()
=>
[]
},
total
:
{
// 总条数
type
:
Number
,
default
:
0
},
params
:
{
// 分页参数
type
:
Object
,
default
:
()
=>
({
pageNum
:
1
,
pageSize
:
10
,
})
},
isLoading
:
{
// 表格加载状态
type
:
Boolean
,
default
:
false
},
formatter
:
{
// 格式化函数
type
:
Function
,
default
:
(
row
,
col
,
cellValue
)
=>
cellValue
}
})
const
emit
=
defineEmits
([
'getTableList'
,
'updateShowSearch'
])
/*************** 工具栏 ***************/
const
showFill
=
userStore
().
hasQcMarketEmpInfo
// 是否启用填报模式
const
operation
=
ref
(
'展示模式'
);
// 切换平铺/填报模式
// const operation = ref('填报模式'); // 切换平铺/填报模式
const
tableRef
=
ref
(
null
)
const
chooseColumns
=
ref
([])
// 右上角工具显隐列选择
// 使用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
(()
=>
{
if
(
tableRef
.
value
)
{
tableRef
.
value
.
doLayout
()
}
});
},
{
immediate
:
true
});
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
)
watch
(
showSearch
,
(
newVal
)
=>
{
emit
(
'updateShowSearch'
,
newVal
)
})
// 刷新数据
const
getTableList
=
()
=>
{
emit
(
'getTableList'
)
}
/************** 弹框控制 ***************/
// 控制表格弹框显隐
const
tableContainer
=
ref
(
null
)
// 原始表格容器引用
const
dialogTableContainer
=
ref
(
null
)
// 弹窗内表格容器引用
const
showTableInDialog
=
ref
(
false
)
// DOM移动需要的引用
let
containerElement
=
null
// 保存整个可移动容器
let
originalParent
=
null
// 保存原始父容器
// 打开表格弹窗并移动DOM
const
openTableDialog
=
async
()
=>
{
// 保存容器元素和原始父容器引用
if
(
tableContainer
.
value
)
{
containerElement
=
tableContainer
.
value
originalParent
=
containerElement
.
parentElement
}
// 显示弹窗
showTableInDialog
.
value
=
true
// 等待弹窗渲染完成后移动DOM
await
nextTick
()
moveContentToDialog
()
}
// 移动内容到弹窗
const
moveContentToDialog
=
()
=>
{
if
(
containerElement
&&
dialogTableContainer
.
value
)
{
// 关键DOM移动操作 - 现在会移动整个容器(包含表格和分页器)
dialogTableContainer
.
value
.
appendChild
(
containerElement
)
// 调整表格布局
nextTick
(()
=>
{
if
(
tableRef
.
value
)
{
tableRef
.
value
.
doLayout
()
}
})
}
}
// 移动内容回原位
const
moveContentBack
=
()
=>
{
if
(
containerElement
&&
originalParent
)
{
// 关键DOM移动操作
originalParent
.
appendChild
(
containerElement
)
// 调整表格布局
nextTick
(()
=>
{
if
(
tableRef
.
value
)
{
tableRef
.
value
.
doLayout
()
}
})
}
}
// 关闭弹窗
const
handleDialogClose
=
()
=>
{
// 先移动内容回原位
moveContentBack
()
// 然后关闭弹窗
showTableInDialog
.
value
=
false
}
/*************** 非当月置灰行 ***************/
// 获取当前月份的函数
const
getCurrentMonth
=
()
=>
{
const
now
=
new
Date
();
const
year
=
now
.
getFullYear
();
const
month
=
String
(
now
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
);
return
`
${
year
}
-
${
month
}
`
;
};
// 检查是否为当前月的函数
const
isCurrentMonth
=
(
salesMonth
)
=>
{
return
salesMonth
===
getCurrentMonth
();
};
// 行样式函数
const
tableRowStyle
=
({
row
})
=>
{
if
(
!
isCurrentMonth
(
row
.
salesMonth
))
{
return
{
backgroundColor
:
'#f5f7fa'
};
// 灰色背景
}
return
{};
};
</
script
>
<
style
scoped
lang=
"scss"
>
/* 根容器设置为flex布局,占据整个可用空间 */
.flex-container
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
/* 工具栏 */
.el-row
{
.el-form-item
{
.tip-title
{
font-size
:
32px
;
color
:
red
;
margin-left
:
50px
;
font-weight
:
900
;
margin-top
:
-5px
;
}
}
}
}
/* 因为表格会被挪走,所以必须独立样式无法嵌套在别人内 */
/* 表格样式 */
.table-container
{
flex
:
1
;
/* 这是关键,让表格容器自动占据剩余空间 */
display
:
flex
;
flex-direction
:
column
;
// min-height: 0;
// overflow-y: scroll;
/* 解决flex子项内容溢出问题 */
.auto-fit-header-table
{
flex
:
1
;
/* 列样式 */
.column-style
{
/* 列头样式 */
.formula-column
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
.column
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
flex-direction
:
column
;
p
{
margin
:
0
;
font-size
:
12px
;
color
:
#606266
;
}
}
.el-icon
{
margin-left
:
2px
;
}
}
/* 单元格样式 */
/* 展示模式单元格(仅展示模式生效) */
.show-cell-style
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
/* 自定义单元格样式(仅填充模式生效) */
.cell-style
{
>
div
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
>
span
{
text-align
:
left
;
text-indent
:
5px
;
display
:
inline-block
;
width
:
80%
;
background-color
:
#e1e2e6
;
border-bottom
:
1px
solid
#ebeef5
;
}
}
/* 表格内下拉框 */
.el-select
{
width
:
100%
!
important
;
padding
:
10px
;
/* 非 disabled 状态下的背景颜色 */
&.
no-disabled
:
:
v-deep
(
.
el-select__wrapper
)
{
border
:
4px
solid
var
(
--
el-background-editor-cell
)
!
important
;
}
}
.el-input
{
height
:
32px
!
important
;
/* box-sizing: content-box; */
padding
:
0
10px
;
width
:
100%
;
/* 非 disabled 状态下的背景颜色 */
&.
no-disabled
:
:
v-deep
(
.
el-input__wrapper
)
{
border
:
4px
solid
var
(
--
el-background-editor-cell
)
!
important
;
}
}
.date-picker
{
width
:
100%
;
padding
:
10px
;
/* 非 disabled 状态下的背景颜色 */
&.
no-disabled
:
:
v-deep
(
.
el-input__wrapper
)
{
border
:
4px
solid
var
(
--
el-background-editor-cell
)
!
important
;
}
::v-deep
(
.el-input
)
{
width
:
100%
;
padding
:
0
;
}
}
}
/* 普通文字单元格(仅填充模式生效) */
.fill-span-wrap
{
/* 超出省略号 */
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
padding
:
0
10px
;
}
}
/* 填报模式-单元格 */
&
.cell-no-padding
{
/* 无上下内边距 */
::v-deep
(
.el-table__row
)
{
.el-table__cell
{
padding-top
:
0
;
padding-bottom
:
0
;
.cell
{
padding
:
0
!
important
;
}
}
}
}
}
/* 分页器 */
.pagination-container
{
margin
:
10px
;
}
}
</
style
>
src/views/mobile/pages/storeExecution/report/index.vue
0 → 100644
浏览文件 @
017cd04d
<
template
>
<div
class=
"app-container"
>
<div
class=
"container"
>
<van-nav-bar
fixed
left-arrow
@
click-left=
"router.back()"
title=
"店内执行上报浏览"
right-text=
"筛选"
@
click-right=
"handleClickRight"
/>
<SearchList
v-model:showSearch=
"showSearch"
:queryParams=
"params"
@
change=
"getTableList"
/>
<el-tabs
v-model=
"activeName"
class=
"demo-tabs"
@
tab-click=
"handleClickTabs"
>
<el-tab-pane
label=
"常规陈列"
name=
"常规陈列"
>
<Display
:params=
"params"
ref=
"display"
/>
</el-tab-pane>
<el-tab-pane
label=
"档期计划"
name=
"档期计划"
>
<Schedule
:params=
"params"
ref=
"schedule"
/>
</el-tab-pane>
<el-tab-pane
label=
"档期陈列"
name=
"档期陈列"
>
<ScheduleDis
:params=
"params"
ref=
"scheduleDis"
/>
</el-tab-pane>
<el-tab-pane
label=
"零食陈列"
name=
"零食陈列"
>
<Snack
:params=
"params"
ref=
"snack"
/>
</el-tab-pane>
<el-tab-pane
label=
"三米两秒"
name=
"三米两秒"
>
<ThreeTwoSeconds
:params=
"params"
ref=
"threeTwoSeconds"
/>
</el-tab-pane>
<el-tab-pane
label=
"六小金刚"
name=
"六小金刚"
>
<SixLittleDiamonds
:params=
"params"
ref=
"sixLittleDiamonds"
/>
</el-tab-pane>
</el-tabs>
</div>
</div>
</
template
>
<
script
setup
>
import
Display
from
'./tabs/display.vue'
import
Schedule
from
'./tabs/schedule.vue'
import
ScheduleDis
from
'./tabs/schedule_dis.vue'
import
Snack
from
'./tabs/snack.vue'
import
ThreeTwoSeconds
from
'./tabs/three_two_seconds.vue'
import
SixLittleDiamonds
from
'./tabs/six_little_diamonds.vue'
import
SearchList
from
'./components/SearchList'
const
router
=
useRouter
()
const
activeName
=
ref
(
'常规陈列'
);
const
handleClickTabs
=
(
tab
)
=>
{
activeName
.
value
=
tab
.
name
;
}
const
showSearch
=
ref
(
false
)
const
handleClickRight
=
()
=>
{
showSearch
.
value
=
true
;
}
const
params
=
ref
({
pageNum
:
1
,
pageSize
:
50
,
salesMonth
:
new
Date
(),
deptName
:
''
,
dealerCN
:
''
,
lineNameLike
:
''
,
storeCN
:
''
})
const
display
=
ref
(
null
)
const
schedule
=
ref
(
null
)
const
scheduleDis
=
ref
(
null
)
const
snack
=
ref
(
null
)
const
threeTwoSeconds
=
ref
(
null
)
const
sixLittleDiamonds
=
ref
(
null
)
const
getTableList
=
()
=>
{
display
.
value
.
getTableList
()
schedule
.
value
.
getTableList
()
scheduleDis
.
value
.
getTableList
()
snack
.
value
.
getTableList
()
threeTwoSeconds
.
value
.
getTableList
()
sixLittleDiamonds
.
value
.
getTableList
()
}
</
script
>
<
style
scoped
lang=
"scss"
>
.app-container
{
padding
:
10px
;
padding-top
:
46px
;
.container
{
padding
:
0px
;
.el-tabs
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column-reverse
;
::v-deep
(
.el-tabs__header
)
{
// 确保底部边框线完整显示
border-bottom
:
1px
solid
var
(
--
el-border-color-light
);
width
:
100%
;
}
::v-deep
(
.el-tabs__nav-wrap
)
{
overflow-x
:
auto
;
overflow-y
:
hidden
;
-webkit-overflow-scrolling
:
touch
;
// iOS平滑滚动
scrollbar-width
:
none
;
// Firefox隐藏滚动条
&
:
:
after
{
// 隐藏el-tabs默认的底部伪元素边框
display
:
none
;
}
&
:
:-
webkit-scrollbar
{
display
:
none
;
// Chrome/Safari隐藏滚动条
}
}
::v-deep
(
.el-tabs__nav-scroll
)
{
overflow
:
visible
;
width
:
max-content
;
}
::v-deep
(
.el-tabs__content
)
{
display
:
flex
;
flex-direction
:
column
;
overflow-y
:
scroll
;
// height: 100%;
.el-tab-pane
{
// height: 100%;
display
:
flex
;
flex-direction
:
column
;
}
}
}
}
}
</
style
>
\ No newline at end of file
src/views/mobile/pages/storeExecution/report/tabs/data.jsx
0 → 100644
浏览文件 @
017cd04d
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/views/mobile/pages/storeExecution/report/tabs/display.vue
0 → 100644
浏览文件 @
017cd04d
<
template
>
<!-- 常规陈列 -->
<CustomTable
:tableData=
"tableData"
:baseColumns=
"baseColumns"
:total=
"total"
:params=
"params"
:isLoading=
"isLoading"
@
getTableList=
"getTableList"
@
updateShowSearch=
"v => showSearch.value = v"
/>
</
template
>
<
script
setup
lang=
"jsx"
>
import
CustomTable
from
'../components/Table'
import
SearchList
from
'../components/SearchList'
import
{
getDisplayList
,
submitDisplayPlan
}
from
'@/api'
import
{
parseTime
}
from
'@/utils'
import
{
getDisplayConfig
}
from
'./data.jsx'
/*************** 表格操作相关 ***************/
const
props
=
defineProps
({
params
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
// 提交变更
const
tableColumns
=
getDisplayConfig
(
async
(
row
,
col
)
=>
{
// 需要特殊处理的
// 实际主货架-形式,为空时,置空实际主货架-数量
if
(
col
.
prop
===
'actualMainShelfType'
&&
!
row
.
actualMainShelfType
)
{
row
.
actualMainShelfQty
=
''
}
let
requestObj
=
{}
if
(
col
.
requestKey
)
{
// 关联的公式计算列,需要特殊处理
for
(
const
str
of
col
.
requestKey
)
{
// 找到目标列的列对象,调用列对象自己的公式函数进行计算
const
obj
=
getDisplayConfig
().
flatMap
(
item
=>
{
if
(
item
.
children
)
{
return
item
.
children
.
filter
(
child
=>
!
child
.
onlyFill
);
}
return
[];
}).
find
(
item
=>
item
.
prop
===
str
)
if
(
obj
&&
obj
.
type
===
'formula'
)
{
obj
.
func
(
row
)
}
}
requestObj
=
col
.
requestKey
.
reduce
((
acc
,
key
)
=>
({
...
acc
,
[
key
]:
row
[
key
]
}),
{})
}
await
submitDisplayPlan
({
id
:
row
.
sadId
,
[
col
.
prop
]:
row
[
col
.
prop
],
// 当前修改列的值
...
requestObj
,
// 特殊类型数据处理(比如前端要字符串'',后端要数字0)
actualMainShelfQty
:
row
.
actualMainShelfQty
||
0
,
actualEndCapQty
:
row
.
actualEndCapQty
||
0
,
actualFloorStackArea
:
row
.
actualFloorStackArea
||
0
,
actualFloorStackQty
:
row
.
actualFloorStackQty
||
0
,
})
})
// 全部列
const
baseColumns
=
ref
(
tableColumns
);
// 表格数据
const
tableData
=
ref
([])
const
isLoading
=
ref
(
true
)
// const params = ref({
// pageNum: 1,
// pageSize: 50,
// salesMonth: new Date(),
// deptName: '',
// dealerCN: '',
// lineNameLike: '',
// storeCN: ''
// })
const
total
=
ref
(
0
)
// 筛选列表数据
const
getTableList
=
async
()
=>
{
isLoading
.
value
=
true
const
res
=
await
getDisplayList
({
...
props
.
params
,
salesMonth
:
parseTime
(
props
.
params
.
salesMonth
,
'{y}-{m}'
)
})
res
.
data
.
rows
.
forEach
(
item
=>
{
// 计划月份
item
.
salesMonth
=
parseTime
(
item
.
salesMonth
,
'{y}-{m}'
)
// 开户日期
item
.
openingDate
=
parseTime
(
item
.
openingDate
,
'{y}-{m}-{d}'
)
// 闭户日期
item
.
closingDate
=
parseTime
(
item
.
closingDate
,
'{y}-{m}-{d}'
)
// 修改时间
item
.
updateTime
=
parseTime
(
item
.
updateTime
,
'{y}-{m}-{d} {h}:{i}:{s}'
)
// 动态新增列:门店名称+门店编码+经销山名称(填报模式下,合并到一起)
item
.
storeNameCodeDealerName
=
item
.
storeName
+
'
\
n('
+
item
.
storeCode
+
')'
+
'
\
n('
+
item
.
dealerName
+
')'
// 特殊类型数据处理,前端要字符串'',后端要数字0
// item.actualMainShelfQty = item.actualMainShelfQty || ''
// item.actualEndCapQty = item.actualEndCapQty || ''
// item.actualFloorStackArea = item.actualFloorStackArea || ''
// item.actualFloorStackQty = item.actualFloorStackQty || ''
})
tableData
.
value
=
res
.
data
.
rows
total
.
value
=
res
.
data
.
total
isLoading
.
value
=
false
}
getTableList
()
defineExpose
({
getTableList
})
/*************** 筛选 ***************/
const
showSearch
=
ref
(
true
)
</
script
>
<
style
lang=
"scss"
>
// 动态列内容的 render 内样式
// 操作提示列
.operation_tip_cell
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-start
;
p
{
width
:
100%
;
margin
:
0
;
}
p
:first-child
{
background-color
:
#e1e2e6
;
border-bottom
:
1px
solid
#ebeef5
;
}
p
:last-child
{
padding
:
15px
0
;
}
}
// 只在填报模式出现的门店名称+门店编码+经销山名称(合并到一起)
.store-name-render-cell
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-start
;
p
{
width
:
100%
;
margin
:
0
;
}
}
</
style
>
\ No newline at end of file
src/views/mobile/pages/storeExecution/report/tabs/schedule.vue
0 → 100644
浏览文件 @
017cd04d
<
template
>
<!-- 档期计划 -->
<!-- 隐藏门店搜索 -->
<CustomTable
:tableData=
"tableData"
:baseColumns=
"baseColumns"
:total=
"total"
:params=
"params"
:isLoading=
"isLoading"
:formatter=
"formatterFn"
@
getTableList=
"getTableList"
@
updateShowSearch=
"v => showSearch.value = v"
/>
<!-- 弹窗:实际与计划不一致,让用户补充实际内容 -->
<el-dialog
v-model=
"showPromotionDialog"
title=
"请输入实际促销机制内容"
width=
"500%"
:before-close=
"handleDialogClose"
>
<el-form
:model=
"dialogForm"
label-width=
"80px"
>
<el-form-item
label=
"实际内容"
>
<el-input
v-model=
"dialogForm.actualPromotionContent"
type=
"textarea"
:rows=
"4"
placeholder=
"请输入实际促销机制内容"
/>
</el-form-item>
</el-form>
<template
#
footer
>
<span
class=
"dialog-footer"
>
<el-button
@
click=
"handleDialogClose"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"handleDialogConfirm"
>
确认
</el-button>
</span>
</
template
>
</el-dialog>
</template>
<
script
setup
lang=
"jsx"
>
import
CustomTable
from
'../components/Table'
import
SearchList
from
'../components/SearchList'
import
{
getDisplayScheduleList
,
submitDisplaySchedulePlan
}
from
'@/api'
import
{
parseTime
}
from
'@/utils'
import
{
getSchedulePlanConfig
}
from
'./data.jsx'
const
{
proxy
}
=
getCurrentInstance
()
/*************** 操作类型 ***************/
const
props
=
defineProps
({
params
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
// 提交变更
const
submitChange
=
async
(
row
,
col
)
=>
{
// 需要特殊处理的
// 实际主货架-形式,为空时,置空实际主货架-数量
if
(
col
.
prop
===
'actualMainShelfType'
&&
!
row
.
actualMainShelfType
)
{
row
.
actualMainShelfQty
=
0
}
let
requestObj
=
{}
if
(
col
.
requestKey
)
{
// 关联的公式计算列,需要特殊处理
for
(
const
str
of
col
.
requestKey
)
{
const
obj
=
getSchedulePlanConfig
().
flatMap
(
item
=>
{
if
(
item
.
children
)
{
return
item
.
children
.
filter
(
child
=>
!
child
.
onlyFill
);
}
return
[];
}).
find
(
item
=>
item
.
prop
==
str
)
if
(
obj
&&
obj
.
type
===
'formula'
)
{
obj
.
func
(
row
)
}
}
requestObj
=
col
.
requestKey
.
reduce
((
acc
,
key
)
=>
({
...
acc
,
[
key
]:
row
[
key
]
}),
{})
}
await
submitDisplaySchedulePlan
({
id
:
row
.
sapId
,
[
col
.
prop
]:
row
[
col
.
prop
],
// 当前修改列的值
...
requestObj
,
actualPromotionFlavor
:
Array
.
isArray
(
row
.
actualPromotionFlavor
)
?
row
.
actualPromotionFlavor
.
join
(
','
)
:
'-'
,
// 档期执行-促销口味,为数组时,转成字符串
actualPromotionStartDate
:
row
.
actualPromotionStartDate
?
parseTime
(
row
.
actualPromotionStartDate
,
'{y}-{m}-{d}'
)
:
''
,
// 档期执行-促销开始日期,为字符串时,转成日期格式
})
}
// 基础列配置
const
baseColumns
=
ref
(
getSchedulePlanConfig
(
submitChange
));
// 表格数据
const
tableData
=
ref
([])
const
isLoading
=
ref
(
true
)
const
params
=
ref
({
pageNum
:
1
,
pageSize
:
50
,
salesMonth
:
new
Date
(),
deptName
:
''
,
dealerCN
:
''
,
lineNameLike
:
''
,
storeCN
:
''
})
const
total
=
ref
(
0
)
// 获取表格数据
const
getTableList
=
async
()
=>
{
isLoading
.
value
=
true
const
res
=
await
getDisplayScheduleList
({
...
props
.
params
,
salesMonth
:
parseTime
(
props
.
params
.
salesMonth
,
'{y}-{m}'
)
})
// 处理日期格式
res
.
data
.
rows
.
forEach
(
item
=>
{
item
.
salesMonth
=
parseTime
(
item
.
salesMonth
,
'{y}-{m}'
)
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
,
'{y}-{m}-{d}'
)
item
.
actualPromotionStartDate
=
parseTime
(
item
.
actualPromotionStartDate
,
'{y}-{m}-{d}'
)
item
.
plannedPromotionEndDate
=
parseTime
(
item
.
plannedPromotionEndDate
,
'{y}-{m}-{d}'
)
item
.
actualPromotionEndDate
=
parseTime
(
item
.
actualPromotionEndDate
,
'{y}-{m}-{d}'
)
item
.
totalCostRate
=
item
.
totalCostRate
?
`
${(
item
.
totalCostRate
).
toFixed
(
2
)}
%`
:
'-'
item
.
adjustmentCostRatio
=
item
.
adjustmentCostRatio
?
`
${(
item
.
adjustmentCostRatio
).
toFixed
(
2
)}
%`
:
'-'
// 档期执行-促销口味从字符串转成数组(回显用)
item
.
actualPromotionFlavor
=
item
.
actualPromotionFlavor
?
item
.
actualPromotionFlavor
.
split
(
','
)
:
[]
// 修改时间
item
.
updateTime
=
parseTime
(
item
.
updateTime
,
'{y}-{m}-{d} {h}:{i}:{s}'
)
})
tableData
.
value
=
res
.
data
.
rows
total
.
value
=
res
.
data
.
total
isLoading
.
value
=
false
}
defineExpose
({
getTableList
})
// 表格格式化指定列的数据内容
const
formatterFn
=
(
row
,
col
,
cellValue
)
=>
{
if
(
col
.
prop
===
'actualPromotionFlavor'
)
{
// 对数组内容格式化,为空时,显示'-'
return
cellValue
.
length
?
cellValue
.
join
(
','
)
:
'-'
}
return
cellValue
}
onMounted
(()
=>
{
getTableList
()
})
const
showSearch
=
ref
(
true
)
/*************** 弹窗 ***************/
const
showPromotionDialog
=
ref
(
false
)
const
nowEnterRow
=
ref
({})
// 当前弹窗弹出时,要填写哪行的数据对象
const
nowEnterRowProp
=
ref
(
''
)
// 当前弹窗弹出时,要填写哪行的数据对象的属性
const
dialogForm
=
reactive
({
actualPromotionContent
:
''
,
})
// 弹窗关闭时,清空表单数据
const
handleDialogClose
=
()
=>
{
showPromotionDialog
.
value
=
false
dialogForm
.
actualPromotionContent
=
''
nowEnterRow
.
value
=
{}
nowEnterRowProp
.
value
=
''
}
// 确定
const
handleDialogConfirm
=
async
()
=>
{
if
(
!
dialogForm
.
actualPromotionContent
)
{
proxy
.
$modal
.
msgError
(
'请输入实际促销机制内容'
)
return
}
// 赋值
nowEnterRow
.
value
[
nowEnterRowProp
.
value
]
=
dialogForm
.
actualPromotionContent
showPromotionDialog
.
value
=
false
}
</
script
>
src/views/mobile/pages/storeExecution/report/tabs/schedule_dis.vue
0 → 100644
浏览文件 @
017cd04d
<
template
>
<!-- 档期陈列 -->
<CustomTable
:tableData=
"tableData"
:baseColumns=
"baseColumns"
:total=
"total"
:params=
"params"
:isLoading=
"isLoading"
@
getTableList=
"getTableList"
@
updateShowSearch=
"v => showSearch.value = v"
/>
</
template
>
<
script
setup
lang=
"jsx"
>
import
CustomTable
from
'../components/Table'
import
SearchList
from
'../components/SearchList'
import
{
getDisplayScheduleDetail
,
submitDisplayScheduleDetail
}
from
'@/api'
import
{
parseTime
}
from
'@/utils'
import
{
getScheduleDisConfig
}
from
'./data'
/*************** 表格数据 ***************/
const
props
=
defineProps
({
params
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
// 提交变更
const
submitChange
=
async
(
row
,
col
)
=>
{
// 需要特殊处理的
// 1. 实际主货架-形式,为空时,置空实际主货架-数量
if
(
col
.
prop
===
'actualMainShelfType'
&&
!
row
.
actualMainShelfType
)
{
row
.
actualMainShelfQty
=
0
}
// 关联的公式计算列,需要特殊处理
for
(
const
str
of
col
.
requestKey
)
{
const
obj
=
getScheduleDisConfig
().
flatMap
(
item
=>
{
if
(
item
.
children
)
{
return
item
.
children
.
filter
(
child
=>
!
child
.
onlyFill
);
}
return
[];
}).
find
(
item
=>
item
.
prop
===
str
)
if
(
obj
&&
obj
.
type
===
'formula'
)
{
obj
.
func
(
row
)
}
}
await
submitDisplayScheduleDetail
({
id
:
row
.
sapdId
,
[
col
.
prop
]:
row
[
col
.
prop
],
// 当前修改列的值
...
col
.
requestKey
.
reduce
((
acc
,
key
)
=>
({
...
acc
,
[
key
]:
row
[
key
]
}),
{}),
// 额外携带影响的列字段值
// 特殊类型字段处理
// 端架数量实际
actualEndCapQty
:
row
.
actualEndCapQty
||
0
,
// 地堆平米数实际
actualFloorStackArea
:
row
.
actualFloorStackArea
||
0
,
})
}
// 全部列
const
baseColumns
=
ref
(
getScheduleDisConfig
(
submitChange
));
// 表格数据
const
tableData
=
ref
([])
const
isLoading
=
ref
(
true
)
const
params
=
ref
({
pageNum
:
1
,
pageSize
:
50
,
salesMonth
:
new
Date
(),
deptName
:
''
,
dealerCN
:
''
,
lineNameLike
:
''
,
storeCN
:
''
})
const
total
=
ref
(
0
)
// 筛选工具
const
getTableList
=
async
()
=>
{
isLoading
.
value
=
true
const
res
=
await
getDisplayScheduleDetail
({
...
props
.
params
,
salesMonth
:
parseTime
(
props
.
params
.
salesMonth
,
'{y}-{m}'
)
})
res
.
data
.
rows
.
forEach
(
item
=>
{
// 计划月份
item
.
salesMonth
=
parseTime
(
item
.
salesMonth
,
'{y}-{m}'
)
// 开户日期
item
.
openingDate
=
parseTime
(
item
.
openingDate
,
'{y}-{m}-{d}'
)
// 闭户日期
item
.
closingDate
=
parseTime
(
item
.
closingDate
,
'{y}-{m}-{d}'
)
// 计划 - 档期开始时间
item
.
plannedPromotionStartDate
=
parseTime
(
item
.
plannedPromotionStartDate
,
'{y}-{m}-{d}'
)
// 计划 - 补差开始时间
item
.
plannedAdjustmentStartDate
=
parseTime
(
item
.
plannedAdjustmentStartDate
,
'{y}-{m}-{d}'
)
// 计划 - 档期结束时间
item
.
plannedPromotionEndDate
=
parseTime
(
item
.
plannedPromotionEndDate
,
'{y}-{m}-{d}'
)
// 计划 - 补差结束时间
item
.
plannedAdjustmentEndDate
=
parseTime
(
item
.
plannedAdjustmentEndDate
,
'{y}-{m}-{d}'
)
// 计划 - 档期陈列开始时间
item
.
plannedPromotionDisplayStartDate
=
parseTime
(
item
.
plannedPromotionDisplayStartDate
,
'{y}-{m}-{d}'
)
// 计划 - 档期陈列结束时间
item
.
plannedPromotionDisplayEndDate
=
parseTime
(
item
.
plannedPromotionDisplayEndDate
,
'{y}-{m}-{d}'
)
// 修改时间
item
.
updateTime
=
parseTime
(
item
.
updateTime
,
'{y}-{m}-{d} {h}:{i}:{s}'
)
// 特殊类型处理
// item.actualEndCapQty = item.actualEndCapQty || ''
// item.actualFloorStackArea = item.actualFloorStackArea || ''
})
tableData
.
value
=
res
.
data
.
rows
total
.
value
=
res
.
data
.
total
isLoading
.
value
=
false
}
getTableList
()
defineExpose
({
getTableList
})
const
showSearch
=
ref
(
true
)
</
script
>
\ No newline at end of file
src/views/mobile/pages/storeExecution/report/tabs/six_little_diamonds.vue
0 → 100644
浏览文件 @
017cd04d
<
template
>
<!-- 六小金刚 -->
<CustomTable
:tableData=
"tableData"
:baseColumns=
"baseColumns"
:total=
"total"
:params=
"params"
:isLoading=
"isLoading"
@
getTableList=
"getTableList"
@
updateShowSearch=
"v => showSearch.value = v"
/>
</
template
>
<
script
setup
lang=
"jsx"
>
import
CustomTable
from
'../components/Table'
import
SearchList
from
'../components/SearchList'
import
{
getSixLittleDiamondsPlanList
,
submitSixLittleDiamondsPlan
}
from
'@/api'
import
{
getSixLittleDiamondsConfig
}
from
'./data.jsx'
import
{
parseTime
}
from
'@/utils'
const
{
proxy
}
=
getCurrentInstance
()
/*************** 搜索列表 ***************/
const
showSearch
=
ref
(
true
)
/*************** 表格 ***************/
const
props
=
defineProps
({
params
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
// 提交变更
const
submitChange
=
async
(
row
,
col
)
=>
{
let
requestObj
=
{}
if
(
col
.
requestKey
)
{
// 关联的公式计算列,需要特殊处理
for
(
const
str
of
col
.
requestKey
)
{
const
obj
=
getSixLittleDiamondsConfig
().
flatMap
(
item
=>
{
if
(
item
.
children
)
{
return
item
.
children
.
filter
(
child
=>
!
child
.
onlyFill
);
}
return
[];
}).
find
(
item
=>
item
.
prop
===
str
)
if
(
obj
&&
obj
.
type
===
'formula'
)
{
obj
.
func
(
row
)
}
}
requestObj
=
col
.
requestKey
.
reduce
((
acc
,
key
)
=>
({
...
acc
,
[
key
]:
row
[
key
]
}),
{})
}
await
submitSixLittleDiamondsPlan
({
id
:
row
.
sadjId
,
[
col
.
prop
]:
row
[
col
.
prop
],
// 当前修改列的值
...
requestObj
})
}
// 全部列
const
baseColumns
=
ref
(
getSixLittleDiamondsConfig
(
submitChange
));
const
tableData
=
ref
([])
const
isLoading
=
ref
(
false
)
const
total
=
ref
(
0
)
const
params
=
ref
({
pageNum
:
1
,
pageSize
:
50
,
salesMonth
:
new
Date
(),
deptName
:
''
,
dealerCN
:
''
,
lineNameLike
:
''
,
storeCN
:
''
})
const
getTableList
=
()
=>
{
isLoading
.
value
=
true
getSixLittleDiamondsPlanList
({
...
props
.
params
,
salesMonth
:
proxy
.
parseTime
(
props
.
params
.
salesMonth
,
'{y}-{m}'
)
}).
then
(
res
=>
{
isLoading
.
value
=
false
tableData
.
value
=
res
.
data
.
rows
.
map
(
item
=>
{
// 计划月份
item
.
salesMonth
=
proxy
.
parseTime
(
item
.
salesMonth
,
'{y}-{m}'
)
return
item
})
||
[]
total
.
value
=
res
.
data
.
total
||
0
})
}
getTableList
()
defineExpose
({
getTableList
})
</
script
>
<
style
scoped
></
style
>
\ No newline at end of file
src/views/mobile/pages/storeExecution/report/tabs/snack.vue
0 → 100644
浏览文件 @
017cd04d
<
template
>
<!-- 零食陈列 -->
<CustomTable
:tableData=
"tableData"
:baseColumns=
"baseColumns"
:total=
"total"
:params=
"params"
:isLoading=
"isLoading"
@
getTableList=
"getTableList"
@
updateShowSearch=
"v => showSearch.value = v"
/>
</
template
>
<
script
setup
lang=
"jsx"
>
import
CustomTable
from
'../components/Table'
import
SearchList
from
'../components/SearchList'
import
{
getSnackPlanList
,
submitSnackPlan
}
from
'@/api'
import
{
parseTime
}
from
'@/utils'
import
{
getSnackCofing
}
from
'./data.jsx'
;
/*************** 操作类型 ***************/
const
props
=
defineProps
({
params
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
// 提交变更
const
submitChange
=
async
(
row
,
col
)
=>
{
// 需要特殊处理的
// 1. 实际主货架-形式,为空时,置空实际主货架-数量
// if (col.prop === 'actualMainShelfType' && !row.actualMainShelfType) {
// row.actualMainShelfQty = 0
// }
// 关联的公式计算列,需要特殊处理
for
(
const
str
of
col
.
requestKey
)
{
const
obj
=
getSnackCofing
().
flatMap
(
item
=>
{
if
(
item
.
children
)
{
return
item
.
children
.
filter
(
child
=>
!
child
.
onlyFill
);
}
return
[];
}).
find
(
item
=>
item
.
prop
===
str
)
if
(
obj
&&
obj
.
type
===
'formula'
)
{
obj
.
func
(
row
)
}
}
await
submitSnackPlan
({
id
:
row
.
sasdId
,
[
col
.
prop
]:
row
[
col
.
prop
],
// 当前修改列的值
...
col
.
requestKey
.
reduce
((
acc
,
key
)
=>
({
...
acc
,
[
key
]:
row
[
key
]
}),
{}),
// 额外携带影响的列字段值
})
// // 这些提交变化的,同时会影响公式计算的,需要把公式计算的字段列结果,一起发给后台
// // 注意:实际主货架形式改变并为空时,要置空实际主货架数量
// if (col.prop === 'actualMainShelfType' && !row.actualMainShelfType) {
// row.actualMainShelfQty = ''
// // 并提交保存一次
// await submitDisplayPlan({
// id: row.sadId,
// actualMainShelfQty: row.actualMainShelfQty,
// })
// }
// // 主货架
// if (['actualMainShelfType', 'actualMainShelfQty'].includes(col.prop)) {
// await submitDisplayPlan({
// id: row.sadId,
// actualMainShelfExecuted: row.actualMainShelfExecuted,
// })
// }
// // 端架
// if (['actualEndCapQty'].includes(col.prop)) {
// await submitDisplayPlan({
// id: row.sadId,
// actualEndCapExecuted: row.actualEndCapExecuted,
// })
// }
// // 地堆
// if (['actualFloorStackArea', 'actualFloorStackQty'].includes(col.prop)) {
// await submitDisplayPlan({
// id: row.sadId,
// actualFloorStackExecuted: row.actualFloorStackExecuted,
// })
// }
// // 常规陈列是否执行
// await submitDisplayPlan({
// id: row.sadId,
// regularDisplayExecuted: row.regularDisplayExecuted,
// })
}
// 全部列
const
baseColumns
=
ref
(
getSnackCofing
(
submitChange
));
// 表格数据
const
tableData
=
ref
([])
const
isLoading
=
ref
(
true
)
const
params
=
ref
({
pageNum
:
1
,
pageSize
:
50
,
salesMonth
:
new
Date
(),
deptName
:
''
,
dealerCN
:
''
,
lineNameLike
:
''
,
storeCN
:
''
})
const
total
=
ref
(
0
)
// 筛选工具
const
getTableList
=
async
()
=>
{
isLoading
.
value
=
true
const
res
=
await
getSnackPlanList
({
...
props
.
params
,
salesMonth
:
parseTime
(
props
.
params
.
salesMonth
,
'{y}-{m}'
)
})
res
.
data
.
rows
.
forEach
(
item
=>
{
// 计划月份
item
.
salesMonth
=
parseTime
(
item
.
salesMonth
,
'{y}-{m}'
)
// 开户日期
item
.
openingDate
=
parseTime
(
item
.
openingDate
,
'{y}-{m}-{d}'
)
// 闭户日期
item
.
closingDate
=
parseTime
(
item
.
closingDate
,
'{y}-{m}-{d}'
)
// 修改时间
item
.
updateTime
=
parseTime
(
item
.
updateTime
,
'{y}-{m}-{d} {h}:{i}:{s}'
)
})
tableData
.
value
=
res
.
data
.
rows
total
.
value
=
res
.
data
.
total
isLoading
.
value
=
false
}
getTableList
()
defineExpose
({
getTableList
})
const
showSearch
=
ref
(
true
)
</
script
>
<
style
scoped
lang=
"scss"
>
.container
{
.el-tabs
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column-reverse
;
.el-tabs__content
{
display
:
flex
;
flex-direction
:
column
;
height
:
100%
;
.el-tab-pane
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
.pagination-container
{
margin
:
10px
;
}
}
.formula-column
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
.el-icon
{
margin-left
:
2px
;
}
}
}
}
.el-form-item
{
align-items
:
center
;
}
/* 表格区域 */
.auto-fit-header-table
{
/* 优化超长文本的显示效果 */
.cell
{
/* padding: 0 .2133rem; */
}
::v-deep
(
.el-table__row
)
{
.el-table__cell
{
padding
:
0
;
}
}
::v-deep
(
.column-style
)
{
.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
;
}
.el-input
{
padding
:
10px
;
}
}
}
}
}
</
style
>
\ No newline at end of file
src/views/mobile/pages/storeExecution/report/tabs/three_two_seconds.vue
0 → 100644
浏览文件 @
017cd04d
<
template
>
<!-- 三米两秒 -->
<CustomTable
:tableData=
"tableData"
:baseColumns=
"baseColumns"
:total=
"total"
:params=
"params"
:isLoading=
"isLoading"
@
getTableList=
"getTableList"
@
updateShowSearch=
"v => showSearch.value = v"
/>
</
template
>
<
script
setup
lang=
"jsx"
>
import
CustomTable
from
'../components/Table'
import
{
getThreeMetersTwoSecondsPlanList
,
submitThreeMetersTwoSecondsPlan
}
from
'@/api'
import
{
getThreeTwoSecondsConfig
}
from
'./data.jsx'
const
{
proxy
}
=
getCurrentInstance
()
/*************** 搜索列表 ***************/
const
showSearch
=
ref
(
true
)
/*************** 表格 ***************/
const
props
=
defineProps
({
params
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
// 提交变更
const
submitChange
=
async
(
row
,
col
)
=>
{
let
requestObj
=
{}
if
(
col
.
requestKey
)
{
// 关联的公式计算列,需要特殊处理
for
(
const
str
of
col
.
requestKey
)
{
const
obj
=
getThreeTwoSecondsConfig
().
flatMap
(
item
=>
{
if
(
item
.
children
)
{
return
item
.
children
.
filter
(
child
=>
!
child
.
onlyFill
);
}
return
[];
}).
find
(
item
=>
item
.
prop
===
str
)
if
(
obj
&&
obj
.
type
===
'formula'
)
{
obj
.
func
(
row
)
}
}
requestObj
=
col
.
requestKey
.
reduce
((
acc
,
key
)
=>
({
...
acc
,
[
key
]:
row
[
key
]
}),
{})
}
await
submitThreeMetersTwoSecondsPlan
({
id
:
row
.
sadsId
,
[
col
.
prop
]:
row
[
col
.
prop
],
// 当前修改列的值
...
requestObj
})
}
// 全部列
const
baseColumns
=
ref
(
getThreeTwoSecondsConfig
(
submitChange
));
const
tableData
=
ref
([])
const
isLoading
=
ref
(
false
)
const
total
=
ref
(
0
)
const
params
=
ref
({
pageNum
:
1
,
pageSize
:
50
,
salesMonth
:
new
Date
(),
deptName
:
''
,
dealerCN
:
''
,
lineNameLike
:
''
,
storeCN
:
''
})
const
getTableList
=
()
=>
{
isLoading
.
value
=
true
getThreeMetersTwoSecondsPlanList
({
...
params
.
value
,
salesMonth
:
proxy
.
parseTime
(
params
.
value
.
salesMonth
,
'{y}-{m}'
)
}).
then
(
res
=>
{
isLoading
.
value
=
false
tableData
.
value
=
res
.
data
.
rows
.
map
(
item
=>
{
// 计划月份
item
.
salesMonth
=
proxy
.
parseTime
(
item
.
salesMonth
,
'{y}-{m}'
)
return
item
})
||
[]
total
.
value
=
res
.
data
.
total
||
0
})
}
getTableList
()
defineExpose
({
getTableList
})
</
script
>
<
style
scoped
></
style
>
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论