| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- <template>
- <main class="cm-detail-host" v-loading="loading">
- <div v-if="detailRow" class="cm-create-page cm-detail-page">
- <div class="cm-create-employee-card cm-detail-employee">
- <span class="cm-employee-avatar">{{
- detailRow.employeeName ? detailRow.employeeName.slice(0, 1) : '?'
- }}</span>
- <div class="cm-employee-info">
- <b
- >员工姓名:{{ detailRow.employeeName
- }}<span class="cm-employee-no"
- >员工工号:{{ detailRow.employeeNo }}</span
- ></b
- >
- </div>
- <div class="cm-detail-status">
- <small>合同状态</small>
- <span class="cm-status" :class="statusClass(detailRow.status)">{{
- detailRow.status
- }}</span>
- </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">{{ detailRow.contractNo }}</span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">合同类型:</span
- ><span class="cm-compare-value">{{ detailRow.contractType }}</span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">所属机构:</span
- ><span class="cm-compare-value">{{ detailRow.legalEntity }}</span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">所属部门:</span
- ><span class="cm-compare-value">{{ detailRow.department }}</span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">岗位名称:</span
- ><span class="cm-compare-value">{{ detailRow.positionName }}</span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">岗位层级:</span
- ><span class="cm-compare-value">{{
- detailRow.level || '-'
- }}</span>
- </div>
- <!-- <div class="cm-compare-item">
- <span class="cm-compare-label">直属上级:</span
- ><span class="cm-compare-value">{{
- detailRow.manager || '-'
- }}</span>
- </div> -->
- </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">{{
- detailRow.startDate || '-'
- }}</span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">合同终止:</span
- ><span class="cm-compare-value">{{
- detailRow.endDate || '长期'
- }}</span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">月薪资:</span
- ><span class="cm-compare-value is-highlight">{{
- detailRow.salary
- ? '¥ ' + Number(detailRow.salary).toLocaleString() + ' 元/月'
- : '待定'
- }}</span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">试用期至:</span
- ><span class="cm-compare-value">{{
- detailRow.probationEnd || '无试用期'
- }}</span>
- </div>
- </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">{{
- detailRow.signMethod || '-'
- }}</span>
- </div>
- <!-- <div class="cm-compare-item">
- <span class="cm-compare-label">签署状态:</span
- ><span class="cm-compare-value">{{
- detailRow.signingStatusLabel || '-'
- }}</span>
- </div> -->
- <div
- v-if="detailRow.flowSignStatus"
- class="cm-compare-item"
- >
- <span class="cm-compare-label">流程节点电子签章:</span
- ><span class="cm-compare-value">{{
- detailRow.flowSignStatusLabel || '-'
- }}</span>
- </div>
- <div
- class="cm-compare-item is-span-2"
- v-if="detailRow.flowSignNodes && detailRow.flowSignNodes.length"
- >
- <span class="cm-compare-label">签章节点:</span>
- <span class="cm-compare-value">
- {{
- detailRow.flowSignNodes
- .map(
- (n) =>
- (n.name || n.nodeName || n.taskName || '节点') +
- '(' +
- (n.statusLabel || '-') +
- ')'
- )
- .join('、')
- }}
- </span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">合同附件:</span
- ><span class="cm-compare-value">
- <fileMain
- v-if="
- detailRow.attachmentFileIds &&
- detailRow.attachmentFileIds.length
- "
- :value="detailRow.attachmentFileIds"
- type="view"
- size="small"
- />
- <span v-else class="cm-detail-muted">暂无附件</span>
- </span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">签订日期:</span
- ><span class="cm-compare-value">{{
- detailRow.signDate || detailRow.createdAt || '-'
- }}</span>
- </div>
- <div class="cm-compare-item">
- <span class="cm-compare-label">创建时间:</span
- ><span class="cm-compare-value">{{
- detailRow.createdAt || '-'
- }}</span>
- </div>
- </div>
- <div v-if="detailRow.remark" class="cm-detail-remark">
- <strong>备注:</strong>{{ detailRow.remark }}
- </div>
- </div>
- </div>
- <el-empty v-else-if="!loading" description="暂无合同详情" />
- </main>
- </template>
- <script>
- import {
- getContractById,
- adaptContractFlowSignNodes,
- contractSigningStatusLabel,
- contractStatusLabel,
- contractFlowSignStatusLabel,
- pickFlowSignStatus
- } from '@/api/hr';
- import { parseAttachmentIds } from '@/utils/attachment';
- const CONTRACT_TYPES = [
- { value: 'FIXED', label: '固定期限劳动合同' },
- { value: 'NON_FIXED', label: '无固定期限劳动合同' },
- { value: 'TASK', label: '以完成一定任务为期限' },
- { value: 'DISPATCH', label: '劳务派遣合同' },
- { value: 'INTERN', label: '实习协议' },
- { value: 'CONFIDENTIAL', label: '保密协议' },
- { value: 'NON_COMPETE', label: '竞业限制协议' },
- { value: 'CHANGE', label: '合同变更协议' },
- { value: 'TERMINATION', label: '合同终止协议' }
- ];
- function formatDate(value) {
- if (!value) return '';
- return String(value).slice(0, 10);
- }
- function formatDateTime(value) {
- if (!value) return '';
- return String(value).replace('T', ' ').slice(0, 16);
- }
- function typeLabel(value) {
- return CONTRACT_TYPES.find((t) => t.value === value)?.label || value || '';
- }
- function signMethodLabel(value) {
- if (value === 'ONLINE') return '线上';
- if (value === 'OFFLINE') return '线下';
- return value || '';
- }
- // 附件 ID 解析已统一由 src/utils/attachment.js 的 parseAttachmentIds 处理
- function adaptContract(item = {}) {
- const files = item.files || [];
- const startDate = formatDate(item.startDate);
- const endDate = formatDate(item.endDate);
- const termText =
- item.contractTerm ||
- (item.contractTermMonths != null && item.contractTermMonths !== ''
- ? `${item.contractTermMonths}个月`
- : '');
- return {
- ...item,
- employeeNo: item.employeeCode || item.employeeNo || '',
- employeeCode: item.employeeCode || item.employeeNo || '',
- legalEntity: item.legalEntityName || '',
- department: item.departmentName || '',
- contractTypeCode: item.contractType || '',
- contractType: typeLabel(item.contractType),
- signMethod: signMethodLabel(item.signingMethod),
- signingStatus: item.signingStatus || '',
- signingStatusLabel: contractSigningStatusLabel(item.signingStatus),
- flowSignStatus: pickFlowSignStatus(item),
- flowSignStatusLabel: contractFlowSignStatusLabel(pickFlowSignStatus(item)),
- flowSignNodes: adaptContractFlowSignNodes(item),
- status: contractStatusLabel(item.contractStatus),
- statusCode: item.contractStatus || '',
- salary: item.salaryStandard,
- signDate: formatDate(item.signingDate),
- startDate,
- endDate,
- contractTerm: termText,
- remainingDays:
- item.remainingDays === null ||
- item.remainingDays === undefined ||
- item.remainingDays === ''
- ? null
- : Number(item.remainingDays),
- probationMonths: item.probationMonths,
- createdAt: formatDateTime(item.createTime),
- probationEnd: formatDate(item.probationEndDate),
- attachmentFileIds: parseAttachmentIds(item),
- level: item.positionLevel || item.level || '',
- manager: item.managerName || item.manager || '',
- archived:
- item.contractStatus === 'ARCHIVED' ||
- item.archived === true ||
- item.archived === 1
- };
- }
- export default {
- name: 'HrContractDetail',
- props: {
- businessId: {
- default: ''
- }
- },
- data() {
- return {
- loading: false,
- detailRow: null
- };
- },
- watch: {
- businessId: {
- immediate: true,
- handler(id) {
- if (id) this.getInfo(id);
- }
- }
- },
- methods: {
- async getInfo(id) {
- if (!id) return;
- this.loading = true;
- try {
- const detail = await getContractById(id);
- this.detailRow = adaptContract(detail || {});
- } catch (e) {
- this.detailRow = null;
- this.$message.error(e.message || '合同详情加载失败');
- } finally {
- this.loading = false;
- }
- },
- statusClass(s) {
- const label = contractStatusLabel(s, s);
- const map = {
- 草稿: 'draft',
- 审批中: 'pending',
- 待签署: 'pending',
- 待签: 'pending',
- 签署中: 'signing',
- 已签待生效: 'pending',
- 待生效: 'pending',
- 生效: 'active',
- 生效中: 'active',
- 临期: 'expiring',
- 即将到期: 'expiring',
- 已变更: 'changed',
- 已续签: 'active',
- 已解除: 'terminated',
- 已终止: 'terminated',
- 已作废: 'expired',
- 已取消: 'expired',
- 已归档: 'archived',
- 试用期: 'trial',
- 已到期: 'expired',
- 已过期: 'expired'
- };
- return map[label] || map[s] || 'pending';
- }
- }
- };
- </script>
- <style lang="scss" scoped src="@/styles/views/hrContractManagement/index.scss"></style>
|