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
0bef0175
Commit
0bef0175
authored
Dec 29, 2025
by
wangchunyang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
前台样式调整及测试问题调整
parent
64b56af8
隐藏空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
1087 行增加
和
165 行删除
+1087
-165
src/api/key-dm-user.js
+3
-2
src/api/key-dm.js
+74
-0
src/router/group/key-person.js
+8
-0
src/view/key-person/key_dm_conf/chartAnalysis.vue
+471
-0
src/view/key-person/key_dm_conf/index.vue
+226
-60
src/view/key-person/key_dm_inventory/stats.vue
+111
-67
src/view/key-person/key_dm_leave/index.vue
+14
-19
src/view/key-person/key_dm_user/index.vue
+25
-7
src/view/key-person/key_dm_user/userMultiSelector.vue
+8
-10
src/view/key-person/key_dm_user/userSelector.vue
+147
-0
没有找到文件。
src/api/key-dm-user.js
View file @
0bef0175
...
...
@@ -47,8 +47,9 @@ export const dmUserOffice = (param) => {
export
const
getUserTypeList
=
(
param
)
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/selectList'
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/selectList'
,
method
:
'post'
,
data
:
param
})
}
// 获取人员多选器列表(所有在职人员)
...
...
src/api/key-dm.js
View file @
0bef0175
...
...
@@ -167,3 +167,77 @@ export const getWorkloadDetails = (param) => {
data
:
param
})
}
// ===== 图表分析 =====
// 汇总统计数据
export
const
getSummaryStats
=
()
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/getSummaryStats'
,
method
:
'post'
})
}
// 请假类型统计
export
const
getLeaveTypeStats
=
()
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/getLeaveTypeStats'
,
method
:
'post'
})
}
// 人员请假统计
export
const
getLeaveUserStats
=
()
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/getLeaveUserStats'
,
method
:
'post'
})
}
// 用品领用统计
export
const
getMaterialUsageStats
=
()
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/getMaterialUsageStats'
,
method
:
'post'
})
}
// 库存预警列表
export
const
getStockWarningList
=
()
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/getStockWarningList'
,
method
:
'post'
})
}
// ===== 部门管理 =====
export
const
getOrgList
=
(
param
)
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/selectOrgList'
,
method
:
'post'
,
data
:
param
})
}
export
const
saveOrg
=
(
param
)
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/saveOrg'
,
method
:
'post'
,
data
:
param
})
}
export
const
deleteOrg
=
(
param
)
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/deleteOrg'
,
method
:
'post'
,
data
:
param
})
}
export
const
assignUsersToOrg
=
(
param
)
=>
{
return
axios
.
request
({
url
:
'/api/ac/jilinsscgsdp/keyDmUserCategory/assignUsersToOrg'
,
method
:
'post'
,
data
:
param
})
}
src/router/group/key-person.js
View file @
0bef0175
...
...
@@ -254,5 +254,13 @@ export default [
title
:
'日常管理统计'
},
component
:
()
=>
import
(
'@/view/key-person/key_dm_inventory/stats'
)
},
{
path
:
'/key-person/dmChartAnalysis'
,
name
:
'dmChartAnalysis'
,
meta
:
{
title
:
'日常数据统计分析'
},
component
:
()
=>
import
(
'@/view/key-person/key_dm_conf/chartAnalysis'
)
}
]
src/view/key-person/key_dm_conf/chartAnalysis.vue
0 → 100644
View file @
0bef0175
<
template
>
<div
class=
"chart-analysis-wrapper"
>
<!-- 第一行:统计标签 -->
<div
class=
"header-container"
>
<div
class=
"title-wrapper"
>
<div
class=
"title-bar"
></div>
<h3
class=
"title-text"
>
数据概览
</h3>
</div>
</div>
<Row
class=
"statistics-bar"
>
<Col
span=
"8"
>
<div
class=
"statistics-item leave-count"
>
<div
class=
"stat-icon"
>
<Icon
type=
"ios-calendar-outline"
size=
"32"
/>
</div>
<div
class=
"stat-content"
>
<div
class=
"stat-title"
>
请假申请次数
</div>
<div
class=
"stat-number"
>
{{
summaryData
.
leaveCount
}}
</div>
<div
class=
"stat-unit"
>
次
</div>
</div>
</div>
</Col>
<Col
span=
"8"
>
<div
class=
"statistics-item borrow-count"
>
<div
class=
"stat-icon"
>
<Icon
type=
"ios-paper-outline"
size=
"32"
/>
</div>
<div
class=
"stat-content"
>
<div
class=
"stat-title"
>
办公用品申领次数
</div>
<div
class=
"stat-number"
>
{{
summaryData
.
borrowCount
}}
</div>
<div
class=
"stat-unit"
>
次
</div>
</div>
</div>
</Col>
<Col
span=
"8"
>
<div
class=
"statistics-item inbound-count"
>
<div
class=
"stat-icon"
>
<Icon
type=
"ios-archive-outline"
size=
"32"
/>
</div>
<div
class=
"stat-content"
>
<div
class=
"stat-title"
>
办公用品入库次数
</div>
<div
class=
"stat-number"
>
{{
summaryData
.
inboundCount
}}
</div>
<div
class=
"stat-unit"
>
次
</div>
</div>
</div>
</Col>
</Row>
<!-- 第二行:请假相关图表 -->
<div
class=
"header-container"
>
<div
class=
"title-wrapper"
>
<div
class=
"title-bar"
></div>
<h3
class=
"title-text"
>
请假数据分析
</h3>
</div>
</div>
<Row
:gutter=
"16"
>
<Col
span=
"10"
>
<Card>
<div
class=
"chart-title"
>
请假类型占比
</div>
<div
ref=
"leaveTypeChart"
class=
"chart-container"
></div>
</Card>
</Col>
<Col
span=
"14"
>
<Card>
<div
class=
"chart-title"
>
月度各人员请假次数
</div>
<div
ref=
"leaveUserChart"
class=
"chart-container"
></div>
</Card>
</Col>
</Row>
<!-- 第三行:办公用品相关图表和表格 -->
<div
class=
"header-container"
>
<div
class=
"title-wrapper"
>
<div
class=
"title-bar"
></div>
<h3
class=
"title-text"
>
办公用品数据分析
</h3>
</div>
</div>
<Row
:gutter=
"16"
>
<Col
span=
"10"
>
<Card>
<div
class=
"chart-title"
>
月度各用品领用量
</div>
<div
ref=
"materialUsageChart"
class=
"chart-container"
></div>
</Card>
</Col>
<Col
span=
"14"
>
<Card
class=
"stock-warning-card"
>
<div
class=
"chart-title"
>
库存预警信息
</div>
<div
class=
"table-container"
>
<Table
:data=
"stockWarningData"
:columns=
"stockWarningColumns"
size=
"small"
border
:height=
"chartHeight"
>
<template
slot=
"threshold"
slot-scope=
"
{ row }">
<span>
{{
row
.
min_stock
}}
-
{{
row
.
max_stock
}}
</span>
</
template
>
<
template
slot=
"status"
slot-scope=
"{ row }"
>
<Tag
:color=
"row.status === 'low' ? 'red' : 'orange'"
>
{{
row
.
status
===
'low'
?
'库存不足'
:
'库存过高'
}}
</Tag>
</
template
>
</Table>
</div>
</Card>
</Col>
</Row>
</div>
</template>
<
script
>
import
*
as
echarts
from
'echarts'
import
{
getSummaryStats
,
getLeaveTypeStats
,
getLeaveUserStats
,
getMaterialUsageStats
,
getStockWarningList
}
from
'@/api/key-dm'
export
default
{
name
:
'chart-analysis'
,
data
()
{
return
{
summaryData
:
{
leaveCount
:
0
,
borrowCount
:
0
,
inboundCount
:
0
},
leaveTypeChart
:
null
,
leaveUserChart
:
null
,
materialUsageChart
:
null
,
chartHeight
:
240
,
stockWarningData
:
[],
stockWarningColumns
:
[
{
title
:
'用品名称'
,
key
:
'material_name'
,
align
:
'center'
,
minWidth
:
50
},
{
title
:
'现有数量'
,
key
:
'available_quantity'
,
align
:
'center'
,
minWidth
:
50
},
{
title
:
'阙值范围'
,
slot
:
'threshold'
,
align
:
'center'
,
minWidth
:
50
},
{
title
:
'状态'
,
slot
:
'status'
,
align
:
'center'
,
minWidth
:
50
}
]
}
},
mounted
()
{
this
.
loadData
()
},
beforeDestroy
()
{
if
(
this
.
leaveTypeChart
)
{
this
.
leaveTypeChart
.
dispose
()
}
if
(
this
.
leaveUserChart
)
{
this
.
leaveUserChart
.
dispose
()
}
if
(
this
.
materialUsageChart
)
{
this
.
materialUsageChart
.
dispose
()
}
},
methods
:
{
loadData
()
{
this
.
loadSummaryStats
()
this
.
loadLeaveTypeStats
()
this
.
loadLeaveUserStats
()
this
.
loadMaterialUsageStats
()
this
.
loadStockWarningList
()
},
loadSummaryStats
()
{
getSummaryStats
().
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
summaryData
=
ret
.
data
.
data
||
this
.
summaryData
}
}).
catch
(()
=>
{
this
.
$Message
.
error
(
'获取统计数据失败'
)
})
},
loadLeaveTypeStats
()
{
getLeaveTypeStats
().
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
initLeaveTypeChart
(
ret
.
data
.
data
||
[])
}
}).
catch
(()
=>
{
this
.
$Message
.
error
(
'获取请假类型统计失败'
)
})
},
loadLeaveUserStats
()
{
getLeaveUserStats
().
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
initLeaveUserChart
(
ret
.
data
.
data
||
[])
}
}).
catch
(()
=>
{
this
.
$Message
.
error
(
'获取人员请假统计失败'
)
})
},
loadMaterialUsageStats
()
{
getMaterialUsageStats
().
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
initMaterialUsageChart
(
ret
.
data
.
data
||
[])
}
}).
catch
(()
=>
{
this
.
$Message
.
error
(
'获取用品领用统计失败'
)
})
},
loadStockWarningList
()
{
getStockWarningList
().
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
stockWarningData
=
ret
.
data
.
data
||
[]
}
}).
catch
(()
=>
{
this
.
$Message
.
error
(
'获取库存预警数据失败'
)
})
},
initLeaveTypeChart
(
data
)
{
this
.
$nextTick
(()
=>
{
const
chartDom
=
this
.
$refs
.
leaveTypeChart
if
(
!
chartDom
)
return
this
.
leaveTypeChart
=
echarts
.
init
(
chartDom
)
const
colors
=
[
'#73c0de'
,
'#3ba272'
,
'#fc8452'
,
'#9a60b4'
,
'#ea7ccc'
,
'#91cc75'
,
'#fac858'
,
'#ee6666'
]
const
option
=
{
tooltip
:
{
trigger
:
'item'
,
formatter
:
'{a} <br/>{b}: {c} ({d}%)'
},
legend
:
{
orient
:
'vertical'
,
left
:
'left'
,
textStyle
:
{
fontSize
:
12
}
},
color
:
colors
,
series
:
[
{
name
:
'请假类型'
,
type
:
'pie'
,
radius
:
[
'50%'
,
'70%'
],
avoidLabelOverlap
:
false
,
label
:
{
show
:
true
,
position
:
'outside'
,
formatter
:
'{b}: {c}'
,
fontSize
:
12
},
emphasis
:
{
label
:
{
show
:
true
,
fontSize
:
'16'
,
fontWeight
:
'bold'
}
},
labelLine
:
{
show
:
true
,
length
:
10
,
length2
:
10
},
data
:
data
.
map
((
item
,
index
)
=>
({
value
:
item
.
count
,
name
:
item
.
type_name
,
itemStyle
:
{
color
:
colors
[
index
%
colors
.
length
]
}
}))
}
]
}
this
.
leaveTypeChart
.
setOption
(
option
)
})
},
initLeaveUserChart
(
data
)
{
this
.
$nextTick
(()
=>
{
const
chartDom
=
this
.
$refs
.
leaveUserChart
if
(
!
chartDom
)
return
this
.
leaveUserChart
=
echarts
.
init
(
chartDom
)
const
option
=
{
tooltip
:
{
trigger
:
'axis'
,
axisPointer
:
{
type
:
'shadow'
}
},
grid
:
{
left
:
'3%'
,
right
:
'4%'
,
bottom
:
'3%'
,
containLabel
:
true
},
xAxis
:
{
type
:
'category'
,
data
:
data
.
map
(
item
=>
item
.
user_name
),
axisLabel
:
{
rotate
:
45
}
},
yAxis
:
{
type
:
'value'
},
series
:
[
{
name
:
'请假次数'
,
type
:
'bar'
,
data
:
data
.
map
(
item
=>
item
.
leave_count
),
itemStyle
:
{
color
:
'#409EFF'
}
}
]
}
this
.
leaveUserChart
.
setOption
(
option
)
})
},
initMaterialUsageChart
(
data
)
{
this
.
$nextTick
(()
=>
{
const
chartDom
=
this
.
$refs
.
materialUsageChart
if
(
!
chartDom
)
return
this
.
materialUsageChart
=
echarts
.
init
(
chartDom
)
const
colors
=
[
'#73c0de'
,
'#3ba272'
,
'#fc8452'
,
'#9a60b4'
,
'#ea7ccc'
,
'#91cc75'
,
'#fac858'
,
'#ee6666'
]
const
option
=
{
tooltip
:
{
trigger
:
'item'
,
formatter
:
'{a} <br/>{b}: {c} ({d}%)'
},
legend
:
{
orient
:
'vertical'
,
left
:
'left'
,
textStyle
:
{
fontSize
:
12
}
},
color
:
colors
,
series
:
[
{
name
:
'领用量'
,
type
:
'pie'
,
radius
:
[
'50%'
,
'70%'
],
avoidLabelOverlap
:
false
,
label
:
{
show
:
true
,
position
:
'outside'
,
formatter
:
'{b}: {c}'
,
fontSize
:
12
},
emphasis
:
{
label
:
{
show
:
true
,
fontSize
:
'16'
,
fontWeight
:
'bold'
}
},
labelLine
:
{
show
:
true
,
length
:
10
,
length2
:
10
},
data
:
data
.
map
((
item
,
index
)
=>
({
value
:
item
.
total_quantity
,
name
:
item
.
material_name
,
itemStyle
:
{
color
:
colors
[
index
%
colors
.
length
]
}
}))
}
]
}
this
.
materialUsageChart
.
setOption
(
option
)
})
}
}
}
</
script
>
<
style
scoped
>
.chart-analysis-wrapper
{
padding
:
20px
;
}
.header-container
{
margin
:
20px
0
10px
0
;
}
.title-wrapper
{
display
:
flex
;
align-items
:
center
;
}
.title-bar
{
width
:
4px
;
height
:
20px
;
background-color
:
#409EFF
;
margin-right
:
10px
;
}
.title-text
{
margin
:
0
;
font-size
:
18px
;
font-weight
:
600
;
color
:
#333
;
}
.statistics-bar
{
margin-bottom
:
20px
;
}
.statistics-item
{
display
:
flex
;
align-items
:
center
;
padding
:
20px
;
background
:
linear-gradient
(
135deg
,
#667eea
0%
,
#764ba2
100%
);
border-radius
:
8px
;
margin
:
0
10px
;
box-shadow
:
0
4px
6px
rgba
(
0
,
0
,
0
,
0.1
);
}
.statistics-item.leave-count
{
background
:
linear-gradient
(
135deg
,
#f093fb
0%
,
#f5576c
100%
);
}
.statistics-item.borrow-count
{
background
:
linear-gradient
(
135deg
,
#4facfe
0%
,
#00f2fe
100%
);
}
.statistics-item.inbound-count
{
background
:
linear-gradient
(
135deg
,
#43e97b
0%
,
#38f9d7
100%
);
}
.stat-icon
{
color
:
white
;
margin-right
:
20px
;
}
.stat-content
{
flex
:
1
;
}
.stat-title
{
font-size
:
14px
;
color
:
rgba
(
255
,
255
,
255
,
0.8
);
margin-bottom
:
8px
;
}
.stat-number
{
font-size
:
36px
;
font-weight
:
bold
;
color
:
white
;
margin-bottom
:
4px
;
display
:
inline
;
}
.stat-unit
{
font-size
:
16px
;
color
:
rgba
(
255
,
255
,
255
,
0.8
);
display
:
inline
;
}
.chart-container
{
width
:
100%
;
height
:
240px
;
}
.chart-title
{
font-size
:
16px
;
font-weight
:
600
;
margin-bottom
:
16px
;
text-align
:
center
;
}
.stock-warning-card
{
height
:
315px
;
display
:
flex
;
flex-direction
:
column
;
}
.table-container
{
flex
:
1
;
overflow
:
hidden
;
}
</
style
>
src/view/key-person/key_dm_conf/index.vue
View file @
0bef0175
...
...
@@ -9,17 +9,51 @@
</
template
>
</Table>
</TabPane>
<!-- 部门管理 -->
<TabPane
label=
"部门管理"
name=
"org"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
>
<Col
span=
"12"
>
<span>
部门名称:
</span>
<Input
v-model=
"filters.org.org_name"
placeholder=
"请输入"
style=
"width: 200px"
/>
</Col>
<Col
span=
"12"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch('org')"
>
搜索
</Button>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleReset('org')"
>
重置
</Button>
<Button
type=
"primary"
@
click=
"openAddModal('org')"
>
新增
</Button>
</Col>
</Row>
</div>
<Table
border
:loading=
"loading.org"
:columns=
"orgColumns"
:data=
"tables.org"
>
<
template
slot=
"action"
slot-scope=
"{ row }"
>
<Button
size=
"small"
type=
"primary"
class=
"mr5"
@
click=
"openEditModal('org', row)"
>
修改
</Button>
<Button
size=
"small"
type=
"info"
class=
"mr5"
@
click=
"openUserAssignModal(row)"
>
人员划分
</Button>
<Poptip
confirm
title=
"确认删除?"
transfer
@
on-ok=
"handleDelete('org', row)"
>
<Button
size=
"small"
type=
"error"
>
删除
</Button>
</Poptip>
</
template
>
</Table>
<Page
class=
"page_style"
:total=
"pagers.org.totalRecord"
:current=
"pagers.org.pageNo"
:page-size=
"pagers.org.pageSize"
show-total
show-sizer
@
on-change=
"pageChange('org', $event)"
@
on-page-size-change=
"sizeChange('org', $event)"
/>
</TabPane>
<!-- 假种管理 -->
<TabPane
label=
"假种管理"
name=
"leaveType"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
>
<Col
span=
"6"
>
<span>
类型名称:
</span>
<Input
v-model=
"filters.leaveType.type_name"
placeholder=
"请输入"
style=
"width: 70%"
/>
</Col>
<Col
span=
"6"
>
<Col
span=
"12"
>
<span>
类型编码:
</span>
<Input
v-model=
"filters.leaveType.type_code"
placeholder=
"请输入"
style=
"width: 70%"
/>
<Input
v-model=
"filters.leaveType.type_code"
placeholder=
"请输入"
style=
"width: 200px"
class=
"mr10"
/>
<span>
类型名称:
</span>
<Input
v-model=
"filters.leaveType.type_name"
placeholder=
"请输入"
style=
"width: 200px"
/>
</Col>
<Col
span=
"12"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch('leaveType')"
>
搜索
</Button>
...
...
@@ -52,13 +86,11 @@
<TabPane
label=
"办公用品分类管理"
name=
"materialCategory"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
>
<Col
span=
"6"
>
<span>
分类名称:
</span>
<Input
v-model=
"filters.materialCategory.category_name"
placeholder=
"请输入"
style=
"width: 70%"
/>
</Col>
<Col
span=
"6"
>
<Col
span=
"12"
>
<span>
分类编码:
</span>
<Input
v-model=
"filters.materialCategory.category_code"
placeholder=
"请输入"
style=
"width: 70%"
/>
<Input
v-model=
"filters.materialCategory.category_code"
placeholder=
"请输入"
style=
"width: 200px"
class=
"mr10"
/>
<span>
分类名称:
</span>
<Input
v-model=
"filters.materialCategory.category_name"
placeholder=
"请输入"
style=
"width: 200px"
/>
</Col>
<Col
span=
"12"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch('materialCategory')"
>
搜索
</Button>
...
...
@@ -91,19 +123,15 @@
<TabPane
label=
"办公用品管理"
name=
"material"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
>
<Col
span=
"6"
>
<span>
名称:
</span>
<Input
v-model=
"filters.material.material_name"
placeholder=
"请输入"
style=
"width: 70%"
/>
</Col>
<Col
span=
"6"
>
<span>
编码:
</span>
<Input
v-model=
"filters.material.material_code"
placeholder=
"请输入"
style=
"width: 70%"
/>
</Col>
<Col
span=
"6"
>
<Col
span=
"18"
>
<span>
分类:
</span>
<Select
v-model=
"filters.material.category_id"
clearable
style=
"width:
70%
"
>
<Select
v-model=
"filters.material.category_id"
clearable
style=
"width:
200px"
class=
"mr10
"
>
<Option
v-for=
"cat in materialCategoryOptions"
:key=
"cat.id"
:value=
"cat.id"
>
{{ cat.category_name }}
</Option>
</Select>
<span>
编码:
</span>
<Input
v-model=
"filters.material.material_code"
placeholder=
"请输入"
style=
"width: 200px"
class=
"mr10"
/>
<span>
名称:
</span>
<Input
v-model=
"filters.material.material_name"
placeholder=
"请输入"
style=
"width: 200px"
/>
</Col>
<Col
span=
"6"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch('material')"
>
搜索
</Button>
...
...
@@ -180,27 +208,12 @@
<Input
type=
"textarea"
:rows=
"3"
v-model=
"modals.leaveType.form.remark"
placeholder=
"请输入类型描述"
/>
</FormItem>
<Row
:gutter=
"16"
>
<Col
span=
"12"
>
<FormItem
label=
"基准天数"
prop=
"base_days"
>
<InputNumber
v-model=
"modals.leaveType.form.base_days"
:min=
"0"
:precision=
"2"
style=
"width: 100%"
/>
</FormItem>
</Col>
<Col
span=
"12"
>
<!-- <Col span="12">
<FormItem label="年度上限" prop="max_days_per_year">
<InputNumber v-model="modals.leaveType.form.max_days_per_year" :min="0" :precision="2" style="width: 100%" />
</FormItem>
</Col>
</Row>
<Row
:gutter=
"16"
>
<Col
span=
"12"
>
<FormItem
label=
"需要审批"
>
<Select
v-model=
"modals.leaveType.form.need_approval"
style=
"width: 100%"
>
<Option
:value=
"1"
>
需要
</Option>
<Option
:value=
"0"
>
不需要
</Option>
</Select>
</FormItem>
</Col>
<Col
span=
"12"
>
</Col> -->
<Col
span=
"24"
>
<FormItem
label=
"排序号"
prop=
"order_no"
>
<InputNumber
v-model=
"modals.leaveType.form.order_no"
:min=
"0"
style=
"width: 100%"
/>
</FormItem>
...
...
@@ -356,9 +369,55 @@
</div>
</Modal>
<!-- 部门管理弹窗 -->
<Modal
v-model=
"modals.org.visible"
:title=
"modals.org.isEdit ? '修改部门' : '新增部门'"
width=
"600"
:mask-closable=
"false"
>
<Form
:label-width=
"120"
:model=
"modals.org.form"
:rules=
"modals.org.rules"
ref=
"orgForm"
>
<!-- <FormItem label="部门编码" prop="org_code">
<Input v-model="modals.org.form.org_code" placeholder="请输入部门编码" />
</FormItem> -->
<FormItem
label=
"部门名称"
prop=
"org_name"
>
<Input
v-model=
"modals.org.form.org_name"
placeholder=
"请输入部门名称"
/>
</FormItem>
<!-- <FormItem label="所属机构编码" prop="source_org">
<Input v-model="modals.org.form.source_org" placeholder="请输入所属机构编码" />
</FormItem> -->
<FormItem
label=
"部门描述"
prop=
"remark"
>
<Input
type=
"textarea"
:rows=
"3"
v-model=
"modals.org.form.remark"
placeholder=
"请输入部门描述"
/>
</FormItem>
<FormItem
label=
"排序号"
prop=
"order_no"
>
<InputNumber
v-model=
"modals.org.form.order_no"
:min=
"0"
style=
"width: 100%"
/>
</FormItem>
</Form>
<div
slot=
"footer"
>
<Button
@
click=
"modals.org.visible = false"
>
取消
</Button>
<Button
type=
"primary"
:loading=
"modals.org.saving"
@
click=
"handleSave('org')"
>
保存
</Button>
</div>
</Modal>
<!-- 人员划分弹窗 -->
<Modal
v-model=
"userAssignModal.visible"
title=
"人员划分"
width=
"800"
:mask-closable=
"false"
>
<div
style=
"margin-bottom: 16px;"
>
<span
style=
"font-weight: bold;"
>
部门:
</span>
{{ userAssignModal.orgName }}
</div>
<div
style=
"margin-bottom: 16px;"
>
<span
style=
"font-weight: bold;"
>
已划分人员:
</span>
<div
style=
"margin-top: 8px;"
>
<Tag
v-for=
"user in userAssignModal.selectedUsers"
:key=
"user.user_id"
closable
@
on-close=
"removeAssignedUser(user)"
>
{{ user.user_name }}
</Tag>
</div>
</div>
<div
slot=
"footer"
>
<Button
@
click=
"userAssignModal.visible = false"
>
取消
</Button>
<Button
type=
"primary"
@
click=
"addUsersToOrg"
>
添加人员
</Button>
<Button
type=
"primary"
:loading=
"userAssignModal.saving"
@
click=
"saveUserAssignment"
>
保存
</Button>
</div>
</Modal>
<!-- 人员选择器 -->
<UserMultiSelector
v-model=
"userSelectorVisible"
:round=
"userRound"
@
on-ok=
"handleUserSelectorOk"
@
cancel=
"userSelectorVisible = false"
/>
...
...
@@ -379,7 +438,11 @@ import {
importMaterial
,
getPermissionConfigList
,
savePermissionUsers
,
getUserDmPermissionList
getUserDmPermissionList
,
getOrgList
,
saveOrg
,
deleteOrg
,
assignUsersToOrg
}
from
'@/api/key-dm'
import
axios
from
'axios'
import
UserMultiSelector
from
'@/view/key-person/key_dm_user/userMultiSelector.vue'
...
...
@@ -393,25 +456,29 @@ export default {
filters
:
{
leaveType
:
{
type_name
:
''
,
type_code
:
''
},
materialCategory
:
{
category_name
:
''
,
category_code
:
''
},
material
:
{
material_name
:
''
,
material_code
:
''
,
category_id
:
''
}
material
:
{
material_name
:
''
,
material_code
:
''
,
category_id
:
''
},
org
:
{
org_name
:
''
,
org_code
:
''
}
},
tables
:
{
permissionConfig
:
[],
leaveType
:
[],
materialCategory
:
[],
material
:
[]
material
:
[],
org
:
[]
},
loading
:
{
permissionConfig
:
false
,
leaveType
:
false
,
materialCategory
:
false
,
material
:
false
material
:
false
,
org
:
false
},
pagers
:
{
permissionConfig
:
{
pageNo
:
1
,
pageSize
:
10
,
totalRecord
:
0
},
leaveType
:
{
pageNo
:
1
,
pageSize
:
10
,
totalRecord
:
0
},
materialCategory
:
{
pageNo
:
1
,
pageSize
:
10
,
totalRecord
:
0
},
material
:
{
pageNo
:
1
,
pageSize
:
10
,
totalRecord
:
0
}
material
:
{
pageNo
:
1
,
pageSize
:
10
,
totalRecord
:
0
},
org
:
{
pageNo
:
1
,
pageSize
:
10
,
totalRecord
:
0
}
},
modals
:
{
leaveType
:
{
...
...
@@ -473,6 +540,23 @@ export default {
category_id
:
[{
required
:
true
,
message
:
'请选择分类'
,
trigger
:
'change'
}],
material_name
:
[{
required
:
true
,
message
:
'请输入物料名称'
,
trigger
:
'blur'
}]
}
},
org
:
{
visible
:
false
,
isEdit
:
false
,
saving
:
false
,
form
:
{
id
:
''
,
source_org
:
''
,
org_code
:
''
,
org_name
:
''
,
remark
:
''
,
order_no
:
0
},
rules
:
{
// org_code: [{ required: true, message: '请输入部门编码', trigger: 'blur' }],
org_name
:
[{
required
:
true
,
message
:
'请输入部门名称'
,
trigger
:
'blur'
}]
}
}
},
userConfigModal
:
{
...
...
@@ -482,6 +566,13 @@ export default {
permissionName
:
''
,
selectedUsers
:
[]
},
userAssignModal
:
{
visible
:
false
,
saving
:
false
,
orgId
:
''
,
orgName
:
''
,
selectedUsers
:
[]
},
userSelectorVisible
:
false
,
importShow
:
false
,
impBtnDisabled
:
false
,
...
...
@@ -490,8 +581,8 @@ export default {
{
type
:
'index'
,
title
:
'序号'
,
width
:
60
,
align
:
'center'
},
{
title
:
'类型编码'
,
key
:
'type_code'
,
align
:
'center'
},
{
title
:
'类型名称'
,
key
:
'type_name'
,
align
:
'center'
},
{
title
:
'基准天数'
,
key
:
'base_days'
,
align
:
'center'
,
width
:
100
},
{
title
:
'需要审批'
,
key
:
'need_approval'
,
align
:
'center'
,
width
:
100
,
render
:
(
h
,
{
row
})
=>
h
(
'span'
,
row
.
need_approval
===
1
?
'需要'
:
'不需要'
)
},
//
{ title: '基准天数', key: 'base_days', align: 'center', width: 100 },
//
{ title: '需要审批', key: 'need_approval', align: 'center', width: 100, render: (h, { row }) => h('span', row.need_approval === 1 ? '需要' : '不需要') },
{
title
:
'排序号'
,
key
:
'order_no'
,
align
:
'center'
,
width
:
100
},
{
title
:
'操作'
,
slot
:
'action'
,
align
:
'center'
,
width
:
180
,
fixed
:
'right'
}
],
...
...
@@ -528,12 +619,23 @@ export default {
{
title
:
'配置人员'
,
key
:
'user_names'
,
align
:
'center'
,
minWidth
:
300
},
{
title
:
'操作'
,
slot
:
'action'
,
align
:
'center'
,
width
:
120
,
fixed
:
'right'
}
],
orgColumns
:
[
{
type
:
'index'
,
title
:
'序号'
,
width
:
60
,
align
:
'center'
},
// { title: '部门编码', key: 'org_code', align: 'center' },
{
title
:
'部门名称'
,
key
:
'org_name'
,
align
:
'center'
},
// { title: '所属机构编码', key: 'source_org', align: 'center' },
{
title
:
'部门人员'
,
key
:
'user_names'
,
align
:
'center'
},
{
title
:
'描述'
,
key
:
'remark'
,
align
:
'center'
},
{
title
:
'排序号'
,
key
:
'order_no'
,
align
:
'center'
,
width
:
100
},
{
title
:
'操作'
,
slot
:
'action'
,
align
:
'center'
,
width
:
200
,
fixed
:
'right'
}
],
power
:
{
leave_approval
:
false
,
// 请假审核
leave_view
:
false
,
// 请假查询(统计)
supply_approval
:
false
,
// 用品申领审核
supply_view
:
false
// 用品查询(统计)
}
},
userRound
:
'1'
}
},
created
()
{
...
...
@@ -572,7 +674,8 @@ export default {
permissionConfig
:
()
=>
Promise
.
resolve
({
data
:
{
errcode
:
0
,
data
:
[]
}
}),
leaveType
:
getLeaveTypeList
,
materialCategory
:
getMaterialCategoryList
,
material
:
getMaterialList
material
:
getMaterialList
,
org
:
getOrgList
}
const
api
=
apiMap
[
tab
]
if
(
!
api
)
return
...
...
@@ -597,7 +700,8 @@ export default {
permissionConfig
:
()
=>
({}),
leaveType
:
()
=>
({
type_name
:
''
,
type_code
:
''
}),
materialCategory
:
()
=>
({
category_name
:
''
,
category_code
:
''
}),
material
:
()
=>
({
material_name
:
''
,
material_code
:
''
,
category_id
:
''
})
material
:
()
=>
({
material_name
:
''
,
material_code
:
''
,
category_id
:
''
}),
org
:
()
=>
({
org_name
:
''
,
org_code
:
''
})
}
this
.
filters
[
tab
]
=
resetMap
[
tab
]()
this
.
pagers
[
tab
].
pageNo
=
1
...
...
@@ -662,6 +766,14 @@ export default {
can_borrow
:
1
,
material_desc
:
''
,
order_no
:
0
},
org
:
{
id
:
''
,
source_org
:
''
,
org_code
:
''
,
org_name
:
''
,
remark
:
''
,
order_no
:
0
}
}
return
JSON
.
parse
(
JSON
.
stringify
(
defaults
[
tab
]))
...
...
@@ -676,7 +788,8 @@ export default {
const
saveApiMap
=
{
leaveType
:
saveLeaveType
,
materialCategory
:
saveMaterialCategory
,
material
:
saveMaterial
material
:
saveMaterial
,
org
:
saveOrg
}
const
api
=
saveApiMap
[
tab
]
api
(
modal
.
form
).
then
(
ret
=>
{
...
...
@@ -698,7 +811,8 @@ export default {
const
deleteApiMap
=
{
leaveType
:
deleteLeaveType
,
materialCategory
:
deleteMaterialCategory
,
material
:
deleteMaterial
material
:
deleteMaterial
,
org
:
deleteOrg
}
const
api
=
deleteApiMap
[
tab
]
api
({
id
:
row
.
id
}).
then
(
ret
=>
{
...
...
@@ -748,17 +862,29 @@ export default {
console
.
log
(
'this.userConfigModal'
,
this
.
userConfigModal
)
},
addUsers
()
{
this
.
userRound
=
'1'
this
.
userSelectorVisible
=
true
},
handleUserSelectorOk
(
selectedUsers
)
{
// 将新选择的用户添加到已选用户列表中,避免重复
const
existingIds
=
this
.
userConfigModal
.
selectedUsers
.
map
(
u
=>
u
.
user_id
)
const
newUsers
=
selectedUsers
.
filter
(
u
=>
!
existingIds
.
includes
(
u
.
id
)).
map
(
u
=>
({
user_id
:
u
.
id
,
user_name
:
u
.
name
,
gh
:
u
.
gh
}))
this
.
userConfigModal
.
selectedUsers
=
[...
this
.
userConfigModal
.
selectedUsers
,
...
newUsers
]
if
(
this
.
userConfigModal
.
visible
)
{
// 权限配置弹窗
const
existingIds
=
this
.
userConfigModal
.
selectedUsers
.
map
(
u
=>
u
.
user_id
)
const
newUsers
=
selectedUsers
.
filter
(
u
=>
!
existingIds
.
includes
(
u
.
id
)).
map
(
u
=>
({
user_id
:
u
.
id
,
user_name
:
u
.
name
,
gh
:
u
.
gh
}))
this
.
userConfigModal
.
selectedUsers
=
[...
this
.
userConfigModal
.
selectedUsers
,
...
newUsers
]
}
else
if
(
this
.
userAssignModal
.
visible
)
{
// 人员划分弹窗
const
existingIds
=
this
.
userAssignModal
.
selectedUsers
.
map
(
u
=>
u
.
user_id
)
const
newUsers
=
selectedUsers
.
filter
(
u
=>
!
existingIds
.
includes
(
u
.
id
)).
map
(
u
=>
({
user_id
:
u
.
id
,
user_name
:
u
.
name
,
gh
:
u
.
gh
}))
this
.
userAssignModal
.
selectedUsers
=
[...
this
.
userAssignModal
.
selectedUsers
,
...
newUsers
]
}
this
.
userSelectorVisible
=
false
},
removeUser
(
user
)
{
...
...
@@ -876,6 +1002,46 @@ export default {
const
areaId
=
info
.
area_id
||
''
if
(
areaId
&&
areaId
.
startsWith
(
'2201'
))
return
true
return
false
},
openUserAssignModal
(
row
)
{
this
.
userAssignModal
.
visible
=
true
this
.
userAssignModal
.
orgId
=
row
.
id
this
.
userAssignModal
.
orgName
=
row
.
org_name
this
.
userAssignModal
.
selectedUsers
=
row
.
user_names
?
(
JSON
.
parse
(
row
.
users
)
||
[])
:
[]
// 加载该部门已分配的人员
// this.loadOrgAssignedUsers(row.id)
},
// loadOrgAssignedUsers (orgId) {
// getOrgList({ pageNo: 1, pageSize: 1000, params: { id: orgId } }).then(ret => {
// if (ret.data && ret.data.errcode === 0) {
// const data = ret.data.data || {}
// // 这里可以根据实际需求调整如何获取已分配的人员
// // 暂时设置为空,后续根据实际业务逻辑调整
// }
// })
// },
addUsersToOrg
()
{
this
.
userRound
=
'2'
this
.
userSelectorVisible
=
true
},
removeAssignedUser
(
user
)
{
this
.
userAssignModal
.
selectedUsers
=
this
.
userAssignModal
.
selectedUsers
.
filter
(
u
=>
u
.
user_id
!==
user
.
user_id
)
},
saveUserAssignment
()
{
this
.
userAssignModal
.
saving
=
true
const
userIds
=
this
.
userAssignModal
.
selectedUsers
.
map
(
u
=>
u
.
user_id
)
assignUsersToOrg
({
org_id
:
this
.
userAssignModal
.
orgId
,
user_ids
:
userIds
}).
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
fetchList
(
"org"
)
this
.
$Message
.
success
(
'保存成功'
)
this
.
userAssignModal
.
visible
=
false
}
else
{
this
.
$Notice
.
error
({
title
:
'保存失败'
,
desc
:
ret
.
data
&&
ret
.
data
.
errmsg
})
}
}).
finally
(()
=>
{
})
}
}
}
...
...
src/view/key-person/key_dm_inventory/stats.vue
View file @
0bef0175
...
...
@@ -152,84 +152,128 @@ export default {
const
et
=
this
.
workEnd
?
normalizeVisitTimeValue
(
this
.
workEnd
)
:
null
if
(
type
===
'leave'
)
{
this
.
detailModal
.
columns
=
[
{
title
:
'人员'
,
key
:
'user_name'
,
align
:
'center'
},
{
title
:
'开始'
,
key
:
'start_time'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
time
=
params
.
row
.
start_time
if
(
time
)
{
const
date
=
new
Date
(
time
)
const
year
=
date
.
getFullYear
()
const
month
=
String
(
date
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)
const
day
=
String
(
date
.
getDate
()).
padStart
(
2
,
'0'
)
const
hours
=
String
(
date
.
getHours
()).
padStart
(
2
,
'0'
)
const
minutes
=
String
(
date
.
getMinutes
()).
padStart
(
2
,
'0'
)
const
seconds
=
String
(
date
.
getSeconds
()).
padStart
(
2
,
'0'
)
return
h
(
'span'
,
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
:
${
seconds
}
`
)
{
title
:
'人员'
,
key
:
'user_name'
,
align
:
'center'
},
{
title
:
'开始'
,
key
:
'start_time'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
time
=
params
.
row
.
start_time
if
(
time
)
{
const
date
=
new
Date
(
time
)
const
year
=
date
.
getFullYear
()
const
month
=
String
(
date
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)
const
day
=
String
(
date
.
getDate
()).
padStart
(
2
,
'0'
)
const
hours
=
String
(
date
.
getHours
()).
padStart
(
2
,
'0'
)
const
minutes
=
String
(
date
.
getMinutes
()).
padStart
(
2
,
'0'
)
const
seconds
=
String
(
date
.
getSeconds
()).
padStart
(
2
,
'0'
)
return
h
(
'span'
,
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
:
${
seconds
}
`
)
}
return
h
(
'span'
,
'-'
)
}
return
h
(
'span'
,
'-'
)
}},
{
title
:
'结束'
,
key
:
'end_time'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
time
=
params
.
row
.
end_time
if
(
time
)
{
const
date
=
new
Date
(
time
)
const
year
=
date
.
getFullYear
()
const
month
=
String
(
date
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)
const
day
=
String
(
date
.
getDate
()).
padStart
(
2
,
'0'
)
const
hours
=
String
(
date
.
getHours
()).
padStart
(
2
,
'0'
)
const
minutes
=
String
(
date
.
getMinutes
()).
padStart
(
2
,
'0'
)
const
seconds
=
String
(
date
.
getSeconds
()).
padStart
(
2
,
'0'
)
return
h
(
'span'
,
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
:
${
seconds
}
`
)
},
{
title
:
'结束'
,
key
:
'end_time'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
time
=
params
.
row
.
end_time
if
(
time
)
{
const
date
=
new
Date
(
time
)
const
year
=
date
.
getFullYear
()
const
month
=
String
(
date
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)
const
day
=
String
(
date
.
getDate
()).
padStart
(
2
,
'0'
)
const
hours
=
String
(
date
.
getHours
()).
padStart
(
2
,
'0'
)
const
minutes
=
String
(
date
.
getMinutes
()).
padStart
(
2
,
'0'
)
const
seconds
=
String
(
date
.
getSeconds
()).
padStart
(
2
,
'0'
)
return
h
(
'span'
,
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
:
${
seconds
}
`
)
}
return
h
(
'span'
,
'-'
)
}
return
h
(
'span'
,
'-'
)
}},
{
title
:
'时长'
,
key
:
'duration'
,
align
:
'center'
},
{
title
:
'状态'
,
key
:
'status'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
status
=
params
.
row
.
status
let
statusText
=
''
switch
(
status
)
{
case
0
:
statusText
=
'未提交'
;
break
case
1
:
statusText
=
'审核中'
;
break
case
9
:
statusText
=
'审核通过'
;
break
case
-
1
:
statusText
=
'驳回'
;
break
default
:
statusText
=
status
},
{
title
:
'时长'
,
key
:
'duration'
,
align
:
'center'
},
{
title
:
'状态'
,
key
:
'status'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
status
=
params
.
row
.
status
let
statusText
=
''
switch
(
status
)
{
case
0
:
statusText
=
'未提交'
;
break
case
1
:
statusText
=
'审核中'
;
break
case
9
:
statusText
=
'审核通过'
;
break
case
-
1
:
statusText
=
'驳回'
;
break
default
:
statusText
=
status
}
return
h
(
'span'
,
statusText
)
}
return
h
(
'span'
,
statusText
)
}}
}
]
getWorkloadDetails
({
user_id
:
row
.
user_id
,
start
:
st
,
end
:
et
,
type
:
'leave'
}).
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
detailModal
.
rows
=
ret
.
data
.
data
||
[];
this
.
detailModal
.
visible
=
true
}
else
this
.
$Notice
.
error
({
title
:
'查询失败'
,
desc
:
ret
.
data
&&
ret
.
data
.
errmsg
})
})
}
else
{
this
.
detailModal
.
columns
=
[
{
title
:
'申请时间'
,
key
:
'submit_time'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
time
=
params
.
row
.
submit_time
if
(
time
)
{
const
date
=
new
Date
(
time
)
const
year
=
date
.
getFullYear
()
const
month
=
String
(
date
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)
const
day
=
String
(
date
.
getDate
()).
padStart
(
2
,
'0'
)
const
hours
=
String
(
date
.
getHours
()).
padStart
(
2
,
'0'
)
const
minutes
=
String
(
date
.
getMinutes
()).
padStart
(
2
,
'0'
)
const
seconds
=
String
(
date
.
getSeconds
()).
padStart
(
2
,
'0'
)
return
h
(
'span'
,
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
:
${
seconds
}
`
)
{
title
:
'申请时间'
,
key
:
'submit_time'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
time
=
params
.
row
.
submit_time
if
(
time
)
{
const
date
=
new
Date
(
time
)
const
year
=
date
.
getFullYear
()
const
month
=
String
(
date
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
)
const
day
=
String
(
date
.
getDate
()).
padStart
(
2
,
'0'
)
const
hours
=
String
(
date
.
getHours
()).
padStart
(
2
,
'0'
)
const
minutes
=
String
(
date
.
getMinutes
()).
padStart
(
2
,
'0'
)
const
seconds
=
String
(
date
.
getSeconds
()).
padStart
(
2
,
'0'
)
return
h
(
'span'
,
`
${
year
}
-
${
month
}
-
${
day
}
${
hours
}
:
${
minutes
}
:
${
seconds
}
`
)
}
return
h
(
'span'
,
'-'
)
}
return
h
(
'span'
,
'-'
)
}},
{
title
:
'物料'
,
key
:
'material_name'
,
align
:
'center'
},
{
title
:
'申请数量'
,
key
:
'apply_quantity'
,
align
:
'center'
},
{
title
:
'归还数量'
,
key
:
'returned_quantity'
,
align
:
'center'
},
{
title
:
'状态'
,
key
:
'approval_status'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
status
=
params
.
row
.
approval_status
let
statusText
=
''
switch
(
status
)
{
case
0
:
statusText
=
'待提交'
;
break
case
1
:
statusText
=
'审核中'
;
break
case
9
:
statusText
=
'审核通过'
;
break
case
-
1
:
statusText
=
'驳回'
;
break
default
:
statusText
=
status
},
{
title
:
'物料'
,
key
:
'material_name'
,
align
:
'center'
},
{
title
:
'申请数量'
,
key
:
'apply_quantity'
,
align
:
'center'
},
{
title
:
'归还数量'
,
key
:
'returned_quantity'
,
align
:
'center'
},
{
title
:
'状态'
,
key
:
'approval_status'
,
align
:
'center'
,
render
:
(
h
,
params
)
=>
{
const
status
=
params
.
row
.
approval_status
let
statusText
=
''
switch
(
status
)
{
case
0
:
statusText
=
'待提交'
;
break
case
1
:
statusText
=
'审核中'
;
break
case
9
:
statusText
=
'审核通过'
;
break
case
-
1
:
statusText
=
'驳回'
;
break
default
:
statusText
=
status
}
return
h
(
'span'
,
statusText
)
}
return
h
(
'span'
,
statusText
)
}}
}
]
getWorkloadDetails
({
user_id
:
row
.
user_id
,
start
:
st
,
end
:
et
,
type
:
'inventory'
}).
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
this
.
detailModal
.
rows
=
ret
.
data
.
data
||
[];
this
.
detailModal
.
visible
=
true
}
else
this
.
$Notice
.
error
({
title
:
'查询失败'
,
desc
:
ret
.
data
&&
ret
.
data
.
errmsg
})
...
...
src/view/key-person/key_dm_leave/index.vue
View file @
0bef0175
...
...
@@ -4,24 +4,22 @@
<TabPane
label=
"请假申请"
name=
"apply"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
class=
"mt8"
>
<Col
span=
"
12
"
>
<Col
span=
"
20
"
>
<span>
开始:
</span>
<DatePicker
v-model=
"filters.apply.start_time"
type=
"date"
placeholder=
"开始日期"
style=
"min-width:110px;margin-right:20px"
/>
<span>
结束:
</span>
<DatePicker
v-model=
"filters.apply.end_time"
type=
"date"
placeholder=
"结束日期"
style=
"min-width:110px;margin-right:20px"
/>
</Col>
<Col
span=
"8"
>
<span>
状态:
</span>
<Select
v-model=
"filters.apply.status"
style=
"width:
60%
"
>
<Select
v-model=
"filters.apply.status"
style=
"width:
150px
"
>
<Option
v-for=
"opt in statusOptions"
:key=
"opt.id"
:value=
"opt.id"
>
{{
opt
.
name
}}
</Option>
</Select>
</Col>
<Col
span=
"4"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch('apply')"
>
搜索
</Button>
<Button
class=
"mr10"
@
click=
"handleReset('apply')"
>
重置
</Button>
<Button
type=
"
success
"
@
click=
"openApplyModal"
>
申请
</Button>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleReset('apply')"
>
重置
</Button>
<Button
type=
"
primary
"
@
click=
"openApplyModal"
>
申请
</Button>
</Col>
</Row>
</Row>
</div>
<Table
border
:loading=
"loading.apply"
:columns=
"applyColumns"
:data=
"tables.apply"
>
<template
slot=
"action"
slot-scope=
"
{ row }">
...
...
@@ -53,21 +51,19 @@
<TabPane
label=
"审核历史查询"
name=
"history"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
align=
"middle"
>
<Col
span=
"
12
"
>
<Col
span=
"
20
"
>
<span>
开始:
</span>
<DatePicker
v-model=
"filters.history.start_time"
type=
"date"
placeholder=
"开始日期"
style=
"min-width:110px;margin-right:20px"
/>
<span>
结束:
</span>
<DatePicker
v-model=
"filters.history.end_time"
type=
"date"
placeholder=
"结束日期"
style=
"min-width:110px;margin-right:20px"
/>
</Col>
<Col
span=
"8"
>
<span>
状态:
</span>
<Select
v-model=
"filters.history.status"
style=
"width:
60%
"
>
<Select
v-model=
"filters.history.status"
style=
"width:
150px"
class=
"mr10
"
>
<Option
v-for=
"opt in statusOptions"
:key=
"opt.id"
:value=
"opt.id"
>
{{ opt.name }}
</Option>
</Select>
</Col>
<Col
span=
"4"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch('history')"
>
搜索
</Button>
<Button
@
click=
"handleReset('history')"
>
重置
</Button>
<Button
type=
"primary"
@
click=
"handleReset('history')"
>
重置
</Button>
</Col>
</Row>
</div>
...
...
@@ -83,21 +79,19 @@
<TabPane
label=
"请假申请查询"
name=
"query"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
align=
"middle"
>
<Col
span=
"
8
"
>
<Col
span=
"
16
"
>
<span>
开始:
</span>
<DatePicker
v-model=
"filters.query.start_time"
type=
"date"
placeholder=
"开始日期"
style=
"min-width:110px;margin-right:20px"
/>
<span>
结束:
</span>
<DatePicker
v-model=
"filters.query.end_time"
type=
"date"
placeholder=
"结束日期"
style=
"min-width:110px;margin-right:20px"
/>
</Col>
<Col
span=
"8"
>
<span>
状态:
</span>
<Select
v-model=
"filters.query.status"
style=
"width:
60%
"
>
<Select
v-model=
"filters.query.status"
style=
"width:
150px
"
>
<Option
v-for=
"opt in statusOptions"
:key=
"opt.id"
:value=
"opt.id"
>
{{ opt.name }}
</Option>
</Select>
</Col>
<Col
span=
"8"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch('query')"
>
搜索
</Button>
<Button
@
click=
"handleReset('query')"
>
重置
</Button>
<Button
type=
"primary"
@
click=
"handleReset('query')"
>
重置
</Button>
</Col>
</Row>
</div>
...
...
@@ -119,11 +113,11 @@
<span>
结束:
</span>
<DatePicker
v-model=
"statsEnd"
type=
"date"
placeholder=
"结束日期"
style=
"min-width:110px;margin-right:20px"
/>
<span>
部门:
</span>
<Input
v-model=
"statsDept"
placeholder=
"请输入部门名称"
style=
"width:
65%
"
/>
<Input
v-model=
"statsDept"
placeholder=
"请输入部门名称"
style=
"width:
200px
"
/>
</Col>
<Col
span=
"8"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"loadStats"
>
统计
</Button>
<Button
@
click=
"resetStats"
>
重置
</Button>
<Button
type=
"primary"
@
click=
"resetStats"
>
重置
</Button>
</Col>
</Row>
</div>
...
...
@@ -415,6 +409,7 @@ export default {
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
:
getPendingList
,
history
:
getApprovalHistory
,
query
:
getLeaveList
}
...
...
src/view/key-person/key_dm_user/index.vue
View file @
0bef0175
...
...
@@ -10,11 +10,11 @@
</Col>
-->
<Col
:span=
"12"
class=
"text-left"
>
<span>
姓名:
</span>
<Input
v-model=
"filters.name"
placeholder=
"请输入姓名"
style=
"width:
40%
"
/>
<Input
v-model=
"filters.name"
placeholder=
"请输入姓名"
style=
"width:
200px
"
/>
</Col>
<Col
:span=
"12"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch"
>
搜索
</Button>
<Button
@
click=
"handleReset"
class=
"mr10"
>
重置
</Button>
<Button
type=
"primary"
@
click=
"handleReset"
class=
"mr10"
>
重置
</Button>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSync"
>
同步
</Button>
</Col>
</Row>
...
...
@@ -56,10 +56,10 @@
<!--
角色已移除
-->
<!--
<
FormItem
label
=
"归属部门"
>
<
SelectDisplay
v
-
model
=
"editModal.form.office_id"
placeholder
=
"请输入机构"
@
open
=
"openOfficeSelect(editModal.form)"
/>
<
/FormItem
>
<
FormItem
label
=
"直属领导"
>
<
SelectDisplay
v
-
model
=
"editModal.form.leader"
placeholder
=
"只能选择本级或父机构人员"
@
open
=
"openSelectLeader(editModal.form)"
/>
<
/FormItem> --
>
<
FormItem
label
=
"直属领导"
>
<
Input
v
-
model
=
"editModal.form.leader_name"
readonly
placeholder
=
"点击选择直属领导"
@
click
.
native
=
"selectLeader"
style
=
"cursor: pointer"
/>
<
/FormItem
>
<
FormItem
label
=
"是否离职"
>
<
Select
v
-
model
=
"editModal.form.is_leave"
style
=
"width: 160px"
>
<
Option
:
value
=
"0"
>
未离职
<
/Option
>
...
...
@@ -72,16 +72,25 @@
<
Button
type
=
"primary"
:
loading
=
"editModal.saving"
@
click
=
"saveEdit"
>
保存
<
/Button
>
<
/div
>
<
/Modal
>
<!--
人员选择器
-->
<
UserSelector
v
-
model
=
"userSelectorVisible"
permission
=
""
@
on
-
ok
=
"handleLeaderSelected"
@
cancel
=
"userSelectorVisible = false"
/>
<!--
领导与归属部门选择已移除
-->
<
/div
>
<
/template
>
<
script
>
import
{
getDmUserList
,
syncDmUsersByOffice
,
saveDmUser
}
from
'@/api/key-dm-user'
import
UserSelector
from
'./userSelector.vue'
export
default
{
name
:
'key-dm-user-index'
,
components
:
{
}
,
components
:
{
UserSelector
}
,
data
()
{
return
{
officeCode
:
''
,
...
...
@@ -103,7 +112,8 @@ export default {
visible
:
false
,
saving
:
false
,
form
:
{
}
}
}
,
userSelectorVisible
:
false
// leader / office state 已移除
}
}
,
...
...
@@ -188,6 +198,14 @@ export default {
this
.
editModal
.
form
=
copy
this
.
editModal
.
visible
=
true
}
,
selectLeader
()
{
this
.
userSelectorVisible
=
true
}
,
handleLeaderSelected
(
user
)
{
this
.
editModal
.
form
.
leader
=
user
.
id
this
.
editModal
.
form
.
leader_name
=
user
.
name
this
.
userSelectorVisible
=
false
}
,
/* leader / office 相关方法已移除 */
saveEdit
()
{
this
.
$refs
.
editForm
.
validate
(
valid
=>
{
...
...
src/view/key-person/key_dm_user/userMultiSelector.vue
View file @
0bef0175
...
...
@@ -4,7 +4,7 @@
<Row
type=
"flex"
:gutter=
"16"
align=
"middle"
>
<Col
:span=
"12"
>
<span>
姓名:
</span>
<Input
v-model=
"filters.name"
placeholder=
"请输入姓名"
@
on-enter=
"handleSearch
"
/>
<Input
v-model=
"filters.name"
placeholder=
"请输入姓名"
style=
"width: 200px
"
/>
</Col>
<Col
:span=
"12"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch"
>
搜索
</Button>
...
...
@@ -37,7 +37,9 @@ export default {
name
:
'user-multi-selector'
,
props
:
{
// v-model: value 控制显示
value
:
{
type
:
Boolean
,
default
:
false
}
value
:
{
type
:
Boolean
,
default
:
false
},
// 范围参数1父,本级,下级2本级
round
:
{
type
:
String
,
default
:
'1'
}
},
data
()
{
return
{
...
...
@@ -50,12 +52,12 @@ export default {
confirming
:
false
,
columns
:
[
{
type
:
'selection'
,
width
:
60
,
align
:
'center'
},
{
title
:
'归属部门'
,
key
:
'office_name'
,
align
:
'center'
,
minWidth
:
150
},
{
title
:
'姓名'
,
key
:
'name'
,
align
:
'center'
,
minWidth
:
100
},
{
title
:
'工号'
,
key
:
'gh'
,
align
:
'center'
,
minWidth
:
120
},
{
title
:
'邮箱'
,
key
:
'email'
,
align
:
'center'
,
minWidth
:
150
},
//
{ title: '邮箱', key: 'email', align: 'center', minWidth: 150 },
{
title
:
'电话'
,
key
:
'phone'
,
align
:
'center'
,
minWidth
:
120
},
{
title
:
'手机'
,
key
:
'mobile'
,
align
:
'center'
,
minWidth
:
120
},
{
title
:
'归属部门'
,
key
:
'office_name'
,
align
:
'center'
,
minWidth
:
150
}
{
title
:
'手机'
,
key
:
'mobile'
,
align
:
'center'
,
minWidth
:
120
}
]
}
},
...
...
@@ -78,11 +80,7 @@ export default {
methods
:
{
fetchList
()
{
this
.
loading
=
true
const
payload
=
{
pageNo
:
this
.
pager
.
pageNo
,
pageSize
:
this
.
pager
.
pageSize
,
params
:
this
.
filters
}
const
payload
=
Object
.
assign
({},
{
pageNo
:
this
.
pager
.
pageNo
,
pageSize
:
this
.
pager
.
pageSize
,
round
:
this
.
round
},
this
.
filters
)
getUserMultiSelectorList
(
payload
).
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
const
data
=
ret
.
data
.
data
||
{}
...
...
src/view/key-person/key_dm_user/userSelector.vue
0 → 100644
View file @
0bef0175
<
template
>
<Modal
v-model=
"visible"
title=
"选择人员"
width=
"900"
:mask-closable=
"false"
>
<div
class=
"search-div"
>
<Row
type=
"flex"
:gutter=
"16"
align=
"middle"
>
<Col
:span=
"12"
>
<span>
姓名:
</span>
<Input
v-model=
"filters.name"
placeholder=
"请输入姓名"
style=
"width: 200px"
/>
</Col>
<Col
:span=
"12"
class=
"text-right"
>
<Button
type=
"primary"
class=
"mr10"
@
click=
"handleSearch"
>
搜索
</Button>
<Button
@
click=
"handleReset"
>
重置
</Button>
</Col>
</Row>
</div>
<Table
:data=
"rows"
:loading=
"loading"
:columns=
"columns"
border
highlight-row
@
on-current-change=
"onCurrentRowChange"
@
on-row-dblclick=
"onRowDblclick"
/>
<Page
class=
"page_style"
:total=
"pager.totalRecord"
:current=
"pager.pageNo"
:page-size=
"pager.pageSize"
show-total
show-sizer
@
on-change=
"pageChange"
@
on-page-size-change=
"sizeChange"
/>
<div
slot=
"footer"
>
<Button
@
click=
"handleCancel"
>
取消
</Button>
<Button
type=
"primary"
:loading=
"confirming"
@
click=
"handleConfirm"
:disabled=
"!selectedRow"
>
确定
</Button>
</div>
</Modal>
</
template
>
<
script
>
import
{
getUserSelectorList
}
from
'@/api/key-dm-user'
export
default
{
name
:
'user-selector'
,
props
:
{
// v-model: value 控制显示
value
:
{
type
:
Boolean
,
default
:
false
},
// 权限参数
permission
:
{
type
:
String
,
default
:
''
}
},
data
()
{
return
{
visibleInternal
:
false
,
filters
:
{
name
:
''
},
rows
:
[],
loading
:
false
,
pager
:
{
pageNo
:
1
,
pageSize
:
10
,
totalRecord
:
0
},
selectedRow
:
null
,
confirming
:
false
,
columns
:
[
{
title
:
'姓名'
,
key
:
'name'
,
align
:
'center'
,
minWidth
:
100
},
{
title
:
'工号'
,
key
:
'gh'
,
align
:
'center'
,
minWidth
:
120
},
{
title
:
'邮箱'
,
key
:
'email'
,
align
:
'center'
,
minWidth
:
150
},
{
title
:
'电话'
,
key
:
'phone'
,
align
:
'center'
,
minWidth
:
120
},
{
title
:
'手机'
,
key
:
'mobile'
,
align
:
'center'
,
minWidth
:
120
},
{
title
:
'归属部门'
,
key
:
'office_name'
,
align
:
'center'
,
minWidth
:
150
},
{
title
:
'人员分类'
,
key
:
'category_names'
,
align
:
'center'
,
minWidth
:
200
}
]
}
},
computed
:
{
visible
:
{
get
()
{
return
this
.
value
},
set
(
v
)
{
this
.
$emit
(
'input'
,
v
)
}
}
},
watch
:
{
visible
(
v
)
{
if
(
v
)
{
this
.
pager
.
pageNo
=
1
this
.
selectedRow
=
null
this
.
filters
.
name
=
''
this
.
fetchList
()
}
}
},
methods
:
{
fetchList
()
{
this
.
loading
=
true
const
payload
=
Object
.
assign
({},
{
pageNo
:
this
.
pager
.
pageNo
,
pageSize
:
this
.
pager
.
pageSize
,
office_code
:
this
.
officeCode
,
permission
:
this
.
permission
},
this
.
filters
)
getUserSelectorList
(
payload
).
then
(
ret
=>
{
if
(
ret
.
data
&&
ret
.
data
.
errcode
===
0
)
{
const
data
=
ret
.
data
.
data
||
{}
this
.
rows
=
data
.
results
||
[]
this
.
pager
.
totalRecord
=
data
.
totalRecord
||
0
}
else
{
this
.
$Notice
.
error
({
title
:
'查询失败'
,
desc
:
ret
.
data
&&
ret
.
data
.
errmsg
})
}
}).
finally
(()
=>
{
this
.
loading
=
false
})
},
handleSearch
()
{
this
.
pager
.
pageNo
=
1
this
.
fetchList
()
},
handleReset
()
{
this
.
filters
=
{
name
:
''
}
this
.
pager
.
pageNo
=
1
this
.
fetchList
()
},
pageChange
(
pageNo
)
{
this
.
pager
.
pageNo
=
pageNo
this
.
fetchList
()
},
sizeChange
(
size
)
{
this
.
pager
.
pageSize
=
size
this
.
pager
.
pageNo
=
1
this
.
fetchList
()
},
onCurrentRowChange
(
currentRow
,
oldCurrentRow
)
{
this
.
selectedRow
=
currentRow
},
onRowDblclick
(
row
,
index
)
{
this
.
selectedRow
=
row
this
.
handleConfirm
()
},
handleCancel
()
{
this
.
$emit
(
'cancel'
)
this
.
$emit
(
'input'
,
false
)
},
handleConfirm
()
{
if
(
!
this
.
selectedRow
)
{
this
.
$Message
.
warning
(
'请先选择人员'
)
return
}
this
.
confirming
=
true
// emit selected user to parent
this
.
$emit
(
'on-ok'
,
this
.
selectedRow
)
this
.
$emit
(
'input'
,
false
)
this
.
confirming
=
false
}
}
}
</
script
>
<
style
scoped
>
.search-div
{
border
:
1px
solid
#dce1e7
;
padding
:
12px
;
margin-bottom
:
12px
;
background-color
:
#f8fbff
;
}
.mr10
{
margin-right
:
10px
;
}
.page_style
{
margin-top
:
12px
;
text-align
:
right
;
}
.text-right
{
text-align
:
right
;
}
</
style
>
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论