Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
J
jilinzhongdianrenqun-web
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Members
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
吴超
jilinzhongdianrenqun-web
Commits
e6fdd1fc
Commit
e6fdd1fc
authored
Dec 31, 2025
by
yubin
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
# Conflicts: # src/view/key-person/key_dm_leave/index.vue
parents
8a78816c
ff3b6f3b
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
184 行增加
和
108 行删除
+184
-108
src/view/key-person/key-person-visit-record/index.vue
+1
-1
src/view/key-person/key_dm_inventory/index.vue
+47
-21
src/view/key-person/key_dm_leave/index.vue
+136
-86
没有找到文件。
src/view/key-person/key-person-visit-record/index.vue
View file @
e6fdd1fc
...
...
@@ -118,7 +118,7 @@
>
<Button
icon=
"ios-cloud-upload-outline"
>
上传图片
</Button>
</Upload>
<
/Upload
>
<
!-- </Upload> --
>
<!-- <div class="upload-tips">支持多张图片上传,单张图片不超过5MB</div>
<div v-if="visitModal.form.visit_img_list.length" class="upload-preview">
<div
...
...
src/view/key-person/key_dm_inventory/index.vue
View file @
e6fdd1fc
...
...
@@ -80,7 +80,7 @@
show-total
show-sizer
@
on-change=
"pageChange('apply', $event)"
@
on-page-size-change=
"sizeChange('apply', $event)"
/>
</TabPane>
<TabPane
label=
"办公用品待审核"
name=
"pending"
>
<TabPane
label=
"办公用品待审核"
name=
"pending"
v-if=
"power.supply_approval"
>
<Table
:data=
"tables.pending"
:loading=
"loading.pending"
:columns=
"pendingColumns"
border
>
<
template
slot=
"action"
slot-scope=
"{ row }"
>
<Button
size=
"small"
type=
"primary"
@
click=
"openApproveModal(row)"
>
处理
</Button>
...
...
@@ -90,7 +90,7 @@
show-total
show-sizer
@
on-change=
"pageChange('pending', $event)"
@
on-page-size-change=
"sizeChange('pending', $event)"
/>
</TabPane>
<TabPane
label=
"办公用品审核历史查询"
name=
"history"
>
<TabPane
label=
"办公用品审核历史查询"
name=
"history"
v-if=
"power.supply_view"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
>
<Col
span=
"18"
>
...
...
@@ -158,7 +158,7 @@
show-total
show-sizer
@
on-change=
"pageChange('history', $event)"
@
on-page-size-change=
"sizeChange('history', $event)"
/>
</TabPane>
<TabPane
label=
"办公用品入库"
name=
"inbound"
>
<TabPane
label=
"办公用品入库"
name=
"inbound"
v-if=
"power.inventory_manager"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
>
<Col
span=
"18"
>
...
...
@@ -246,7 +246,7 @@
show-total
show-sizer
@
on-change=
"pageChange('inbound', $event)"
@
on-page-size-change=
"sizeChange('inbound', $event)"
/>
</TabPane>
<TabPane
label=
"办公用品归还"
name=
"return"
>
<TabPane
label=
"办公用品归还"
name=
"return"
v-if=
"power.inventory_manager"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
>
<Col
span=
"18"
>
...
...
@@ -280,7 +280,7 @@
show-total
show-sizer
@
on-change=
"pageChange('return', $event)"
@
on-page-size-change=
"sizeChange('return', $event)"
/>
</TabPane>
<TabPane
label=
"库存查询"
name=
"inventory"
>
<TabPane
label=
"库存查询"
name=
"inventory"
v-if=
"power.inventory_manager"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
>
<Col
span=
"18"
>
...
...
@@ -424,12 +424,12 @@
<h4>
明细(从物料库选择)
<div
style=
"float: right;"
>
<Button
size=
"small"
class=
"mr5"
type=
"primary"
@
click=
"showMaterialSelector = true"
>
添加
</Button>
<Button
size=
"small"
class=
"mr5"
type=
"primary"
@
click=
"show
Inbound
MaterialSelector = true"
>
添加
</Button>
<Button
size=
"small"
type=
"error"
@
click=
"deleteSelectedInboundDetails"
>
删除
</Button>
</div>
</h4>
<Table
:data=
"inboundModal.details"
:columns=
"inboundDetailColumns"
size=
"small"
border
@
on-selection-change=
"onInboundDetailSelectionChange"
style=
"width: 100%"
/>
<MaterialSelector
v-model=
"show
MaterialSelector"
:selected=
"[]"
@
on-ok=
"handleInboundMaterialSelectorOk"
@
cancel=
"show
MaterialSelector = false"
/>
<MaterialSelector
v-model=
"show
InboundMaterialSelector"
:selected=
"[]"
@
on-ok=
"handleInboundMaterialSelectorOk"
@
cancel=
"showInbound
MaterialSelector = false"
/>
</Form>
<div
slot=
"footer"
>
<Button
@
click=
"inboundModal.visible=false"
>
取消
</Button>
...
...
@@ -544,7 +544,8 @@ import {
getInventoryList
,
getInboundById
,
getPendingReturnById
,
importInbound
importInbound
,
getUserDmPermissionList
}
from
'@/api/key-dm'
import
MaterialSelector
from
'@/view/key-person/key_dm_conf/materialSelector.vue'
import
{
normalizeVisitTimeValue
}
from
'@/view/key-person/key_dm_conf/dates.js'
...
...
@@ -587,7 +588,6 @@ export default {
editingCellField
:
''
,
// 审批状态映射字典
approvalStatusMap
:
{
'0'
:
'待提交'
,
'1'
:
'审核中'
,
'9'
:
'审核通过'
,
'-1'
:
'驳回'
},
opTypeMap
:
{
'1'
:
'入库'
,
'2'
:
'出库'
},
activeTab
:
'apply'
,
filters
:
{
apply
:
{
application_no
:
''
,
applicant_name
:
''
,
approval_status
:
null
,
startDate
:
null
,
endDate
:
null
},
...
...
@@ -792,7 +792,13 @@ export default {
{
title
:
'物料名称'
,
key
:
'material_name'
},
{
title
:
'申请数量'
,
key
:
'apply_quantity'
},
{
title
:
'单位'
,
key
:
'unit'
},
{
title
:
'可用库存'
,
key
:
'available_quantity'
}
{
title
:
'可用库存'
,
key
:
'available_quantity'
,
render
:
(
h
,
{
row
})
=>
{
return
h
(
'span'
,
row
.
available_quantity
||
0
)
}
}
],
detailDetailColumns
:
[
{
title
:
'物料编码'
,
key
:
'material_code'
},
...
...
@@ -973,6 +979,7 @@ export default {
],
// 选择器控制与已选明细
showMaterialSelector
:
false
,
showInboundMaterialSelector
:
false
,
applySelectedDetails
:
[],
applyModal
:
{
visible
:
false
,
isEdit
:
false
,
saving
:
false
,
form
:
{},
details
:
[],
isEditing
:
false
},
approveModal
:
{
visible
:
false
,
record
:
{},
details
:
[],
opinion
:
''
,
submitting
:
false
},
...
...
@@ -987,14 +994,38 @@ export default {
inboundSelectedDetails
:
[],
inboundModal
:
{
visible
:
false
,
isEdit
:
false
,
saving
:
false
,
form
:
{},
details
:
[]
},
returnModal
:
{
visible
:
false
,
record
:
{},
details
:
[],
saving
:
false
},
inboundDetailModal
:
{
visible
:
false
,
loading
:
false
,
data
:
{},
details
:
[],
logs
:
[]
}
inboundDetailModal
:
{
visible
:
false
,
loading
:
false
,
data
:
{},
details
:
[],
logs
:
[]
},
power
:
{
leave_approval
:
false
,
// 请假审核
leave_view
:
false
,
// 请假查询(统计)
supply_approval
:
false
,
// 用品申领审核
supply_view
:
false
,
// 用品查询(统计)
inventory_manager
:
false
// 库存管理
}
}
},
created
()
{
this
.
fetchList
(
'apply'
)
this
.
fetchApproverList
()
this
.
getUserDmPermission
()
},
methods
:
{
getUserDmPermission
()
{
getUserDmPermissionList
({}).
then
(
ret
=>
{
console
.
log
(
'ret'
,
ret
)
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
const
data
=
ret
.
data
.
data
||
[]
for
(
let
i
=
0
;
i
<
data
.
length
;
i
++
)
{
var
ele
=
data
[
i
]
if
(
this
.
power
.
hasOwnProperty
(
ele
.
code
))
{
this
.
power
[
ele
.
code
]
=
true
}
}
}
else
{
this
.
$Notice
.
error
({
title
:
'查询失败'
,
desc
:
ret
.
data
.
errmsg
||
'请稍后重试'
})
}
})
},
// 新增:获取审批人列表
async
fetchApproverList
()
{
await
getSupplyApproval
().
then
(
ret
=>
{
...
...
@@ -1201,6 +1232,7 @@ export default {
return
}
selectedRows
.
forEach
(
sel
=>
{
console
.
log
(
sel
)
const
code
=
sel
.
material_code
const
exist
=
this
.
applyModal
.
details
.
find
(
d
=>
d
.
material_code
===
code
)
if
(
exist
)
{
...
...
@@ -1282,10 +1314,12 @@ export default {
return
(
row
.
approval_status
===
1
&&
row
.
applicant_id
===
userId
)
},
submit
(
row
)
{
console
.
log
(
row
)
// 暂存当前申请ID
this
.
approverModal
.
currentBorrowId
=
row
.
id
// 清空上次选择的审批人
this
.
approverModal
.
form
.
approver_id
=
''
this
.
approverModal
.
form
.
approver_id
=
row
.
approver_id
// 获取审批人列表
this
.
fetchApproverList
()
// 打开审批人选择弹窗
...
...
@@ -1295,7 +1329,6 @@ export default {
// 新增:确认选择审批人后提交
confirmSubmitWithApprover
()
{
const
approverId
=
this
.
approverModal
.
form
.
approver_id
this
.
approverModal
.
submitting
=
true
// 调用提交接口,携带审批人ID(需后端接口支持)
submitBorrow
({
...
...
@@ -1426,13 +1459,6 @@ export default {
})
}
},
getTodayDate
()
{
const
today
=
new
Date
()
const
year
=
today
.
getFullYear
()
const
month
=
String
(
today
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)
const
day
=
String
(
today
.
getDate
()).
padStart
(
2
,
'0'
)
return
`
${
year
}
-
${
month
}
-
${
day
}
`
},
openInboundModal
()
{
this
.
inboundModal
.
isEdit
=
false
this
.
inboundModal
.
form
=
{
inbound_no
:
''
,
batch_no
:
''
,
inbound_date
:
this
.
getTodayDate
(),
inbound_type
:
1
,
storage_location
:
''
,
remark
:
''
}
...
...
@@ -1464,7 +1490,7 @@ export default {
})
}
})
this
.
showMaterialSelector
=
false
this
.
show
Inbound
MaterialSelector
=
false
},
deleteSelectedInboundDetails
()
{
if
(
!
this
.
inboundSelectedDetails
||
this
.
inboundSelectedDetails
.
length
===
0
)
{
...
...
@@ -1534,7 +1560,7 @@ export default {
}
else
{
this
.
$Notice
.
error
({
title
:
'保存失败'
,
desc
:
ret
.
data
&
&
ret
.
data
.
errmsg
||
'未知错误'
desc
:
ret
.
data
&
ret
.
data
.
errmsg
||
'未知错误'
})
}
}).
catch
(
error
=>
{
...
...
src/view/key-person/key_dm_leave/index.vue
View file @
e6fdd1fc
...
...
@@ -28,9 +28,7 @@
<template
slot=
"action"
slot-scope=
"
{ row }">
<Button
size=
"small"
class=
"mr10"
@
click=
"openDetail(row)"
>
详细
</Button>
<Button
size=
"small"
type=
"primary"
class=
"mr10"
@
click=
"openEdit(row)"
v-if=
"canEdit(row)"
>
修改
</Button>
<Poptip
confirm
title=
"确认提交此请假申请进入审批流程?"
transfer
@
on-ok=
"submit(row)"
v-if=
"canSubmit(row)"
>
<Button
size=
"small"
type=
"success"
class=
"mr10"
>
提交
</Button>
</Poptip>
<Button
size=
"small"
type=
"success"
class=
"mr10"
@
click=
"submit(row)"
v-if=
"canSubmit(row)"
>
提交
</Button>
<Poptip
confirm
title=
"确认删除?"
transfer
@
on-ok=
"deleteApply(row)"
v-if=
"canDelete(row)"
>
<Button
size=
"small"
type=
"error"
class=
"mr10"
>
删除
</Button>
</Poptip>
...
...
@@ -44,7 +42,7 @@
show-total
show-sizer
@
on-change=
"pageChange('apply', $event)"
@
on-page-size-change=
"sizeChange('apply', $event)"
/>
</TabPane>
<TabPane
:label=
"'请假待审核'"
name=
"pending"
v-if=
"power.leave_approval"
>
<TabPane
:label=
"'请假待审核'"
name=
"pending"
>
<Table
border
:loading=
"loading.pending"
:columns=
"pendingColumns"
:data=
"tables.pending"
>
<
template
slot=
"action"
slot-scope=
"{ row }"
>
<div
class=
"action-buttons"
>
...
...
@@ -56,7 +54,7 @@
show-total
show-sizer
@
on-change=
"pageChange('pending', $event)"
@
on-page-size-change=
"sizeChange('pending', $event)"
/>
</TabPane>
<TabPane
label=
"审核历史查询"
name=
"history"
v-if=
"power.leave_view"
>
<TabPane
label=
"审核历史查询"
name=
"history"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
align=
"middle"
>
<Col
span=
"18"
>
...
...
@@ -64,8 +62,10 @@
<DatePicker
v-model=
"filters.history.start_time"
type=
"date"
placeholder=
"开始日期"
style=
"width: 200px"
class=
"mr10"
/>
<span>
结束:
</span>
<DatePicker
v-model=
"filters.history.end_time"
type=
"date"
placeholder=
"结束日期"
style=
"width: 200px"
class=
"mr10"
/>
<span>
审批人:
</span>
<Input
v-model=
"filters.history.approver_name"
placeholder=
"请输入审批人姓名"
style=
"width: 200px"
/>
<span>
状态:
</span>
<Select
v-model=
"filters.history.status"
style=
"width: 200px"
>
<Option
v-for=
"opt in statusOptionsFor('history')"
:key=
"opt.id"
:value=
"opt.id"
>
{{ opt.name }}
</Option>
</Select>
</Col>
<Col
span=
"6"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch('history')"
>
搜索
</Button>
...
...
@@ -82,7 +82,7 @@
show-total
show-sizer
@
on-change=
"pageChange('history', $event)"
@
on-page-size-change=
"sizeChange('history', $event)"
/>
</TabPane>
<TabPane
label=
"请假申请查询"
name=
"query"
v-if=
"power.leave_view"
>
<TabPane
label=
"请假申请查询"
name=
"query"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
align=
"middle"
>
<Col
span=
"18"
>
...
...
@@ -110,7 +110,7 @@
show-total
show-sizer
@
on-change=
"pageChange('query', $event)"
@
on-page-size-change=
"sizeChange('query', $event)"
/>
</TabPane>
<TabPane
label=
"请假统计"
name=
"stats"
v-if=
"power.leave_view"
>
<TabPane
label=
"请假统计"
name=
"stats"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
align=
"middle"
>
<Col
span=
"18"
>
...
...
@@ -156,7 +156,7 @@
<Input
v-model=
"applyModal.form.emergency_phone"
/>
</FormItem>
<FormItem
label=
"审批人"
prop=
"approver_id"
>
<Select
v-if=
"leaveApprovalOptions.length > 0"
v-model=
"applyModal.form.approver_id"
style=
"width: 60%"
filterable
>
<Select
v-if=
"leaveApprovalOptions.length > 0"
v-model=
"applyModal.form.approver_id"
style=
"width: 60%"
>
<Option
v-for=
"opt in leaveApprovalOptions"
:key=
"opt.id"
:value=
"opt.id"
>
{{ opt.name }}
</Option>
</Select>
<span
v-else
style=
"color: #999; font-style: italic;"
>
请先进行审批人配置
</span>
...
...
@@ -180,9 +180,6 @@
<FormItem
label=
"起止时间"
>
<span>
{{ formatDatetime(approveModal.record.start_time) }} - {{ formatDatetime(approveModal.record.end_time) }}
</span>
</FormItem>
<FormItem
label=
"请假时长(天)"
>
<span>
{{ approveModal.record.duration || '-' }}
</span>
</FormItem>
<FormItem
label=
"请假事由"
>
<span>
{{ approveModal.record.reason }}
</span>
</FormItem>
...
...
@@ -206,7 +203,7 @@
<Checkbox
v-model=
"approveModal.transferEnabled"
>
转审核
</Checkbox>
</FormItem>
<FormItem
v-if=
"approveModal.transferEnabled"
label=
"选择审批人"
prop=
"transferApprover"
>
<Select
v-if=
"leaveApprovalOptions.length > 0"
v-model=
"approveModal.transferApprover"
style=
"width: 60%"
placeholder=
"请选择审批人"
filterable
>
<Select
v-if=
"leaveApprovalOptions.length > 0"
v-model=
"approveModal.transferApprover"
style=
"width: 60%"
placeholder=
"请选择审批人"
>
<Option
v-for=
"opt in leaveApprovalOptions"
:key=
"opt.id"
:value=
"opt.id"
>
{{ opt.name }}
</Option>
</Select>
<span
v-else
style=
"color: #999; font-style: italic;"
>
请先进行审批人配置
</span>
...
...
@@ -238,7 +235,6 @@
</Row>
<Row
class=
"mt8"
><Col
span=
"24"
><p><strong>
请假类型:
</strong>
{{ detailModal.data.leave_type_name || '-' }}
</p></Col></Row>
<Row
class=
"mt8"
><Col
span=
"24"
><p><strong>
起止时间:
</strong>
{{ formatDatetime(detailModal.data.start_time) }} - {{ formatDatetime(detailModal.data.end_time) }}
</p></Col></Row>
<Row
class=
"mt8"
><Col
span=
"24"
><p><strong>
请假时长(天):
</strong>
{{ detailModal.data.duration || '-' }}
</p></Col></Row>
<Row
class=
"mt8"
><Col
span=
"24"
><p><strong>
请假事由:
</strong>
{{ detailModal.data.reason || '-' }}
</p></Col></Row>
<Row
class=
"mt8"
><Col
span=
"24"
><p><strong>
状态:
</strong>
{{ mapStatusText(detailModal.data.status) }}
</p></Col></Row>
<Row
v-if=
"detailModal.data.status === -1 || String(detailModal.data.status) === '-1'"
class=
"mt8"
><Col
span=
"24"
><p><strong>
驳回理由:
</strong>
{{ detailModal.data.back_reason || detailModal.data.backReason || '-' }}
</p></Col></Row>
...
...
@@ -286,7 +282,6 @@ import {
getLeaveById
,
getLeaveTypeList
,
deleteLeaveById
,
getUserDmPermissionList
,
selectTransferApprovalList
,
transferLeaveApproval
,
getLeaveApprovalPermission
...
...
@@ -298,7 +293,7 @@ export default {
data
()
{
return
{
activeTab
:
'apply'
,
filters
:
{
apply
:
{
start_time
:
null
,
end_time
:
null
,
status
:
''
},
history
:
{
start_time
:
null
,
end_time
:
null
,
approver_id
:
''
},
query
:
{
start_time
:
null
,
end_time
:
null
,
status
:
''
}
},
filters
:
{
apply
:
{
start_time
:
null
,
end_time
:
null
,
status
:
''
},
history
:
{
start_time
:
null
,
end_time
:
null
,
status
:
''
},
query
:
{
start_time
:
null
,
end_time
:
null
,
status
:
''
}
},
// 下拉:请假审核权限可选人员
leaveApprovalOptions
:
[],
// 下拉:转审核审批人列表
...
...
@@ -341,16 +336,14 @@ export default {
{
type
:
'index'
,
title
:
'序号'
,
width
:
60
,
align
:
'center'
},
{
title
:
'申请人'
,
key
:
'user_name'
,
align
:
'center'
},
{
title
:
'请假类型'
,
key
:
'leave_type_name'
,
align
:
'center'
},
{
title
:
'起止时间'
,
key
:
'start_time'
,
align
:
'center'
,
width
:
300
,
render
:
(
h
,
{
row
})
=>
h
(
'span'
,
`
${
row
.
start_time
||
'-'
}
~
${
row
.
end_time
||
'-'
}
`
)
},
{
title
:
'起止时间'
,
key
:
'start_time'
,
align
:
'center'
,
render
:
(
h
,
{
row
})
=>
h
(
'span'
,
`
${
row
.
start_time
||
'-'
}
~
${
row
.
end_time
||
'-'
}
`
)
},
{
title
:
'审批完成时间'
,
key
:
'approval_complete_time'
,
align
:
'center'
},
{
title
:
'处理结果'
,
key
:
'op_result'
,
align
:
'center'
,
render
:
(
h
,
{
row
})
=>
h
(
'span'
,
this
.
renderApproveResult
(
row
.
op_result
))
},
{
title
:
'操作'
,
slot
:
'action'
,
align
:
'center'
,
width
:
100
}
],
queryColumns
:
[
{
type
:
'index'
,
title
:
'序号'
,
width
:
60
,
align
:
'center'
},
{
title
:
'申请人'
,
key
:
'user_name'
,
align
:
'center'
},
{
title
:
'状态'
,
key
:
'status'
,
align
:
'center'
,
render
:
(
h
,
{
row
})
=>
h
(
'span'
,
this
.
mapStatusText
(
row
.
status
))
},
{
title
:
'提交时间'
,
key
:
'submit_time'
,
align
:
'center'
},
{
title
:
'操作'
,
slot
:
'action'
,
align
:
'center'
,
width
:
100
}
],
...
...
@@ -385,43 +378,78 @@ export default {
}
],
applyModal
:
{
visible
:
false
,
isEdit
:
false
,
saving
:
false
,
form
:
{}
},
// NOTE: 自动计算时长逻辑已移除,保留字段移除
// 控制是否在赋值时触发自动计算(true = 允许计算;false = 赋值时不计算)
suppressDurationCalc
:
false
,
approveModal
:
{
visible
:
false
,
record
:
{},
comment
:
''
,
submitting
:
false
,
transferEnabled
:
false
,
transferApprover
:
''
,
approvalFlow
:
[]
},
transferModal
:
{
visible
:
false
,
selectedApprover
:
''
,
comment
:
''
,
processing
:
false
,
record
:
{}
},
detailModal
:
{
visible
:
false
,
loading
:
false
,
data
:
{},
approvals
:
[]
},
statsStart
:
new
Date
(
new
Date
().
getFullYear
(),
new
Date
().
getMonth
(),
1
),
statsEnd
:
new
Date
(),
statsDept
:
''
,
power
:
{
leave_approval
:
false
,
// 请假审核
leave_view
:
false
,
// 请假查询(统计)
supply_approval
:
false
,
// 用品申领审核
supply_view
:
false
,
// 用品查询(统计)
inventory_manager
:
false
// 库存管理
},
// 表单验证规则
applyRules
:
{
leave_type_id
:
[
{
required
:
true
,
message
:
'请选择请假类型'
,
trigger
:
'
input
'
}
{
required
:
true
,
message
:
'请选择请假类型'
,
trigger
:
'
change
'
}
],
start_time
:
[
{
required
:
true
,
message
:
'请选择开始时间'
,
trigger
:
'
input
'
,
type
:
'date'
}
{
required
:
true
,
message
:
'请选择开始时间'
,
trigger
:
'
change
'
,
type
:
'date'
}
],
end_time
:
[
{
required
:
true
,
message
:
'请选择结束时间'
,
trigger
:
'
input
'
,
type
:
'date'
}
{
required
:
true
,
message
:
'请选择结束时间'
,
trigger
:
'
change
'
,
type
:
'date'
}
],
duration
:
[
{
required
:
true
,
message
:
'请填写请假时长'
,
trigger
:
'input'
},
validator
:
function
(
rule
,
value
,
callback
)
{
const
form
=
(
this
&&
this
.
applyModal
&&
this
.
applyModal
.
form
)
?
this
.
applyModal
.
form
:
{}
const
parseToDateLocal
=
(
v
)
=>
{
if
(
v
===
null
||
v
===
undefined
||
v
===
''
)
return
null
if
(
typeof
v
===
'number'
)
return
new
Date
(
v
)
if
(
typeof
v
===
'string'
)
{
if
(
/^
\d
+$/
.
test
(
v
))
return
new
Date
(
Number
(
v
))
const
s
=
v
.
includes
(
'T'
)
?
v
:
v
.
replace
(
' '
,
'T'
)
const
parsed
=
new
Date
(
s
)
return
isNaN
(
parsed
.
getTime
())
?
null
:
parsed
}
if
(
v
instanceof
Date
)
return
isNaN
(
v
.
getTime
())
?
null
:
v
const
parsed
=
new
Date
(
v
)
return
isNaN
(
parsed
.
getTime
())
?
null
:
parsed
}
// 解析起止时间的整天差
const
sd
=
parseToDateLocal
(
form
.
start_time
)
const
ed
=
parseToDateLocal
(
form
.
end_time
)
let
fullDays
=
0
if
(
sd
&&
ed
)
{
const
diff
=
ed
.
getTime
()
-
sd
.
getTime
()
fullDays
=
Math
.
floor
(
diff
/
(
1000
*
60
*
60
*
24
))
}
// 如果不足整天,不校验(允许用户填写任意时长)
if
(
fullDays
<
1
)
{
callback
();
return
}
// 整天或以上时,必须填写且整数部分需与计算天数一致
if
(
value
===
null
||
value
===
undefined
||
String
(
value
).
trim
()
===
''
)
{
callback
(
new
Error
(
'请填写请假时长'
));
return
}
const
num
=
Number
(
value
)
if
(
isNaN
(
num
)
||
num
<=
0
)
{
callback
(
new
Error
(
'请假天数必须为大于 0 的数字'
));
return
}
const
integerPart
=
Math
.
floor
(
num
)
if
(
integerPart
!==
fullDays
)
{
callback
(
new
Error
(
`请假整数天应为
${
fullDays
}
天,请确认`
));
return
}
callback
()
},
trigger
:
'blur'
}
],
approver_id
:
[
{
required
:
true
,
message
:
'请选择审批人'
,
trigger
:
'
input
'
}
{
required
:
true
,
message
:
'请选择审批人'
,
trigger
:
'
change
'
}
],
reason
:
[
{
required
:
true
,
message
:
'请填写请假事由'
,
trigger
:
'
input
'
}
{
required
:
true
,
message
:
'请填写请假事由'
,
trigger
:
'
change
'
}
],
emergency_phone
:
[
{
message
:
'请输入紧急电话'
,
trigger
:
'blur'
},
...
...
@@ -430,7 +458,7 @@ export default {
message
:
'请输入有效的电话号码'
,
trigger
:
'blur'
}
]
,
]
}
}
},
...
...
@@ -440,11 +468,23 @@ export default {
this
.
loadLeaveApprovalOptions
()
// 加载待审批计数,用于页面顶部/选项卡徽章显示
this
.
loadPendingCount
()
//
已移除自动计算时长,保留表单规则在 data 中定义(不在 created 中覆盖)
this
.
getUserDmPermission
()
//
将 duration 的 validator 绑定到组件实例的方法,确保内部能访问 this.applyModal.form
this
.
applyRules
.
duration
=
[{
validator
:
this
.
validateDuration
,
trigger
:
'blur'
}]
},
watch
:
{
// 自动计算时长逻辑已移除:开始/结束时间变化不再自动修改 duration 字段
// 监听开始时间和结束时间变化,自动计算天数
'applyModal.form.start_time'
(
newVal
)
{
if
(
this
.
suppressDurationCalc
)
return
// 用户修改起始时间时,先清空已有时长(避免与新时间不符),再进行自动计算
if
(
this
.
applyModal
&&
this
.
applyModal
.
form
)
this
.
applyModal
.
form
.
duration
=
''
this
.
calculateDuration
()
},
'applyModal.form.end_time'
(
newVal
)
{
if
(
this
.
suppressDurationCalc
)
return
// 用户修改结束时间时,先清空已有时长(避免与新时间不符),再进行自动计算
if
(
this
.
applyModal
&&
this
.
applyModal
.
form
)
this
.
applyModal
.
form
.
duration
=
''
this
.
calculateDuration
()
},
// 当弹窗关闭时清理选择的审批人,确保下次打开时下拉框能正确刷新显示
'applyModal.visible'
(
val
)
{
if
(
!
val
&&
this
.
applyModal
&&
this
.
applyModal
.
form
)
{
...
...
@@ -472,22 +512,7 @@ export default {
}
},
methods
:
{
getUserDmPermission
()
{
getUserDmPermissionList
({}).
then
(
ret
=>
{
console
.
log
(
'ret'
,
ret
)
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
const
data
=
ret
.
data
.
data
||
[]
for
(
let
i
=
0
;
i
<
data
.
length
;
i
++
)
{
var
ele
=
data
[
i
]
if
(
this
.
power
.
hasOwnProperty
(
ele
.
code
))
{
this
.
power
[
ele
.
code
]
=
true
}
}
}
else
{
this
.
$Notice
.
error
({
title
:
'查询失败'
,
desc
:
ret
.
data
.
errmsg
||
'请稍后重试'
})
}
})
},
// validator 方法:确保能通过 this 访问组件数据
validateDuration
(
rule
,
value
,
callback
)
{
const
form
=
this
.
applyModal
&&
this
.
applyModal
.
form
?
this
.
applyModal
.
form
:
{}
const
parseToDateLocal
=
(
v
)
=>
{
...
...
@@ -535,13 +560,36 @@ export default {
// 过滤掉 id 为 '0' 或 0 的未提交选项
return
(
this
.
statusOptions
||
[]).
filter
(
opt
=>
String
(
opt
.
id
)
!==
'0'
)
},
// 自动计算请假时长逻辑已移除,duration 由用户手动填写/后端计算
// 计算请假天数(只计算整天,忽略零点几部分)
calculateDuration
()
{
const
form
=
this
.
applyModal
.
form
if
(
!
form
||
!
form
.
start_time
||
!
form
.
end_time
)
return
const
startDate
=
new
Date
(
form
.
start_time
)
const
endDate
=
new
Date
(
form
.
end_time
)
if
(
isNaN
(
startDate
.
getTime
())
||
isNaN
(
endDate
.
getTime
()))
return
if
(
endDate
.
getTime
()
<=
startDate
.
getTime
())
return
// 计算整天数(向下取整),只要整天 >=1 则自动填充为整数天
const
diffTime
=
endDate
.
getTime
()
-
startDate
.
getTime
()
const
fullDays
=
Math
.
floor
(
diffTime
/
(
1000
*
60
*
60
*
24
))
const
existing
=
form
.
duration
!==
null
&&
form
.
duration
!==
undefined
&&
String
(
form
.
duration
).
trim
()
!==
''
if
(
fullDays
>=
1
)
{
// 只有当表单中尚未填写时才自动填充,避免覆盖后端/用户已有值
if
(
!
existing
)
form
.
duration
=
String
(
fullDays
)
}
else
{
// 少于整天时不自动计算,交由用户手动填写(例如半天、几小时)
// 不覆盖已有用户填写的值
if
(
!
existing
)
form
.
duration
=
''
}
},
handleTabChange
(
name
)
{
this
.
activeTab
=
name
if
(
name
===
'pending'
)
this
.
fetchList
(
'pending'
)
if
(
name
===
'history'
)
this
.
fetchList
(
'history'
)
if
(
name
===
'query'
)
this
.
fetchList
(
'query'
)
if
(
name
===
'stats'
)
this
.
loadStats
()
},
fetchList
(
tab
)
{
const
apiMap
=
{
apply
:
getLeaveListByUserId
,
pending
:
getPendingLeaveList
,
history
:
getLeaveApprovalHistory
,
query
:
getLeaveList
}
...
...
@@ -701,15 +749,7 @@ export default {
return
String
(
status
)
},
handleSearch
(
tab
)
{
(
this
.
pagers
[
tab
]
||
{}).
pageNo
=
1
;
this
.
fetchList
(
tab
)
},
handleReset
(
tab
)
{
if
(
tab
===
'history'
)
{
this
.
filters
.
history
=
{
start_time
:
null
,
end_time
:
null
,
approver_id
:
''
}
}
else
{
this
.
filters
[
tab
]
=
{}
}
(
this
.
pagers
[
tab
]
||
{}).
pageNo
=
1
this
.
fetchList
(
tab
)
},
handleReset
(
tab
)
{
this
.
filters
[
tab
]
=
{};
(
this
.
pagers
[
tab
]
||
{}).
pageNo
=
1
;
this
.
fetchList
(
tab
)
},
pageChange
(
tab
,
pageNo
)
{
(
this
.
pagers
[
tab
]
||
{}).
pageNo
=
pageNo
;
this
.
fetchList
(
tab
)
},
sizeChange
(
tab
,
size
)
{
(
this
.
pagers
[
tab
]
||
{}).
pageSize
=
size
;
(
this
.
pagers
[
tab
]
||
{}).
pageNo
=
1
;
this
.
fetchList
(
tab
)
},
loadLeaveTypes
()
{
...
...
@@ -815,14 +855,18 @@ export default {
// 默认开始时间为当天(时分秒置为 0),精确到天
const
today
=
new
Date
()
today
.
setHours
(
0
,
0
,
0
,
0
)
// 不再自动计算时长,表单由用户手动填写 duration
// 在赋值期间禁止自动计算,直到下一个 tick 再恢复,避免渲染期间 watcher 覆盖表单值
this
.
suppressDurationCalc
=
true
this
.
applyModal
.
form
=
{
user_id
:
''
,
user_name
:
''
,
leave_type_id
:
''
,
start_time
:
today
,
end_time
:
''
,
duration_unit
:
2
,
duration
:
''
,
reason
:
''
,
emergency_contact
:
''
,
emergency_phone
:
''
,
approver_id
:
this
.
selectedApprovalUser
||
''
}
this
.
$nextTick
(()
=>
{
this
.
suppressDurationCalc
=
false
})
this
.
applyModal
.
visible
=
true
},
openEdit
(
row
)
{
this
.
applyModal
.
isEdit
=
true
// 编辑模式:直接将行数据赋值到表单,不再触发自动计算
// 在赋值期间禁止自动计算,直到渲染稳定后再恢复,避免覆盖已有 duration
this
.
suppressDurationCalc
=
true
this
.
applyModal
.
form
=
Object
.
assign
({},
row
)
this
.
$nextTick
(()
=>
{
this
.
suppressDurationCalc
=
false
})
// ensure approver_id exists on form when editing
if
(
!
this
.
applyModal
.
form
.
approver_id
)
this
.
applyModal
.
form
.
approver_id
=
row
.
approver_id
||
row
.
approverId
||
row
.
transfer_to_id
||
''
// 保证与 leaveApprovalOptions 中 id 的类型一致(字符串)
...
...
@@ -901,9 +945,13 @@ export default {
return
status
===
0
},
submit
(
row
)
{
submitLeaveApplication
({
id
:
row
.
id
,
leave_id
:
row
.
leave_id
}).
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
$Message
.
success
(
'提交成功'
);
this
.
fetchList
(
'apply'
)
}
else
this
.
$Notice
.
error
({
title
:
'提交失败'
,
desc
:
ret
.
data
&&
ret
.
data
.
errmsg
})
})
this
.
$Modal
.
confirm
({
title
:
'确认提交'
,
content
:
'确认提交此请假申请进入审批流程?'
,
onOk
:
()
=>
{
submitLeaveApplication
({
id
:
row
.
id
,
leave_id
:
row
.
leave_id
}).
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
$Message
.
success
(
'提交成功'
);
this
.
fetchList
(
'apply'
)
}
else
this
.
$Notice
.
error
({
title
:
'提交失败'
,
desc
:
ret
.
data
&&
ret
.
data
.
errmsg
})
})
}
})
},
revoke
(
row
)
{
revokeLeaveApplication
({
id
:
row
.
id
,
leave_id
:
row
.
leave_id
}).
then
(
ret
=>
{
...
...
@@ -1041,6 +1089,8 @@ export default {
refillApply
()
{
// 将批准记录数据反显到申请表单,清除 id 和 leave_id
this
.
applyModal
.
isEdit
=
false
// 在赋值期间禁止自动计算,直到渲染稳定后再恢复
this
.
suppressDurationCalc
=
true
this
.
applyModal
.
form
=
{
leave_type_id
:
this
.
approveModal
.
record
.
leave_type_id
||
''
,
start_time
:
this
.
approveModal
.
record
.
start_time
||
''
,
...
...
@@ -1051,6 +1101,7 @@ export default {
approver_id
:
this
.
approveModal
.
record
.
approver_id
||
this
.
selectedApprovalUser
||
''
}
// 不保留 id 和 leave_id,保持为空
this
.
$nextTick
(()
=>
{
this
.
suppressDurationCalc
=
false
})
this
.
applyModal
.
visible
=
true
// 关闭审批弹窗
this
.
approveModal
.
visible
=
false
...
...
@@ -1058,6 +1109,8 @@ export default {
refillApplyDirect
(
row
)
{
// 直接从列表行数据进行重新填报,清除 id 和 leave_id
this
.
applyModal
.
isEdit
=
false
// 在赋值期间禁止自动计算,直到渲染稳定后再恢复
this
.
suppressDurationCalc
=
true
this
.
applyModal
.
form
=
{
leave_type_id
:
row
.
leave_type_id
||
''
,
start_time
:
row
.
start_time
||
''
,
...
...
@@ -1068,6 +1121,7 @@ export default {
approver_id
:
row
.
approver_id
||
this
.
selectedApprovalUser
||
''
}
// 不保留 id 和 leave_id,保持为空
this
.
$nextTick
(()
=>
{
this
.
suppressDurationCalc
=
false
})
this
.
applyModal
.
visible
=
true
},
openDetail
(
row
)
{
...
...
@@ -1109,20 +1163,16 @@ export default {
}).
finally
(()
=>
{
this
.
detailModal
.
loading
=
false
})
},
openHistoryDetail
(
row
)
{
this
.
openDetail
(
row
)
},
renderApproveResult
(
result
)
{
if
(
result
===
1
||
result
===
'1'
)
return
'通过'
if
(
result
===
-
1
||
result
===
'-1'
)
return
'驳回'
if
(
result
===
2
||
result
===
'2'
)
return
'转审'
return
'未处理'
},
renderApproveResult
(
h
,
{
row
})
{
return
row
.
approver_result
===
1
?
'通过'
:
(
row
.
approver_result
===
-
1
?
'驳回'
:
'未处理'
)
},
formatDatetime
(
val
)
{
if
(
!
val
)
return
'-'
;
return
String
(
val
).
replace
(
'T'
,
' '
)
},
loadStats
()
{
this
.
loading
.
stats
=
true
getLeaveStats
(
{
start
:
this
.
statsStart
?
this
.
formatForDbDatetime
(
this
.
statsStart
)
:
null
,
end
:
this
.
statsEnd
?
this
.
formatForDbDatetime
(
this
.
statsEnd
)
:
null
,
const
params
=
{
start
:
this
.
statsStart
,
end
:
this
.
statsEnd
,
department
:
this
.
statsDept
}).
then
(
ret
=>
{
}
getLeaveStats
({
params
}).
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
console
.
log
(
'ret.data.data'
,
ret
.
data
.
data
)
this
.
tables
.
stats
=
ret
.
data
.
data
||
[]
...
...
@@ -1132,10 +1182,10 @@ export default {
}).
finally
(()
=>
{
this
.
loading
.
stats
=
false
})
},
resetStats
()
{
this
.
statsStart
=
n
ew
Date
(
new
Date
().
getFullYear
(),
new
Date
().
getMonth
(),
1
)
this
.
statsEnd
=
n
ew
Date
()
this
.
statsStart
=
n
ull
this
.
statsEnd
=
n
ull
this
.
statsDept
=
''
this
.
loadStats
()
this
.
tables
.
stats
=
[]
},
deleteApply
(
row
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论