2025-12-08 20:03:34 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<BasicLayout>
|
2025-12-20 21:46:38 +08:00
|
|
|
|
<!-- 统一的滚动容器,包含编辑组件和流程组件 -->
|
|
|
|
|
|
<scroll-view scroll-y class="unified-scroll">
|
|
|
|
|
|
<!-- 引入编辑组件(不包含滚动) -->
|
|
|
|
|
|
<JfEdit v-if="isLoginReady" ref="jfEditRef" :jf-id="jfId" @saved="handleDataSaved" @loaded="handleJfEditLoaded" />
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 审批流程展示 -->
|
|
|
|
|
|
<view class="flow-section" v-if="jfId">
|
|
|
|
|
|
<LcglSp :yw-id="jfId" yw-type="JF" :key="jfId" />
|
2025-12-08 20:03:34 +08:00
|
|
|
|
</view>
|
2025-12-20 21:46:38 +08:00
|
|
|
|
</scroll-view>
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
|
|
|
|
|
<template #bottom>
|
|
|
|
|
|
<YwConfirm
|
|
|
|
|
|
v-if="showButton"
|
2025-12-20 21:46:38 +08:00
|
|
|
|
:spApi="wrappedJfSpApi"
|
|
|
|
|
|
:stopApi="wrappedJfStopApi"
|
|
|
|
|
|
:transferApi="wrappedJfTransferApi"
|
2025-12-08 20:03:34 +08:00
|
|
|
|
:params="spParams"
|
2025-12-20 21:46:38 +08:00
|
|
|
|
:autoToMessage="false"
|
2025-12-08 20:03:34 +08:00
|
|
|
|
:showXt="false"
|
2025-12-20 21:46:38 +08:00
|
|
|
|
:showReject="!isYiban"
|
|
|
|
|
|
:showTransfer="false"
|
|
|
|
|
|
:showApprove="!isYiban"
|
2025-12-08 20:03:34 +08:00
|
|
|
|
:showReturn="false"
|
|
|
|
|
|
:showStop="true"
|
|
|
|
|
|
:showXtDk="false"
|
2025-12-20 21:46:38 +08:00
|
|
|
|
approveText="通过"
|
|
|
|
|
|
@submit="handleSubmit"
|
|
|
|
|
|
@reject="handleReject"
|
|
|
|
|
|
@transfer="handleTransfer"
|
|
|
|
|
|
@stop="handleStop"
|
2025-12-08 20:03:34 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</template>
|
2025-12-20 21:46:38 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 遮罩层 -->
|
|
|
|
|
|
<view v-if="loading" class="loading-mask">
|
|
|
|
|
|
<view class="loading-content">
|
|
|
|
|
|
<view class="loading-spinner"></view>
|
|
|
|
|
|
<text class="loading-text">{{ loadingText }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
2025-12-08 20:03:34 +08:00
|
|
|
|
</BasicLayout>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2025-12-20 21:46:38 +08:00
|
|
|
|
import { onLoad, onBackPress } from "@dcloudio/uni-app";
|
2025-12-08 20:03:34 +08:00
|
|
|
|
import { ref, computed } from "vue";
|
|
|
|
|
|
import dayjs from "dayjs";
|
|
|
|
|
|
import BasicLayout from "@/components/BasicLayout/Layout.vue";
|
|
|
|
|
|
import LcglSp from "@/components/LcglSp/index.vue";
|
|
|
|
|
|
import YwConfirm from "@/pages/components/YwConfirm/index.vue";
|
2025-12-20 21:46:38 +08:00
|
|
|
|
import JfEdit from "./JfEdit.vue";
|
|
|
|
|
|
import { jfFlowByIdApi, jfSpApi, jfTransferApi, jfStopApi, jfSaveApi } from "@/api/base/jfApi";
|
|
|
|
|
|
import { xxtsFindByIdApi } from "@/api/base/xxtsApi";
|
|
|
|
|
|
import { useUserStore } from "@/store/modules/user";
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
const { loginByOpenId, getJs } = useUserStore();
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
|
|
|
|
|
const jfId = ref<string>("");
|
|
|
|
|
|
const jfInfo = ref<any>({});
|
|
|
|
|
|
const showButton = ref<boolean>(false);
|
2025-12-20 21:46:38 +08:00
|
|
|
|
const isLoginReady = ref<boolean>(false); // 登录是否准备就绪
|
|
|
|
|
|
// 编辑组件的引用,用于获取表单数据
|
|
|
|
|
|
const jfEditRef = ref<any>(null);
|
|
|
|
|
|
// 遮罩层状态
|
|
|
|
|
|
const loading = ref<boolean>(false);
|
|
|
|
|
|
const loadingText = ref<string>("处理中...");
|
|
|
|
|
|
// 数据加载状态
|
|
|
|
|
|
const jfInfoLoaded = ref<boolean>(false); // 流程数据是否已加载
|
|
|
|
|
|
const jfEditLoaded = ref<boolean>(false); // 编辑组件数据是否已加载
|
|
|
|
|
|
// 是否已办(dbZt === "B" 表示已办)
|
|
|
|
|
|
const dbZtFromUrl = ref<string>("");
|
|
|
|
|
|
// 直接用一个 ref 保存 xxtsId
|
|
|
|
|
|
const xxtsId = ref<string>("");
|
|
|
|
|
|
const isYiban = computed(() => {
|
|
|
|
|
|
return dbZtFromUrl.value === "B";
|
|
|
|
|
|
});
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 审批参数(只包含审批相关字段,业务字段通过 save 接口保存)
|
|
|
|
|
|
const spParams = computed(() => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
xxtsId: xxtsId.value,
|
|
|
|
|
|
ywId: jfId.value,
|
|
|
|
|
|
// 业务字段已通过 save 接口保存,这里不再传递
|
|
|
|
|
|
};
|
|
|
|
|
|
});
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 读取流程详情(用于审批时获取最新数据)
|
2025-12-08 20:03:34 +08:00
|
|
|
|
const getJfInfo = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res: any = await jfFlowByIdApi({ id: jfId.value });
|
|
|
|
|
|
if (res && res.resultCode === 1 && res.result) {
|
|
|
|
|
|
jfInfo.value = res.result.jfInfo || {};
|
|
|
|
|
|
const spResult = jfInfo.value?.spResult;
|
2025-12-20 21:46:38 +08:00
|
|
|
|
const spJd = jfInfo.value?.spJd;
|
|
|
|
|
|
|
|
|
|
|
|
// 已完结或驳回:隐藏审批按钮
|
|
|
|
|
|
if (spResult === "C" || (spJd === "Z" && spResult === "B")) {
|
|
|
|
|
|
showButton.value = false;
|
|
|
|
|
|
} else if (spResult && spResult !== "A" && dbZtFromUrl.value === "A") {
|
|
|
|
|
|
// 历史逻辑:当流程已完成且待办状态关闭时,不显示审批按钮
|
2025-12-08 20:03:34 +08:00
|
|
|
|
showButton.value = false;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showButton.value = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showButton.value = false;
|
|
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
jfInfoLoaded.value = true;
|
|
|
|
|
|
checkAllDataLoaded();
|
2025-12-08 20:03:34 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error("获取积分流程失败:", error);
|
|
|
|
|
|
showButton.value = false;
|
2025-12-20 21:46:38 +08:00
|
|
|
|
jfInfoLoaded.value = true;
|
|
|
|
|
|
checkAllDataLoaded();
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 获取编辑组件的表单数据
|
|
|
|
|
|
const getJfEditFormData = () => {
|
|
|
|
|
|
if (!jfEditRef.value) {
|
|
|
|
|
|
console.warn('JfEdit 组件引用不存在');
|
|
|
|
|
|
return null;
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 通过 ref 访问子组件的 formData
|
|
|
|
|
|
const formData = jfEditRef.value.formData;
|
|
|
|
|
|
if (!formData) {
|
|
|
|
|
|
console.warn('无法从 JfEdit 组件获取 formData');
|
|
|
|
|
|
return null;
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
console.log('获取到表单数据:', formData);
|
|
|
|
|
|
return formData;
|
|
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 保存编辑组件数据(审批前调用)
|
|
|
|
|
|
const saveJfDataBeforeApprove = async () => {
|
|
|
|
|
|
console.log('开始保存编辑组件数据...');
|
|
|
|
|
|
console.log('jfEditRef.value:', jfEditRef.value);
|
|
|
|
|
|
|
|
|
|
|
|
// 显示遮罩层
|
|
|
|
|
|
loading.value = true;
|
|
|
|
|
|
loadingText.value = '正在保存数据...';
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 等待一下,确保组件已挂载
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
|
|
|
|
|
|
|
|
const formData = getJfEditFormData();
|
|
|
|
|
|
if (!formData) {
|
|
|
|
|
|
console.error('无法获取表单数据');
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
return { success: false, message: '无法获取表单数据,请确保编辑组件已加载' };
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
|
|
|
|
|
|
// 验证必要字段
|
|
|
|
|
|
if (!formData.jfTypeId) {
|
|
|
|
|
|
console.warn('表单数据缺少 jfTypeId');
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
return { success: false, message: '请先选择业绩类别' };
|
|
|
|
|
|
}
|
|
|
|
|
|
const jfTypeId = typeof formData.jfTypeId === 'object' && formData.jfTypeId !== null
|
|
|
|
|
|
? formData.jfTypeId.value
|
|
|
|
|
|
: formData.jfTypeId;
|
|
|
|
|
|
|
|
|
|
|
|
let hjtime = formData.hjtime;
|
|
|
|
|
|
if (hjtime && hjtime.length === 7 && hjtime.match(/^\d{4}-\d{2}$/)) {
|
|
|
|
|
|
hjtime = hjtime + '-01';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let fileUrl = '';
|
|
|
|
|
|
let fileName = '';
|
|
|
|
|
|
let fileFormat = '';
|
|
|
|
|
|
if (formData.attachments && formData.attachments.length > 0) {
|
|
|
|
|
|
const urls: string[] = [];
|
|
|
|
|
|
const names: string[] = [];
|
|
|
|
|
|
const exts: string[] = [];
|
|
|
|
|
|
formData.attachments.forEach((att: any) => {
|
|
|
|
|
|
if (att.url) urls.push(att.url);
|
|
|
|
|
|
if (att.name) names.push(att.name);
|
|
|
|
|
|
const ext = (att.name || '').split('.').pop()?.toLowerCase() || '';
|
|
|
|
|
|
if (ext) exts.push(ext);
|
|
|
|
|
|
});
|
|
|
|
|
|
fileUrl = urls.join(',');
|
|
|
|
|
|
fileName = names.join(',');
|
|
|
|
|
|
fileFormat = exts.join(',');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前用户信息,设置考核人
|
|
|
|
|
|
const js = getJs;
|
|
|
|
|
|
let khJsId = '';
|
|
|
|
|
|
let khjsxm = '';
|
|
|
|
|
|
if (js) {
|
|
|
|
|
|
khJsId = js.id || '';
|
|
|
|
|
|
khjsxm = js.jsxm || js.xm || '';
|
|
|
|
|
|
}
|
|
|
|
|
|
// 设置考核时间为今天
|
|
|
|
|
|
const today = new Date();
|
|
|
|
|
|
const khTime = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`;
|
|
|
|
|
|
|
|
|
|
|
|
const submitData: any = {
|
|
|
|
|
|
...formData,
|
|
|
|
|
|
id: jfId.value, // 确保有ID
|
|
|
|
|
|
jfTypeId: jfTypeId,
|
|
|
|
|
|
hjtime: hjtime,
|
|
|
|
|
|
fileUrl: fileUrl,
|
|
|
|
|
|
fileName: fileName,
|
|
|
|
|
|
fileFormat: fileFormat,
|
|
|
|
|
|
khJsId: khJsId,
|
|
|
|
|
|
khjsxm: khjsxm,
|
|
|
|
|
|
khTime: khTime,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
delete submitData.attachments;
|
|
|
|
|
|
|
|
|
|
|
|
// 处理学生获奖名单:转换为 studentList 格式(只保存有效状态的学生)
|
|
|
|
|
|
// 注意:需要判断是否需要保存学生名单(根据 showStudentAward 或 formData 中的标识)
|
|
|
|
|
|
if (formData.hjmdList && Array.isArray(formData.hjmdList) && formData.hjmdList.length > 0) {
|
|
|
|
|
|
const validStudents = formData.hjmdList.filter((s: any) => s.status !== 'D');
|
|
|
|
|
|
submitData.studentList = validStudents.map((student: any) => {
|
|
|
|
|
|
// 如果没有 bc,根据 njbc、njmc、bjmc 组合生成
|
|
|
|
|
|
let bc = student.bc;
|
|
|
|
|
|
if (!bc && (student.njmc || student.njbc || student.bjmc)) {
|
|
|
|
|
|
const parts: string[] = [];
|
|
|
|
|
|
if (student.njmc) parts.push(student.njmc);
|
|
|
|
|
|
if (student.njbc) parts.push(`(${student.njbc})`);
|
|
|
|
|
|
if (student.bjmc) parts.push(student.bjmc);
|
|
|
|
|
|
bc = parts.join('');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
id: student.id, // 编辑时保留ID
|
|
|
|
|
|
xsId: student.xsId,
|
|
|
|
|
|
xsxm: student.xsxm,
|
|
|
|
|
|
njId: student.njId,
|
|
|
|
|
|
njmcId: student.njmcId,
|
|
|
|
|
|
bjId: student.bjId,
|
|
|
|
|
|
njbc: student.njbc,
|
|
|
|
|
|
njmc: student.njmc,
|
|
|
|
|
|
bjmc: student.bjmc,
|
|
|
|
|
|
bc: bc || '',
|
|
|
|
|
|
status: student.status || 'A',
|
|
|
|
|
|
remark: student.remark || ''
|
|
|
|
|
|
};
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果没有学生,传递空数组(用于删除所有学生)
|
|
|
|
|
|
submitData.studentList = [];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('准备调用保存接口,数据:', submitData);
|
|
|
|
|
|
const res: any = await jfSaveApi(submitData);
|
|
|
|
|
|
console.log('保存接口返回:', res);
|
|
|
|
|
|
|
|
|
|
|
|
if (res && res.resultCode === 1) {
|
|
|
|
|
|
console.log('数据保存成功(包含学生获奖名单)');
|
|
|
|
|
|
|
|
|
|
|
|
// 保存成功后,更新 jfInfo 用于审批参数
|
|
|
|
|
|
await getJfInfo();
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
return { success: true };
|
|
|
|
|
|
} else {
|
|
|
|
|
|
console.error('数据保存失败:', res?.resultMsg);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
return { success: false, message: res?.resultMsg || '保存失败' };
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('保存数据失败:', error);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
return { success: false, message: '保存数据失败' };
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 包装审批接口,先保存数据再审批
|
|
|
|
|
|
const wrappedJfSpApi = async (params: any) => {
|
|
|
|
|
|
console.log('审批接口被调用,参数:', params);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 先保存编辑组件的数据
|
|
|
|
|
|
console.log('步骤1: 保存编辑组件数据');
|
|
|
|
|
|
const saveResult = await saveJfDataBeforeApprove();
|
|
|
|
|
|
|
|
|
|
|
|
if (!saveResult.success) {
|
|
|
|
|
|
console.error('保存数据失败:', saveResult.message);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: saveResult.message || '保存数据失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration: 2000
|
|
|
|
|
|
});
|
|
|
|
|
|
throw new Error(saveResult.message || '保存数据失败');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log('步骤2: 数据保存成功,开始审批');
|
|
|
|
|
|
loadingText.value = '正在审批...';
|
|
|
|
|
|
|
|
|
|
|
|
// 保存成功后,再调用审批接口(只传递审批相关参数,不传递业务字段)
|
|
|
|
|
|
const spParams = {
|
|
|
|
|
|
xxtsId: params.xxtsId,
|
|
|
|
|
|
ywId: params.ywId,
|
|
|
|
|
|
spStatus: params.spStatus,
|
|
|
|
|
|
spRemark: params.spRemark
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log('步骤3: 调用审批接口,参数:', spParams);
|
|
|
|
|
|
const result = await jfSpApi(spParams);
|
|
|
|
|
|
console.log('审批接口返回:', result);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
return result;
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
console.error('审批流程出错:', error);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
throw error;
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 包装转办接口,先保存数据再转办
|
|
|
|
|
|
const wrappedJfTransferApi = async (params: any) => {
|
|
|
|
|
|
console.log('转办接口被调用,参数:', params);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 先保存编辑组件的数据
|
|
|
|
|
|
console.log('步骤1: 保存编辑组件数据');
|
|
|
|
|
|
const saveResult = await saveJfDataBeforeApprove();
|
|
|
|
|
|
|
|
|
|
|
|
if (!saveResult.success) {
|
|
|
|
|
|
console.error('保存数据失败:', saveResult.message);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: saveResult.message || '保存数据失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration: 2000
|
|
|
|
|
|
});
|
|
|
|
|
|
throw new Error(saveResult.message || '保存数据失败');
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
|
|
|
|
|
|
console.log('步骤2: 数据保存成功,开始转办');
|
|
|
|
|
|
loadingText.value = '正在转办...';
|
|
|
|
|
|
|
|
|
|
|
|
// 保存成功后,再调用转办接口
|
|
|
|
|
|
const transferParams = {
|
|
|
|
|
|
xxtsId: params.xxtsId,
|
|
|
|
|
|
ywId: params.ywId,
|
|
|
|
|
|
zbrIds: params.zbrIds,
|
|
|
|
|
|
csrIds: params.csrIds,
|
|
|
|
|
|
spRemark: params.spRemark,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log('步骤3: 调用转办接口,参数:', transferParams);
|
|
|
|
|
|
const result = await jfTransferApi(transferParams);
|
|
|
|
|
|
console.log('转办接口返回:', result);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
return result;
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
console.error('转办流程出错:', error);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 包装终止接口,先保存数据再终止
|
|
|
|
|
|
const wrappedJfStopApi = async (params: any) => {
|
|
|
|
|
|
console.log('终止接口被调用,参数:', params);
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 先保存编辑组件的数据
|
|
|
|
|
|
console.log('步骤1: 保存编辑组件数据');
|
|
|
|
|
|
const saveResult = await saveJfDataBeforeApprove();
|
|
|
|
|
|
|
|
|
|
|
|
if (!saveResult.success) {
|
|
|
|
|
|
console.error('保存数据失败:', saveResult.message);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: saveResult.message || '保存数据失败',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration: 2000
|
|
|
|
|
|
});
|
|
|
|
|
|
throw new Error(saveResult.message || '保存数据失败');
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
|
|
|
|
|
|
console.log('步骤2: 数据保存成功,开始终止');
|
|
|
|
|
|
loadingText.value = '正在终止...';
|
|
|
|
|
|
|
|
|
|
|
|
// 保存成功后,再调用终止接口
|
|
|
|
|
|
const stopParams = {
|
|
|
|
|
|
xxtsId: params.xxtsId,
|
|
|
|
|
|
ywId: params.ywId,
|
|
|
|
|
|
spRemark: params.spRemark,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
console.log('步骤3: 调用终止接口,参数:', stopParams);
|
|
|
|
|
|
const result = await jfStopApi(stopParams);
|
|
|
|
|
|
console.log('终止接口返回:', result);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
return result;
|
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
|
console.error('终止流程出错:', error);
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
throw error;
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 处理编辑组件数据加载完成
|
|
|
|
|
|
const handleJfEditLoaded = () => {
|
|
|
|
|
|
jfEditLoaded.value = true;
|
|
|
|
|
|
checkAllDataLoaded();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 检查所有数据是否已加载完成
|
|
|
|
|
|
const checkAllDataLoaded = () => {
|
|
|
|
|
|
if (jfInfoLoaded.value && jfEditLoaded.value) {
|
|
|
|
|
|
// 延迟一点时间,确保界面渲染完成
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
loading.value = false;
|
|
|
|
|
|
}, 300);
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 处理数据保存后的回调
|
|
|
|
|
|
const handleDataSaved = async () => {
|
|
|
|
|
|
// 数据保存后,重新获取最新数据用于审批
|
|
|
|
|
|
await getJfInfo();
|
|
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 处理审批操作完成后的跳转
|
|
|
|
|
|
const handleSubmit = () => {
|
|
|
|
|
|
navigateToIndex();
|
|
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
const handleReject = () => {
|
|
|
|
|
|
navigateToIndex();
|
|
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
const handleTransfer = () => {
|
|
|
|
|
|
navigateToIndex();
|
|
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
const handleStop = () => {
|
|
|
|
|
|
navigateToIndex();
|
|
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 跳转回审批列表页面
|
|
|
|
|
|
const navigateToIndex = () => {
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
uni.redirectTo({
|
|
|
|
|
|
url: '/pages/view/routine/JiFenPingJia/jfsp/index'
|
|
|
|
|
|
});
|
|
|
|
|
|
}, 500);
|
|
|
|
|
|
};
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 返回按钮监听(仅 App 端生效,H5 端已在 ImagePreviewWithRotate 组件内部处理)
|
|
|
|
|
|
onBackPress(() => {
|
|
|
|
|
|
// 检查 JfEdit 子组件是否正在预览图片
|
|
|
|
|
|
if (jfEditRef.value && jfEditRef.value.certificateUploadRef) {
|
|
|
|
|
|
const certUpload = jfEditRef.value.certificateUploadRef;
|
|
|
|
|
|
const isPreviewing = certUpload.isPreviewing;
|
|
|
|
|
|
if (isPreviewing) {
|
|
|
|
|
|
// 如果正在预览图片,关闭预览并阻止返回
|
|
|
|
|
|
certUpload.closePreview();
|
|
|
|
|
|
return true; // 阻止默认返回行为
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 没有预览图片,允许正常返回
|
|
|
|
|
|
return false;
|
|
|
|
|
|
});
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
onLoad(async (options: any) => {
|
|
|
|
|
|
if (!options || !options.id) {
|
|
|
|
|
|
uni.showToast({ title: "缺少积分ID", icon: "none" });
|
|
|
|
|
|
setTimeout(() => uni.navigateBack(), 1500);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 如果有 openId,先进行认证(防止 token 过期)
|
|
|
|
|
|
if (options.openId) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const loginSuccess = await loginByOpenId(options.openId);
|
|
|
|
|
|
if (!loginSuccess) {
|
|
|
|
|
|
// 登录失败,停止后续流程
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 等待一下,确保 token 已保存到 store 中
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.error("openId认证失败:", e);
|
|
|
|
|
|
// 认证失败,停止后续流程
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 标记登录准备就绪,允许组件开始加载数据(无论是否有 openId)
|
|
|
|
|
|
isLoginReady.value = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 显示遮罩层
|
|
|
|
|
|
loading.value = true;
|
|
|
|
|
|
loadingText.value = '正在加载数据...';
|
|
|
|
|
|
// 重置加载状态
|
|
|
|
|
|
jfInfoLoaded.value = false;
|
|
|
|
|
|
jfEditLoaded.value = false;
|
|
|
|
|
|
|
|
|
|
|
|
let actualJfId = options.id; // 默认使用传入的 ID
|
|
|
|
|
|
|
|
|
|
|
|
// 如果是从待办进入的(from=db),需要先获取 xxts 信息,然后获取业务 ID
|
|
|
|
|
|
if (options.from === 'db') {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 从后端根据 url 中的 id(xxts ID)查询待办信息
|
|
|
|
|
|
const xxtsRes = await xxtsFindByIdApi({ id: options.id });
|
|
|
|
|
|
|
|
|
|
|
|
if (xxtsRes && xxtsRes.result) {
|
|
|
|
|
|
const xxts = xxtsRes.result;
|
|
|
|
|
|
|
|
|
|
|
|
// 直接保存 xxtsId
|
|
|
|
|
|
if (xxts.id) {
|
|
|
|
|
|
xxtsId.value = xxts.id;
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
|
|
|
|
|
|
// 从 xxts 中获取业务 ID(xxzbId)
|
|
|
|
|
|
if (xxts.xxzbId) {
|
|
|
|
|
|
actualJfId = xxts.xxzbId;
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
|
|
|
|
|
|
// 从 xxts 获取 dbZt
|
|
|
|
|
|
if (xxts.dbZt) {
|
|
|
|
|
|
dbZtFromUrl.value = xxts.dbZt;
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取待办信息失败:', error);
|
|
|
|
|
|
// 如果获取失败,继续使用原始 ID
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果不是从待办进入,检查 URL 参数中是否有 xxtsId
|
|
|
|
|
|
if (options.xxtsId) {
|
|
|
|
|
|
xxtsId.value = options.xxtsId;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从 URL 参数获取 dbZt(如果传递了的话)
|
|
|
|
|
|
if (options.dbZt) {
|
|
|
|
|
|
dbZtFromUrl.value = options.dbZt;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
// 使用实际的业务 ID
|
|
|
|
|
|
jfId.value = actualJfId;
|
|
|
|
|
|
|
|
|
|
|
|
getJfInfo();
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.unified-scroll {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
height: calc(100vh - 120rpx);
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
}
|
2025-12-08 20:03:34 +08:00
|
|
|
|
|
2025-12-20 21:46:38 +08:00
|
|
|
|
.flow-section {
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
margin-top: 30rpx;
|
|
|
|
|
|
|
|
|
|
|
|
// 确保流程组件与编辑组件有间距
|
|
|
|
|
|
:deep(.lcgl-info) {
|
|
|
|
|
|
padding-top: 0;
|
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
|
padding-left: 0;
|
|
|
|
|
|
padding-right: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 流程组件的 section 也要移除左右边距
|
|
|
|
|
|
:deep(.info-section) {
|
|
|
|
|
|
border-radius: 0;
|
|
|
|
|
|
margin-left: 0;
|
|
|
|
|
|
margin-right: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 统一滚动容器的样式
|
|
|
|
|
|
.unified-scroll {
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 遮罩层样式
|
|
|
|
|
|
.loading-mask {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
right: 0;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
z-index: 9999;
|
|
|
|
|
|
|
|
|
|
|
|
.loading-content {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
padding: 60rpx 80rpx;
|
|
|
|
|
|
min-width: 300rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.loading-spinner {
|
|
|
|
|
|
width: 60rpx;
|
|
|
|
|
|
height: 60rpx;
|
|
|
|
|
|
border: 6rpx solid #f3f3f3;
|
|
|
|
|
|
border-top: 6rpx solid #007aff;
|
|
|
|
|
|
border-radius: 50%;
|
|
|
|
|
|
animation: spin 1s linear infinite;
|
|
|
|
|
|
margin-bottom: 30rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.loading-text {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
color: #333333;
|
|
|
|
|
|
text-align: center;
|
2025-12-08 20:03:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-20 21:46:38 +08:00
|
|
|
|
|
|
|
|
|
|
@keyframes spin {
|
|
|
|
|
|
0% { transform: rotate(0deg); }
|
|
|
|
|
|
100% { transform: rotate(360deg); }
|
|
|
|
|
|
}
|
2025-12-08 20:03:34 +08:00
|
|
|
|
</style>
|
|
|
|
|
|
|