feat(erp): 新增项目历史详细变更记录查看功能

dev
Yangk 2 weeks ago
parent 964bd8741d
commit 681b574beb

@ -108,3 +108,14 @@ export const queryProjectChangeByProjectPlanId = (projectPlanId: string | number
method: 'get' method: 'get'
}); });
}; };
/**
*
* @param projectId
*/
export const getProjectChangeHistory = (projectId: string | number): AxiosPromise<ErpProjectChangeVO[]> => {
return request({
url: '/oa/erp/erpProjectChange/queryHistoryByProjectId/' + projectId,
method: 'get'
});
};

@ -550,7 +550,6 @@ const loadFormData = async () => {
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
const dateOnly = toDateOnly(form.value.applyChangeDate); const dateOnly = toDateOnly(form.value.applyChangeDate);
form.value.applyChangeDate = dateOnly ?? formatToday(); form.value.applyChangeDate = dateOnly ?? formatToday();
// handleProjectChange/loadProjectDataByProjectId BigDecimal Number el-input-number
form.value.budgetList = (res.data.budgetList ?? []).map((item: any) => ({ form.value.budgetList = (res.data.budgetList ?? []).map((item: any) => ({
...item, ...item,
budgetBefore: Number(item.budgetBefore || 0), budgetBefore: Number(item.budgetBefore || 0),

@ -177,6 +177,10 @@
<el-tooltip v-if="scope.row.projectChangeStatus === '2' || scope.row.projectChangeStatus === '3'" content="审批记录" placement="top"> <el-tooltip v-if="scope.row.projectChangeStatus === '2' || scope.row.projectChangeStatus === '3'" content="审批记录" placement="top">
<el-button link type="info" icon="DocumentCopy" @click="handleApprovalRecord(scope.row)"></el-button> <el-button link type="info" icon="DocumentCopy" @click="handleApprovalRecord(scope.row)"></el-button>
</el-tooltip> </el-tooltip>
<!-- 历史变更记录按钮 -->
<el-tooltip content="查看历史变更记录" placement="top">
<el-button link type="warning" icon="Clock" @click="handleViewHistory(scope.row)"></el-button>
</el-tooltip>
<!-- 删除按钮草稿驳回或撤回状态显示 --> <!-- 删除按钮草稿驳回或撤回状态显示 -->
<el-tooltip <el-tooltip
v-if="scope.row.projectChangeStatus === '1' || scope.row.flowStatus === 'back' || scope.row.flowStatus === 'cancel'" v-if="scope.row.projectChangeStatus === '1' || scope.row.flowStatus === 'back' || scope.row.flowStatus === 'cancel'"
@ -199,11 +203,34 @@
</el-card> </el-card>
<!-- 审批记录 --> <!-- 审批记录 -->
<ApprovalRecord ref="approvalRecordRef" /> <ApprovalRecord ref="approvalRecordRef" />
<!-- 项目变更历史记录抽屉 -->
<el-drawer v-model="historyDrawer.visible" :title="historyDrawer.title" size="700px">
<el-timeline v-if="historyDrawer.list && historyDrawer.list.length > 0">
<el-timeline-item
v-for="(item, index) in historyDrawer.list"
:key="index"
:timestamp="`第 ${item.changeNumber} 次变更 (${parseTime(item.createTime, '{y}-{m}-{d} {h}:{i}')} 申请人: ${item.createName || '未知'})`"
placement="top"
type="primary"
size="large"
>
<el-card shadow="hover">
<div v-for="(msg, mIndex) in item.messages" :key="mIndex" style="margin-bottom: 15px; font-size: 14px; line-height: 1.5;">
<el-tag :type="msg.type === '预算变更' ? 'success' : 'warning'" size="small" style="margin-right: 10px;" effect="dark">{{ msg.type }}</el-tag>
<span style="color: #606266;">{{ msg.desc }}</span>
</div>
<div v-if="item.messages.length === 0" style="color: #909399; font-size: 13px;"></div>
</el-card>
</el-timeline-item>
</el-timeline>
<el-empty v-else description="暂无历史变更记录数据" />
</el-drawer>
</div> </div>
</template> </template>
<script setup name="ErpProjectChange" lang="ts"> <script setup name="ErpProjectChange" lang="ts">
import { delErpProjectChange, listErpProjectChange } from '@/api/oa/erp/erpProjectChange'; import { delErpProjectChange, listErpProjectChange, getProjectChangeHistory } from '@/api/oa/erp/erpProjectChange';
import { ErpProjectChangeQuery, ErpProjectChangeVO } from '@/api/oa/erp/erpProjectChange/types'; import { ErpProjectChangeQuery, ErpProjectChangeVO } from '@/api/oa/erp/erpProjectChange/types';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import { onActivated } from 'vue'; import { onActivated } from 'vue';
@ -215,8 +242,8 @@ const router = useRouter();
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>(); const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
const refreshFlagKey = 'erpProjectChangeListShouldRefresh'; const refreshFlagKey = 'erpProjectChangeListShouldRefresh';
const { active_flag, change_type, project_change_status, project_category, wf_business_status } = toRefs<any>( const { active_flag, change_type, project_change_status, project_category, wf_business_status, project_phases } = toRefs<any>(
proxy?.useDict('active_flag', 'change_type', 'project_change_status', 'project_category', 'wf_business_status') proxy?.useDict('active_flag', 'change_type', 'project_change_status', 'project_category', 'wf_business_status', 'project_phases')
); );
// //
@ -395,6 +422,126 @@ const handleApprovalRecord = (row: ErpProjectChangeVO) => {
approvalRecordRef.value?.init(row.projectChangeId); approvalRecordRef.value?.init(row.projectChangeId);
}; };
// ================ ================
const historyDrawer = reactive({
visible: false,
title: '',
list: [] as any[]
});
const handleViewHistory = async (row: any) => {
historyDrawer.title = `每一次变更的历史记录(${row.projectName}`;
historyDrawer.visible = true;
historyDrawer.list = [];
try {
proxy?.$modal.loading('正在提取变更历史记录...');
const res = await getProjectChangeHistory(row.projectId);
if (res.data) {
const records = res.data;
const historyList = [];
const previousBudget: Record<string, number> = {};
const previousProgressContent: Record<string, any> = {};
for (let i = 0; i < records.length; i++) {
const item = records[i];
const messages: any[] = [];
// 1.
if (item.budgetList && item.budgetList.length > 0) {
item.budgetList.forEach((budget: any) => {
const after = Number(budget.budgetAfter || 0);
const prev = previousBudget[budget.subjectName];
//
const before = prev !== undefined ? prev : Number(budget.budgetBefore || 0);
if (before !== after) {
messages.push({
type: '预算变更',
desc: `将预算变更中的【${budget.subjectName}】从变更前预算的 ${before.toFixed(2)} 变为变更后预算的 ${after.toFixed(2)}`
});
}
//
previousBudget[budget.subjectName] = after;
});
}
// 2.
if (item.progressList && item.progressList.length > 0) {
item.progressList.forEach((progress: any) => {
const phaseKey = progress.projectPhases;
const prev = previousProgressContent[phaseKey] || {
start: progress.originalStart,
end: progress.originalEnd,
milestone: ''
};
const diffs = [];
let startChanged = false;
let endChanged = false;
//
if (prev.start && progress.changedStart && prev.start !== progress.changedStart) {
diffs.push(`原计划时间起的 ${proxy?.parseTime(prev.start, '{y}-{m}-{d}')} 变为变更后时间起的 ${proxy?.parseTime(progress.changedStart, '{y}-{m}-{d}')}`);
startChanged = true;
}
//
if (prev.end && progress.changedEnd && prev.end !== progress.changedEnd) {
diffs.push(`原计划时间止的 ${proxy?.parseTime(prev.end, '{y}-{m}-{d}')} 变为变更后时间止的 ${proxy?.parseTime(progress.changedEnd, '{y}-{m}-{d}')}`);
endChanged = true;
}
//
let msDiff = '';
//
if (progress.milestoneName && prev.milestone !== progress.milestoneName) {
const oldName = prev.milestone ? `${prev.milestone}` : '空白';
msDiff = `里程碑名称从原来的${oldName}变为“${progress.milestoneName}`;
}
if (diffs.length > 0 || msDiff) {
const phaseLabel = proxy?.selectDictLabel(project_phases.value, progress.projectPhases) || progress.projectPhases || '未知';
const diffStr = diffs.join('');
let finalDescText = diffStr;
if (finalDescText && msDiff) {
finalDescText += `,同时将${msDiff}`;
} else if (msDiff) {
finalDescText = `${msDiff}`;
}
messages.push({
type: '进度变更',
desc: `将进度变更中【${phaseLabel}】阶段的 ` + finalDescText
});
}
//
previousProgressContent[phaseKey] = {
start: startChanged ? progress.changedStart : prev.start,
end: endChanged ? progress.changedEnd : prev.end,
milestone: progress.milestoneName
};
});
}
historyList.push({
changeNumber: item.changeNumber,
createTime: item.createTime,
createName: item.createName || item.projectManagerName,
messages: messages
});
}
historyDrawer.list = historyList;
}
} catch (error) {
console.error("加载变更历史记录失败", error);
} finally {
proxy?.$modal.closeLoading();
}
};
// ========================================================
/** 删除按钮操作 */ /** 删除按钮操作 */
const handleDelete = async (row?: ErpProjectChangeVO) => { const handleDelete = async (row?: ErpProjectChangeVO) => {
const _projectChangeIds = row?.projectChangeId || ids.value; const _projectChangeIds = row?.projectChangeId || ids.value;

Loading…
Cancel
Save