Files
SPDM/src/views/task/projectDetail/components/baseInfo.vue

270 lines
6.2 KiB
Vue

<template>
<div class="info-grid" v-if="enableConfigByTenant([TENANT_ENUM.LYRIC])">
<table class="info-table">
<tbody>
<tr>
<td>项目名称</td>
<td>{{ nodeInfo.nodeName }}</td>
</tr>
<tr>
<td>当前阶段</td>
<td>
{{ nodeInfo.currentPhase || '未设置' }}
</td>
</tr>
</tbody>
</table>
<table class="info-table">
<tbody>
<tr>
<td>项目代号</td>
<td>{{ nodeInfo.nodeCode }}</td>
</tr>
<tr>
<td>仿真专项代表</td>
<td>{{ nodeInfo.pMemberNames }}</td>
</tr>
</tbody>
</table>
</div>
<div class="info-grid" v-else>
<table class="info-table">
<tbody>
<tr>
<td>项目名称</td>
<td>{{ nodeInfo.nodeName }}</td>
</tr>
<tr>
<td>仿真专项代表</td>
<td>{{ nodeInfo.pMemberNames }}</td>
</tr>
<tr>
<td>项目状态</td>
<td>
<StatusDot
:status="projectStatus(nodeInfo.exeStatus)"
:title="PROJECT_EXE_STATUS.O[nodeInfo.exeStatus]"
/>
</td>
</tr>
<tr>
<td>计划开始时间</td>
<td>{{ nodeInfo.beginTime }}</td>
</tr>
<tr>
<td>当前阶段</td>
<td>
{{ nodeInfo.currentPhase || '未设置' }}
</td>
</tr>
</tbody>
</table>
<table class="info-table">
<tbody>
<tr>
<td>项目代号</td>
<td>{{ nodeInfo.nodeCode }}</td>
</tr>
<tr>
<td>创建人</td>
<td>{{ nodeInfo?.creatorObj?.nickname }}</td>
</tr>
<tr>
<td>创建时间</td>
<td>{{ nodeInfo.createTime }}</td>
</tr>
<tr>
<td>计划结束时间</td>
<td>{{ nodeInfo.endTime }}</td>
</tr>
<tr>
<td>备注</td>
<td>{{ nodeInfo.description }}</td>
</tr>
</tbody>
</table>
</div>
<!-- <el-descriptions title="" :column="2" border>
<el-descriptions-item label="项目名称">{{ nodeInfo.nodeName }}</el-descriptions-item>
<el-descriptions-item label="项目代号">{{ nodeInfo.nodeCode }}</el-descriptions-item>
<el-descriptions-item label="项目经理">{{ nodeInfo.pMemberNames }}</el-descriptions-item>
<el-descriptions-item label="创建人">{{ nodeInfo.creator }}</el-descriptions-item>
<el-descriptions-item label="项目状态">{{ nodeInfo.status }}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{ nodeInfo.createTime }}</el-descriptions-item>
<el-descriptions-item label="计划开始时间">{{ nodeInfo.beginTime }}</el-descriptions-item>
<el-descriptions-item label="计划结束时间">{{ nodeInfo.endTime }}</el-descriptions-item>
<el-descriptions-item label="当前阶段">{{ nodeInfo.currentPhase }}</el-descriptions-item>
<el-descriptions-item label="备注">{{ nodeInfo.description }}</el-descriptions-item>
</el-descriptions> -->
</template>
<script lang="ts" setup>
import { getNodeDetailApi } from '@/api/project/node';
import { onMounted, reactive, watch } from 'vue';
import { useDict } from '@/utils/useDict';
import StatusDot from '@/components/common/statusDot/index.vue';
import { projectStatus } from '@/components/common/statusDot/statusMap';
import { enableConfigByTenant, TENANT_ENUM } from '@/tenants/tenant';
const props = defineProps({
nodeId: {
type: String,
default: '',
},
});
const { PROJECT_EXE_STATUS } = useDict('PROJECT_EXE_STATUS');
const emits = defineEmits(['update:projectInfo', 'loaded']);
const nodeInfo = reactive<any>({
nodeName: '',
creator: '',
creatorObj: '',
exeStatusName: '',
exeStatus: '',
nodeCode: '',
createTime: '',
description: '',
memberList: [],
pMemberNames: '',
beginTime: '',
currentPhase: '',
endTime: '',
});
const getNodeDetailFun = async () => {
const res: any = await getNodeDetailApi({ projectNodeId: props.nodeId });
if (res.code === 200) {
for (const key in nodeInfo) {
// if (key === 'exeStatus') {
// nodeInfo[key] = res.data[key];
// nodeInfo.exeStatusName = res.data[key];
// } else {
nodeInfo[key] = res.data[key];
// }
}
if (Array.isArray(res.data.memberList)) {
nodeInfo.pMemberNames = res.data.memberList
.map((item: any) => {
return item.nickname || item.name || item.realName;
})
.join();
}
emits('update:projectInfo', res.data);
}
};
const updateBaseInfo = (info: any) => {
for (const key in nodeInfo) {
if (info[key]) {
nodeInfo[key] = info[key];
}
}
};
const refresh = async () => {
await getNodeDetailFun();
};
onMounted(() => {
// getNodeDetailFun();
});
defineExpose({
updateBaseInfo,
refresh,
});
watch(
() => props.nodeId,
async () => {
await getNodeDetailFun();
emits('loaded');
},
{ immediate: true }
);
</script>
<style scoped>
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 24px;
margin-top: 20px;
}
.info-table {
width: 100%;
border-collapse: collapse;
}
.info-table tr {
border-bottom: 1px solid #e9ecef;
transition: background-color 0.2s;
}
.info-table tr:last-child {
border-bottom: none;
}
.info-table tr:hover {
background-color: rgba(0, 0, 0, 0.02);
}
.info-table td {
padding: 12px 8px;
vertical-align: middle;
}
.info-table td:first-child {
width: 120px;
color: #8d99ae;
font-weight: 500;
font-size: 14px;
}
.info-table td:nth-child(2) {
color: #2b2d42;
font-weight: 500;
font-size: 14px;
}
.status-badge {
display: inline-block;
padding: 4px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 500;
}
.status-3 {
background-color: rgba(76, 201, 240, 0.1);
color: #4cc9f0;
}
.status-1 {
background-color: rgba(67, 97, 238, 0.1);
color: #4361ee;
}
.status-5 {
background-color: rgba(248, 37, 133, 0.1);
color: #f72585;
}
.status-2 {
background-color: rgba(248, 150, 30, 0.1);
color: #f8961e;
}
.status-0 {
background-color: rgba(248, 150, 30, 0.1);
color: #8d99ae;
}
.empty-value {
color: #8d99ae !important;
font-style: italic;
}
</style>