| | |
| | | <view class="approve-apply-page"> |
| | | <PageHeader :title="pageTitle" |
| | | @back="goBack" /> |
| | | |
| | | <scroll-view class="form-scroll" |
| | | scroll-y |
| | | :show-scrollbar="false"> |
| | |
| | | </up-form-item> |
| | | </u-cell-group> |
| | | </up-form> |
| | | |
| | | <view class="section-card"> |
| | | <view class="section-head"> |
| | | <text class="section-title">填报内容</text> |
| | |
| | | </up-form> |
| | | <view v-else |
| | | class="empty-hint">该模板暂无填报项</view> |
| | | |
| | | <!-- 请假:假期余额 + 时长自动计算 --> |
| | | <view v-if="isLeaveModule" |
| | | class="module-extra-block"> |
| | |
| | | </up-form-item> |
| | | </up-form> |
| | | </view> |
| | | |
| | | <!-- 加班:时长自动计算 --> |
| | | <view v-if="isOvertimeModule" |
| | | class="module-extra-block"> |
| | |
| | | </up-form-item> |
| | | </up-form> |
| | | </view> |
| | | |
| | | <!-- 调岗:原岗位自动带出 --> |
| | | <view v-if="isTransferModule" |
| | | class="module-extra-block"> |
| | |
| | | </up-form> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="section-card"> |
| | | <view class="section-head"> |
| | | <text class="section-title">审批流程</text> |
| | |
| | | text="未获取到模板详情" /> |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | <FooterButtons v-if="!loading && detail" |
| | | cancel-text="取消" |
| | | :confirm-text="confirmText" |
| | | :loading="submitting" |
| | | @cancel="goBack" |
| | | @confirm="handleSubmit" /> |
| | | |
| | | <up-popup :show="showDatePicker" |
| | | mode="bottom" |
| | | @close="showDatePicker = false"> |
| | |
| | | @confirm="onDateConfirm" |
| | | @cancel="onDatePickerCancel" /> |
| | | </up-popup> |
| | | |
| | | <up-action-sheet :show="showSelectSheet" |
| | | :title="selectSheetTitle" |
| | | :actions="selectSheetActions" |
| | |
| | | parseFieldDateToTs, |
| | | } from "../../_utils/approvalFormField.js"; |
| | | |
| | | import { EDIT_STORAGE_KEY } from "../../_utils/approveListUtils.js"; |
| | | import { |
| | | EDIT_STORAGE_KEY, |
| | | mapFlowNodesToTasks, |
| | | } from "../../_utils/approveListUtils.js"; |
| | | |
| | | const LEVEL_TEXT = ["", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十"]; |
| | | const LEVEL_TEXT = [ |
| | | "", |
| | | "一", |
| | | "二", |
| | | "三", |
| | | "四", |
| | | "五", |
| | | "六", |
| | | "七", |
| | | "八", |
| | | "九", |
| | | "十", |
| | | ]; |
| | | |
| | | const userStore = useUserStore(); |
| | | const moduleKey = ref(""); |
| | |
| | | const isEditMode = computed(() => !!instanceId.value); |
| | | |
| | | const pageTitle = computed(() => (isEditMode.value ? "修改审批" : "发起审批")); |
| | | const confirmText = computed(() => (isEditMode.value ? "保存修改" : "提交审批")); |
| | | const confirmText = computed(() => |
| | | isEditMode.value ? "保存修改" : "提交审批" |
| | | ); |
| | | |
| | | const applicantName = computed( |
| | | () => userStore.nickName || userStore.name || "-" |
| | |
| | | |
| | | const levelLabel = n => LEVEL_TEXT[Number(n)] || String(n); |
| | | |
| | | const selectSheetTitle = computed( |
| | | () => (activeSelectField.value?.label ? `选择${activeSelectField.value.label}` : "请选择") |
| | | const selectSheetTitle = computed(() => |
| | | activeSelectField.value?.label |
| | | ? `选择${activeSelectField.value.label}` |
| | | : "请选择" |
| | | ); |
| | | |
| | | const selectSheetActions = computed(() => { |
| | |
| | | }); |
| | | const matched = options.find( |
| | | opt => |
| | | String(opt.value) === String(stored) || String(opt.label) === String(stored) |
| | | String(opt.value) === String(stored) || |
| | | String(opt.label) === String(stored) |
| | | ); |
| | | return ( |
| | | matched?.label || |
| | |
| | | const val = formValues[field.key]; |
| | | if (val === undefined || val === null || String(val).trim() === "") { |
| | | const action = |
| | | isSelectField(field) || isDateLikeField(field) || isDatetimerangeField(field) |
| | | isSelectField(field) || |
| | | isDateLikeField(field) || |
| | | isDatetimerangeField(field) |
| | | ? "请选择" |
| | | : "请填写"; |
| | | uni.showToast({ title: `${action}${field.label}`, icon: "none" }); |
| | |
| | | options.length && |
| | | !options.some( |
| | | opt => |
| | | String(opt.value) === String(val) || String(opt.label) === String(val) |
| | | String(opt.value) === String(val) || |
| | | String(opt.label) === String(val) |
| | | ) |
| | | ) { |
| | | uni.showToast({ title: `${field.label}选项无效`, icon: "none" }); |
| | |
| | | formConfigData.value.fields |
| | | ); |
| | | const allFields = formConfigData.value.fields || []; |
| | | const formPayload = {}; |
| | | allFields.forEach(field => { |
| | | if (!field?.key) return; |
| | | formPayload[field.key] = formValues[field.key] ?? ""; |
| | | }); |
| | | Object.entries(formValues).forEach(([key, val]) => { |
| | | if (key && formPayload[key] === undefined) formPayload[key] = val; |
| | | }); |
| | | return JSON.stringify({ |
| | | prompt: formConfigData.value.prompt, |
| | | fields: allFields.map(field => ({ |
| | | ...field, |
| | | value: formValues[field.key] ?? "", |
| | | })), |
| | | summaryPlaceholder: formConfigData.value.prompt || "", |
| | | approvalType: formConfigData.value.approvalType || "", |
| | | fields: allFields.map(({ value: _value, ...rest }) => rest), |
| | | formPayload, |
| | | }); |
| | | }; |
| | | |
| | | /** 模板 nodes → 审批任务(与 Web buildInstanceDto 一致) */ |
| | | const buildInstanceTasks = instanceIdValue => |
| | | mapFlowNodesToTasks(detail.value?.nodes, { |
| | | instanceId: instanceIdValue, |
| | | templateId: detail.value?.id, |
| | | }); |
| | | |
| | | const buildSavePayload = () => ({ |
| | | templateId: detail.value.id, |
| | |
| | | applyTime: parseTime(new Date()), |
| | | deptId: userStore.currentDeptId || undefined, |
| | | formConfig: buildFormConfigPayload(), |
| | | tasks: buildInstanceTasks(), |
| | | }); |
| | | |
| | | const buildUpdatePayload = () => { |
| | |
| | | deptId: row.deptId, |
| | | deleted: row.deleted, |
| | | formConfig: buildFormConfigPayload(), |
| | | tasks: buildInstanceTasks(instanceId.value), |
| | | approveAction: row.approveAction, |
| | | approveComment: row.approveComment, |
| | | }; |
| | |
| | | try { |
| | | const res = await findPostOptions(); |
| | | const rows = res?.data ?? res?.rows ?? []; |
| | | postIdToName.value = buildPostIdToNameMap(Array.isArray(rows) ? rows : []); |
| | | postIdToName.value = buildPostIdToNameMap( |
| | | Array.isArray(rows) ? rows : [] |
| | | ); |
| | | } catch { |
| | | postIdToName.value = {}; |
| | | } |
| | |
| | | return; |
| | | } |
| | | const user = userById(transferUserPool.value, uid); |
| | | extraForm.originalPostName = resolveOriginalPostName(user, postIdToName.value); |
| | | extraForm.originalPostName = resolveOriginalPostName( |
| | | user, |
| | | postIdToName.value |
| | | ); |
| | | } |
| | | |
| | | const goBack = () => { |