Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
H
hr-admin-view
Project
Project
Details
Activity
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
anjia-hr
hr-admin-view
Commits
e0cf2e3f
Commit
e0cf2e3f
authored
Nov 19, 2025
by
刘斌
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 增加电话本管理
parent
fc891eb2
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
623 additions
and
51 deletions
+623
-51
employeeModel.d.ts
apps/web-antd/src/api/hr/employeeModel.d.ts
+16
-7
phoneBook.ts
apps/web-antd/src/api/hr/phoneBook.ts
+98
-0
hr.ts
apps/web-antd/src/router/routes/modules/hr.ts
+12
-0
apply-entry-model.vue
.../web-antd/src/views/hr/employeeInfo/apply-entry-model.vue
+12
-0
apply-resign-model.vue
...web-antd/src/views/hr/employeeInfo/apply-resign-model.vue
+11
-0
apply-transfer-model.vue
...b-antd/src/views/hr/employeeInfo/apply-transfer-model.vue
+44
-44
data.ts
apps/web-antd/src/views/hr/phoneBook/data.ts
+138
-0
form.vue
apps/web-antd/src/views/hr/phoneBook/form.vue
+161
-0
list.vue
apps/web-antd/src/views/hr/phoneBook/list.vue
+131
-0
No files found.
apps/web-antd/src/api/hr/employeeModel.d.ts
View file @
e0cf2e3f
...
...
@@ -374,26 +374,35 @@ export namespace EmployeeInfoApi {
transferApplyStatusName
?:
number
;
}
export
interface
EmployeeApplyBo
{
export
interface
EmployeeApplyB
aseB
o
{
/**
* 序号
*/
id
?:
number
;
/**
*
入职时间
*
员工姓名
*/
entryDate
?:
Date
;
name
?:
string
;
/**
* 备注
*/
remark
?:
string
;
}
export
interface
EmployeeTransferApplyBo
extends
EmployeeApplyBo
{
export
interface
EmployeeApplyBo
extends
EmployeeApplyBaseBo
{
/**
* 入职时间
*/
entryDate
?:
Date
;
}
export
interface
EmployeeTransferApplyBo
extends
EmployeeApplyBaseBo
{
/**
* 板块
*/
plate
:
string
;
plate
?
:
string
;
/**
* 一级部门
*/
...
...
@@ -412,11 +421,11 @@ export namespace EmployeeInfoApi {
deptId
?:
number
;
}
export
interface
EmployeeResignApplyBo
extends
EmployeeApplyBo
{
export
interface
EmployeeResignApplyBo
extends
EmployeeApplyB
aseB
o
{
/**
* 离职类型
*/
resignationType
:
string
;
resignationType
?
:
string
;
/**
* 离职时间
*/
...
...
apps/web-antd/src/api/hr/phoneBook.ts
0 → 100644
View file @
e0cf2e3f
import
type
{
BaseModel
,
PageQuery
}
from
'#/api/baseModel'
;
import
{
commonExport
}
from
'#/api/helper'
;
import
{
requestClient
}
from
'#/api/request'
;
export
namespace
PhoneBookApi
{
export
interface
PhoneBook
extends
BaseModel
{
/**
* 板块
*/
plate
?:
string
;
/**
* 一级部门
*/
firstLevelDepartment
?:
string
;
/**
* 二级部门
*/
secondLevelDepartment
?:
string
;
/**
* 三级部门
*/
thirdLevelDepartment
?:
string
;
/**
* 部门ID
*/
deptId
?:
number
;
/**
* 主岗位
*/
position
?:
string
;
/**
* 姓名
*/
name
?:
string
;
/**
* 手机号码
*/
phoneNumber
?:
string
;
/**
* 办公电话
*/
officePhone
?:
string
;
/**
* 短线
*/
shortLine
?:
string
;
/**
* 备注
*/
remarks
?:
string
;
}
}
/**
* 查询电话本管理列表
* @param params
* @returns {*} page
*/
export
function
apiPage
(
params
:
PageQuery
)
{
return
requestClient
.
get
(
'/employee/phoneBook/page'
,
{
params
});
}
// /**
// * 查询电话本管理详细
// * @param id
// */
// export function apiDetail(id: number) {
// return requestClient.get(`/hr/phoneBook/${id}`);
// }
// /**
// * 新增电话本管理
// * @param data
// */
// export function apiAdd(data: PhoneBookApi.PhoneBook) {
// return requestClient.post('/hr/phoneBook', data);
// }
// /**
// * 修改电话本管理
// * @param data
// */
// export function apiUpdate(data: PhoneBookApi.PhoneBook) {
// return requestClient.put('/hr/phoneBook', data);
// }
// /**
// * 删除电话本管理
// * @param id
// */
// export function apiDelete(id: Array<number> | number) {
// return requestClient.delete(`/hr/phoneBook/${id}`);
// }
/**
* 导出电话本管理
* @param params
*/
export
function
apiExport
(
params
:
PageQuery
)
{
return
commonExport
(
'/employee/phoneBook/export'
,
params
);
}
apps/web-antd/src/router/routes/modules/hr.ts
View file @
e0cf2e3f
...
...
@@ -36,6 +36,18 @@ const routes: RouteRecordRaw[] = [
componentPath
:
'#/views/hr/resignEmployee/list.vue'
,
},
},
{
path
:
'/hr/phoneBook/list'
,
name
:
'PhoneBookList'
,
component
:
()
=>
import
(
'#/views/hr/phoneBook/list.vue'
),
meta
:
{
title
:
'电话本管理'
,
icon
:
'solar:monitor-smartphone-outline'
,
keepAlive
:
true
,
permission
:
[
'dashboard'
],
componentPath
:
'#/views/hr/phoneBook/list.vue'
,
},
},
{
name
:
'EmployeeFlowList'
,
path
:
'/hr/employee/flow'
,
...
...
apps/web-antd/src/views/hr/employeeInfo/apply-entry-model.vue
View file @
e0cf2e3f
...
...
@@ -5,6 +5,7 @@ import type { EmployeeInfoApi } from '#/api/hr/employeeModel';
import
{
ref
}
from
'vue'
;
import
{
useVbenModal
}
from
'@vben/common-ui'
;
import
{
getVxePopupContainer
}
from
'@vben/utils'
;
import
{
useVbenForm
}
from
'#/adapter/form'
;
import
{
applyEntry
}
from
'#/api/hr/employeeInfo'
;
...
...
@@ -31,6 +32,17 @@ const formSchema: VbenFormSchema[] = [
label
:
'姓名'
,
disabled
:
true
,
},
{
component
:
'DatePicker'
,
componentProps
:
{
format
:
'YYYY-MM-DD'
,
valueFormat
:
'YYYY-MM-DD'
,
getVxePopupContainer
,
},
fieldName
:
'entryDate'
,
label
:
'入职时间'
,
rules
:
'required'
,
},
// {
// component: 'Input',
// fieldName: 'dictType',
...
...
apps/web-antd/src/views/hr/employeeInfo/apply-resign-model.vue
View file @
e0cf2e3f
...
...
@@ -49,6 +49,17 @@ const formSchema: VbenFormSchema[] = [
label
:
'离职原因'
,
// rules: 'required',
},
{
component
:
'DatePicker'
,
componentProps
:
{
format
:
'YYYY-MM-DD'
,
valueFormat
:
'YYYY-MM-DD'
,
getVxePopupContainer
,
},
fieldName
:
'finalPayDate'
,
label
:
'最后结薪日'
,
// rules: 'required',
},
// {
// component: 'Input',
// fieldName: 'description',
...
...
apps/web-antd/src/views/hr/employeeInfo/apply-transfer-model.vue
View file @
e0cf2e3f
...
...
@@ -5,13 +5,10 @@ import type { EmployeeInfoApi } from '#/api/hr/employeeModel';
import
{
ref
}
from
'vue'
;
import
{
useVbenModal
}
from
'@vben/common-ui'
;
import
{
getVxePopupContainer
}
from
'@vben/utils'
;
import
{
addFullName
,
getVxePopupContainer
}
from
'@vben/utils'
;
import
{
useVbenForm
}
from
'#/adapter/form'
;
import
{
selectDeptNamesByLevel
,
selectDeptNamesByParent
,
}
from
'#/api/hr/employeeDept'
;
import
{
treeList
}
from
'#/api/auth/dept'
;
import
{
applyTransfer
}
from
'#/api/hr/employeeInfo'
;
import
{
defaultFormValueGetter
,
useBeforeCloseDiff
}
from
'#/utils/popup'
;
...
...
@@ -37,38 +34,56 @@ const formSchema: VbenFormSchema[] = [
disabled
:
true
,
},
{
component
:
'ApiSelect'
,
component
:
'Api
Tree
Select'
,
componentProps
:
(
formModel
)
=>
({
api
:
async
()
=>
{
const
data
:
string
[]
=
await
selectDeptNamesByLevel
(
1
);
return
data
.
map
((
item
)
=>
({
label
:
item
,
value
:
item
,
}));
const
deptArray
=
await
treeList
();
// const deptTree = genDeptTree(deptArray);
addFullName
(
deptArray
,
'label'
,
' / '
);
return
deptArray
;
},
async
onSelect
(
name
:
string
)
{
/** 根据部门ID加载岗位 */
await
setupDeptLevel2Options
(
name
);
/** 变化后需要重新选择岗位 */
formModel
.
secondLevelDepartment
=
[];
async
onSelect
(
deptId
:
number
|
string
,
node
:
Record
<
string
,
any
>
)
{
/** 根据部门Node获取部门等级数组 */
const
result
=
node
.
fullName
.
split
(
'/'
)
.
map
((
item
:
string
)
=>
item
.
trim
())
.
filter
(
Boolean
);
/** 变化后需要重新设置部门信息 */
formModel
.
plate
=
result
[
0
];
formModel
.
firstLevelDepartment
=
result
[
1
];
formModel
.
secondLevelDepartment
=
result
[
2
];
formModel
.
thirdLevelDepartment
=
result
[
3
];
},
getVxePopupContainer
,
class
:
'w-full'
,
treeLine
:
{
showLeafIcon
:
false
},
treeIcon
:
false
,
// 筛选的字段
treeNodeFilterProp
:
'label'
,
// 选中后显示在输入框的值
treeNodeLabelProp
:
'fullName'
,
// fieldNames: { label: 'label', value: 'id' },
labelField
:
'label'
,
showSearch
:
true
,
treeDefaultExpandAll
:
true
,
valueField
:
'id'
,
childrenField
:
'children'
,
}),
fieldName
:
'firstLevelDepartment'
,
label
:
'一级部门'
,
rules
:
'required'
,
},
{
component
:
'Select'
,
componentProps
:
{
getVxePopupContainer
,
placeholder
:
'请先选择一级部门'
,
},
fieldName
:
'secondLevelDepartment'
,
label
:
'二级部门'
,
rules
:
'required'
,
fieldName
:
'deptId'
,
label
:
'新的部门'
,
rules
:
'selectRequired'
,
},
// {
// component: 'Select',
// componentProps: {
// getVxePopupContainer,
// placeholder: '请先选择一级部门',
// },
// fieldName: 'secondLevelDepartment',
// label: '二级部门',
// rules: 'required',
// },
// {
// component: 'Input',
// fieldName: 'description',
// label: '描述',
...
...
@@ -141,21 +156,6 @@ async function onSubmit() {
}
}
async
function
setupDeptLevel2Options
(
name
:
string
)
{
const
deptNameList
:
string
[]
=
await
selectDeptNamesByParent
(
name
);
const
options
=
deptNameList
.
map
((
item
)
=>
({
label
:
item
,
value
:
item
,
}));
const
placeholder
=
options
.
length
>
0
?
'请选择'
:
'该部门下暂无岗位'
;
formApi
.
updateSchema
([
{
componentProps
:
{
options
,
placeholder
},
fieldName
:
'secondLevelDepartment'
,
},
]);
}
async
function
handleClosed
()
{
await
formApi
.
resetForm
();
resetInitialized
();
...
...
apps/web-antd/src/views/hr/phoneBook/data.ts
0 → 100644
View file @
e0cf2e3f
import
type
{
VbenFormSchema
}
from
'#/adapter/form'
;
import
type
{
VxeTableGridOptions
}
from
'#/adapter/vxe-table'
;
import
type
{
PhoneBookApi
}
from
'#/api/hr/phoneBook'
;
export
const
querySchema
:
VbenFormSchema
[]
=
[
{
component
:
'Input'
,
fieldName
:
'plate'
,
label
:
'板块'
,
},
{
component
:
'Input'
,
fieldName
:
'firstLevelDepartment'
,
label
:
'一级部门'
,
},
{
component
:
'Input'
,
fieldName
:
'secondLevelDepartment'
,
label
:
'二级部门'
,
},
{
component
:
'Input'
,
fieldName
:
'thirdLevelDepartment'
,
label
:
'三级部门'
,
},
// {
// component: 'Input',
// fieldName: 'deptId',
// label: '部门ID',
// },
{
component
:
'Input'
,
fieldName
:
'position'
,
label
:
'主岗位'
,
},
{
component
:
'Input'
,
fieldName
:
'name'
,
label
:
'姓名'
,
},
{
component
:
'Input'
,
fieldName
:
'phoneNumber'
,
label
:
'手机号码'
,
},
{
component
:
'Input'
,
fieldName
:
'officePhone'
,
label
:
'办公电话'
,
},
{
component
:
'Input'
,
fieldName
:
'shortLine'
,
label
:
'短线'
,
},
// {
// component: 'Input',
// fieldName: 'remarks',
// label: '备注',
// },
];
export
function
useColumns
():
VxeTableGridOptions
<
PhoneBookApi
.
PhoneBook
>
[
'columns'
]
{
return
[
{
title
:
'板块'
,
field
:
'plate'
,
},
{
title
:
'一级部门'
,
field
:
'firstLevelDepartment'
,
},
{
title
:
'二级部门'
,
field
:
'secondLevelDepartment'
,
},
{
title
:
'三级部门'
,
field
:
'thirdLevelDepartment'
,
},
// {
// title: '部门ID',
// field: 'deptId',
// },
{
title
:
'主岗位'
,
field
:
'position'
,
},
{
title
:
'姓名'
,
field
:
'name'
,
},
{
title
:
'手机号码'
,
field
:
'phoneNumber'
,
},
{
title
:
'办公电话'
,
field
:
'officePhone'
,
},
{
title
:
'短线'
,
field
:
'shortLine'
,
},
{
title
:
'备注'
,
field
:
'remarks'
,
},
// {
// align: 'right',
// cellRender: {
// attrs: {
// nameField: 'name',
// nameTitle: '电话本管理',
// onClick: onActionClick,
// },
// name: 'CellOperation',
// options: [
// {
// code: 'edit',
// accessCode: ['hr:phoneBook:edit'],
// }, // 默认的编辑按钮
// {
// code: 'delete',
// accessCode: ['hr:phoneBook:remove'],
// }, // 默认的删除按钮
// ],
// },
// field: 'action',
// fixed: 'right',
// headerAlign: 'center',
// resizable: false,
// showOverflow: false,
// title: '操作',
// width: 'auto',
// },
];
}
apps/web-antd/src/views/hr/phoneBook/form.vue
0 → 100644
View file @
e0cf2e3f
<
script
lang=
"ts"
setup
>
import
type
{
VbenFormSchema
}
from
'#/adapter/form'
;
import
type
{
PhoneBookApi
}
from
'#/api/hr/phoneBook'
;
import
{
computed
,
ref
}
from
'vue'
;
import
{
useVbenDrawer
}
from
'@vben/common-ui'
;
import
{
DictEnum
}
from
'@vben/constants'
;
import
{
getVxePopupContainer
}
from
'@vben/utils'
;
import
{
useVbenForm
,
z
}
from
'#/adapter/form'
;
import
{
apiAdd
,
apiUpdate
}
from
'#/api/hr/phoneBook'
;
import
{
getDictOptions
}
from
'#/utils/dict'
;
import
{
defaultFormValueGetter
,
useBeforeCloseDiff
}
from
'#/utils/popup'
;
const
emit
=
defineEmits
<
{
success
:
[];
}
>
();
const
formData
=
ref
<
PhoneBookApi
.
PhoneBook
>
();
const
formSchema
:
VbenFormSchema
[]
=
[
{
component
:
'Input'
,
fieldName
:
'plate'
,
label
:
'板块'
,
rules
:
'required'
,
},
{
component
:
'Input'
,
fieldName
:
'firstLevelDepartment'
,
label
:
'一级部门'
,
rules
:
'required'
,
},
{
component
:
'Input'
,
fieldName
:
'secondLevelDepartment'
,
label
:
'二级部门'
,
rules
:
'required'
,
},
{
component
:
'Input'
,
fieldName
:
'thirdLevelDepartment'
,
label
:
'三级部门'
,
rules
:
'required'
,
},
{
component
:
'Input'
,
fieldName
:
'deptId'
,
label
:
'部门ID'
,
rules
:
'required'
,
},
{
component
:
'Input'
,
fieldName
:
'position'
,
label
:
'主岗位'
,
rules
:
'required'
,
},
{
component
:
'Input'
,
fieldName
:
'name'
,
label
:
'姓名'
,
rules
:
'required'
,
},
{
component
:
'Input'
,
fieldName
:
'phoneNumber'
,
label
:
'手机号码'
,
rules
:
'required'
,
},
{
component
:
'Input'
,
fieldName
:
'officePhone'
,
label
:
'办公电话'
,
rules
:
'required'
,
},
{
component
:
'Input'
,
fieldName
:
'shortLine'
,
label
:
'短线'
,
rules
:
'required'
,
},
{
component
:
'Textarea'
,
fieldName
:
'remarks'
,
label
:
'备注'
,
rules
:
'required'
,
},
];
const
[
BasicForm
,
formApi
]
=
useVbenForm
({
commonConfig
:
{
componentProps
:
{
class
:
'w-full'
,
},
formItemClass
:
'col-span-2'
,
labelWidth
:
90
,
},
schema
:
formSchema
,
showDefaultActions
:
false
,
wrapperClass
:
'grid-cols-2'
,
});
const
{
onBeforeClose
,
markInitialized
,
resetInitialized
}
=
useBeforeCloseDiff
(
{
initializedGetter
:
defaultFormValueGetter
(
formApi
),
currentGetter
:
defaultFormValueGetter
(
formApi
),
},
);
const
[
Drawer
,
drawerApi
]
=
useVbenDrawer
({
onBeforeClose
,
onClosed
:
handleClosed
,
onConfirm
:
onSubmit
,
async
onOpenChange
(
isOpen
)
{
if
(
!
isOpen
)
{
return
null
;
}
const
data
=
drawerApi
.
getData
<
PhoneBookApi
.
PhoneBook
>
();
if
(
data
)
{
formData
.
value
=
data
;
await
formApi
.
setValues
(
formData
.
value
);
}
else
{
formApi
.
resetForm
();
}
await
markInitialized
();
},
});
async
function
onSubmit
()
{
const
{
valid
}
=
await
formApi
.
validate
();
if
(
valid
)
{
drawerApi
.
lock
();
const
data
=
await
formApi
.
getValues
<
PhoneBookApi
.
PhoneBook
>
();
try
{
await
(
formData
.
value
?.
id
?
apiUpdate
({
id
:
formData
.
value
.
id
,
...
data
})
:
apiAdd
(
data
));
resetInitialized
();
emit
(
'success'
);
drawerApi
.
close
();
}
finally
{
drawerApi
.
unlock
();
}
}
}
async
function
handleClosed
()
{
await
formApi
.
resetForm
();
resetInitialized
();
}
const
getDrawerTitle
=
computed
(()
=>
formData
.
value
?.
id
?
'修改电话本管理'
:
'新增电话本管理'
,
);
</
script
>
<
template
>
<Drawer
class=
"w-full max-w-[800px]"
:title=
"getDrawerTitle"
>
<BasicForm
class=
"mx-4"
/>
</Drawer>
</
template
>
apps/web-antd/src/views/hr/phoneBook/list.vue
0 → 100644
View file @
e0cf2e3f
<
script
lang=
"ts"
setup
>
import
type
{
VbenFormProps
}
from
'@vben/common-ui'
;
import
type
{
VxeTableGridOptions
}
from
'#/adapter/vxe-table'
;
import
{
Page
}
from
'@vben/common-ui'
;
import
{
Button
,
Space
}
from
'ant-design-vue'
;
import
{
useVbenVxeGrid
}
from
'#/adapter/vxe-table'
;
import
{
apiExport
,
apiPage
}
from
'#/api/hr/phoneBook'
;
import
{
commonDownloadExcel
}
from
'#/utils/file/download'
;
import
{
querySchema
,
useColumns
}
from
'./data'
;
// import Form from './form.vue';
const
formOptions
:
VbenFormProps
=
{
commonConfig
:
{
labelWidth
:
80
,
componentProps
:
{
allowClear
:
true
,
},
},
schema
:
querySchema
,
wrapperClass
:
'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'
,
};
// const [FormDrawer, formDrawerApi] = useVbenDrawer({
// connectedComponent: Form,
// });
const
[
Grid
,
gridApi
]
=
useVbenVxeGrid
({
formOptions
,
gridOptions
:
{
columns
:
useColumns
(),
height
:
'auto'
,
keepSource
:
true
,
pagerConfig
:
{
enabled
:
true
,
},
proxyConfig
:
{
ajax
:
{
query
:
async
({
page
},
formValues
=
{})
=>
{
return
await
apiPage
({
pageNo
:
page
.
currentPage
,
pageSize
:
page
.
pageSize
,
...
formValues
,
});
},
},
},
rowConfig
:
{
keyField
:
'id'
,
// 高亮当前行
isCurrent
:
true
,
},
}
as
VxeTableGridOptions
,
});
// function onActionClick({ code, row }: OnActionClickParams
<
PhoneBookApi
.
PhoneBook
>
)
{
// switch (code) {
// case 'delete': {
// onDelete(row);
// break;
// }
// case 'edit': {
// onEdit(row);
// break;
// }
// default: {
// break;
// }
// }
// }
// function onRefresh() {
// gridApi.query();
// }
// function onEdit(row: PhoneBookApi.PhoneBook) {
// formDrawerApi.setData(row).open();
// }
// function onCreate() {
// formDrawerApi.setData({}).open();
// }
// function onDelete(row: PhoneBookApi.PhoneBook) {
// const hideLoading = message.loading({
// content: `正在删除${row.name}...`,
// duration: 0,
// key: 'action_process_msg',
// });
// apiDelete(row.id || 0)
// .then(() => {
// message.success({
// content: `${row.name}删除成功`,
// key: 'action_process_msg',
// });
// onRefresh();
// })
// .catch(() => {
// hideLoading();
// });
// }
function
handleDownloadExcel
()
{
commonDownloadExcel
(
apiExport
,
'电话本'
,
gridApi
.
formApi
.
form
.
values
);
}
</
script
>
<
template
>
<Page
auto-content-height
>
<!--
<FormDrawer
@
success=
"onRefresh"
/>
-->
<Grid
table-title=
"电话本"
>
<template
#
toolbar-tools
>
<Space>
<Button
v-access:code=
"['employee:phoneBook:export']"
@
click=
"handleDownloadExcel"
>
导出
</Button>
<!--
<Button
v-access:code=
"['hr:phoneBook:add']"
type=
"primary"
@
click=
"onCreate"
>
<Plus
class=
"size-5"
/>
新增
</Button>
-->
</Space>
</
template
>
</Grid>
</Page>
</template>
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