Przeglądaj źródła

feat(onboard): 扩充入职数据层 — onboardingDepartments/employmentTypes/invitationValidDays 与草稿/邀请 storage

xieyong 5 dni temu
rodzic
commit
35052cf249
2 zmienionych plików z 222 dodań i 10 usunięć
  1. 175 9
      src/data/mock.js
  2. 47 1
      src/utils/storage.js

+ 175 - 9
src/data/mock.js

@@ -73,22 +73,116 @@ export const onboardStages = [
   { key: 'onboard', label: '部门接收', desc: '工位分配、直属上级、试用期安排' },
 ]
 
+// 办理步骤(与 PC 端 onboardingHandling 五步一致)
+export const onboardingStepDefs = [
+  { key: 'offer',    label: 'Offer 发起',  icon: '发', desc: '候选人确认入职意向与 Offer' },
+  { key: 'profile',  label: '档案录入',    icon: '录', desc: '候选人手机端提交档案资料' },
+  { key: 'contract', label: '签署合同',    icon: '签', desc: '电子合同 / 纸质合同签署' },
+  { key: 'assets',   label: '物品领用',    icon: '领', desc: '工牌、工位、办公设备发放' },
+  { key: 'complete', label: '完成入职',    icon: '完', desc: '完成全部流程,进入试用期' },
+]
+
+export const onboardingStepText = {
+  offer:    { empty: '未发起', done: '已发起' },
+  profile:  { empty: '待录入', done: '档案已完善' },
+  contract: { empty: '未签署', done: '已签署' },
+  assets:   { empty: '未领用', done: '已领用' },
+  complete: { empty: '待确认', done: '已完成' },
+}
+
+export const onboardingDepartments = [
+  { id: 10, name: '中盈智能科技股份有限公司', type: 'company', parentId: 0, sort: 1 },
+  { id: 11, name: '中盈产业集团有限公司',     type: 'company', parentId: 0, sort: 2 },
+  { id: 20, name: '北京天成伟达工程有限公司', type: 'company', parentId: 0, sort: 3 },
+  { id: 101, name: '总经办',         type: 'dept', parentId: 10, sort: 1 },
+  { id: 102, name: '人力资源部',     type: 'dept', parentId: 10, sort: 2 },
+  { id: 103, name: '财务部',         type: 'dept', parentId: 10, sort: 3 },
+  { id: 104, name: '产品研发部',     type: 'dept', parentId: 10, sort: 4 },
+  { id: 105, name: '生产运营部',     type: 'dept', parentId: 10, sort: 5 },
+  { id: 110, name: '人力资源部',     type: 'dept', parentId: 11, sort: 1 },
+  { id: 111, name: '市场部',         type: 'dept', parentId: 11, sort: 2 },
+  { id: 112, name: '商务部',         type: 'dept', parentId: 11, sort: 3 },
+  { id: 201, name: '前端组',         type: 'dept', parentId: 104, sort: 1 },
+  { id: 202, name: '后端组',         type: 'dept', parentId: 104, sort: 2 },
+  { id: 203, name: '测试组',         type: 'dept', parentId: 104, sort: 3 },
+  { id: 204, name: '生产一部',       type: 'dept', parentId: 105, sort: 1 },
+  { id: 205, name: '生产二部',       type: 'dept', parentId: 105, sort: 2 },
+  { id: 206, name: '设备管理部',     type: 'dept', parentId: 105, sort: 3 },
+  { id: 207, name: '品质管理部',     type: 'dept', parentId: 105, sort: 4 },
+  { id: 301, name: '3 号产线',       type: 'dept', parentId: 204, sort: 1 },
+  { id: 302, name: '装配班组',       type: 'dept', parentId: 205, sort: 1 },
+]
+
+export const employmentTypes = [
+  { value: 'FULL_TIME', label: '全职' },
+  { value: 'INTERN',    label: '实习' },
+  { value: 'PART_TIME', label: '兼职' },
+  { value: 'OTHER',     label: '其他' },
+]
+
+export const probationMonthOptions = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+
+export const invitationValidDays = [3, 7, 14, 30, 60, 90]
+
+export const defaultOnboardingInvitations = [
+  {
+    invitationId: 'INV20260915001',
+    invitationNo: 'INV20260915001',
+    onboardingId: 'ZY20260915',
+    name: '孙浩',
+    department: '生产一部',
+    position: '工艺员',
+    legalId: 10,
+    employmentType: 'FULL_TIME',
+    offer: '待填写',
+    invitationStatus: 'PENDING',
+    publicPath: '/onboarding/public/ZY20260915',
+    publicToken: 'ZY20260915',
+    expiresAt: '2026-10-15T00:00:00',
+    createdAt: '2026-09-12T00:00:00',
+  },
+]
+
 export const onboardings = [
   {
     id: 'ZY20260915',
+    onboardingId: 'ZY20260915',
+    invitationId: 'INV20260915001',
+    invitationNo: 'INV20260915001',
+    employeeNo: 'ZY20260915',
     name: '孙浩',
     avatar: '孙',
+    company: '中盈智能科技股份有限公司',
+    legalId: 10,
     department: '生产一部',
+    deptId: 204,
     position: '工艺员',
+    positionId: 5,
     source: '社会招聘',
     status: 'pending',
     expectedEntryDate: '2026-09-15',
     entryDate: null,
     probationMonths: 3,
     probationEndDate: '2026-12-15',
-    mentor: '李明',
+    probationFlag: 1,
+    validDays: 7,
+    createMode: 'manual',
+    flow: '待补充档案',
+    offer: '待填写',
+    contract: '未签署',
+    assets: '未领用',
+    remark: '',
+    publicPath: '/onboarding/public/ZY20260915',
+    publicToken: 'ZY20260915',
+    invitationStatus: 'PENDING',
+    rowType: 'record',
     phone: '186 1234 5678',
     email: 'sunhao@aimill.com',
+    idNumber: '430102********1826',
+    gender: '男',
+    age: 28,
+    employmentType: 'FULL_TIME',
+    mentor: '李明',
     materials: {
       identityCard: true,
       degreeCertificate: true,
@@ -97,7 +191,7 @@ export const onboardings = [
       bankCard: true,
       resignationCert: false,
     },
-    contract: { status: '待签订', signMethod: '电子签', deadline: '2026-09-14' },
+    contractDetail: { status: '待签订', signMethod: '电子签', deadline: '2026-09-14' },
     socialSecurity: { status: '办理中', city: '北京', deadline: '2026-09-30' },
     training: { status: '未开始', name: '新员工入职培训', duration: '2天', deadline: '2026-09-20' },
     workstation: { status: '已分配', location: '生产一部 3号工位' },
@@ -106,19 +200,43 @@ export const onboardings = [
   },
   {
     id: 'ZY20260918',
+    onboardingId: 'ZY20260918',
+    invitationId: '',
+    invitationNo: '',
+    employeeNo: 'ZY20260918',
     name: '胡静',
     avatar: '胡',
+    company: '中盈智能科技股份有限公司',
+    legalId: 10,
     department: '财务部',
+    deptId: 103,
     position: '出纳',
-    source: '校园招聘',
+    positionId: 5,
+    source: '社会招聘',
     status: 'processing',
     expectedEntryDate: '2026-09-18',
     entryDate: '2026-09-18',
     probationMonths: 6,
     probationEndDate: '2027-03-18',
-    mentor: '周倩',
+    probationFlag: 1,
+    validDays: 7,
+    createMode: 'manual',
+    flow: '档案已完善',
+    offer: '已发起',
+    contract: '已签署',
+    assets: '已领用',
+    remark: '',
+    publicPath: '',
+    publicToken: '',
+    invitationStatus: '',
+    rowType: 'record',
     phone: '135 7721 4521',
     email: 'hujing@aimill.com',
+    idNumber: '110108********3261',
+    gender: '女',
+    age: 24,
+    employmentType: 'FULL_TIME',
+    mentor: '周倩',
     materials: {
       identityCard: true,
       degreeCertificate: true,
@@ -127,7 +245,7 @@ export const onboardings = [
       bankCard: true,
       resignationCert: true,
     },
-    contract: { status: '已签订', signMethod: '电子签', signDate: '2026-09-10' },
+    contractDetail: { status: '已签订', signMethod: '电子签', signDate: '2026-09-10' },
     socialSecurity: { status: '已办理', city: '北京', deadline: '2026-09-25' },
     training: { status: '进行中', name: '新员工入职培训', duration: '2天', deadline: '2026-09-20' },
     workstation: { status: '已分配', location: '财务部 2楼 201' },
@@ -136,19 +254,43 @@ export const onboardings = [
   },
   {
     id: 'ZY20260804',
+    onboardingId: 'ZY20260804',
+    invitationId: '',
+    invitationNo: '',
+    employeeNo: 'ZY20260804',
     name: '郑凯',
     avatar: '郑',
+    company: '中盈智能科技股份有限公司',
+    legalId: 10,
     department: '设备管理部',
+    deptId: 206,
     position: '技工',
+    positionId: 5,
     source: '社会招聘',
     status: 'done',
     expectedEntryDate: '2026-08-04',
     entryDate: '2026-08-04',
     probationMonths: 3,
     probationEndDate: '2026-11-04',
-    mentor: '王建国',
+    probationFlag: 1,
+    validDays: 7,
+    createMode: 'manual',
+    flow: '档案已完善',
+    offer: '已发起',
+    contract: '已签署',
+    assets: '已领用',
+    remark: '',
+    publicPath: '',
+    publicToken: '',
+    invitationStatus: '',
+    rowType: 'record',
     phone: '137 2098 3201',
     email: 'zhengkai@aimill.com',
+    idNumber: '370105********9214',
+    gender: '男',
+    age: 32,
+    employmentType: 'FULL_TIME',
+    mentor: '王建国',
     materials: {
       identityCard: true,
       degreeCertificate: true,
@@ -157,7 +299,7 @@ export const onboardings = [
       bankCard: true,
       resignationCert: true,
     },
-    contract: { status: '已签订', signMethod: '纸质签', signDate: '2026-08-03' },
+    contractDetail: { status: '已签订', signMethod: '纸质签', signDate: '2026-08-03' },
     socialSecurity: { status: '已办理', city: '北京', deadline: '2026-08-20' },
     training: { status: '已完成', name: '新员工入职培训', duration: '2天', deadline: '2026-08-08' },
     workstation: { status: '已分配', location: '设备管理部 主楼 B102' },
@@ -166,19 +308,43 @@ export const onboardings = [
   },
   {
     id: 'ZY20260905',
+    onboardingId: 'ZY20260905',
+    invitationId: '',
+    invitationNo: '',
+    employeeNo: 'ZY20260905',
     name: '刘洋',
     avatar: '刘',
+    company: '中盈智能科技股份有限公司',
+    legalId: 10,
     department: '品质管理部',
+    deptId: 207,
     position: '质量工程师',
+    positionId: 5,
     source: '社会招聘',
     status: 'overdue',
     expectedEntryDate: '2026-09-05',
     entryDate: null,
     probationMonths: 3,
     probationEndDate: null,
-    mentor: '赵磊',
+    probationFlag: 1,
+    validDays: 7,
+    createMode: 'manual',
+    flow: '档案已完善',
+    offer: '已发起',
+    contract: '待签署',
+    assets: '未领用',
+    remark: '',
+    publicPath: '',
+    publicToken: '',
+    invitationStatus: '',
+    rowType: 'record',
     phone: '186 9988 1100',
     email: 'liuyang@aimill.com',
+    idNumber: '510104********5418',
+    gender: '女',
+    age: 29,
+    employmentType: 'FULL_TIME',
+    mentor: '赵磊',
     materials: {
       identityCard: true,
       degreeCertificate: true,
@@ -187,7 +353,7 @@ export const onboardings = [
       bankCard: false,
       resignationCert: true,
     },
-    contract: { status: '待签订', signMethod: '电子签', deadline: '2026-09-04' },
+    contractDetail: { status: '待签订', signMethod: '电子签', deadline: '2026-09-04' },
     socialSecurity: { status: '未办理', city: '北京', deadline: null },
     training: { status: '未开始', name: '新员工入职培训', duration: '2天', deadline: null },
     workstation: { status: '待分配', location: '' },

+ 47 - 1
src/utils/storage.js

@@ -7,6 +7,8 @@ const TRAINING_KEY = 'aimill_hr_training_progress'
 const PROFILE_KEY = 'aimill_hr_profile_changes'
 const ONBOARD_MATERIALS_KEY = 'aimill_hr_onboard_materials'
 const ONBOARD_LIST_KEY = 'aimill_hr_onboardings'
+const ONBOARD_INVITATION_KEY = 'aimill_hr_onboarding_invitations'
+const ONBOARD_DRAFT_KEY = 'aimill_hr_onboarding_drafts'
 const RESIGN_KEY = 'aimill_hr_resignations'
 const AUTH_KEY = 'aimill_hr_auth'
 const REMEMBER_KEY = 'aimill_hr_remembered_account'
@@ -183,7 +185,7 @@ export function getAuthCredentials() {
 }
 
 export function clearDemoStorage() {
-  [APPLY_KEY, DRAFT_KEY, APPROVAL_KEY, TRAINING_KEY, PROFILE_KEY, ONBOARD_MATERIALS_KEY, ONBOARD_LIST_KEY, RESIGN_KEY].forEach((key) =>
+  [APPLY_KEY, DRAFT_KEY, APPROVAL_KEY, TRAINING_KEY, PROFILE_KEY, ONBOARD_MATERIALS_KEY, ONBOARD_LIST_KEY, ONBOARD_INVITATION_KEY, ONBOARD_DRAFT_KEY, RESIGN_KEY].forEach((key) =>
     uni.removeStorageSync(key),
   )
 }
@@ -234,6 +236,50 @@ export function mergeOnboardings(defaults = []) {
   return [...custom, ...defaults.filter((o) => !ids.has(o.id))]
 }
 
+// 入职邀请链接持久化(mock 中 defaultOnboardingInvitations 是只读示例)
+export function getOnboardingInvitations() {
+  const saved = uni.getStorageSync(ONBOARD_INVITATION_KEY)
+  return Array.isArray(saved) ? saved : []
+}
+
+export function addOnboardingInvitation(invite) {
+  if (!invite || !invite.invitationId) return getOnboardingInvitations()
+  const list = getOnboardingInvitations()
+  list.unshift(invite)
+  uni.setStorageSync(ONBOARD_INVITATION_KEY, list)
+  return list
+}
+
+export function updateOnboardingInvitation(invitationId, patch) {
+  if (!invitationId) return getOnboardingInvitations()
+  const list = getOnboardingInvitations()
+  const idx = list.findIndex((i) => i.invitationId === invitationId)
+  if (idx >= 0) {
+    list[idx] = { ...list[idx], ...patch }
+    uni.setStorageSync(ONBOARD_INVITATION_KEY, list)
+  }
+  return list
+}
+
+export function getOnboardingInvitationById(invitationId) {
+  return getOnboardingInvitations().find((i) => i.invitationId === invitationId) || null
+}
+
+// 入职创建表单草稿(按 latest-by-type 持久化一份)
+export function saveOnboardingDraft(draft) {
+  if (!draft) return null
+  uni.setStorageSync(ONBOARD_DRAFT_KEY, { ...draft, savedAt: Date.now() })
+  return draft
+}
+
+export function loadOnboardingDraft() {
+  return uni.getStorageSync(ONBOARD_DRAFT_KEY) || null
+}
+
+export function clearOnboardingDraft() {
+  uni.removeStorageSync(ONBOARD_DRAFT_KEY)
+}
+
 // 入职材料上传:按 employeeId → materialKey → FileInfo[] 索引
 // FileInfo = { id, name, path, size, uploadedAt, sourceType }
 // 演示版只存元信息 + 本地临时路径,不上传到对象存储