hrm前端一版
This commit is contained in:
190
klp-ui/src/views/hrm/org/index.vue
Normal file
190
klp-ui/src/views/hrm/org/index.vue
Normal file
@@ -0,0 +1,190 @@
|
||||
<template>
|
||||
<div class="hrm-page">
|
||||
<section class="panel-grid">
|
||||
<el-card class="metal-panel" shadow="hover">
|
||||
<div slot="header" class="panel-header">
|
||||
<span>组织树</span>
|
||||
<el-button size="mini" icon="el-icon-refresh" @click="loadOrg">刷新</el-button>
|
||||
</div>
|
||||
<el-tree
|
||||
v-loading="orgLoading"
|
||||
:data="orgTree"
|
||||
node-key="orgId"
|
||||
:props="{ label: 'orgName', children: 'children' }"
|
||||
accordion
|
||||
highlight-current
|
||||
@node-click="handleOrgClick"
|
||||
>
|
||||
<span slot-scope="{ data }" class="custom-tree-node">
|
||||
<span>{{ data.orgName }}</span>
|
||||
<el-tag size="mini" effect="plain" type="info" class="tree-tag">{{ data.orgType || '组织' }}</el-tag>
|
||||
</span>
|
||||
</el-tree>
|
||||
</el-card>
|
||||
|
||||
<el-card class="metal-panel" shadow="hover">
|
||||
<div slot="header" class="panel-header">
|
||||
<span>员工档案</span>
|
||||
<div class="actions-inline">
|
||||
<el-input
|
||||
v-model="empQuery.empName"
|
||||
placeholder="姓名/工号"
|
||||
size="mini"
|
||||
clearable
|
||||
@keyup.enter.native="loadEmployee"
|
||||
style="width: 180px"
|
||||
/>
|
||||
<el-select
|
||||
v-model="empQuery.status"
|
||||
size="mini"
|
||||
placeholder="状态"
|
||||
clearable
|
||||
style="width: 140px"
|
||||
@change="loadEmployee"
|
||||
>
|
||||
<el-option label="在职" value="active" />
|
||||
<el-option label="离职" value="inactive" />
|
||||
</el-select>
|
||||
<el-button size="mini" type="primary" icon="el-icon-search" @click="loadEmployee">查询</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="employeeList" v-loading="empLoading" height="700" stripe>
|
||||
<el-table-column label="工号" prop="empNo" min-width="110" />
|
||||
<el-table-column label="姓名" prop="empName" min-width="120" />
|
||||
<el-table-column label="性别" prop="gender" min-width="80" />
|
||||
<el-table-column label="手机" prop="mobile" min-width="130" />
|
||||
<el-table-column label="雇佣类型" prop="employmentType" min-width="120" />
|
||||
<el-table-column label="状态" prop="status" min-width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="statusType(scope.row.status)">{{ scope.row.status || '-' }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="入职日期" prop="hireDate" min-width="140">
|
||||
<template slot-scope="scope">{{ formatDate(scope.row.hireDate) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" prop="remark" min-width="160" show-overflow-tooltip />
|
||||
</el-table>
|
||||
</el-card>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listOrg, listEmployee } from '@/api/hrm'
|
||||
|
||||
export default {
|
||||
name: 'HrmOrgEmployee',
|
||||
data() {
|
||||
return {
|
||||
orgTree: [],
|
||||
orgLoading: false,
|
||||
orgSelected: null,
|
||||
employeeList: [],
|
||||
empLoading: false,
|
||||
empQuery: { empName: '', status: undefined, mainOrgId: undefined }
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadOrg()
|
||||
},
|
||||
methods: {
|
||||
statusType(status) {
|
||||
if (!status) return 'info'
|
||||
const map = { pending: 'warning', draft: 'info', approved: 'success', rejected: 'danger', active: 'success', inactive: 'info' }
|
||||
return map[status] || 'info'
|
||||
},
|
||||
formatDate(val) {
|
||||
if (!val) return ''
|
||||
const d = new Date(val)
|
||||
const p = n => (n < 10 ? `0${n}` : n)
|
||||
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`
|
||||
},
|
||||
loadOrg() {
|
||||
this.orgLoading = true
|
||||
listOrg({ pageNum: 1, pageSize: 999 })
|
||||
.then(res => {
|
||||
const rows = res.rows || []
|
||||
this.orgTree = this.buildTree(rows)
|
||||
if (!this.orgSelected && this.orgTree.length) this.orgSelected = this.orgTree[0].orgId
|
||||
this.empQuery.mainOrgId = this.orgSelected
|
||||
this.loadEmployee()
|
||||
})
|
||||
.finally(() => {
|
||||
this.orgLoading = false
|
||||
})
|
||||
},
|
||||
buildTree(list) {
|
||||
const map = {}
|
||||
list.forEach(item => {
|
||||
map[item.orgId] = { ...item, children: [] }
|
||||
})
|
||||
const roots = []
|
||||
list.forEach(item => {
|
||||
const parent = map[item.parentId]
|
||||
if (parent) parent.children.push(map[item.orgId])
|
||||
else roots.push(map[item.orgId])
|
||||
})
|
||||
return roots
|
||||
},
|
||||
handleOrgClick(node) {
|
||||
this.orgSelected = node.orgId
|
||||
this.empQuery.mainOrgId = node.orgId
|
||||
this.loadEmployee()
|
||||
},
|
||||
loadEmployee() {
|
||||
if (!this.empQuery.mainOrgId) return
|
||||
this.empLoading = true
|
||||
listEmployee({ ...this.empQuery, pageNum: 1, pageSize: 50 })
|
||||
.then(res => {
|
||||
this.employeeList = res.rows || []
|
||||
})
|
||||
.finally(() => {
|
||||
this.empLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.hrm-page {
|
||||
padding: 16px 20px 32px;
|
||||
background: #f8f9fb;
|
||||
}
|
||||
.panel-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
.metal-panel {
|
||||
border: 1px solid #d7d9df;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
}
|
||||
.panel-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
.actions-inline {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
.custom-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
.tree-tag {
|
||||
margin-left: 8px;
|
||||
}
|
||||
@media (max-width: 1200px) {
|
||||
.panel-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user