Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
psa-web
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
高滢
psa-web
Commits
e295ebac
Commit
e295ebac
authored
Mar 26, 2025
by
huanghaoting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
请假审批
parent
bc9712e0
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
407 additions
and
0 deletions
+407
-0
application.js
src/api/application/application.js
+19
-0
approval.vue
src/views/attendance/leaveApplication/approval.vue
+388
-0
No files found.
src/api/application/application.js
View file @
e295ebac
...
@@ -77,3 +77,22 @@ export function getGeneralManagerNickName() {
...
@@ -77,3 +77,22 @@ export function getGeneralManagerNickName() {
method
:
'get'
method
:
'get'
})
})
}
}
// 获取总经理的nick_name
export
function
getShenpiList
(
id
)
{
return
request
({
url
:
'/approvalConfiguration/getNodeList/'
+
id
,
method
:
'get'
})
}
// 更新节点和审批状态
export
function
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus
(
data
)
{
return
request
({
url
:
'/application/application/updateNodeAndApprovalStatus'
,
method
:
'put'
,
data
:
data
})
}
src/views/attendance/leaveApplication/approval.vue
0 → 100644
View file @
e295ebac
<
template
>
<div
class=
"app-container"
>
<!-- 查询表单 -->
<div
class=
"formSearch"
>
<el-form
:model=
"queryParams"
ref=
"queryRef"
:inline=
"true"
v-show=
"showSearch"
label-width=
"120px"
>
<el-form-item
label=
"姓名"
prop=
"uname"
>
<el-input
v-model=
"queryParams.uname"
placeholder=
"请输入姓名"
clearable
@
keyup
.
enter=
"handleQuery"
style=
"width: 220px"
/>
</el-form-item>
<el-form-item
label=
"请假类型"
prop=
"leaveType"
>
<el-select
v-model=
"queryParams.leaveType"
placeholder=
"请选择请假类型"
clearable
@
keyup
.
enter=
"handleQuery"
style=
"width: 220px"
>
<el-option
v-for=
"dict in leave_types"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"审批状态"
prop=
"approvalStatus"
>
<el-select
v-model=
"queryParams.approvalStatus"
placeholder=
"请选择审批状态"
style=
"width: 220px"
clearable
>
<el-option
v-for=
"dict in approval_status"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
style=
"padding-left: 5.4%"
>
<el-button
@
click=
"resetQuery"
class=
"el-button-defalut"
>
<img
src=
"@/assets/icons/common/reset.png"
alt=
"重置图标"
>
重置
</el-button>
<el-button
type=
"primary"
@
click=
"handleQuery"
class=
"el-button-primary"
>
<img
src=
"@/assets/icons/common/search.png"
alt=
"查询图标"
>
查询
</el-button>
<el-button
size=
"large"
icon=
"ArrowDown"
type=
"text"
v-show=
"!isExpanded"
@
click=
"toggleSearch"
>
展开
</el-button>
<el-button
size=
"large"
type=
"text"
icon=
"ArrowUp"
v-show=
"isExpanded"
@
click=
"toggleSearch"
>
收起
</el-button>
</el-form-item>
<!-- 可折叠的查询条件 -->
<transition>
<div
v-if=
"isExpanded"
>
<el-form-item
label=
"申请日期"
prop=
"requestDate"
>
<el-date-picker
v-model=
"queryParams.requestDate"
type=
"date"
value-format=
"YYYY-MM-DD"
placeholder=
"请选择申请日期"
clearable
@
keyup
.
enter=
"handleQuery"
style=
"width: 220px"
/>
</el-form-item>
</div>
</transition>
</el-form>
</div>
<!-- 数据列表及操作 -->
<div
class=
"contentTable"
>
<!-- 按钮区域 -->
<div
style=
"margin-bottom: 30px"
>
<el-button
class=
"el-button-defalut"
type=
"default"
@
click=
"handleBatchReject"
>
一键驳回
</el-button>
<el-button
class=
"el-button-primary"
style=
"margin-left: 20px"
type=
"primary"
@
click=
"handleBatchPass"
>
一键通过
</el-button>
</div>
<!-- 表格数据 -->
<div
class=
"table-wrapper"
>
<el-table
v-loading=
"loading"
:data=
"applicationList"
@
selection-change=
"handleSelectionChange"
:border=
"true"
>
<el-table-column
type=
"selection"
align=
"center"
/>
<el-table-column
v-if=
"showIndexColumn"
label=
"序号"
align=
"center"
prop=
"id"
/>
<el-table-column
label=
"姓名"
align=
"center"
prop=
"uname"
/>
<el-table-column
label=
"申请日期"
align=
"center"
prop=
"requestDate"
>
<template
#
default=
"scope"
>
<span>
{{
parseTime
(
scope
.
row
.
requestDate
,
'{y
}
-{m
}
-{d
}
'
)
}}
<
/span
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"请假类型"
align
=
"center"
prop
=
"leaveType"
>
<
template
#
default
=
"scope"
>
<
dict
-
tag
:
options
=
"leave_types"
:
value
=
"scope.row.leaveType"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"请假开始时间"
align
=
"center"
prop
=
"startTime"
fit
>
<
template
#
default
=
"scope"
>
<
span
>
{{
parseTime
(
scope
.
row
.
startTime
,
'{y
}
-{m
}
-{d
}
{h
}
:{i
}
'
)
}}
<
/span
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"请假结束时间"
align
=
"center"
prop
=
"endTime"
fit
>
<
template
#
default
=
"scope"
>
<
span
>
{{
parseTime
(
scope
.
row
.
endTime
,
'{y
}
-{m
}
-{d
}
{h
}
:{i
}
'
)
}}
<
/span
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"请假时长(小时)"
align
=
"center"
prop
=
"leavetimeHours"
/>
<
el
-
table
-
column
label
=
"请假天数"
align
=
"center"
prop
=
"leaveDaysSubtotal"
/>
<
el
-
table
-
column
label
=
"抵扣加班时长(小时)"
align
=
"center"
prop
=
"deductionOvertimeHours"
width
=
"180px"
/>
<
el
-
table
-
column
label
=
"审批状态"
align
=
"center"
>
<
template
#
default
=
"scope"
>
<
dict
-
tag
:
options
=
"approval_status"
:
value
=
"getDisplayStatus(scope.row)"
/>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
prop
=
"detail"
label
=
"详情"
align
=
"center"
width
=
"100px"
>
<
template
#
default
=
"scope"
>
<
el
-
tooltip
content
=
"详情"
placement
=
"top"
>
<
el
-
button
link
type
=
"text"
@
click
=
"handleView(scope.row)"
>
<
img
src
=
"@/assets/icons/common/check.png"
height
=
"32"
width
=
"32"
/>
<
/el-button
>
<
/el-tooltip
>
<
/template
>
<
/el-table-column
>
<
el
-
table
-
column
label
=
"操作"
align
=
"center"
width
=
"150px"
height
=
"56px"
>
<
template
#
default
=
"scope"
>
<
el
-
button
link
type
=
"primary"
size
=
"small"
style
=
"font-size: 15px"
@
click
=
"handlePass(scope.row)"
>
通过
<
/el-button
>
<
el
-
button
link
type
=
"danger"
size
=
"small"
style
=
"font-size: 15px"
@
click
=
"handleReject(scope.row)"
>
驳回
<
/el-button
>
<
/template
>
<
/el-table-column
>
<
/el-table
>
<
/div
>
<!--
分页
-->
<
div
class
=
"pagination-container"
>
<
pagination
v
-
show
=
"total > 0"
:
total
=
"total"
v
-
model
:
page
=
"queryParams.pageNum"
v
-
model
:
limit
=
"queryParams.pageSize"
@
pagination
=
"getList"
/>
<
/div
>
<
/div
>
<
/div
>
<
/template
>
<
script
setup
>
import
{
ref
,
reactive
,
toRefs
,
onMounted
,
getCurrentInstance
}
from
"vue"
;
import
{
useRouter
}
from
"vue-router"
;
import
useUserStore
from
'@/store/modules/user'
;
import
{
listApplication
,
getShenpiList
,
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus
}
from
"../../../api/application/application"
;
// ----- 状态及字典定义 -----
const
userStore
=
useUserStore
();
const
router
=
useRouter
();
const
currentRole
=
ref
(
''
);
// 当前用户角色
const
{
proxy
}
=
getCurrentInstance
();
// 示例字典,实际可用你的 useDict
const
{
leave_types
}
=
proxy
.
useDict
(
"leave_types"
);
const
{
approval_status
}
=
proxy
.
useDict
(
"approval_status"
);
const
showSearch
=
ref
(
true
);
const
isExpanded
=
ref
(
false
);
const
loading
=
ref
(
true
);
const
total
=
ref
(
0
);
const
applicationList
=
ref
([]);
const
ids
=
ref
([]);
// 存放表格选中行的 ID
const
showIndexColumn
=
ref
(
false
);
// 查询表单
const
data
=
reactive
({
form
:
{
}
,
queryParams
:
{
pageNum
:
1
,
pageSize
:
10
,
// 其他查询条件省略
}
,
}
);
const
{
queryParams
,
form
}
=
toRefs
(
data
);
// ----- 辅助函数 -----
const
toggleSearch
=
()
=>
(
isExpanded
.
value
=
!
isExpanded
.
value
);
const
reset
=
()
=>
{
form
.
value
=
{
}
;
proxy
.
resetForm
(
"applicationRef"
);
}
;
const
handleSelectionChange
=
(
selection
)
=>
{
ids
.
value
=
selection
.
map
(
item
=>
item
.
id
);
}
;
// ----- 核心逻辑函数 -----
/**
* 根据行数据和当前用户角色返回 dict‑tag 需要显示的状态值
* (仅示例保留,不需要可去掉)
*/
const
getDisplayStatus
=
(
row
)
=>
{
const
status
=
Number
(
row
.
approvalStatus
);
// 如果 nodeId=111 && approvalStatus=1,根据角色显示不同
if
(
row
.
nodeId
===
112
&&
status
===
1
)
{
if
(
currentRole
.
value
===
'project-manager'
)
{
return
2
;
// “已通过”
}
else
if
(
currentRole
.
value
===
'general-manager'
)
{
return
1
;
// “审批中”
}
}
return
status
;
}
;
/**
* 查询请假申请列表
*/
const
getList
=
()
=>
{
loading
.
value
=
true
;
listApplication
(
queryParams
.
value
)
.
then
((
response
)
=>
{
applicationList
.
value
=
response
.
rows
.
map
(
row
=>
({
...
row
,
isSubmitted
:
false
}
));
total
.
value
=
response
.
total
;
// 如果当前角色是 general-manager,则只显示“请假天数 >= 3”的行
if
(
currentRole
.
value
===
'general-manager'
)
{
applicationList
.
value
=
applicationList
.
value
.
filter
(
(
item
)
=>
item
.
leaveDaysSubtotal
>=
3
);
}
}
)
.
finally
(()
=>
{
loading
.
value
=
false
;
}
);
}
;
const
handleQuery
=
()
=>
{
queryParams
.
value
.
pageNum
=
1
;
getList
();
}
;
const
resetQuery
=
()
=>
{
proxy
.
resetForm
(
"queryRef"
);
handleQuery
();
}
;
const
handleView
=
(
row
)
=>
{
router
.
push
({
path
:
'leave/detail'
,
query
:
{
id
:
row
.
id
,
from
:
'/attendance/approval'
}
}
);
}
;
/**
* 单条“通过”
* 若请假天数 < 3,则 nodeId=111, approvalStatus=2
* 若请假天数 >= 3,则根据角色判断
*/
const
handlePass
=
(
row
)
=>
{
if
(
row
.
leaveDaysSubtotal
<
3
)
{
const
params
=
{
ids
:
[
row
.
id
],
nodeId
:
111
,
approvalStatus
:
2
}
;
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus
(
params
)
.
then
(()
=>
{
console
.
log
(
"更新成功"
);
getList
();
}
)
.
catch
((
err
)
=>
console
.
error
(
"更新失败:"
,
err
));
}
else
{
userStore
.
getInfo
()
.
then
(
userInfo
=>
{
const
role
=
userInfo
.
roles
[
0
];
let
nodeIdVal
,
approvalStatusVal
;
if
(
role
===
'project-manager'
)
{
nodeIdVal
=
112
;
approvalStatusVal
=
1
;
}
else
if
(
role
===
'general-manager'
)
{
nodeIdVal
=
112
;
approvalStatusVal
=
2
;
}
else
{
return
Promise
.
reject
(
"角色不匹配,无法更新"
);
}
const
params
=
{
ids
:
[
row
.
id
],
nodeId
:
nodeIdVal
,
approvalStatus
:
approvalStatusVal
}
;
return
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus
(
params
);
}
)
.
then
(()
=>
{
console
.
log
(
"更新成功"
);
getList
();
}
)
.
catch
(
err
=>
console
.
error
(
"更新失败:"
,
err
));
}
}
;
/**
* 一键通过:对选中且请假天数 < 3 的记录设置 nodeId=111, approvalStatus=2
*/
const
handleBatchPass
=
()
=>
{
const
rowsToPass
=
applicationList
.
value
.
filter
(
(
item
)
=>
ids
.
value
.
includes
(
item
.
id
)
&&
item
.
leaveDaysSubtotal
<
3
);
if
(
!
rowsToPass
.
length
)
{
console
.
warn
(
"没有符合条件的记录"
);
return
;
}
const
params
=
{
ids
:
rowsToPass
.
map
((
row
)
=>
row
.
id
),
nodeId
:
111
,
approvalStatus
:
2
}
;
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus
(
params
)
.
then
(()
=>
{
console
.
log
(
"批量通过成功"
);
getList
();
}
)
.
catch
(
err
=>
console
.
error
(
"批量通过出错:"
,
err
));
}
;
/**
* 单条“驳回”:不限制角色,nodeId=110, approvalStatus=3
*/
const
handleReject
=
(
row
)
=>
{
const
params
=
{
ids
:
[
row
.
id
],
nodeId
:
110
,
approvalStatus
:
3
}
;
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus
(
params
)
.
then
(()
=>
{
console
.
log
(
"驳回成功"
);
getList
();
}
)
.
catch
(
err
=>
console
.
error
(
"驳回失败:"
,
err
));
}
;
/**
* 一键驳回:对选中的记录,nodeId=110, approvalStatus=3
*/
const
handleBatchReject
=
()
=>
{
const
rowsToReject
=
applicationList
.
value
.
filter
(
(
item
)
=>
ids
.
value
.
includes
(
item
.
id
)
);
if
(
!
rowsToReject
.
length
)
{
console
.
warn
(
"未选中任何记录"
);
return
;
}
const
params
=
{
ids
:
rowsToReject
.
map
(
row
=>
row
.
id
),
nodeId
:
110
,
approvalStatus
:
3
}
;
batchUpdateLeaveApplicationByNodeIdAndApprovalStatus
(
params
)
.
then
(()
=>
{
console
.
log
(
"一键驳回成功"
);
getList
();
}
)
.
catch
(
err
=>
console
.
error
(
"一键驳回出错:"
,
err
));
}
;
// ----- 生命周期钩子 -----
onMounted
(()
=>
{
userStore
.
getInfo
()
.
then
(
userInfo
=>
{
currentRole
.
value
=
userInfo
.
roles
[
0
]
||
''
;
console
.
log
(
'当前用户角色:'
,
currentRole
.
value
);
getList
();
}
)
.
catch
(
err
=>
console
.
error
(
"获取用户信息失败:"
,
err
));
}
);
<
/script
>
<
style
scoped
>
.
pagination
-
container
{
margin
-
top
:
12
px
;
margin
-
right
:
285
px
;
}
<
/style
>
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