hcm前端2版
This commit is contained in:
@@ -1,19 +1,20 @@
|
||||
<template>
|
||||
<div class="hrm-page">
|
||||
<section class="panel-grid quad">
|
||||
<el-card v-for="item in requestBlocks" :key="item.key" class="metal-panel" shadow="hover">
|
||||
<div slot="header" class="panel-header">
|
||||
<span>{{ item.title }}</span>
|
||||
<div class="actions-inline">
|
||||
<el-select
|
||||
v-if="item.statusField"
|
||||
v-model="item.query.status"
|
||||
size="mini"
|
||||
placeholder="状态"
|
||||
clearable
|
||||
style="width: 120px"
|
||||
@change="item.loader"
|
||||
>
|
||||
<el-card v-for="item in requestBlocks" :key="item.key" class="metal-panel" shadow="hover">
|
||||
<div slot="header" class="panel-header">
|
||||
<span>{{ item.title }}</span>
|
||||
<div class="actions-inline">
|
||||
<el-button size="mini" type="primary" plain icon="el-icon-plus" @click="openCreate(item.key)">新增</el-button>
|
||||
<el-select
|
||||
v-if="item.statusField"
|
||||
v-model="item.query.status"
|
||||
size="mini"
|
||||
placeholder="状态"
|
||||
clearable
|
||||
style="width: 120px"
|
||||
@change="item.loader"
|
||||
>
|
||||
<el-option label="草稿" value="draft" />
|
||||
<el-option label="审批中" value="pending" />
|
||||
<el-option label="通过" value="approved" />
|
||||
@@ -129,6 +130,107 @@
|
||||
<el-button type="primary" :loading="stampSubmitting" @click="submitStamp">盖章</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
title="新增申请"
|
||||
:visible.sync="createDialogVisible"
|
||||
width="520px"
|
||||
append-to-body
|
||||
>
|
||||
<div class="create-type-switch">
|
||||
<el-radio-group v-model="createType" size="small" @change="() => (createForm = defaultCreateForm(createType))">
|
||||
<el-radio-button label="leave">请假</el-radio-button>
|
||||
<el-radio-button label="overtime">加班</el-radio-button>
|
||||
<el-radio-button label="travel">出差</el-radio-button>
|
||||
<el-radio-button label="seal">用印</el-radio-button>
|
||||
</el-radio-group>
|
||||
<span class="hint-text" style="margin-left:8px">先选类型,再填写必填项</span>
|
||||
</div>
|
||||
<el-form ref="createFormRef" :model="createForm" :rules="currentCreateRules" label-width="110px" size="small">
|
||||
<el-form-item label="申请人">
|
||||
<el-select
|
||||
v-model="createForm.empId"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="选择员工"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="emp in employees"
|
||||
:key="emp.empId"
|
||||
:label="`${emp.empName || emp.empNo || emp.empId}`"
|
||||
:value="emp.empId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<template v-if="createType === 'leave'">
|
||||
<el-form-item label="请假类型" prop="leaveType">
|
||||
<el-input v-model="createForm.leaveType" placeholder="年假/事假等" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="startTime">
|
||||
<el-date-picker v-model="createForm.startTime" type="datetime" placeholder="开始" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endTime">
|
||||
<el-date-picker v-model="createForm.endTime" type="datetime" placeholder="结束" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="时长(小时)" prop="hours">
|
||||
<el-input-number v-model="createForm.hours" :min="0.5" :step="0.5" />
|
||||
</el-form-item>
|
||||
<el-form-item label="事由" prop="reason">
|
||||
<el-input v-model="createForm.reason" type="textarea" :rows="2" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-else-if="createType === 'overtime'">
|
||||
<el-form-item label="加班类型" prop="otType">
|
||||
<el-input v-model="createForm.otType" placeholder="工作日/休息日等" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="startTime">
|
||||
<el-date-picker v-model="createForm.startTime" type="datetime" placeholder="开始" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endTime">
|
||||
<el-date-picker v-model="createForm.endTime" type="datetime" placeholder="结束" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="时长(小时)" prop="hours">
|
||||
<el-input-number v-model="createForm.hours" :min="0.5" :step="0.5" />
|
||||
</el-form-item>
|
||||
<el-form-item label="事由" prop="reason">
|
||||
<el-input v-model="createForm.reason" type="textarea" :rows="2" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-else-if="createType === 'travel'">
|
||||
<el-form-item label="开始时间" prop="startTime">
|
||||
<el-date-picker v-model="createForm.startTime" type="datetime" placeholder="开始" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endTime">
|
||||
<el-date-picker v-model="createForm.endTime" type="datetime" placeholder="结束" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="目的地" prop="destination">
|
||||
<el-input v-model="createForm.destination" />
|
||||
</el-form-item>
|
||||
<el-form-item label="事由" prop="reason">
|
||||
<el-input v-model="createForm.reason" type="textarea" :rows="2" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-else-if="createType === 'seal'">
|
||||
<el-form-item label="用印类型" prop="sealType">
|
||||
<el-input v-model="createForm.sealType" placeholder="合同章/法人章..." />
|
||||
</el-form-item>
|
||||
<el-form-item label="用途说明" prop="purpose">
|
||||
<el-input v-model="createForm.purpose" type="textarea" :rows="2" />
|
||||
</el-form-item>
|
||||
<el-form-item label="申请材料附件" prop="applyFileIds">
|
||||
<file-upload v-model="createForm.applyFileIds" :limit="5" :file-size="50" :file-type="['pdf']" />
|
||||
</el-form-item>
|
||||
<el-form-item label="需要回执">
|
||||
<el-switch v-model="createForm.receiptRequired" :active-value="1" :inactive-value="0" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="createDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="createSubmitting" @click="submitCreate">提交</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -138,15 +240,23 @@ import {
|
||||
listOvertimeReq,
|
||||
listTravelReq,
|
||||
listSealReq,
|
||||
listEmployee,
|
||||
addLeaveReq,
|
||||
addOvertimeReq,
|
||||
addTravelReq,
|
||||
addSealReq,
|
||||
approveSealReq,
|
||||
rejectSealReq,
|
||||
cancelSealReq,
|
||||
stampSealJava,
|
||||
stampSealPython
|
||||
} from '@/api/hrm'
|
||||
import FileUpload from '@/components/FileUpload'
|
||||
|
||||
export default {
|
||||
name: 'HrmRequests',
|
||||
dicts: ['hrm_stamp_image'],
|
||||
components: { FileUpload },
|
||||
data() {
|
||||
return {
|
||||
requestBlocks: [],
|
||||
@@ -164,11 +274,52 @@ export default {
|
||||
currentSeal: null,
|
||||
previewNatural: { width: 0, height: 0 },
|
||||
marker: { visible: false, x: 0, y: 0, width: 0, height: 0 },
|
||||
stampImageNatural: { width: 0, height: 0 }
|
||||
stampImageNatural: { width: 0, height: 0 },
|
||||
employees: [],
|
||||
createDialogVisible: false,
|
||||
createType: '',
|
||||
createSubmitting: false,
|
||||
createForm: {},
|
||||
createRules: {
|
||||
empId: [{ required: true, message: '请选择申请人', trigger: 'change' }],
|
||||
leaveType: [{ required: true, message: '请选择请假类型', trigger: 'blur' }],
|
||||
otType: [{ required: true, message: '请输入加班类型', trigger: 'blur' }],
|
||||
sealType: [{ required: true, message: '请输入用印类型', trigger: 'blur' }],
|
||||
startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
|
||||
endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
|
||||
hours: [{ required: true, message: '请输入时长', trigger: 'blur' }],
|
||||
destination: [{ required: true, message: '请输入目的地', trigger: 'blur' }],
|
||||
purpose: [{ required: true, message: '请输入用途说明', trigger: 'blur' }],
|
||||
applyFileIds: [{ required: true, message: '请上传附件', trigger: 'change' }],
|
||||
reason: [{ required: true, message: '请输入事由', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initRequests()
|
||||
this.loadEmployees()
|
||||
},
|
||||
computed: {
|
||||
applicantDisplay() {
|
||||
const user = this.$store?.state?.user || {}
|
||||
const name = user.nickName || user.userName || ''
|
||||
const id = user.userId || user.userId === 0 ? user.userId : ''
|
||||
return name ? `${name}${id ? ` (${id})` : ''}` : id || '当前登录人'
|
||||
},
|
||||
currentCreateRules() {
|
||||
// 动态裁剪规则,避免多余必填影响校验
|
||||
const keys = {
|
||||
leave: ['empId', 'leaveType', 'startTime', 'endTime', 'hours', 'reason'],
|
||||
overtime: ['empId', 'otType', 'startTime', 'endTime', 'hours', 'reason'],
|
||||
travel: ['empId', 'startTime', 'endTime', 'destination', 'reason'],
|
||||
seal: ['empId', 'sealType', 'purpose', 'applyFileIds']
|
||||
}[this.createType] || []
|
||||
const picked = {}
|
||||
keys.forEach(k => {
|
||||
if (this.createRules[k]) picked[k] = this.createRules[k]
|
||||
})
|
||||
return picked
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
statusType(status) {
|
||||
@@ -322,6 +473,67 @@ export default {
|
||||
width: wRatio * displayWidth,
|
||||
height: hRatio * displayHeight
|
||||
}
|
||||
},
|
||||
openCreate(type) {
|
||||
this.createType = type
|
||||
this.createDialogVisible = true
|
||||
this.createForm = this.defaultCreateForm(type)
|
||||
this.$nextTick(() => this.$refs.createFormRef && this.$refs.createFormRef.clearValidate())
|
||||
},
|
||||
defaultCreateForm(type) {
|
||||
const common = { empId: '', remark: '' }
|
||||
if (type === 'leave') {
|
||||
return { ...common, leaveType: '', startTime: '', endTime: '', hours: 0, reason: '' }
|
||||
}
|
||||
if (type === 'overtime') {
|
||||
return { ...common, otType: '', startTime: '', endTime: '', hours: 0, reason: '' }
|
||||
}
|
||||
if (type === 'travel') {
|
||||
return { ...common, startTime: '', endTime: '', destination: '', reason: '' }
|
||||
}
|
||||
if (type === 'seal') {
|
||||
return { ...common, sealType: '', purpose: '', applyFileIds: '', receiptRequired: 0 }
|
||||
}
|
||||
return common
|
||||
},
|
||||
loadEmployees() {
|
||||
listEmployee({ pageNum: 1, pageSize: 500 }).then(res => {
|
||||
this.employees = res.rows || res.data || []
|
||||
})
|
||||
},
|
||||
submitCreate() {
|
||||
if (!this.createType) return
|
||||
const apiMap = {
|
||||
leave: addLeaveReq,
|
||||
overtime: addOvertimeReq,
|
||||
travel: addTravelReq,
|
||||
seal: addSealReq
|
||||
}
|
||||
const fn = apiMap[this.createType]
|
||||
if (!fn) return
|
||||
// 默认申请人取当前登录用户
|
||||
const payload = { ...this.createForm }
|
||||
const userId = this.$store?.state?.user?.userId
|
||||
if (userId) {
|
||||
payload.empId = userId
|
||||
} else {
|
||||
this.$message.error('未获取到当前登录用户,无法提交')
|
||||
return
|
||||
}
|
||||
this.$refs.createFormRef.validate(valid => {
|
||||
if (!valid) return
|
||||
this.createSubmitting = true
|
||||
fn(payload)
|
||||
.then(() => {
|
||||
this.$message.success('提交成功')
|
||||
this.createDialogVisible = false
|
||||
const block = this.requestBlocks.find(i => i.key === this.createType)
|
||||
block && block.loader()
|
||||
})
|
||||
.finally(() => {
|
||||
this.createSubmitting = false
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user