diff --git a/src/views/system-resource/device-management/detail.vue b/src/views/system-resource/device-management/detail.vue new file mode 100644 index 0000000..e740ae2 --- /dev/null +++ b/src/views/system-resource/device-management/detail.vue @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + 添加维护记录 + + + + + + + + + + + + + + + + + + + + + + + 上传文件 + + + + + + + + + + + + diff --git a/src/views/system/post/PostDetailDrawer.vue b/src/views/system/post/PostDetailDrawer.vue index a82dd34..61d3ffa 100644 --- a/src/views/system/post/PostDetailDrawer.vue +++ b/src/views/system/post/PostDetailDrawer.vue @@ -2,13 +2,14 @@ visible = false" > + {{ primaryInfo?.name || '-' }} @@ -16,40 +17,198 @@ - - 基本信息 - - - 岗位ID - {{ primaryInfo?.id || '-' }} + + + + + + + + 岗位名称 + {{ primaryInfo?.name || '-' }} + + + 所属部门 + {{ primaryInfo?.department || '技术部' }} + + + 直接上级岗位 + {{ primaryInfo?.superior || '技术总监' }} + + + 岗位等级/职级 + {{ primaryInfo?.level || 'P5' }} + + + 编写日期/版本号 + {{ primaryInfo?.version || '2024-06-01 / V1.0' }} + + + 岗位编号 + {{ primaryInfo?.id || '10001' }} + + + 工作地点 + {{ primaryInfo?.location || '上海/远程' }} + + + + + 岗位目的 + + {{ primaryInfo?.summary || '负责公司核心产品开发,支撑业务增长。' }} + - - 岗位排序 - {{ primaryInfo?.sort || '-' }} - - - + - - 岗位说明 - - {{ primaryInfo.remark }} - - + + + + + 主要职责与工作任务 + + + {{ task }} + + + + + 工作权限 + + + {{ perm }} + + + + + 汇报关系 + + + 直接上级 + {{ primaryInfo?.superior || '技术总监' }} + + + 直接下级 + {{ primaryInfo?.subordinates || '无' }} + + + 协作关系 + {{ primaryInfo?.collaboration || '与产品部、销售部、客服部紧密合作' }} + + + + - - 时间信息 - - - 创建时间 - {{ primaryInfo?.createTime || '-' }} + + + + + + 教育背景 + {{ primaryInfo?.education || '本科及以上学历,计算机相关专业' }} + + + 工作经验 + {{ primaryInfo?.experience || '5年以上相关工作经验' }} + + + 专业知识与技能 + {{ primaryInfo?.skills || '精通Java/Python,良好的沟通与团队协作能力' }} + + + 证书/执照 + {{ primaryInfo?.certificates || 'PMP、注册会计师等' }} + + + 其他要求 + {{ primaryInfo?.otherRequirements || '英语流利,能适应短期出差' }} + + - - 更新时间 - {{primaryInfo?.updateTime || '-' }} + + + + + + + + 工作环境 + {{ primaryInfo?.workEnv || '办公室/远程' }} + + + 工作时间 + {{ primaryInfo?.workTime || '标准工时,偶有加班' }} + + + 出差要求 + {{ primaryInfo?.travel || '偶尔出差' }} + + + 体力要求 + {{ primaryInfo?.physical || '无特殊要求' }} + + + 特殊设备/工具 + {{ primaryInfo?.tools || '电脑、办公软件' }} + + + 健康与安全 + {{ primaryInfo?.health || '注意用眼卫生' }} + + - - + + + + + + + 绩效衡量标准 + + {{ primaryInfo?.performance || '根据项目按时交付率、代码质量、产品性能指标提升情况进行评估。' }} + + + + 薪酬范围 + + {{ primaryInfo?.salaryRange || '20-30万/年' }} + + + + + + + + + 公司文化与价值观要求 + + {{ primaryInfo?.culture || '客户第一、创新、诚信、合作' }} + + + + 职业发展路径 + + {{ primaryInfo?.careerPath || '可晋升为高级工程师、技术经理,或横向发展至产品/项目管理岗位。' }} + + + + + + + + + + 创建时间 + {{ primaryInfo?.createTime || '-' }} + + + 更新时间 + {{ primaryInfo?.updateTime || '-' }} + + + + + @@ -65,30 +224,57 @@ import { nextTick, ref } from 'vue' import { getPostDetail } from '@/apis/system/post' import { useLoading } from '@/hooks' -//import { formatDate } from '@/utils/date' defineOptions({ name: 'PostDetailDrawer' }) const visible = ref(false) const { loading, setLoading } = useLoading() const primaryInfo = ref(null) +const activeTab = ref('basic') // 获取详情 const getDetail = async (id: string) => { try { setLoading(true) primaryInfo.value = null - const response = await getPostDetail(id) const data = response?.data || response - if (data && typeof data === 'object') { primaryInfo.value = { - id: data.postId ?? data.id, - name: data.postName ?? data.name, - sort: data.postSort, + id: data.postId ?? data.id ?? '10001', + name: data.postName ?? data.name ?? '-', status: data.status, - remark: data.remark, + department: data.department ?? '技术部', + superior: data.superior ?? '技术总监', + level: data.level ?? 'P5', + version: data.version ?? '2024-06-01 / V1.0', + location: data.location ?? '上海/远程', + summary: data.summary ?? '负责公司核心产品开发,支撑业务增长。', + tasks: data.tasks ?? [ + '负责XXX产品的需求分析、架构设计、核心模块编码和单元测试。', + '制定并执行季度社交媒体营销计划,提升品牌曝光度和用户互动率。' + ], + permissions: data.permissions ?? [ + '有权审批部门内5000元以下的采购申请。', + '有权对项目团队成员的工作任务进行分配和调整。' + ], + subordinates: data.subordinates ?? '无', + collaboration: data.collaboration ?? '与产品部、销售部、客服部紧密合作', + education: data.education ?? '本科及以上学历,计算机相关专业', + experience: data.experience ?? '5年以上相关工作经验', + skills: data.skills ?? '精通Java/Python,良好的沟通与团队协作能力', + certificates: data.certificates ?? 'PMP、注册会计师等', + otherRequirements: data.otherRequirements ?? '英语流利,能适应短期出差', + workEnv: data.workEnv ?? '办公室/远程', + workTime: data.workTime ?? '标准工时,偶有加班', + travel: data.travel ?? '偶尔出差', + physical: data.physical ?? '无特殊要求', + tools: data.tools ?? '电脑、办公软件', + health: data.health ?? '注意用眼卫生', + performance: data.performance ?? '根据项目按时交付率、代码质量、产品性能指标提升情况进行评估。', + careerPath: data.careerPath ?? '可晋升为高级工程师、技术经理,或横向发展至产品/项目管理岗位。', + salaryRange: data.salaryRange ?? '20-30万/年', + culture: data.culture ?? '客户第一、创新、诚信、合作', createTime: data.createTime, updateTime: data.updateTime, } @@ -114,15 +300,14 @@ const getStatusColor = (status: number | string) => { return 'rgb(150, 150, 150)' } -// 关闭抽屉 const handleClose = () => { visible.value = false } -// 查看详情 const onDetail = async (id: string) => { if (!id) return visible.value = true + activeTab.value = 'basic' // 重置到第一个标签页 await nextTick() await getDetail(id) } @@ -158,13 +343,13 @@ defineExpose({ .detail-header { display: flex; align-items: center; - margin-bottom: 28px; - padding-bottom: 20px; + margin-bottom: 20px; + padding-bottom: 15px; border-bottom: 1px solid var(--border-color); } .post-name { - font-size: 22px; + font-size: 20px; font-weight: 600; color: var(--value-color); margin-right: 15px; @@ -180,37 +365,34 @@ defineExpose({ color: white !important; } -.detail-group { - margin-bottom: 25px; - position: relative; - background-color: var(--group-bg); - border-radius: 8px; - padding: 12px 16px; +.detail-tabs { + margin-top: 10px; } -.detail-group:last-child { - margin-bottom: 0; +.tab-content { + padding: 20px 0; + max-height: 500px; + overflow-y: auto; + overflow-x: hidden; } -.group-title { - font-size: 16px; - font-weight: 600; - color: var(--group-title-color); - padding-bottom: 12px; - border-bottom: 1px solid var(--border-color); - margin-bottom: 15px; - display: flex; - align-items: center; +/* 自定义滚动条样式 */ +.tab-content::-webkit-scrollbar { + width: 6px; } -.group-title::before { - content: ''; - display: inline-block; - width: 4px; - height: 16px; - background-color: var(--primary-color); - margin-right: 8px; - border-radius: 2px; +.tab-content::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 3px; +} + +.tab-content::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 3px; +} + +.tab-content::-webkit-scrollbar-thumb:hover { + background: #a8a8a8; } .info-grid { @@ -256,17 +438,38 @@ defineExpose({ word-break: break-word; } -.remark-container { +.salary-value { + color: #e74c3c; + font-weight: 600; +} + +.content-container { padding: 16px; background: white; border-radius: 6px; border: 1px solid var(--border-color); } -.remark-content { +.content-text { color: var(--value-color); line-height: 1.7; font-size: 15px; + white-space: pre-wrap; + word-break: break-word; +} + +.section-title { + font-size: 18px; + font-weight: 600; + color: var(--group-title-color); + margin-top: 20px; + margin-bottom: 10px; + padding-bottom: 8px; + border-bottom: 1px solid var(--border-color); +} + +.section-title:first-child { + margin-top: 0; } .footer-actions { @@ -274,4 +477,52 @@ defineExpose({ justify-content: flex-end; padding: 16px 24px; } + +/* 标签页样式优化 */ +:deep(.arco-tabs-nav) { + background-color: var(--light-bg); + border-radius: 8px; + padding: 4px; + margin-bottom: 16px; +} + +:deep(.arco-tabs-nav-tab) { + background-color: transparent; + border: none; +} + +:deep(.arco-tabs-tab) { + border-radius: 6px; + margin: 0 2px; + padding: 8px 16px; + font-weight: 400; + font-size: 14px; + transition: all 0.3s ease; + border: 2px solid transparent; + color: #666; +} + +:deep(.arco-tabs-tab:hover) { + background-color: rgba(52, 152, 219, 0.1); + color: var(--primary-color); + font-weight: 500; +} + +:deep(.arco-tabs-tab-active) { + background-color: var(--primary-color); + color: white !important; + border-color: var(--primary-color); + box-shadow: 0 2px 8px rgba(52, 152, 219, 0.3); + font-weight: 700 !important; + font-size: 15px !important; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); +} + +:deep(.arco-tabs-content) { + padding: 0; +} + +:deep(.arco-tabs-tabpane) { + padding: 0; +}