Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
wangxiaolu-sfa-ui
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
sfa
wangxiaolu-sfa-ui
Commits
f552a6b9
提交
f552a6b9
authored
1月 07, 2025
作者:
lidongxu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor(bi/product/index.vue): bi 商品管理重构完成-包括单屏幕适配
同上
上级
16c93ed7
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
264 行增加
和
195 行删除
+264
-195
element-ui.scss
src/assets/styles/element-ui.scss
+5
-0
index.scss
src/assets/styles/index.scss
+6
-1
index.vue
src/components/CategoryTree/index.vue
+180
-170
AppMain.vue
src/layout/components/AppMain.vue
+0
-1
index.vue
src/layout/index.vue
+32
-2
index.vue
src/views/bi/competitor/index.vue
+1
-0
index.vue
src/views/bi/product/index.vue
+39
-17
index.vue
src/views/bi/sale/index.vue
+1
-4
没有找到文件。
src/assets/styles/element-ui.scss
浏览文件 @
f552a6b9
...
...
@@ -91,6 +91,7 @@
color
:
var
(
--
el-color-primary
)
!
important
;
}
// 覆盖默认样式
.el-select
{
width
:
215px
;
}
...
...
@@ -98,3 +99,7 @@
.el-tabs
{
flex
:
1
;
}
.el-form-item
{
margin-bottom
:
0
;
}
src/assets/styles/index.scss
浏览文件 @
f552a6b9
...
...
@@ -127,6 +127,10 @@ aside {
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
padding
:
20px
;
>
div
{
width
:
100%
;
}
}
.components-container
{
...
...
@@ -184,4 +188,4 @@ aside {
vertical-align
:
middle
;
margin-bottom
:
10px
;
}
}
}
\ No newline at end of file
src/components/CategoryTree/index.vue
浏览文件 @
f552a6b9
<
template
>
<el-col
:span=
"hideSideBar ?
colSpan : 0
"
<el-col
:span=
"hideSideBar ?
0 : colSpan
"
:xs=
"24"
class=
"col"
@
click
.
native=
"cancelSel"
>
<div
v-show=
"hideSideBar"
<div
v-show=
"
!
hideSideBar"
class=
"content"
>
<div
class=
"buttons_wrap"
>
<!-- 扩展的按钮
集合
-->
<!-- 扩展的按钮 -->
<slot
name=
"buttons"
></slot>
<el-input
v-model=
"searchValue"
:placeholder=
"placeholder"
clearable
prefix-icon=
"
el-icon-s
earch"
/>
prefix-icon=
"
S
earch"
/>
</div>
<div
class=
"scroll"
:class=
"
{'row_gap': rowGap}">
<div
class=
"scroll"
:class=
"
{ 'row_gap': customOptions.rowGap }">
<el-tree
:data=
"options"
v-loading=
"loading"
:props=
"defaultProps"
:expand-on-click-node=
"false"
:filter-node-method=
"filterNode"
ref=
"tree"
ref=
"tree
Ref
"
:node-key=
"nodeKey"
highlight-current
default
...
...
@@ -27,10 +27,12 @@
@
node-click=
"handleNodeClick"
>
<template
class=
"custom-tree-node"
v-slot=
"
{ node, data }"
:style="{margin: rowGap * 3 + 'px !important'}">
<svg-icon
v-if=
"showIcon"
icon-class=
"tab"
style=
"fill: #409eff; stroke: red; margin-right: 10px;"
/>
:style="{ margin: rowGap + 'px !important' }">
<svg-icon
v-if=
"customOptions.showIcon"
icon-class=
"tab"
style=
"fill: #409eff; stroke: red; margin-right: 10px;"
/>
<span>
{{
node
.
label
}}
</span>
<span
v-if=
"
showEditDe
l"
<span
v-if=
"
customOptions.showToo
l"
class=
"edit_del"
>
<span
style=
"margin-right: 10px;"
>
创建人:
{{
data
.
createBy
}}
</span>
<i
class=
"el-icon-edit"
...
...
@@ -41,173 +43,177 @@
</
template
>
</el-tree>
<!-- 分页 -->
<pagination
v-if=
"isPagination"
:total=
"total"
v-model:page=
"queryParams.pageNum"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getPageList"
/>
<!-- 折叠箭头 -->
<pagination
v-if=
"customOptions.showPagination"
:total=
"customOptions.total"
v-model:page=
"queryParams.pageNum"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getPageList"
/>
<!-- 折叠分类侧边栏 -->
<div
class=
"arrow"
@
click=
"hideSideBar =
fals
e"
>
@
click=
"hideSideBar =
tru
e"
>
<svg-icon
icon-class=
"left-arrow"
/>
</div>
</div>
</div>
<!--
表格折叠箭头
-->
<!--
展开分类侧边栏
-->
<div
class=
"arrow"
v-show=
"
!
hideSideBar"
v-show=
"hideSideBar"
@
click=
"hideSideBar = !hideSideBar"
>
<svg-icon
icon-class=
"right-arrow"
/>
</div>
</el-col>
</template>
<
script
>
export
default
{
name
:
"FlodSidebar"
,
props
:
{
// 树结构数据
options
:
{
type
:
Array
,
required
:
true
,
default
:
()
=>
{
return
[];
}
},
// 树结构主键
nodeKey
:
{
type
:
String
,
default
:
'id'
},
// 树结构使用字段
defaultProps
:
{
type
:
Object
,
default
:
()
=>
{
return
{};
}
},
// 默认展开哪些行
defaultExpandList
:
{
type
:
Array
,
default
:
()
=>
{
return
[];
}
},
// 搜索占位符
placeholder
:
{
type
:
String
,
default
:
''
},
// 选中某行数据对象
value
:
{
type
:
[
Number
,
String
]
},
// 占 el-col 几份宽度
colSpan
:
{
type
:
Number
,
default
:
6
},
// 左侧分类框右侧是否出现编辑和删除按钮
showEditDel
:
{
type
:
Boolean
,
default
:
false
},
// 数据重载中
loading
:
{
type
:
Boolean
,
default
:
false
},
// 是否展示图标
showIcon
:
{
type
:
Boolean
,
default
:
false
},
// 行之间的间隙
rowGap
:
{
type
:
Boolean
,
default
:
false
},
// 开启分页
isPagination
:
{
type
:
Boolean
,
default
:
false
},
// (若有分页功能)- 总数
total
:
{
type
:
Number
,
default
:
0
<
script
setup
>
const
props
=
defineProps
({
// 树结构数据
options
:
{
type
:
Array
,
required
:
true
,
default
:
()
=>
{
return
[]
}
},
data
()
{
return
{
// 侧边栏展开与否
hideSideBar
:
true
,
// 搜索关键字
searchValue
:
''
,
// 上次点击的行对象-唯一值
lastRowId
:
null
,
// 分页参数
queryParams
:
{
pageNum
:
1
,
pageSize
:
10
},
};
// 树结构主键
nodeKey
:
{
type
:
String
,
default
:
'id'
},
watch
:
{
// 根据名称筛选树
searchValue
(
val
)
{
// 如果做了分页走网络搜索
if
(
!
this
.
isPagination
)
{
// 没有分页,用本地列表搜索
this
.
$refs
.
tree
.
filter
(
val
);
}
else
{
// 有分页,走外面搜索
this
.
queryParams
.
searchKey
=
val
this
.
$emit
(
'pageChange'
,
this
.
queryParams
)
}
},
value
(
val
)
{
this
.
$nextTick
(()
=>
{
this
.
$refs
.
tree
.
setCurrentKey
(
val
)
this
.
lastRowId
=
val
})
}
// 树结构使用字段
defaultProps
:
{
type
:
Object
},
methods
:
{
// 空白位置-取消选中效果
cancelSel
()
{
// 刚才有过点击的某行
if
(
this
.
lastRow
)
{
this
.
$refs
.
tree
.
setCurrentKey
(
null
)
this
.
lastRow
=
null
this
.
$emit
(
'update:modelValue'
,
''
)
this
.
$emit
(
'search'
)
}
},
// 点击某行
handleNodeClick
(
row
)
{
// 当前点击和上次点击一样->取消
if
(
this
.
lastRowId
===
row
[
this
.
nodeKey
])
{
this
.
$refs
.
tree
.
setCurrentKey
(
null
)
this
.
lastRowId
=
null
}
else
{
this
.
lastRowId
=
row
[
this
.
nodeKey
]
}
this
.
$emit
(
'update:modelValue'
,
this
.
lastRowId
?
row
[
this
.
nodeKey
]
:
''
)
this
.
$emit
(
'search'
)
},
// tree 筛选节点
filterNode
(
value
,
data
)
{
if
(
!
value
)
return
true
;
return
data
[
this
.
defaultProps
.
label
].
indexOf
(
value
)
!==
-
1
;
},
// 分页逻辑触发
getPageList
(){
this
.
$emit
(
'pageChange'
,
this
.
queryParams
)
}
// 默认展开哪些行
defaultExpandList
:
{
type
:
Array
},
// 搜索占位符
placeholder
:
{
type
:
String
,
default
:
'搜索关键字'
},
// 加载状态
loading
:
{
type
:
Boolean
,
default
:
false
},
// 选中某行数据对象
value
:
{
type
:
[
Number
,
String
],
default
:
''
},
// el-col 宽度
colSpan
:
{
type
:
Number
,
default
:
6
},
// 详细配置左侧分类框
customOptions
:
{
type
:
Object
,
default
:
()
=>
({
// 右侧工具是否显示
showTool
:
false
,
// 左侧图表是否显示
showIcon
:
false
,
// 行与行间隙
rowGap
:
0
,
// 底部分页是否显示
showPagination
:
false
,
// 分页数据总条数
total
:
0
})
}
})
// 隐藏左侧分类框
const
hideSideBar
=
ref
(
false
)
// 搜索关键字
const
searchValue
=
ref
(
''
)
// 上次点击的行对象-唯一值
const
lastRowId
=
ref
(
null
)
const
lastRow
=
ref
(
null
)
// 分页参数
const
queryParams
=
reactive
({
pageNum
:
1
,
pageSize
:
10
})
const
treeRef
=
ref
(
null
)
const
emits
=
defineEmits
([
'update:modelValue'
,
'search'
,
'pageChange'
])
watch
(
searchValue
,
(
val
)
=>
{
if
(
!
props
.
customOptions
.
showPagination
)
{
// 没有分页,用本地列表搜索
treeRef
.
value
.
filter
(
val
);
}
else
{
// 有分页,走外面接口搜索
queryParams
.
searchKey
=
val
emits
(
'search'
,
queryParams
)
}
})
// 如果有 v-model 则设置默认选中值
watch
(()
=>
props
.
value
,
(
val
)
=>
{
if
(
val
)
{
nextTick
(()
=>
{
treeRef
.
value
.
setCurrentKey
(
val
)
lastRowId
.
value
=
val
})
}
})
// 点击空白位置-取消选中效果
const
cancelSel
=
()
=>
{
// 刚才有过点击的某行
if
(
lastRow
.
value
)
{
treeRef
.
value
.
setCurrentKey
(
null
)
lastRow
.
value
=
null
emits
(
'update:modelValue'
,
''
)
emits
(
'search'
)
}
}
// 点击某行
const
handleNodeClick
=
(
row
)
=>
{
// 当前点击和上次点击一样->取消
if
(
lastRowId
.
value
===
row
[
props
.
nodeKey
])
{
treeRef
.
value
.
setCurrentKey
(
null
)
lastRowId
.
value
=
null
}
else
{
lastRowId
.
value
=
row
[
props
.
nodeKey
]
}
};
emits
(
'update:modelValue'
,
lastRowId
.
value
?
row
[
props
.
nodeKey
]
:
''
)
emits
(
'search'
)
}
// tree 筛选节点
const
filterNode
=
(
value
,
data
)
=>
{
if
(
!
value
)
return
true
;
return
data
[
props
.
defaultProps
.
label
].
indexOf
(
value
)
!==
-
1
;
}
// 分页逻辑触发
const
getPageList
=
()
=>
{
emits
(
'pageChange'
,
queryParams
)
}
</
script
>
<
style
scoped
lang=
"scss"
>
.el-col
{
padding
:
0
!
important
;
height
:
100%
;
.content
{
height
:
100%
;
.buttons_wrap
{
padding-right
:
10px
;
}
}
}
::v-deep
(
.custom-tree-node
)
{
width
:
100%
;
padding-right
:
20px
;
...
...
@@ -222,17 +228,19 @@ export default {
}
}
}
/* 间距放大 */
::v-deep
(
.row_gap
.el-tree-node
.el-tree-node__content
)
{
::v-deep
(
.row_gap
.el-tree-node
.el-tree-node__content
)
{
padding
:
10px
0
;
height
:
auto
;
}
// el-tree 取消选中时背景还有个颜色去掉
/* el-tree 取消选中时背景还有个颜色去掉 */
::v-deep
(
.el-tree-node
:focus
>
.el-tree-node__content
)
{
background-color
:
transparent
;
}
/
/ el-tree 选中时的背景色设置
/
* el-tree 选中时的背景色设置 */
::v-deep
(
.el-tree--highlight-current
.el-tree-node.is-current
>
.el-tree-node__content
)
{
background-color
:
#edf6ff
!
important
;
}
...
...
@@ -241,8 +249,7 @@ export default {
padding-right
:
10px
;
}
.col
{
height
:
100%
;
.el-col
{
display
:
flex
;
flex-direction
:
column
;
transition
:
all
.3s
;
...
...
@@ -260,6 +267,7 @@ export default {
font-size
:
12px
;
box-shadow
:
0px
0px
10px
rgba
(
0
,
0
,
0
,
0
.5
);
background-color
:
white
;
z-index
:
2
;
}
.content
{
...
...
@@ -277,19 +285,21 @@ export default {
.scroll
{
flex
:
1
;
overflow-y
:
scroll
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
padding-bottom
:
20px
;
&
:
:-
webkit-scrollbar
{
width
:
0
;
/* 灰色滚动条背景 */
&
:
:-
webkit-scrollbar-track
{
background-color
:
transparent
;
}
/* &::-webkit-scrollbar {
width: 0;
} */
}
/
/ 向左折叠的箭头
/
* 向左折叠的箭头 */
.arrow
{
right
:
7
.
5px
;
right
:
-
5px
;
}
&
{
...
...
@@ -299,7 +309,7 @@ export default {
}
::v-deep
.el-input__suffix
:last-of-type
{
::v-deep
(
.el-input__suffix
:last-of-type
)
{
padding-right
:
10px
;
}
...
...
src/layout/components/AppMain.vue
浏览文件 @
f552a6b9
...
...
@@ -41,7 +41,6 @@ function addIframe() {
.app-main
{
/* 50= navbar 50 */
min-height
:
calc
(
100vh
-
50px
);
padding
:
20px
;
width
:
100%
;
position
:
relative
;
overflow
:
hidden
;
...
...
src/layout/index.vue
浏览文件 @
f552a6b9
...
...
@@ -108,7 +108,7 @@ function setLayout() {
// 开启头部固定以后,main的高度需要设置为100vh
.fixed-header
+
.app-main
{
min-height
:
100vh
;
padding-top
:
50px
+
20px
;
padding-top
:
50px
;
}
...
...
@@ -121,7 +121,7 @@ function setLayout() {
}
.fixed-header
+
.app-main
{
padding-top
:
84px
+
20px
;
padding-top
:
84px
;
}
}
...
...
@@ -137,4 +137,33 @@ function setLayout() {
.mobile
.fixed-header
{
width
:
100%
;
}
// 有些页面高度固定就是 100 vh - 头部高度作为可视区域
// 例如:小 BI 分析中的商品管理页面,中间可用区域固定高度,不能撑开整个网页滚动
// 所以要动态计算高度
::v-deep
()
{
// 无头部固定,无头部 Tags-view
.client-fix-height
{
// 头部导航 50,上下内边距 20
height
:
calc
(
100vh
-
50px
-
40px
);
}
// 头部固定时
.fixed-header
+
.app-main
{
.client-fix-height
{
height
:
calc
(
100vh
-
50px
-
40px
)
!
important
;
}
}
// 有头部标签时
.hasTagsView
{
.fixed-header
+
.app-main
{
.client-fix-height
{
height
:
calc
(
100vh
-
50px
-
34px
-
40px
)
!
important
;
}
}
}
}
</
style
>
\ No newline at end of file
src/views/bi/competitor/index.vue
浏览文件 @
f552a6b9
...
...
@@ -62,6 +62,7 @@ provide('activeName', activeName);
flex-direction
:
column
;
justify-content
:
space-around
;
width
:
100%
;
margin-top
:
20px
;
.chart
{
flex
:
1
;
...
...
src/views/bi/product/index.vue
浏览文件 @
f552a6b9
<
template
>
<div
class=
"app-container"
>
<el-row
:gutter=
"20"
class=
"
row
"
>
class=
"
client-fix-height
"
>
<!--商品分类-->
<category-tree
:options=
"seriesOptions"
:defaultProps=
"defaultProps"
...
...
@@ -11,7 +11,7 @@
@
search=
"handleQuery"
:colSpan=
"4"
></category-tree>
<!--商品数据-->
<el-col
:span=
"
18
"
<el-col
:span=
"
20
"
:xs=
"24"
class=
"right_col"
>
<el-form
:model=
"queryParams"
...
...
@@ -63,8 +63,7 @@
align=
"left"
key=
"prdCode"
prop=
"prdCode"
v-if=
"columns[0].visible"
width=
"150"
/>
v-if=
"columns[0].visible"
/>
<el-table-column
label=
"商品名字"
align=
"left"
key=
"prdName"
...
...
@@ -76,20 +75,17 @@
key=
"series"
prop=
"series"
v-if=
"columns[2].visible"
:show-overflow-tooltip=
"true"
width=
"150"
/>
:show-overflow-tooltip=
"true"
/>
<el-table-column
label=
"条码"
align=
"left"
key=
"prdSpec"
prop=
"prdSpec"
v-if=
"columns[3].visible"
:show-overflow-tooltip=
"true"
width=
"180"
/>
:show-overflow-tooltip=
"true"
/>
<el-table-column
label=
"售卖状态"
align=
"center"
key=
"saleStatus"
v-if=
"columns[4].visible"
width=
"80"
>
v-if=
"columns[4].visible"
>
<template
v-slot=
"scope"
>
<el-switch
v-model=
"scope.row.saleStatus"
active-value=
"1"
...
...
@@ -99,18 +95,16 @@
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
width=
"160"
class-name=
"small-padding fixed-width"
v-if=
"columns[5].visible"
>
<
template
slot-scope=
"scope"
>
<el-button
size=
"mini"
type=
"text"
icon=
"el-icon-edit"
>
修改
</el-button>
<el-button
icon=
"el-icon-edit"
>
修改
</el-button>
</
template
>
</el-table-column>
</el-table>
<pagination
v-show=
"total > 0"
<pagination
class=
"pagination"
v-show=
"total > 0"
:total=
"total"
v-model:page=
"queryParams.pageNum"
v-model:limit=
"queryParams.pageSize"
...
...
@@ -182,7 +176,34 @@ getProductList()
<
style
scoped
lang=
"scss"
>
::v-deep
.row
{
.app-container
{
>
.el-row
{
/* flex: 1; */
display
:
flex
;
padding
:
20px
;
background-color
:
var
(
--
el-bg-color-overlay
);
.right_col
{
flex
:
1
!
important
;
transition
:
all
.5s
;
display
:
flex
;
flex-direction
:
column
;
height
:
100%
;
.pagination
{
/* 没办法设置某个子元素单独在主轴排列方式,使用此方式可以 */
margin-top
:
auto
;
}
&
.el-col-20
{
width
:
83
.33333333%
;
max-width
:
none
;
}
}
}
}
/* ::v-deep .row {
height: 100%;
display: flex;
...
...
@@ -195,5 +216,5 @@ getProductList()
}
}
}
}
*/
</
style
>
\ No newline at end of file
src/views/bi/sale/index.vue
浏览文件 @
f552a6b9
...
...
@@ -608,9 +608,9 @@ init()
/* 套表 */
.excel_charts_item
{
background-color
:
var
(
--
el-bg-color-overlay
);
padding
:
20px
;
margin-top
:
20px
;
width
:
100%
;
padding
:
20px
;
/* 图容器 */
.echarts_wrap
{
...
...
@@ -637,9 +637,6 @@ init()
margin-top
:
0
;
}
.el-form-item
{
margin-bottom
:
0
;
}
}
/* 新增套表 */
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论