Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
factory_front
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
qinjianhui
factory_front
Commits
76653b9a
Commit
76653b9a
authored
Jul 09, 2026
by
wuqian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:权限相关bug修复
parent
db9ed506
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
105 additions
and
53 deletions
+105
-53
src/components/TableView.vue
+2
-1
src/components/leftRightLayout.vue
+1
-2
src/router/dynamicRoutes.ts
+1
-0
src/router/index.ts
+2
-4
src/store/menuTree.ts
+1
-1
src/styles/element.scss
+5
-4
src/utils/index.ts
+2
-6
src/views/order/factoryOrderNew/hooks/useOrderStatusTree.ts
+20
-9
src/views/system/RoleManagementPage.vue
+60
-20
src/views/system/UserPage.vue
+4
-3
src/views/warehouse/stockingApplicationOrder/index.vue
+7
-3
No files found.
src/components/TableView.vue
View file @
76653b9a
...
@@ -77,7 +77,8 @@ import {
...
@@ -77,7 +77,8 @@ import {
}
from
'vue'
}
from
'vue'
import
type
{
CustomColumn
}
from
'@/types/table'
import
type
{
CustomColumn
}
from
'@/types/table'
import
RenderColumn
from
'./RenderColumn.vue'
import
RenderColumn
from
'./RenderColumn.vue'
import
{
ElTable
}
from
'element-plus'
// 此处必须注释掉,不然使用该组件的表格样式会错乱
// import { ElTable } from 'element-plus'
import
type
{
TableInstance
}
from
'element-plus'
import
type
{
TableInstance
}
from
'element-plus'
const
tableRef
=
shallowRef
<
TableInstance
>
()
const
tableRef
=
shallowRef
<
TableInstance
>
()
...
...
src/components/leftRightLayout.vue
View file @
76653b9a
<
template
>
<
template
>
<div
class=
"page_main h-100"
:class=
"
{ mobile: isMobile }"
>
<div
class=
"page_main h-100"
>
<!-- 头部插槽 -->
<!-- 头部插槽 -->
<div
v-if=
"$slots.header"
class=
"page_header"
>
<div
v-if=
"$slots.header"
class=
"page_header"
>
<slot
name=
"header"
/>
<slot
name=
"header"
/>
...
@@ -41,7 +41,6 @@
...
@@ -41,7 +41,6 @@
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
ref
,
computed
,
useAttrs
}
from
'vue'
import
{
ref
,
computed
,
useAttrs
}
from
'vue'
import
type
{
CSSProperties
}
from
'vue'
import
type
{
CSSProperties
}
from
'vue'
import
{
isMobile
}
from
'@/utils/index.ts'
const
props
=
defineProps
({
const
props
=
defineProps
({
isleftshow
:
{
isleftshow
:
{
type
:
Boolean
,
type
:
Boolean
,
...
...
src/router/dynamicRoutes.ts
View file @
76653b9a
...
@@ -181,6 +181,7 @@ export function buildDynamicRoutes(
...
@@ -181,6 +181,7 @@ export function buildDynamicRoutes(
if
(
!
loader
)
continue
if
(
!
loader
)
continue
records
.
push
({
records
.
push
({
path
:
p
,
path
:
p
,
name
:
p
,
// 使用异步加载的 component
// 使用异步加载的 component
component
:
loader
as
unknown
as
RouteComponent
,
component
:
loader
as
unknown
as
RouteComponent
,
meta
:
{
title
},
meta
:
{
title
},
...
...
src/router/index.ts
View file @
76653b9a
...
@@ -88,10 +88,8 @@ router.beforeEach(
...
@@ -88,10 +88,8 @@ router.beforeEach(
return
return
}
}
// 把 getSysPermissionApi 从 afterEach 整体挪到 beforeEach 并 await:
// 把 getSysPermissionApi 放到 beforeEach 并 await:
// 保证组件 onMounted 触发 getTreeNum 时,reqMenu.buttons 已就绪,
// 进入新页面前先把 buttons 清空,避免上一页按钮残留。
// 避免 children 一上来就被 roleShow 一次性过滤成空数组。
// 进入新页面前先把 buttons 清空,避免上一页按钮残留(option 4 思路)。
if
(
token
&&
to
.
path
!==
'/user/login'
)
{
if
(
token
&&
to
.
path
!==
'/user/login'
)
{
const
reqMenu
=
(
to
.
meta
?.
permissionRoute
as
string
)
||
to
.
path
const
reqMenu
=
(
to
.
meta
?.
permissionRoute
as
string
)
||
to
.
path
if
(
reqMenu
&&
reqMenu
!==
pendingReqMenu
)
{
if
(
reqMenu
&&
reqMenu
!==
pendingReqMenu
)
{
...
...
src/store/menuTree.ts
View file @
76653b9a
...
@@ -33,7 +33,7 @@ const useMenuTreeStore = defineStore('menuTree', () => {
...
@@ -33,7 +33,7 @@ const useMenuTreeStore = defineStore('menuTree', () => {
const
setMenuTree
=
(
data
:
MenuTreeNode
[])
=>
{
const
setMenuTree
=
(
data
:
MenuTreeNode
[])
=>
{
menusTree
.
value
=
data
menusTree
.
value
=
data
writeToStorage
(
data
)
// writeToStorage(data) // 这里不写入本地存储,避免覆盖 menusTreeNoBtn
}
}
const
clearMenuTree
=
()
=>
{
const
clearMenuTree
=
()
=>
{
...
...
src/styles/element.scss
View file @
76653b9a
.el-table
thead
{
.el-table
thead
{
color
:
#333
;
font-size
:
14px
;
font-size
:
14px
;
height
:
50px
;
height
:
50px
;
min-height
:
50px
;
min-height
:
50px
;
}
}
.el-table
.cell
{
white-space
:
nowrap
;
}
.el-table
thead
th
.el-table__cell
{
.el-table
thead
th
.el-table__cell
{
color
:
#333
;
background-color
:
#fafafa
;
background-color
:
#fafafa
;
}
}
.el-table
.cell
{
white-space
:
nowrap
;
}
.el-table__row
{
.el-table__row
{
height
:
40px
;
height
:
40px
;
min-height
:
40px
;
min-height
:
40px
;
...
...
src/utils/index.ts
View file @
76653b9a
...
@@ -64,8 +64,4 @@ export function downloadByUrl(url: string, filename?: string) {
...
@@ -64,8 +64,4 @@ export function downloadByUrl(url: string, filename?: string) {
document
.
body
.
appendChild
(
a
)
document
.
body
.
appendChild
(
a
)
a
.
click
()
a
.
click
()
document
.
body
.
removeChild
(
a
)
document
.
body
.
removeChild
(
a
)
}
}
export
const
isMobile
:
boolean
=
\ No newline at end of file
/
(
phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone
)
/i
.
test
(
navigator
.
userAgent
,
)
\ No newline at end of file
src/views/order/factoryOrderNew/hooks/useOrderStatusTree.ts
View file @
76653b9a
...
@@ -135,23 +135,34 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
...
@@ -135,23 +135,34 @@ export function useOrderStatusTree(options: UseOrderStatusTreeOptions) {
const
loadStatusTreeCounts
=
async
()
=>
{
const
loadStatusTreeCounts
=
async
()
=>
{
try
{
try
{
const
res
=
await
getPodOrderStateGroupListApi
()
const
res
=
await
getPodOrderStateGroupListApi
()
const
GROUP_MARK
=
new
Set
([
'PICKING'
])
//
"配货中—" 这样的“分组容器”要自己加
const
GROUP_MARK
=
new
Set
([
'PICKING'
])
//
所有分组容器
const
filterTree
=
(
nodes
:
StatusTreeNode
[]):
StatusTreeNode
[]
=>
{
const
filterTree
=
(
nodes
:
StatusTreeNode
[]):
StatusTreeNode
[]
=>
{
const
result
:
StatusTreeNode
[]
=
[]
const
result
:
StatusTreeNode
[]
=
[]
for
(
const
node
of
nodes
)
{
for
(
const
node
of
nodes
)
{
if
(
GROUP_MARK
.
has
(
node
.
status
)
||
roleShow
(
node
.
status
))
{
let
filteredChildren
:
StatusTreeNode
[]
=
[]
const
newNode
=
{
...
node
}
if
(
node
.
children
)
{
if
(
newNode
.
children
)
{
filteredChildren
=
filterTree
(
node
.
children
)
newNode
.
children
=
filterTree
(
newNode
.
children
)
}
}
const
hasPermission
=
roleShow
(
node
.
status
)
result
.
push
(
newNode
)
const
isGroupContainer
=
GROUP_MARK
.
has
(
node
.
status
)
if
(
hasPermission
||
(
isGroupContainer
&&
filteredChildren
.
length
>
0
)
)
{
result
.
push
({
...
node
,
children
:
filteredChildren
})
}
}
}
}
return
result
return
result
}
}
const
result
=
filterTree
(
res
.
data
)
// 递归过滤掉没有权限的节点
const
filteredData
=
filterTree
(
res
.
data
)
statusTree
.
value
=
[
statusTree
.
value
=
[
{
status
:
'ALL'
,
statusName
:
'全部'
,
quantity
:
0
,
children
:
result
},
{
status
:
'ALL'
,
statusName
:
'全部'
,
quantity
:
0
,
children
:
filteredData
,
},
]
]
nextTick
(()
=>
{
nextTick
(()
=>
{
treeRef
.
value
?.
setCurrentKey
(
status
.
value
,
true
)
treeRef
.
value
?.
setCurrentKey
(
status
.
value
,
true
)
...
...
src/views/system/RoleManagementPage.vue
View file @
76653b9a
...
@@ -42,7 +42,7 @@
...
@@ -42,7 +42,7 @@
padding: 10px 10px 0;
padding: 10px 10px 0;
"
"
>
>
<div>
<div
v-if=
"currentRole.name"
style=
"line-height: 40px"
>
<span
style=
"font-weight: bold; font-size: 18px"
>
角色名称:
</span>
<span
style=
"font-weight: bold; font-size: 18px"
>
角色名称:
</span>
<span
style=
"font-weight: bold; font-size: 20px; color: red"
>
<span
style=
"font-weight: bold; font-size: 20px; color: red"
>
{{
currentRole
.
name
}}
{{
currentRole
.
name
}}
...
@@ -51,6 +51,7 @@
...
@@ -51,6 +51,7 @@
<div>
<div>
<ElButton
<ElButton
v-if=
"activeRoleId != '1'"
v-if=
"activeRoleId != '1'"
:disabled=
"!currentRole.name"
type=
"primary"
type=
"primary"
@
click=
"editRole()"
@
click=
"editRole()"
>
>
...
@@ -58,6 +59,7 @@
...
@@ -58,6 +59,7 @@
</ElButton>
</ElButton>
<ElButton
<ElButton
v-if=
"activeRoleId != '1'"
v-if=
"activeRoleId != '1'"
:disabled=
"!currentRole.name"
type=
"success"
type=
"success"
@
click=
"copyRole()"
@
click=
"copyRole()"
>
>
...
@@ -65,16 +67,28 @@
...
@@ -65,16 +67,28 @@
</ElButton>
</ElButton>
<ElButton
<ElButton
v-if=
"activeRoleId != '1'"
v-if=
"activeRoleId != '1'"
:disabled=
"!currentRole.name"
type=
"danger"
type=
"danger"
@
click=
"removeRole()"
@
click=
"removeRole()"
>
>
删除
删除
</ElButton>
</ElButton>
<ElButton
type=
"primary"
@
click=
"addRole()"
>
添加
</ElButton>
<ElButton
type=
"primary"
@
click=
"addRole()"
>
添加
</ElButton>
<ElButton
type=
"success"
@
click=
"saveSelect()"
>
保存
</ElButton>
<ElButton
:disabled=
"!currentRole.name"
type=
"success"
@
click=
"saveSelect()"
>
保存
</ElButton>
</div>
</div>
</div>
</div>
<ElTabs
v-model=
"tabActive"
@
tab-click=
"tabClick"
>
<div
v-if=
"!currentRole.name"
class=
"no_role_tip"
>
<span
style=
"color: red; font-weight: bold; font-size: 18px"
>
请先添加角色吧!
</span
>
</div>
<ElTabs
v-else
v-model=
"tabActive"
@
tab-click=
"tabClick"
>
<ElTabPane
label=
"功能权限"
name=
"second"
>
<ElTabPane
label=
"功能权限"
name=
"second"
>
<div
<div
style=
"
style=
"
...
@@ -458,11 +472,27 @@ function syncNodeCheckState(node: MenuTreeNode) {
...
@@ -458,11 +472,27 @@ function syncNodeCheckState(node: MenuTreeNode) {
const
anyIndeter
=
children
.
some
((
c
)
=>
c
.
indeter
)
const
anyIndeter
=
children
.
some
((
c
)
=>
c
.
indeter
)
node
.
indeter
=
(
childSelectedCount
>
0
&&
!
allSelected
)
||
anyIndeter
node
.
indeter
=
(
childSelectedCount
>
0
&&
!
allSelected
)
||
anyIndeter
const
idx
=
menuCheckList
.
value
.
indexOf
(
node
.
id
)
const
idx
=
menuCheckList
.
value
.
indexOf
(
node
.
id
)
if
(
allSelected
&&
!
anyIndeter
)
{
if
(
childSelectedCount
>
0
)
{
// 只要有任一子节点被选中,父节点 id 也应进入 checklist(视觉上仍由 indeter 决定半/全勾)
if
(
idx
===
-
1
)
menuCheckList
.
value
.
push
(
node
.
id
)
if
(
idx
===
-
1
)
menuCheckList
.
value
.
push
(
node
.
id
)
}
else
if
(
childSelectedCount
===
0
&&
!
anyIndeter
)
{
}
else
{
// 没有任何子节点被选中,移除父节点 id
if
(
idx
!==
-
1
)
menuCheckList
.
value
.
splice
(
idx
,
1
)
if
(
idx
!==
-
1
)
menuCheckList
.
value
.
splice
(
idx
,
1
)
node
.
indeter
=
false
}
}
function
findMenuNode
(
id
:
number
|
string
):
MenuTreeNode
|
undefined
{
const
walk
=
(
list
?:
MenuTreeNode
[]):
MenuTreeNode
|
undefined
=>
{
if
(
!
list
)
return
undefined
for
(
const
node
of
list
)
{
if
(
node
.
id
===
id
)
return
node
const
found
=
walk
(
node
.
children
)
if
(
found
)
return
found
}
return
undefined
}
}
return
walk
(
menuList
.
value
)
}
}
function
updateParentsIndeter
(
function
updateParentsIndeter
(
...
@@ -496,6 +526,8 @@ function selectChecked(item: MenuTreeNode) {
...
@@ -496,6 +526,8 @@ function selectChecked(item: MenuTreeNode) {
}
}
}
}
walk
(
item
.
children
)
walk
(
item
.
children
)
// 同步当前节点的 id 和 indeterminate
syncNodeCheckState
(
item
)
// 更新父级 indeterminate
// 更新父级 indeterminate
updateParentsIndeter
(
menuList
.
value
,
item
)
updateParentsIndeter
(
menuList
.
value
,
item
)
}
}
...
@@ -512,16 +544,20 @@ function clearChecked(item: MenuTreeNode) {
...
@@ -512,16 +544,20 @@ function clearChecked(item: MenuTreeNode) {
}
}
}
}
walk
(
item
.
children
)
walk
(
item
.
children
)
// 同步当前节点的 id 和 indeterminate
syncNodeCheckState
(
item
)
updateParentsIndeter
(
menuList
.
value
,
item
)
updateParentsIndeter
(
menuList
.
value
,
item
)
}
}
function
checkChange
(
item
:
MenuTreeNode
,
value
:
boolean
|
string
|
number
)
{
function
checkChange
(
item
:
MenuTreeNode
,
value
:
boolean
|
string
|
number
)
{
if
(
value
||
item
.
indeter
)
{
// 一级传入的是合成对象,需查找真实树节点,避免只改到临时对象的 indeter
selectChecked
(
item
)
const
target
=
findMenuNode
(
item
.
id
)
??
item
if
(
value
||
target
.
indeter
)
{
selectChecked
(
target
)
}
else
{
}
else
{
clearChecked
(
item
)
clearChecked
(
target
)
}
}
item
.
indeter
=
false
target
.
indeter
=
false
}
}
async
function
saveSelect
()
{
async
function
saveSelect
()
{
...
@@ -552,7 +588,7 @@ async function getActiveData() {
...
@@ -552,7 +588,7 @@ async function getActiveData() {
const
res
=
await
getRolePermsApi
(
activeRoleId
.
value
)
const
res
=
await
getRolePermsApi
(
activeRoleId
.
value
)
if
(
res
.
code
==
200
)
{
if
(
res
.
code
==
200
)
{
menuCheckList
.
value
=
(
res
.
data
?.
menuIds
as
number
[])
||
[]
menuCheckList
.
value
=
(
res
.
data
?.
menuIds
as
number
[])
||
[]
checkMenus
(
menu
CheckList
.
value
,
menu
List
.
value
)
checkMenus
(
menuList
.
value
)
}
}
}
catch
(
e
)
{
}
catch
(
e
)
{
console
.
log
(
e
)
console
.
log
(
e
)
...
@@ -560,20 +596,12 @@ async function getActiveData() {
...
@@ -560,20 +596,12 @@ async function getActiveData() {
await
getUsers
()
await
getUsers
()
}
}
function
checkMenus
(
checklist
:
number
[],
menulist
:
MenuTreeNode
[])
{
function
checkMenus
(
menulist
:
MenuTreeNode
[])
{
const
check
=
(
list
:
MenuTreeNode
[])
=>
{
const
check
=
(
list
:
MenuTreeNode
[])
=>
{
list
.
forEach
((
item
)
=>
{
list
.
forEach
((
item
)
=>
{
if
(
item
.
children
&&
item
.
children
.
length
>
0
)
{
if
(
item
.
children
&&
item
.
children
.
length
>
0
)
{
const
hasSelectedChild
=
item
.
children
.
some
((
c
)
=>
checklist
.
includes
(
c
.
id
),
)
if
(
!
hasSelectedChild
)
{
const
index
=
checklist
.
indexOf
(
item
.
id
)
if
(
index
!==
-
1
)
{
checklist
.
splice
(
index
,
1
)
}
}
check
(
item
.
children
)
check
(
item
.
children
)
syncNodeCheckState
(
item
)
}
}
})
})
}
}
...
@@ -619,6 +647,12 @@ async function getList(role: RoleItem | null = null) {
...
@@ -619,6 +647,12 @@ async function getList(role: RoleItem | null = null) {
currentActiveIndex
>=
0
?
String
(
currentActiveIndex
+
1
)
:
'1'
currentActiveIndex
>=
0
?
String
(
currentActiveIndex
+
1
)
:
'1'
await
getActiveData
()
await
getActiveData
()
}
}
if
(
groupLists
.
value
.
length
===
0
)
{
activeRoleId
.
value
=
''
currentRole
.
value
=
{}
as
RoleItem
menuCheckList
.
value
=
[]
userLists
.
value
=
[]
}
return
res
return
res
}
catch
(
err
)
{
}
catch
(
err
)
{
console
.
log
(
err
)
console
.
log
(
err
)
...
@@ -687,6 +721,12 @@ onMounted(() => {
...
@@ -687,6 +721,12 @@ onMounted(() => {
height
:
100%
;
height
:
100%
;
display
:
flex
;
display
:
flex
;
}
}
.no_role_tip
{
height
:
100%
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
.menu_name
{
.menu_name
{
display
:
inline-block
;
display
:
inline-block
;
min-width
:
160px
;
min-width
:
160px
;
...
...
src/views/system/UserPage.vue
View file @
76653b9a
...
@@ -388,9 +388,10 @@ const save = async () => {
...
@@ -388,9 +388,10 @@ const save = async () => {
const
roleIdsStr
=
Array
.
isArray
(
editForm
.
value
.
roleIds
)
const
roleIdsStr
=
Array
.
isArray
(
editForm
.
value
.
roleIds
)
?
editForm
.
value
.
roleIds
.
join
(
','
)
?
editForm
.
value
.
roleIds
.
join
(
','
)
:
editForm
.
value
.
roleIds
:
editForm
.
value
.
roleIds
const
hasSuper
=
Array
.
isArray
(
editForm
.
value
.
roleIds
)
const
hasSuper
=
getRoleName
(
editForm
.
value
.
roleIds
)
?
editForm
.
value
.
roleIds
.
includes
(
1
)
.
split
(
','
)
:
editForm
.
value
.
roleIds
.
split
(
','
).
map
(
Number
).
includes
(
1
)
.
filter
(
Boolean
)
.
includes
(
'超级管理员'
)
try
{
try
{
if
(
!
editId
.
value
)
{
if
(
!
editId
.
value
)
{
await
addUserApi
({
await
addUserApi
({
...
...
src/views/warehouse/stockingApplicationOrder/index.vue
View file @
76653b9a
...
@@ -138,13 +138,16 @@
...
@@ -138,13 +138,16 @@
><
/ElPagination
>
><
/ElPagination
>
<
/template
>
<
/template
>
<
template
#
bottom
>
<
template
#
bottom
>
<
StockingApplyOrderDetailTabs
:
selected
-
row
=
"selectedRow"
/>
<
StockingApplyOrderDetailTabs
:
selected
-
row
=
"selectedRow
?? null
"
/>
<
/template
>
<
/template
>
<
/SplitDiv
>
<
/SplitDiv
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<!--
提交入库弹框
-->
<!--
提交入库弹框
-->
<
SubmitWarehousingDialog
ref
=
"submitWarehousingDialogRef"
@
refresh
=
"onRefresh"
/>
<
SubmitWarehousingDialog
ref
=
"submitWarehousingDialogRef"
@
refresh
=
"onRefresh"
/>
<
/div
>
<
/div
>
<
/template
>
<
/template
>
<
script
setup
lang
=
"tsx"
>
<
script
setup
lang
=
"tsx"
>
...
@@ -168,7 +171,8 @@ const treeData = ref<TreeData[]>([])
...
@@ -168,7 +171,8 @@ const treeData = ref<TreeData[]>([])
const
treeRef
=
ref
()
const
treeRef
=
ref
()
const
tableRef
=
ref
()
const
tableRef
=
ref
()
const
selectedRow
=
ref
<
TableData
|
null
>
(
null
)
const
selectedRow
=
ref
<
TableData
|
null
>
(
null
)
const
submitWarehousingDialogRef
=
ref
<
InstanceType
<
typeof
SubmitWarehousingDialog
>>
()
const
submitWarehousingDialogRef
=
ref
<
InstanceType
<
typeof
SubmitWarehousingDialog
>>
()
const
[
searchForm
,
resetSearchForm
]
=
useValue
<
SearchForm
>
({
}
as
SearchForm
)
const
[
searchForm
,
resetSearchForm
]
=
useValue
<
SearchForm
>
({
}
as
SearchForm
)
const
status
=
ref
<
string
>
(
'TO_BE_RECEIPT'
)
const
status
=
ref
<
string
>
(
'TO_BE_RECEIPT'
)
const
warehouseList
=
ref
<
WarehouseListData
[]
>
([])
const
warehouseList
=
ref
<
WarehouseListData
[]
>
([])
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment