| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716 |
- import { getApiBaseUrl, getServerConfig, request } from '@/utils/auth'
- import { userChangeStatus, userChangeStages, userChanges } from '@/data/mock'
- import {
- addCreatedUserChange,
- formatNow,
- getCreatedUserChanges,
- getCurrentUser,
- getLoginUser,
- getUserChangeIds,
- getUserChangeStates,
- rememberUserChangeId,
- setUserChangeLocalState,
- updateCreatedUserChange,
- } from '@/utils/storage'
- // ============ 模式判断 ============
- function isServerMode() {
- return getServerConfig().mode === 'server'
- }
- function serverPath() {
- const base = getApiBaseUrl()
- if (!base) throw new Error('缺少服务器地址,请先在登录页右上角配置')
- return base
- }
- function delay(ms = 200) {
- return new Promise((resolve) => setTimeout(resolve, ms))
- }
- // ============ 工具 ============
- function compact(object = {}) {
- return Object.keys(object).reduce((result, key) => {
- const value = object[key]
- if (value !== '' && value !== null && value !== undefined) result[key] = value
- return result
- }, {})
- }
- function dateOnly(value) {
- if (!value) return ''
- return String(value).slice(0, 10)
- }
- function labelOf(map, raw, fallback = '') {
- const text = String(raw || '').trim()
- if (!text) return fallback
- return map[text] || map[text.toUpperCase()] || text
- }
- function asList(data) {
- if (Array.isArray(data)) return data
- if (Array.isArray(data?.list)) return data.list
- if (Array.isArray(data?.records)) return data.records
- if (data && typeof data === 'object' && data.id != null) return [data]
- return []
- }
- function keepBigIntId(value) {
- if (value === undefined || value === null || value === '') return undefined
- const text = String(value).trim()
- if (!/^-?\d+$/.test(text)) return value
- if (!Number.isSafeInteger(Number(text))) return text
- return Number(text)
- }
- function extractId(result) {
- if (result == null) return null
- if (typeof result === 'object') return result.id ?? result.changeId ?? null
- return result
- }
- function parseSnapshot(raw) {
- if (!raw) return {}
- if (typeof raw === 'object') return raw
- try {
- return JSON.parse(raw) || {}
- } catch (error) {
- return {}
- }
- }
- function detailMap(details = []) {
- const map = {}
- const list = Array.isArray(details) ? details : []
- list.forEach((item) => {
- const field = String(item?.changeField || '').toUpperCase()
- if (field) map[field] = item
- })
- return map
- }
- // ============ 枚举(与 PC 端 src/api/hr/userChange.js 对齐)============
- /** 异动类型 */
- export const CHANGE_TYPE_LABELS = {
- POSITION_TRANSFER: '调岗',
- DEPARTMENT_TRANSFER: '调部门',
- GRADE_CHANGE: '职级调整',
- PROMOTION: '晋升',
- DEMOTION: '降级',
- SALARY_CHANGE: '调薪',
- MANAGER_CHANGE: '调整上级',
- WORK_LOCATION_CHANGE: '工作地点变更',
- FACTORY_TRANSFER: '调工厂',
- LEGAL_ENTITY_TRANSFER: '跨法人调动',
- EMPLOYMENT_TYPE_CHANGE: '用工类型变更',
- COMPOSITE_CHANGE: '综合异动',
- }
- /** 员工端可自助提交的异动类型,其余由 HR 在 PC 端办理 */
- export const ESS_CHANGE_TYPE_KEYS = [
- 'POSITION_TRANSFER',
- 'DEPARTMENT_TRANSFER',
- 'PROMOTION',
- 'GRADE_CHANGE',
- 'COMPOSITE_CHANGE',
- ]
- export const ESS_CHANGE_TYPE_OPTIONS = ESS_CHANGE_TYPE_KEYS.map((value) => ({
- value,
- label: CHANGE_TYPE_LABELS[value],
- }))
- export function changeTypeLabel(value) {
- return labelOf(CHANGE_TYPE_LABELS, value, value || '调岗')
- }
- export const APPROVAL_STATUS_LABELS = {
- DRAFT: '草稿',
- PENDING: '审批中',
- APPROVING: '审批中',
- APPROVED: '已通过',
- REJECTED: '已驳回',
- WITHDRAWN: '已撤回',
- CANCELLED: '已取消',
- }
- export const EFFECTIVE_STATUS_LABELS = {
- PENDING: '待生效',
- SCHEDULED: '已排期',
- EFFECTIVE: '已生效',
- CANCELLED: '已取消',
- }
- /** 页面展示态 → 标签 / 样式(枚举定义在 data/mock.js) */
- export const TRANSFER_DISPLAY_STATUS = userChangeStatus
- export const TRANSFER_STATUS_FILTERS = [
- { value: 'all', label: '全部状态' },
- { value: 'draft', label: '草稿' },
- { value: 'pending', label: '审批中' },
- { value: 'approved', label: '已通过' },
- { value: 'rejected', label: '已驳回' },
- ]
- // ============ 状态机 ============
- export function deriveDocStatus(raw = {}) {
- const approval = String(raw.approvalStatus || '').toUpperCase()
- const effective = String(raw.effectiveStatus || '').toUpperCase()
- if (approval === 'CANCELLED' || effective === 'CANCELLED') return 'cancelled'
- if (approval === 'APPROVED' || effective === 'EFFECTIVE') return 'approved'
- if (approval === 'REJECTED') return 'rejected'
- if (approval === 'PENDING' || approval === 'APPROVING') return 'pending'
- if (approval === 'WITHDRAWN') return 'withdrawn'
- return 'draft'
- }
- export function canEditUserChange(row = {}) {
- const status = String(row.approvalStatus || '').toUpperCase()
- return status === 'DRAFT' || status === 'REJECTED' || status === ''
- }
- export function canSubmitUserChange(row = {}) {
- if (!row?.id) return false
- return ['draft', 'rejected'].includes(row.displayStatus)
- }
- export function canWithdrawUserChange(row = {}) {
- const status = String(row.approvalStatus || '').toUpperCase()
- return status === 'PENDING' || status === 'APPROVING'
- }
- export function canCancelUserChange(row = {}) {
- if (!row?.id) return false
- if (String(row.approvalStatus || '').toUpperCase() === 'CANCELLED') return false
- return String(row.effectiveStatus || '').toUpperCase() !== 'EFFECTIVE'
- }
- export function matchDisplayStatus(row = {}, filter = '') {
- if (!filter || filter === 'all') return true
- if (filter === 'rejected') return ['rejected', 'withdrawn', 'cancelled'].includes(row.displayStatus)
- return row.displayStatus === filter
- }
- function stageKeyOf(displayStatus) {
- if (displayStatus === 'approved') return 'effective'
- if (displayStatus === 'pending') return 'approval'
- return 'submit'
- }
- function progressOf(displayStatus, stageKey) {
- if (displayStatus === 'approved') return 100
- if (['rejected', 'withdrawn', 'cancelled'].includes(displayStatus)) return 30
- const index = Math.max(
- userChangeStages.findIndex((stage) => stage.key === stageKey),
- 0,
- )
- return Math.round(((index + 1) / userChangeStages.length) * 100)
- }
- function progressTipOf(displayStatus) {
- switch (displayStatus) {
- case 'draft':
- return '草稿尚未提交,提交后进入审批流程。'
- case 'pending':
- return '调岗审批中,请等待主管与 HR 的审批结果。'
- case 'approved':
- return '调岗审批已通过,将按生效日期更新岗位信息。'
- case 'rejected':
- return '审批已驳回,可修改后重新提交。'
- case 'withdrawn':
- return '本次调岗申请已撤回。'
- case 'cancelled':
- return '本次调岗申请已取消。'
- default:
- return ''
- }
- }
- // ============ VO / 演示记录 → 页面形状 ============
- export function adaptUserChange(raw = {}, extras = {}) {
- const before = parseSnapshot(raw.beforeSnapshot)
- const after = parseSnapshot(raw.afterSnapshot)
- const details = Array.isArray(raw.details) ? raw.details : []
- const map = detailMap(details)
- const deptDetail = map.DEPT
- const positionDetail = map.POSITION
- const gradeDetail = map.GRADE
- const locationDetail = map.WORK_LOCATION
- const changeType = String(raw.changeType || '').toUpperCase()
- const approvalStatus = String(raw.approvalStatus || '').toUpperCase()
- const effectiveStatus = String(raw.effectiveStatus || '').toUpperCase()
- const displayStatus = deriveDocStatus({ approvalStatus, effectiveStatus })
- const statusMeta = TRANSFER_DISPLAY_STATUS[displayStatus] || TRANSFER_DISPLAY_STATUS.draft
- const stageKey = stageKeyOf(displayStatus)
- const name = extras.name || raw.name || raw.employeeName || ''
- const dept =
- extras.dept || raw.dept || raw.originDept || before.deptName || deptDetail?.beforeText || ''
- const position =
- extras.position ||
- raw.position ||
- raw.originPosition ||
- before.positionName ||
- positionDetail?.beforeText ||
- ''
- const targetDept = raw.targetDept || raw.targetDeptName || after.deptName || deptDetail?.afterText || ''
- const targetPosition =
- raw.targetPosition || raw.targetPositionName || after.positionName || positionDetail?.afterText || ''
- return {
- id: raw.id,
- changeNo: raw.changeNo || raw.contractNo || (raw.id == null ? '' : String(raw.id)),
- source: extras.source || raw.source || '',
- userId: raw.userId ?? extras.userId,
- employeeId: raw.userId ?? extras.employeeId,
- name,
- avatar: raw.avatar || String(name).charAt(0),
- employeeNo: extras.employeeNo || raw.employeeNo || raw.userNo || '',
- dept,
- position,
- level: extras.level || raw.level || before.positionLevelName || before.grade || gradeDetail?.beforeText || '',
- targetDept,
- targetDeptId: raw.targetDeptId ?? deptDetail?.afterValue ?? null,
- targetPosition,
- targetPositionId: raw.targetPositionId ?? positionDetail?.afterValue ?? null,
- targetLevel: raw.targetLevel || after.positionLevelName || after.grade || gradeDetail?.afterText || '',
- workLocation: raw.workLocation || locationDetail?.afterText || '',
- changeType,
- changeTypeLabel: changeTypeLabel(changeType),
- effectiveDate: dateOnly(raw.effectiveDate),
- applyDate: dateOnly(raw.applyDate || raw.createTime || raw.submitDate),
- reason: raw.reason || '',
- remark: raw.remark || '',
- approvalNode: raw.approvalNode || '',
- approvalComment: raw.approvalComment || raw.hrComment || '',
- approvalStatus,
- approvalStatusLabel: labelOf(APPROVAL_STATUS_LABELS, approvalStatus, '草稿'),
- effectiveStatus,
- effectiveStatusLabel: labelOf(EFFECTIVE_STATUS_LABELS, effectiveStatus, '-'),
- displayStatus,
- statusLabel: statusMeta.label,
- statusClass: statusMeta.class,
- stageKey,
- progress: progressOf(displayStatus, stageKey),
- progressTip: progressTipOf(displayStatus),
- details,
- createTime: raw.createTime || '',
- raw,
- }
- }
- // ============ 演示模式本地实现 ============
- function mergeDemoRecords() {
- const overrides = getUserChangeStates()
- const created = getCreatedUserChanges()
- const seen = new Set(created.map((item) => String(item.id)))
- const base = [...created, ...userChanges.filter((item) => !seen.has(String(item.id)))]
- return base.map((record) => {
- const merged = { ...record, ...(overrides[String(record.id)] || {}) }
- return adaptUserChange(merged, { source: 'demo' })
- })
- }
- function updateDemoUserChange(id, patch) {
- setUserChangeLocalState(id, patch)
- updateCreatedUserChange(id, patch)
- return mergeDemoRecords().find((item) => String(item.id) === String(id)) || null
- }
- function persistDemoTransfer(id, form, submit) {
- const user = getCurrentUser() || {}
- const name = form.name || user.name || ''
- const record = {
- id: String(id),
- userId: form.userId || form.employeeId || user.id || '',
- name,
- avatar: form.avatar || String(name).charAt(0),
- employeeNo: form.employeeNo || user.id || '',
- dept: form.dept || user.department || '',
- position: form.position || user.position || '',
- level: form.level || '',
- targetDeptId: form.targetDeptId ?? null,
- targetDept: form.targetDeptName || form.targetDept || '',
- targetPositionId: form.targetPositionId ?? null,
- targetPosition: form.targetPositionName || form.targetPosition || '',
- targetLevel: form.targetLevel || '',
- changeType: inferChangeType(form),
- effectiveDate: dateOnly(form.effectiveDate),
- applyDate: dateOnly(formatNow()),
- reason: form.reason || '',
- remark: form.remark || '',
- approvalNode: submit ? '主管审批' : '',
- approvalStatus: submit ? 'PENDING' : 'DRAFT',
- effectiveStatus: 'PENDING',
- source: 'demo',
- createdByApp: true,
- }
- addCreatedUserChange(record)
- return record
- }
- // ============ 服务器接口(M02-人事异动)============
- const employeeCache = new Map()
- async function fetchEmployeeBrief(userId) {
- if (userId === undefined || userId === null || userId === '') return null
- const key = String(userId)
- if (employeeCache.has(key)) return employeeCache.get(key)
- try {
- const res = await request({ url: `${serverPath()}/main/user/getById/${key}`, method: 'GET' })
- const vo = res.data || {}
- const brief = {
- name: vo.name || vo.userName || '',
- employeeNo: vo.jobNumber || '',
- dept: vo.deptName || '',
- position: vo.postName || vo.position || '',
- level: vo.positionLevelName || vo.grade || '',
- }
- employeeCache.set(key, brief)
- return brief
- } catch (error) {
- employeeCache.set(key, null)
- return null
- }
- }
- function extrasOf(brief) {
- if (!brief) return {}
- return {
- name: brief.name,
- employeeNo: brief.employeeNo,
- dept: brief.dept,
- position: brief.position,
- level: brief.level,
- }
- }
- /** 当前登录人的服务端数字主键(登录响应里的 userId) */
- export function currentUserId() {
- const login = getLoginUser() || {}
- const raw = getCurrentUser()?.raw || {}
- const candidates = [login.userId, login.id, raw.userId, raw.id]
- return candidates.find((value) => value !== undefined && value !== null && value !== '')
- }
- function isMine(row = {}) {
- const user = getCurrentUser() || {}
- const login = getLoginUser() || {}
- const mine = [user.id, user.name, login.userId, login.loginName, login.userName]
- .filter((value) => value !== undefined && value !== null && value !== '')
- .map(String)
- if (!mine.length) return true
- const rowIds = [row.userId, row.employeeNo, row.name]
- .filter((value) => value !== undefined && value !== null && value !== '')
- .map(String)
- return rowIds.some((value) => mine.includes(value))
- }
- function transferText(row = {}) {
- return `${row.name}${row.employeeNo}${row.changeNo}${row.dept}${row.position}${row.targetDept}${row.targetPosition}`
- }
- /** 条件查询异动单 GET /main/user-changes */
- export async function getUserChangePage(params = {}) {
- const res = await request({
- url: `${serverPath()}/main/user-changes`,
- method: 'GET',
- data: compact({
- pageNum: params.pageNum,
- size: params.size,
- userId: keepBigIntId(params.userId),
- changeType: params.changeType,
- approvalStatus: params.approvalStatus,
- }),
- })
- const data = res.data || {}
- return { list: asList(data), count: Number(data?.count ?? data?.total ?? 0) }
- }
- /** 某员工的异动记录 GET /main/user-changes/users/{userId} */
- export async function getUserChangesByUserId(userId) {
- const res = await request({
- url: `${serverPath()}/main/user-changes/users/${userId}`,
- method: 'GET',
- })
- return asList(res.data)
- }
- /** 异动单详情 GET /main/user-changes/{id} */
- export async function getUserChangeById(id) {
- const res = await request({ url: `${serverPath()}/main/user-changes/${id}`, method: 'GET' })
- return res.data
- }
- /** 新建异动单(草稿)POST /main/user-changes */
- export async function createUserChange(payload) {
- const res = await request({
- url: `${serverPath()}/main/user-changes`,
- method: 'POST',
- data: payload,
- })
- const id = extractId(res.data)
- if (id != null) rememberUserChangeId(id)
- return id
- }
- /** 修改异动草稿 PUT /main/user-changes */
- export async function updateUserChange(payload) {
- await request({ url: `${serverPath()}/main/user-changes`, method: 'PUT', data: payload })
- if (payload?.id != null) rememberUserChangeId(payload.id)
- return payload.id
- }
- /** 异动预校验 POST /main/user-changes/{id}/validate */
- export async function validateUserChange(id) {
- const res = await request({
- url: `${serverPath()}/main/user-changes/${id}/validate`,
- method: 'POST',
- })
- return res.data
- }
- /** 提交异动审批 POST /main/user-changes/{id}/submit */
- export async function submitUserChange(id) {
- const res = await request({
- url: `${serverPath()}/main/user-changes/${id}/submit`,
- method: 'POST',
- })
- return res.data
- }
- /** 撤回异动审批 POST /main/user-changes/{id}/withdraw */
- export async function withdrawUserChange(id, reason = '') {
- const res = await request({
- url: `${serverPath()}/main/user-changes/${id}/withdraw`,
- method: 'POST',
- data: compact({ reason }),
- })
- return res.data
- }
- /** 取消异动单 POST /main/user-changes/{id}/cancel */
- export async function cancelUserChange(id, reason = '') {
- const res = await request({
- url: `${serverPath()}/main/user-changes/${id}/cancel`,
- method: 'POST',
- data: compact({ reason }),
- })
- return res.data
- }
- // ============ 对外统一入口(页面只调用这些)============
- /**
- * 调岗列表。
- * @param {object} params
- * - scope: 'mine' 只看本人;'all' 全部员工(HR 视图)
- * - status: TRANSFER_STATUS_FILTERS 的 value
- * - keyword: 姓名 / 工号 / 单号 / 岗位 模糊匹配
- */
- export async function loadTransferList(params = {}) {
- const { scope = 'mine', status = 'all', keyword = '', pageNum = 1, size = 50 } = params
- if (!isServerMode()) {
- const list = mergeDemoRecords()
- .filter((row) => (scope === 'mine' ? isMine(row) : true))
- .filter((row) => matchDisplayStatus(row, status))
- .filter((row) => (keyword ? transferText(row).includes(keyword) : true))
- .sort((a, b) =>
- String(b.applyDate || b.createTime).localeCompare(String(a.applyDate || a.createTime)),
- )
- return { list, count: list.length, source: 'demo' }
- }
- const userId = currentUserId()
- let rows = []
- if (scope === 'mine' && userId != null) {
- try {
- rows = await getUserChangesByUserId(userId)
- } catch (error) {
- rows = []
- }
- }
- if (!rows.length) {
- try {
- const page = await getUserChangePage({
- pageNum,
- size,
- userId: scope === 'mine' ? userId : undefined,
- })
- rows = page.list
- } catch (error) {
- rows = []
- }
- }
- // 集合接口不可用时,按本机记住的主键逐个拉详情兜底(与 PC 端策略一致)
- if (!rows.length) {
- const details = await Promise.all(
- getUserChangeIds().map(async (id) => {
- try {
- return await getUserChangeById(id)
- } catch (error) {
- return null
- }
- }),
- )
- rows = details.filter(Boolean)
- }
- const list = []
- for (const vo of rows) {
- if (!vo || vo.id == null) continue
- const extras = vo.name ? {} : extrasOf(await fetchEmployeeBrief(vo.userId))
- const row = adaptUserChange(vo, extras)
- rememberUserChangeId(row.id)
- if (scope === 'mine' && userId != null && !isMine(row)) continue
- if (!matchDisplayStatus(row, status)) continue
- if (keyword && !transferText(row).includes(keyword)) continue
- list.push(row)
- }
- return { list, count: list.length, source: 'api' }
- }
- /** 调岗单详情 */
- export async function loadTransferDetail(id) {
- if (!id) return null
- if (!isServerMode()) {
- return mergeDemoRecords().find((item) => String(item.id) === String(id)) || null
- }
- const vo = await getUserChangeById(id)
- if (!vo) return null
- rememberUserChangeId(id)
- const extras = vo.name ? {} : extrasOf(await fetchEmployeeBrief(vo.userId))
- return adaptUserChange(vo, extras)
- }
- // ============ 员工端申请表单 ============
- function inferChangeType(form = {}) {
- if (form.changeType) return form.changeType
- const hasDept = form.targetDeptId != null && form.targetDeptId !== ''
- const hasPosition = form.targetPositionId != null && form.targetPositionId !== ''
- if (hasDept && hasPosition) return 'COMPOSITE_CHANGE'
- if (hasDept) return 'DEPARTMENT_TRANSFER'
- return 'POSITION_TRANSFER'
- }
- function buildDetails(form = {}) {
- if (Array.isArray(form.details) && form.details.length) return form.details
- const details = []
- if (form.targetDeptName) {
- details.push({
- changeField: 'DEPT',
- beforeValue: form.originDeptId != null ? String(form.originDeptId) : undefined,
- beforeText: form.dept || '',
- afterValue: form.targetDeptId != null ? String(form.targetDeptId) : undefined,
- afterText: form.targetDeptName,
- })
- }
- if (form.targetPositionName) {
- details.push({
- changeField: 'POSITION',
- beforeValue: form.originPositionId != null ? String(form.originPositionId) : undefined,
- beforeText: form.position || '',
- afterValue: form.targetPositionId != null ? String(form.targetPositionId) : undefined,
- afterText: form.targetPositionName,
- })
- }
- // 职级未变化时不产生 GRADE 变动,避免把岗位自带层级误判为职级调整
- if (form.targetLevel && form.targetLevel !== form.level) {
- details.push({
- changeField: 'GRADE',
- beforeValue: form.level || undefined,
- beforeText: form.level || '',
- afterValue: form.targetLevel,
- afterText: form.targetLevel,
- })
- }
- return details
- }
- /**
- * 表单字段 → /main/user-changes 请求参数(与 PC 端 buildUserChangePayload 对齐)。
- * 申请人由服务端按当前任职确定,前端只送变动目标与事由。
- */
- export function buildUserChangePayload(form = {}) {
- return compact({
- id: keepBigIntId(form.id),
- userId: keepBigIntId(form.userId || form.employeeId),
- changeType: inferChangeType(form),
- effectiveDate: dateOnly(form.effectiveDate) || undefined,
- reason: form.reason,
- remark: form.remark,
- targetDeptId: keepBigIntId(form.targetDeptId),
- targetPositionId: keepBigIntId(form.targetPositionId),
- targetPositionName: form.targetPositionName || form.targetPosition,
- details: buildDetails(form),
- })
- }
- /**
- * 提交(或存草稿)调岗申请。
- * 服务器模式:建单 POST /main/user-changes → 提交 POST /{id}/submit
- * 演示模式:本地落一条异动单,提交时状态置为审批中
- *
- * @returns {Promise<string|number>} 异动单主键
- */
- export async function submitTransferApplication({ form, submit = true, existingId = null } = {}) {
- if (!form) throw new Error('申请参数为空')
- const id = existingId || form.id || null
- if (!isServerMode()) {
- await delay(300)
- const localId = id || `DC${Date.now()}`
- persistDemoTransfer(localId, form, submit)
- return localId
- }
- const payload = buildUserChangePayload({ ...form, id })
- const changeId = id || (await createUserChange(payload))
- if (id) await updateUserChange({ ...payload, id: changeId })
- if (submit && changeId != null) await submitUserChange(changeId)
- return changeId
- }
- // —— 流程动作:服务器模式走接口,演示模式改本地态 ——
- export async function actSubmitTransfer(row) {
- if (!row?.id) throw new Error('缺少异动单主键')
- if (isServerMode()) {
- // 与 PC 端一致:先预校验,再提交审批
- const result = await validateUserChange(row.id)
- if (result && result.valid === false) {
- throw new Error((result.messages || []).join(';') || '异动预校验未通过')
- }
- return submitUserChange(row.id)
- }
- return updateDemoUserChange(row.id, { approvalStatus: 'PENDING', approvalNode: '主管审批' })
- }
- export async function actWithdrawTransfer(row, reason = '') {
- if (!row?.id) throw new Error('缺少异动单主键')
- if (isServerMode()) return withdrawUserChange(row.id, reason)
- return updateDemoUserChange(row.id, {
- approvalStatus: 'WITHDRAWN',
- approvalComment: reason,
- approvalNode: '',
- })
- }
- export async function actCancelTransfer(row, reason = '') {
- if (!row?.id) throw new Error('缺少异动单主键')
- if (isServerMode()) return cancelUserChange(row.id, reason)
- return updateDemoUserChange(row.id, {
- approvalStatus: 'CANCELLED',
- effectiveStatus: 'CANCELLED',
- approvalComment: reason,
- approvalNode: '',
- })
- }
|