Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
wangxiaolu-sfa-ui
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
sfa
wangxiaolu-sfa-ui
Commits
19b17451
提交
19b17451
authored
1月 20, 2025
作者:
lidongxu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(bi/finance): 口味规格和直播间支持全选
watch 观察表单参数有值显示对应列,暂时注释了,默认全都显示所有列
上级
4069f78a
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
185 行增加
和
89 行删除
+185
-89
finance.js
src/api/bi/finance.js
+12
-6
index.vue
src/components/XLSelect/index.vue
+19
-16
date.js
src/hooks/date.js
+5
-2
index.vue
src/views/bi/finance/index.vue
+149
-65
没有找到文件。
src/api/bi/finance.js
浏览文件 @
19b17451
...
...
@@ -42,9 +42,12 @@ export const getFinanceListAPI = (data) => {
url
:
'/bi/finance/cost/list'
,
method
:
'POST'
,
data
:
{
zbjQdType
:
data
.
brand
,
flavor
:
data
.
taste
,
specName
:
data
.
spec
,
zbjQdType
:
data
.
zbjQdType
,
flavor
:
data
.
flavorErp
,
specName
:
data
.
specNameErp
,
zbjQdTypeAll
:
data
.
zbjQdTypeAll
,
flavorErpAll
:
data
.
flavorErpAll
,
specNameErpAll
:
data
.
specNameErpAll
,
series
:
data
.
seriesPrdMap
.
map
(
o
=>
o
[
0
]),
goodsName
:
data
.
seriesPrdMap
.
map
(
o
=>
o
[
1
]),
startDate
:
parseTime
(
data
.
date
[
0
],
`{y}-{m}-{d}`
),
...
...
@@ -58,9 +61,12 @@ export const getFinanceDetailAPI = (data) => {
url
:
'/bi/finance/cost/detail/list'
,
method
:
'POST'
,
data
:
{
zbjQdType
:
data
.
brand
,
flavor
:
data
.
taste
,
specName
:
data
.
spec
,
zbjQdType
:
data
.
zbjQdType
,
flavor
:
data
.
flavorErp
,
specName
:
data
.
specNameErp
,
zbjQdTypeAll
:
data
.
zbjQdTypeAll
,
flavorErpAll
:
data
.
flavorErpAll
,
specNameErpAll
:
data
.
specNameErpAll
,
series
:
data
.
seriesPrdMap
.
map
(
o
=>
o
[
0
]),
goodsName
:
data
.
seriesPrdMap
.
map
(
o
=>
o
[
1
]),
startDate
:
parseTime
(
data
.
date
[
0
],
`{y}-{m}-{d}`
),
...
...
src/components/XLSelect/index.vue
浏览文件 @
19b17451
...
...
@@ -2,17 +2,18 @@
<el-select
v-bind=
"$attrs"
v-model=
"selectedOptions"
@
change=
"handleChange"
>
<el-option
v-for=
"str in options"
:label=
"str"
:value=
"str"
>
</el-option>
<li
class=
"el-select-dropdown__item all_item"
:class=
"
{ 'is-selected': isAll }"
v-if="props.options.length > 0"
@click.stop="selectAll"
@mouseenter.stop="over"
@mouseleave.stop="out">
<span>
全选
</span>
</li>
<el-option
v-for=
"obj in options"
:label=
"obj.label"
:value=
"obj.value"
>
</el-option>
</el-select>
</
template
>
...
...
@@ -20,7 +21,7 @@
const
selectedOptions
=
ref
([])
// 当前选中的值集合
const
isAll
=
ref
(
false
)
// 全选状态
const
emits
=
defineEmits
([
'update:modelValue'
]);
const
emits
=
defineEmits
([
'update:modelValue'
,
'change'
]);
const
props
=
defineProps
({
options
:
{
...
...
@@ -35,43 +36,45 @@ const props = defineProps({
watch
(()
=>
props
.
modelValue
,
val
=>
{
selectedOptions
.
value
=
val
;
isAll
.
value
=
val
.
length
===
props
.
options
.
length
if
(
props
.
options
.
length
>
0
)
{
isAll
.
value
=
val
.
length
===
props
.
options
.
length
}
},
{
deep
:
true
,
immediate
:
true
})
// 设置样式
const
noHover
=
()
=>
{
const
list
=
document
.
querySelectorAll
(
'.el-select-dropdown .el-select-dropdown__item'
)
list
.
forEach
(
el
=>
el
.
classList
.
add
(
'no-hovering'
))
}
// 全选点击
const
selectAll
=
()
=>
{
isAll
.
value
=
!
isAll
.
value
if
(
isAll
.
value
)
{
selectedOptions
.
value
=
[...
props
.
options
]
;
selectedOptions
.
value
=
props
.
options
.
map
(
item
=>
item
.
value
)
;
emits
(
'update:modelValue'
,
selectedOptions
.
value
);
emits
(
'change'
)
}
else
{
selectedOptions
.
value
=
[];
emits
(
'update:modelValue'
,
selectedOptions
.
value
);
emits
(
'change'
)
}
nextTick
(()
=>
{
noHover
()
const
list
=
document
.
querySelectorAll
(
'.el-select-dropdown .el-select-dropdown__item'
)
list
.
forEach
(
el
=>
el
.
classList
.
add
(
'no-hovering'
))
})
}
const
handleChange
=
(
val
)
=>
{
isAll
.
value
=
val
.
length
===
props
.
options
.
length
emits
(
'update:modelValue'
,
val
)
emits
(
'change'
)
}
const
over
=
()
=>
{
noHover
()
const
list
=
document
.
querySelectorAll
(
'.el-select-dropdown .el-select-dropdown__item'
)
list
.
forEach
(
el
=>
el
.
classList
.
add
(
'no-hovering'
))
}
const
out
=
()
=>
{
noHover
()
const
list
=
document
.
querySelectorAll
(
'.el-select-dropdown .el-select-dropdown__item'
)
list
.
forEach
(
el
=>
el
.
classList
.
remove
(
'no-hovering'
))
}
</
script
>
...
...
src/hooks/date.js
浏览文件 @
19b17451
...
...
@@ -3,9 +3,10 @@
* @param {*} type 0:从今天开始往前,-1 则是 T - 1 开始日期往前
* @returns {}
*/
export
const
useDatePickerOptions
=
(
type
=
-
1
,
)
=>
{
export
const
useDatePickerOptions
=
(
type
=
-
1
)
=>
{
const
last30Date
=
[
new
Date
().
setDate
((
new
Date
().
getDate
()
-
(
30
-
1
))),
new
Date
().
setDate
((
new
Date
().
getDate
()
+
type
))]
const
last7Date
=
[
new
Date
().
setDate
((
new
Date
().
getDate
()
-
(
7
-
1
))),
new
Date
().
setDate
((
new
Date
().
getDate
()
+
type
))]
const
lastDate
=
[
new
Date
().
setDate
((
new
Date
().
getDate
()
+
type
)),
new
Date
().
setDate
((
new
Date
().
getDate
()
+
type
))]
const
recentPickerOptions
=
ref
([
// 日期选项配置
{
text
:
'最近一周'
,
...
...
@@ -47,9 +48,10 @@ export const useDatePickerOptions = (type = -1,) => {
}
])
return
{
lastDate
,
// 昨天
last30Date
,
// 前 30 天
last7Date
,
// 前 7 天
recentPickerOptions
,
// 最近一周/一月
lastPickerOptions
lastPickerOptions
// 上一周/上一月
}
}
\ No newline at end of file
src/views/bi/finance/index.vue
浏览文件 @
19b17451
...
...
@@ -4,50 +4,50 @@
<!-- 搜索表单 -->
<el-form
:model=
"queryParams"
label-position=
"right"
label-width=
"
6
8px"
label-width=
"
8
8px"
inline
v-show=
"showSearch"
>
<el-form-item
label=
"直播间"
>
<el-select
v-model=
"queryParams.brand"
<el-form-item
label=
"直播间分类"
>
<xl-select
v-model=
"queryParams.zbjQdType"
:options=
"brandList"
selectAllValue=
"ALL"
multiple
clearable
filterable
collapse-tags
collapse-tags-tooltip
@
change=
"getList"
>
<el-option
v-for=
"item in brandList"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</el-select>
</xl-select>
</el-form-item>
<el-form-item
label=
"口味"
>
<
el-select
v-model=
"queryParams.taste
"
<
xl-select
v-model=
"queryParams.flavorErp
"
multiple
:options=
"tasteList"
clearable
filterable
collapse-tags
collapse-tags-tooltip
@
change=
"getList"
>
<el-option
v-for=
"item in tasteList"
<
!--
<
el-option
v-for=
"item in tasteList"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</
e
l-select>
</el-option>
-->
</
x
l-select>
</el-form-item>
<el-form-item
label=
"规格"
>
<el-select
v-model=
"queryParams.spec"
<xl-select
v-model=
"queryParams.specNameErp"
:options=
"specList"
multiple
clearable
filterable
collapse-tags
collapse-tags-tooltip
@
change=
"getList"
>
<el-option
v-for=
"item in specList"
<
!--
<
el-option
v-for=
"item in specList"
:label=
"item.label"
:value=
"item.value"
>
</el-option>
</
e
l-select>
</el-option>
-->
</
x
l-select>
</el-form-item>
<el-form-item
label=
"系列商品"
class=
"series"
>
...
...
@@ -100,13 +100,12 @@
</el-form-item>
</el-form>
<!-- 操作工具 -->
<el-row
class=
"mb8"
>
<el-row
class=
"mb8"
>
<el-button
icon=
"Refresh"
@
click=
"reset"
v-show=
"showSearch"
>
重置
</el-button>
@
click=
"reset"
v-show=
"showSearch"
>
重置
</el-button>
<right-toolbar
v-model:showSearch=
"showSearch"
@
queryTable=
"getList"
:columns=
"columns"
>
...
...
@@ -115,7 +114,10 @@
<!-- 数据 -->
<el-table
:data=
"tableList"
border
@
row-click=
"rowClick"
>
row-key=
"zbjQdType"
lazy
:load=
"load"
:tree-props=
"
{ children: 'children', hasChildren: 'hasChildren' }">
<template
v-for=
"item in columns"
>
<el-table-column
v-if=
"item.visible"
:key=
"item.prop"
...
...
@@ -125,6 +127,13 @@
:formatter=
"formatter"
>
</el-table-column>
</
template
>
<el-table-column
label=
"操作"
width=
"120"
>
<
template
v-slot=
"scope"
>
<el-button
type=
"primary"
link
@
click=
"rowClick(scope.row)"
>
订单详情
</el-button>
</
template
>
</el-table-column>
</el-table>
<!-- 订单详情 -->
<el-dialog
v-model=
"detailVisible"
...
...
@@ -169,16 +178,16 @@ import { getBrandListAPI, getTasteListAPI, getSpecListAPI, getSeriesListAPI, get
import
{
useDatePickerOptions
}
from
'@/hooks'
import
{
formatNumberWithUnit
,
parseTime
}
from
'@/utils'
const
{
lastPickerOptions
:
pickerOptions
}
=
useDatePickerOptions
()
const
{
lastPickerOptions
:
pickerOptions
,
lastDate
}
=
useDatePickerOptions
()
const
showSearch
=
ref
(
true
)
// 搜索
const
detailVisible
=
ref
(
false
)
// 详情
const
data
=
reactive
({
queryParams
:
{
brand
:
[],
// 直播间
taste
:
[],
// 口味
spec
:
[],
// 规格
date
:
[]
,
// 日期
zbjQdType
:
[],
// 直播间
flavorErp
:
[],
// 口味
spec
NameErp
:
[],
// 规格
date
:
lastDate
,
// 日期
seriesPrdMap
:
[]
// 系列商品
},
detailQueryParams
:
{
// 详情查询
...
...
@@ -191,13 +200,11 @@ const { queryParams, detailQueryParams } = toRefs(data)
const
reset
=
()
=>
{
queryParams
.
value
=
{
brand
:
[],
// 直播间
taste
:
[],
// 口味
spec
:
[],
// 规格
date
:
[],
// 日期
seriesPrdMap
:
[],
// 系列商品
pageNum
:
1
,
pageSize
:
10
zbjQdType
:
[],
// 直播间
flavorErp
:
[],
// 口味
specNameErp
:
[],
// 规格
date
:
lastDate
,
// 日期
seriesPrdMap
:
[]
// 系列商品
}
getList
()
}
...
...
@@ -212,6 +219,8 @@ const getBrandList = async () => {
label
:
obj
.
zbjQdType
};
});
// 默认查询所有直播间列表
queryParams
.
value
.
zbjQdType
=
brandList
.
value
.
map
(
obj
=>
obj
.
value
);
};
getBrandList
();
...
...
@@ -248,6 +257,7 @@ const getSeriesList = async () => {
seriesList
.
value
=
response
.
data
.
map
(
obj
=>
{
return
{
value
:
obj
.
seriesId
,
// value: obj.seriesName,
label
:
obj
.
seriesName
};
});
...
...
@@ -262,7 +272,8 @@ const props = reactive({ // 级联选择器配置
const
{
data
:
{
total
}
}
=
await
getProductListAPI
({
seriesId
});
const
{
data
:
{
rows
}
}
=
await
getProductListAPI
({
seriesId
,
pageNum
:
1
,
pageSize
:
total
});
const
nodes
=
rows
.
map
(
item
=>
({
value
:
item
.
prdCode
,
// value: item.prdCode,
value
:
item
.
prdName
,
label
:
item
.
prdName
,
leaf
:
true
// 指定叶子节点
}));
...
...
@@ -277,71 +288,105 @@ const props = reactive({ // 级联选择器配置
// 表格数据
const
columns
=
ref
([
{
label
:
'直播间'
,
label
:
'直播间
分类
'
,
prop
:
'zbjQdType'
,
visible
:
true
,
width
:
140
width
:
140
,
check
:
true
// 根据查询条件有无,判断当前列实/隐
},
{
label
:
'口味'
,
prop
:
'flavorErp'
,
visible
:
true
,
width
:
120
width
:
120
,
check
:
true
},
{
label
:
'规格'
,
prop
:
'specNameErp'
,
visible
:
true
,
width
:
140
width
:
140
,
check
:
true
},
{
label
:
'系列'
,
prop
:
''
,
prop
:
'
series
'
,
visible
:
true
,
width
:
140
width
:
140
,
check
:
true
},
{
label
:
'商品'
,
prop
:
'goodsName'
,
visible
:
true
,
width
:
140
width
:
140
,
check
:
true
},
{
label
:
'分销商 id'
,
prop
:
'fenxiaoId'
,
visible
:
true
,
width
:
100
,
check
:
true
},
{
label
:
'分销商名称'
,
prop
:
'fenxiaoName'
,
visible
:
true
,
width
:
200
,
check
:
true
},
{
label
:
'分摊后总价'
,
prop
:
'shareAmountSum'
,
visible
:
true
,
width
:
120
width
:
120
,
check
:
false
},
{
label
:
'实际成本'
,
prop
:
'actualCostSum'
,
visible
:
true
,
width
:
120
width
:
120
,
check
:
false
},
{
label
:
'实际成本毛利'
,
prop
:
'actualCostGrossProfitSum'
,
visible
:
true
,
width
:
120
width
:
120
,
check
:
false
},
{
label
:
'标准成本'
,
prop
:
'standardCostSum'
,
visible
:
true
,
width
:
120
width
:
120
,
check
:
false
},
{
label
:
'标准成本毛利'
,
prop
:
'standardCostGrossProfitSum'
,
visible
:
true
,
width
:
120
width
:
120
,
check
:
false
}
])
const
tableList
=
ref
([
])
const
getList
=
async
()
=>
{
// 直播间分类全选时,单独增加字段给后台
queryParams
.
value
.
zbjQdTypeAll
=
(
queryParams
.
value
.
zbjQdType
.
length
===
brandList
.
value
.
length
)
// 口味
queryParams
.
value
.
flavorErpAll
=
(
queryParams
.
value
.
flavorErp
.
length
===
tasteList
.
value
.
length
)
// 规格
queryParams
.
value
.
specNameErpAll
=
(
queryParams
.
value
.
specNameErp
.
length
===
specList
.
value
.
length
)
const
res
=
await
getFinanceListAPI
(
queryParams
.
value
)
tableList
.
value
=
res
.
data
.
list
tableList
.
value
=
res
.
data
.
list
.
map
(
o
=>
{
o
.
hasChildren
=
true
return
o
})
}
getList
()
...
...
@@ -353,6 +398,55 @@ const formatter = (row, column, value) => {
}
}
// 观察查询表单选择字段,则显示
// watch(queryParams, (val) => {
// // 日期无需决定列显示与否
// const showQuery = { ...val }
// delete showQuery.date
// // 如果每个筛选条件都无值,则显示直播间分类这一列
// if (Object.values(showQuery).every(item => item.length === 0)) {
// columns.value.forEach(item => {
// if (item.check) {
// item.visible = item.prop === 'zbjQdType'
// }
// })
// return
// }
// // 哪个筛选条件有值,则显示哪一列
// Object.entries(showQuery).forEach(([key, value]) => {
// // 处理查询参数名和列 prop 字段名不同的情况
// // 系列和商品搜索字段叫 seriesPrdMap,但是列字段叫 series 和 goodsName
// if (key === 'seriesPrdMap') {
// const columnSeries = columns.value.find(item => item.prop === 'series')
// const columnGoods = columns.value.find(item => item.prop === 'goodsName')
// if (columnSeries && columnGoods) {
// columnSeries.visible = value.length > 0
// columnGoods.visible = value.length > 0
// }
// } else {
// // 查询参数名和 prop 能对上的
// const columnObj = columns.value.find(item => item.prop === key)
// if (columnObj && columnObj.check) {
// // 显示该列
// columnObj.visible = value.length > 0
// }
// }
// })
// }, {
// deep: true,
// immediate: true
// })
// 展开行
const
load
=
(
options
)
=>
{
// 请求某个展开行下属的数据
console
.
log
(
options
)
// const { page, limit } = options
// queryParams.value.pageNum = page
// queryParams.value.pageSize = limit
// getList()
}
// 详情数据
const
detailList
=
ref
([])
const
detailColumns
=
ref
([
...
...
@@ -508,24 +602,14 @@ const giftType = {
const
rowClick
=
(
row
)
=>
{
detailQueryParams
.
value
=
{
brand
:
row
.
zbjQdType
&&
[
row
.
zbjQdType
],
// 直播间
taste
:
row
.
flavorErp
&&
[
row
.
flavorErp
],
// 口味
spec
:
row
.
specNameErp
&&
[
row
.
specNameErp
],
// 规格
seriesPrdMap
:
[
],
// TODO:行里没有系列字段等会看下
zbjQdType
:
row
.
zbjQdType
&&
[
row
.
zbjQdType
],
// 直播间
flavorErp
:
row
.
flavorErp
&&
[
row
.
flavorErp
],
// 口味
spec
NameErp
:
row
.
specNameErp
&&
[
row
.
specNameErp
],
// 规格
seriesPrdMap
:
row
.
seriesId
&&
[{
value
:
row
.
seriesId
,
label
:
row
.
seriesName
}
],
// TODO:行里没有系列字段等会看下
date
:
queryParams
.
value
.
date
,
// 日期
pageNum
:
1
,
pageSize
:
10
}
// 口味
row
.
flavorErp
&&
(
detailQueryParams
.
value
.
taste
=
[
row
.
flavorErp
])
// 规格
row
.
specNameErp
&&
(
detailQueryParams
.
value
.
spec
=
[
row
.
specNameErp
])
// 系列+商品
row
.
seriesId
&&
(
detailQueryParams
.
value
.
seriesPrdMap
=
[{
value
:
row
.
seriesId
,
label
:
row
.
seriesName
}])
// 日期
detailQueryParams
.
value
.
date
=
queryParams
.
value
.
date
detailQueryParams
.
value
.
pageNum
=
1
detailQueryParams
.
value
.
pageSize
=
10
detailVisible
.
value
=
true
getDetailList
()
}
...
...
@@ -543,7 +627,7 @@ const detailFormatter = (row, column, value) => {
return
goodsType
[
value
]
}
else
if
([
'giftType'
].
includes
(
column
.
property
))
{
return
giftType
[
value
]
}
}
return
value
}
const
changeShowOver
=
()
=>
{
...
...
@@ -554,7 +638,7 @@ const changeShowOver = () => {
<
style
scoped
lang=
"scss"
>
::v-deep
(
.el-form-item
)
{
width
:
25
0px
;
width
:
30
0px
;
&
.date_picker
{
width
:
350px
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论