/** * 申请页「创建 / 查看详情 / 编辑」三态通用逻辑 * * 统一约定(三个提交页共用): * - 从「我的申请」「申请记录」跳转时带 mode=detail,页面按只读详情渲染; * - 只有业务状态为「已驳回」(REJECTED)的申请,详情页底部才出现「编辑」; * - 点「编辑」进入 mode=edit,表单可编辑,底部按钮变为「提交」; * - 管理端(申请记录页)跳转带 admin=1,恒为只读,不出现「编辑」。 * * 页面需要自行实现两个钩子: * - fetchSourceDetail():按来源接口拉取业务明细并回填表单(编辑态用) * - submitApplication():创建态/编辑态的提交动作 */ import { adaptEssApplication, canEditEssApplication, essIdOf, getAdminApplicationDetail, getMyApplicationDetail, } from "@/api/hr/essApplication"; export const APPLICATION_MODE = { CREATE: "create", DETAIL: "detail", EDIT: "edit", }; /** * 解析页面参数 * @param {object} options onLoad 收到的参数 */ export function parseApplicationQuery(options = {}) { const opts = options || {}; const raw = String(opts.mode || "").toLowerCase(); const mode = raw === APPLICATION_MODE.DETAIL || raw === APPLICATION_MODE.EDIT ? raw : APPLICATION_MODE.CREATE; return { mode, essId: essIdOf(opts.id), businessId: essIdOf(opts.businessId), businessType: String(opts.businessType || "").toUpperCase(), processInstanceId: String(opts.processInstanceId || ""), admin: String(opts.admin || "") === "1", }; } export const applicationModeMixin = { data() { return { appMode: APPLICATION_MODE.CREATE, appEssId: "", appBusinessId: "", appBusinessType: "", appProcessInstanceId: "", appAdmin: false, essDetail: {}, essLoading: false, }; }, computed: { isCreateMode() { return this.appMode === APPLICATION_MODE.CREATE; }, isDetailMode() { return this.appMode === APPLICATION_MODE.DETAIL; }, isEditMode() { return this.appMode === APPLICATION_MODE.EDIT; }, /** 详情态 = 全部字段只读 */ isReadonly() { return this.isDetailMode; }, /** 详情态统一申请展示结构 */ essRow() { return adaptEssApplication(this.essDetail || {}); }, /** 仅「已驳回」且非管理端查看时可编辑 */ canEditApplication() { return ( this.isDetailMode && !this.appAdmin && canEditEssApplication(this.essDetail || {}, false) ); }, /** 详情态且不可编辑时,不显示底部操作条 */ showBottomBar() { return this.isCreateMode || this.isEditMode || this.canEditApplication; }, bottomButtonText() { if (this.isDetailMode) return "编辑"; if (this.isEditMode) return "提交"; return "提交申请"; }, detailNo() { return this.essRow.applicationNo || "—"; }, detailStatusLabel() { return this.essRow.statusLabel || "—"; }, detailStatusClass() { return this.essRow.statusClass || "pending"; }, detailNode() { return this.essRow.currentNode || ""; }, detailApplicant() { return this.essRow.applicantName || ""; }, detailCreatedAt() { return this.essRow.createdAt || ""; }, detailTitle() { return this.essRow.title || ""; }, /** 页面基础标题;页面通过覆盖 pageTitle 提供(如「调岗申请」) */ pageTitle() { return ""; }, /** 详情态展示「申请人 / 所属组织」,创建态隐藏 */ showDetailHeader() { return this.isDetailMode || this.isEditMode; }, /** 只读态给 form 传 disabled 用的别名,避免模板里写长表达式 */ formDisabled() { return this.isReadonly; }, }, methods: { /** * 在页面 onLoad 中首先调用 * @returns {object} 解析后的参数 */ initApplicationMode(options = {}) { const query = parseApplicationQuery(options); this.appMode = query.mode; this.appEssId = query.essId; this.appBusinessId = query.businessId; this.appBusinessType = query.businessType; this.appProcessInstanceId = query.processInstanceId; this.appAdmin = query.admin; return query; }, /** 详情/编辑态标题 */ applicationTitle(defaultTitle) { const base = defaultTitle || "申请"; if (this.isDetailMode) return `${base}详情`; if (this.isEditMode) return `编辑${base}`; return base; }, applyNavigationTitle(defaultTitle) { uni.setNavigationBarTitle({ title: this.applicationTitle(defaultTitle) }); }, /** * 拉取统一申请详情(管理端走 admin 接口) * GET /hr/ess/admin/applications/{id} ← id 必须是 M09 申请索引主键(列表 record.id) */ async loadEssDetail(loding = false) { if (!this.appEssId) { this.essDetail = {}; return {}; } this.essLoading = true; try { const detail = this.appAdmin ? await getAdminApplicationDetail(this.appEssId, loding) : await getMyApplicationDetail(this.appEssId, loding); this.essDetail = detail || {}; return this.essDetail; } catch (error) { // 详情拿不到不阻断页面(业务明细仍可展示),但如实提示,不静默吞掉 this.essDetail = {}; console.log( "[统一申请详情] 加载失败:", this.appAdmin ? "/hr/ess/admin/applications/" : "/hr/ess/applications/", this.appEssId, (error && error.message) || error ); uni.showToast({ title: (error && error.message) || "统一申请详情加载失败", icon: "none", }); return {}; } finally { this.essLoading = false; } }, /** 详情模式初始化:拉详情 + 业务明细(只读,不加载草稿) */ async initDetailMode() { uni.showLoading({ title: "加载中..." }); try { await this.loadEssDetail(false); await this.loadDetailBusiness(); } catch (error) { // 业务明细拉取失败时保留统一申请视图(脱敏摘要 + 状态),不阻断只读展示 uni.showToast({ title: (error && error.message) || "申请明细加载失败", icon: "none", }); } finally { uni.hideLoading(); } }, /** 只读详情需要的业务数据;页面可覆盖 */ async loadDetailBusiness() {}, /** * 点「编辑」:拉取来源业务明细回填表单后切到编辑态 */ async enterEditMode() { if (!this.canEditApplication) return; uni.showLoading({ title: "加载中..." }); try { const businessId = this.appBusinessId || this.essRow.businessId; await this.fetchSourceDetail(businessId); this.appMode = APPLICATION_MODE.EDIT; this.applyNavigationTitle(this.pageTitle || "申请"); } catch (error) { uni.showToast({ title: (error && error.message) || "申请明细加载失败,无法编辑", icon: "none", }); return; } finally { uni.hideLoading(); } }, /** 拉取来源业务明细并回填表单;页面必须实现 */ async fetchSourceDetail() { throw new Error("fetchSourceDetail 未实现"); }, /** 底部按钮分发:详情态→编辑,创建/编辑态→提交 */ async onBottomAction() { if (this.isDetailMode) return this.enterEditMode(); return this.submitApplication(); }, /** 提交动作;页面必须实现 */ async submitApplication() { throw new Error("submitApplication 未实现"); }, /** 提交成功/离开页面后回到来源列表 */ backToApplicationList(fallbackUrl = "/pages/hr/apply/list") { const pages = getCurrentPages(); if (pages && pages.length > 1) { uni.navigateBack({ delta: 1 }); return; } uni.redirectTo({ url: fallbackUrl, fail: () => uni.reLaunch({ url: fallbackUrl }), }); }, goBackFromApplication() { const pages = getCurrentPages(); if (pages && pages.length > 1) { uni.navigateBack({ delta: 1 }); return; } uni.redirectTo({ url: "/pages/index/index" }); }, }, };