|
|
@@ -0,0 +1,193 @@
|
|
|
+<template>
|
|
|
+ <main class="cm-detail-host" v-loading="loading">
|
|
|
+ <div v-if="hasData" class="cm-create-page cm-detail-page">
|
|
|
+ <div class="cm-create-employee-card cm-detail-employee">
|
|
|
+ <span class="cm-employee-avatar">{{ avatarText }}</span>
|
|
|
+ <div class="cm-employee-info">
|
|
|
+ <b
|
|
|
+ >申请人:{{ applicantName || '-'
|
|
|
+ }}<span class="cm-employee-no"
|
|
|
+ >所属组织:{{ organizationName }}</span
|
|
|
+ ><span v-if="ess.applicationNo" class="cm-employee-no"
|
|
|
+ >申请编号:{{ ess.applicationNo }}</span
|
|
|
+ ></b
|
|
|
+ >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="cm-create-section">
|
|
|
+ <div class="cm-create-section-title">加班申请信息</div>
|
|
|
+ <div class="cm-create-grid">
|
|
|
+ <div class="cm-compare-item">
|
|
|
+ <span class="cm-compare-label">加班类型:</span
|
|
|
+ ><span class="cm-compare-value">{{ overtimeTypeLabel }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="cm-compare-item">
|
|
|
+ <span class="cm-compare-label">加班时长:</span
|
|
|
+ ><span class="cm-compare-value">{{ durationLabel }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="cm-compare-item">
|
|
|
+ <span class="cm-compare-label">开始日期:</span
|
|
|
+ ><span class="cm-compare-value">{{ datePart(form.startTime) }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="cm-compare-item">
|
|
|
+ <span class="cm-compare-label">开始时间:</span
|
|
|
+ ><span class="cm-compare-value">{{ timePart(form.startTime) }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="cm-compare-item">
|
|
|
+ <span class="cm-compare-label">结束日期:</span
|
|
|
+ ><span class="cm-compare-value">{{ datePart(form.endTime) }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="cm-compare-item">
|
|
|
+ <span class="cm-compare-label">结束时间:</span
|
|
|
+ ><span class="cm-compare-value">{{ timePart(form.endTime) }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="cm-compare-item">
|
|
|
+ <span class="cm-compare-label">附件:</span
|
|
|
+ ><span class="cm-compare-value">
|
|
|
+ <fileMain
|
|
|
+ v-if="attachmentIds.length"
|
|
|
+ :value="attachmentIds"
|
|
|
+ type="view"
|
|
|
+ size="small"
|
|
|
+ />
|
|
|
+ <span v-else class="cm-detail-muted">暂无附件</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-if="form.reason" class="cm-detail-remark">
|
|
|
+ <strong>申请事由:</strong>{{ form.reason }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-empty v-else-if="!loading" description="暂无加班申请详情" />
|
|
|
+ </main>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { loadAttendanceApprovalDetail } from '@/api/hr/attendanceApply';
|
|
|
+import { parseAttachmentIds } from '@/utils/attachment';
|
|
|
+
|
|
|
+/** 加班类型枚举(与 /hr/attendance/applications 的 overtimeType 口径一致) */
|
|
|
+const OVERTIME_TYPE_LABELS = {
|
|
|
+ WORKDAY: '工作日加班',
|
|
|
+ RESTDAY: '休息日加班',
|
|
|
+ LEGAL_HOLIDAY: '法定节假日加班'
|
|
|
+};
|
|
|
+
|
|
|
+function datePart(val) {
|
|
|
+ const text = String(val || '');
|
|
|
+ if (!text) return '-';
|
|
|
+ return text.split('T')[0].split(' ')[0];
|
|
|
+}
|
|
|
+
|
|
|
+function timePart(val) {
|
|
|
+ const text = String(val || '');
|
|
|
+ if (!text) return '-';
|
|
|
+ const time = text.split('T')[1] || text.split(' ')[1] || '';
|
|
|
+ return time ? time.slice(0, 5) : '-';
|
|
|
+}
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'HrOvertimeDetail',
|
|
|
+ props: {
|
|
|
+ // 待办传入的 M09 员工自助申请索引主键
|
|
|
+ businessId: {
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ // 流程实例主键,ESS 明细缺失时回退流程表单变量
|
|
|
+ id: {
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ deptName: {
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ loading: false,
|
|
|
+ ess: {},
|
|
|
+ form: {}
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ hasData() {
|
|
|
+ return Object.keys(this.form).length > 0;
|
|
|
+ },
|
|
|
+ applicantName() {
|
|
|
+ return (
|
|
|
+ this.ess.applicantName ||
|
|
|
+ this.form.userName ||
|
|
|
+ this.form.applicantName ||
|
|
|
+ ''
|
|
|
+ );
|
|
|
+ },
|
|
|
+ organizationName() {
|
|
|
+ return (
|
|
|
+ this.ess.organizationName ||
|
|
|
+ this.form.deptName ||
|
|
|
+ this.form.departmentName ||
|
|
|
+ this.deptName ||
|
|
|
+ '-'
|
|
|
+ );
|
|
|
+ },
|
|
|
+ avatarText() {
|
|
|
+ return this.applicantName ? this.applicantName.slice(0, 1) : '?';
|
|
|
+ },
|
|
|
+ overtimeTypeLabel() {
|
|
|
+ const code = this.form.overtimeType;
|
|
|
+ if (!code) return '-';
|
|
|
+ return OVERTIME_TYPE_LABELS[code] || code;
|
|
|
+ },
|
|
|
+ durationLabel() {
|
|
|
+ const minutes = Number(this.form.durationMinutes);
|
|
|
+ if (!minutes || isNaN(minutes) || minutes <= 0) return '-';
|
|
|
+ const hours = Math.floor(minutes / 60);
|
|
|
+ const mins = minutes % 60;
|
|
|
+ if (!hours) return `${mins} 分钟`;
|
|
|
+ if (!mins) return `${hours} 小时`;
|
|
|
+ return `${hours} 小时 ${mins} 分钟`;
|
|
|
+ },
|
|
|
+ attachmentIds() {
|
|
|
+ return parseAttachmentIds(this.form);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ businessId: {
|
|
|
+ immediate: true,
|
|
|
+ handler() {
|
|
|
+ this.getInfo();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ id() {
|
|
|
+ if (!this.businessId) this.getInfo();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ datePart,
|
|
|
+ timePart,
|
|
|
+ async getInfo() {
|
|
|
+ // 审批详情 = ESS 统一申请详情(申请人/组织/编号)+ 考勤申请明细,
|
|
|
+ // 明细缺失时回退流程实例表单变量
|
|
|
+ if (!this.businessId && !this.id) return;
|
|
|
+ this.loading = true;
|
|
|
+ try {
|
|
|
+ const { ess, detail } = await loadAttendanceApprovalDetail(
|
|
|
+ this.businessId,
|
|
|
+ this.id
|
|
|
+ );
|
|
|
+ this.ess = ess || {};
|
|
|
+ this.form = detail || {};
|
|
|
+ } catch (e) {
|
|
|
+ this.ess = {};
|
|
|
+ this.form = {};
|
|
|
+ this.$message.error(e.message || '加班申请详情加载失败');
|
|
|
+ } finally {
|
|
|
+ this.loading = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped src="@/styles/views/hrContractManagement/index.scss"></style>
|