feat(日志管理): 开发日志管理功能。
fix(项目任务): 1、任务完成后需要依然能够修改工作日志,但是只能修改工作内容和上传附件。2、任务完成后,协办人的工作日志不应该能删除、所有任务里的成员不能新增工作日志,前端不显示新增、删除按钮。3、团队成员的面板,在成员排序时,让有下属的成员提前。4、在任务弹出框有个快速用执行的信息填充的icon。
This commit is contained in:
137
src/views/infra/log-management/shared/log-detail-dialog.vue
Normal file
137
src/views/infra/log-management/shared/log-detail-dialog.vue
Normal file
@@ -0,0 +1,137 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import BusinessFormDialog from '@/components/custom/business-form-dialog.vue';
|
||||
import BusinessFormSection from '@/components/custom/business-form-section.vue';
|
||||
import DictText from '@/components/custom/dict-text.vue';
|
||||
import { type LogDetailField, type LogDetailSection, formatDateTime, formatMultilineText, formatText } from '../shared';
|
||||
|
||||
defineOptions({ name: 'LogDetailDialog' });
|
||||
|
||||
type DetailRecord = { id: string };
|
||||
|
||||
const visible = defineModel<boolean>('visible', { default: false });
|
||||
|
||||
const props = defineProps<{
|
||||
title: string;
|
||||
rowData?: { id: string } | null;
|
||||
sections: LogDetailSection[];
|
||||
fetchDetail: (id: string) => Promise<{
|
||||
error: unknown;
|
||||
data: DetailRecord | null;
|
||||
}>;
|
||||
}>();
|
||||
|
||||
const loading = ref(false);
|
||||
const detail = ref<DetailRecord | null>(null);
|
||||
|
||||
watch(
|
||||
() => [visible.value, props.rowData?.id] as const,
|
||||
([isVisible]) => {
|
||||
if (!isVisible) return;
|
||||
loadDetail();
|
||||
}
|
||||
);
|
||||
|
||||
async function loadDetail() {
|
||||
if (!props.rowData?.id) {
|
||||
detail.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
const result = await props.fetchDetail(props.rowData.id);
|
||||
loading.value = false;
|
||||
|
||||
detail.value = !result.error && result.data ? result.data : null;
|
||||
}
|
||||
|
||||
function getFieldValue(field: LogDetailField) {
|
||||
if (!detail.value || !field.key) return undefined;
|
||||
return (detail.value as Record<string, unknown>)[field.key];
|
||||
}
|
||||
|
||||
function getDictFieldValue(field: LogDetailField): string | number | null | undefined {
|
||||
const value = getFieldValue(field);
|
||||
|
||||
if (value === null || value === undefined) {
|
||||
return value;
|
||||
}
|
||||
|
||||
return typeof value === 'string' || typeof value === 'number' ? value : String(value);
|
||||
}
|
||||
|
||||
function getFieldText(field: LogDetailField) {
|
||||
if (field.formatter && detail.value) {
|
||||
return field.formatter(detail.value);
|
||||
}
|
||||
|
||||
const value = getFieldValue(field);
|
||||
|
||||
if (field.type === 'datetime') {
|
||||
return formatDateTime(value as string | null | undefined);
|
||||
}
|
||||
|
||||
if (field.type === 'multiline') {
|
||||
return formatMultilineText(value);
|
||||
}
|
||||
|
||||
return formatText(value);
|
||||
}
|
||||
|
||||
function getFieldSpan(field: LogDetailField) {
|
||||
return field.span || (field.type === 'multiline' ? 2 : 1);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BusinessFormDialog v-model="visible" :title="title" preset="lg" :loading="loading" :show-footer="false">
|
||||
<div v-if="detail" class="log-detail-dialog">
|
||||
<BusinessFormSection v-for="section in sections" :key="section.title" :title="section.title">
|
||||
<ElDescriptions class="log-detail-dialog__descriptions" :column="2" border size="small">
|
||||
<ElDescriptionsItem
|
||||
v-for="field in section.fields"
|
||||
:key="`${section.title}-${field.label}`"
|
||||
:label="field.label"
|
||||
label-class-name="log-detail-dialog__label"
|
||||
:span="getFieldSpan(field)"
|
||||
>
|
||||
<DictText v-if="field.type === 'dict'" :dict-code="field.dictCode!" :value="getDictFieldValue(field)" />
|
||||
<div v-else-if="field.type === 'multiline'" class="log-detail-dialog__multiline">
|
||||
{{ getFieldText(field) }}
|
||||
</div>
|
||||
<span v-else>{{ getFieldText(field) }}</span>
|
||||
</ElDescriptionsItem>
|
||||
</ElDescriptions>
|
||||
</BusinessFormSection>
|
||||
</div>
|
||||
<ElEmpty v-else description="暂无日志详情" />
|
||||
</BusinessFormDialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.log-detail-dialog {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
:deep(.log-detail-dialog__descriptions .el-descriptions__cell) {
|
||||
line-height: 1.7;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
:deep(.log-detail-dialog__label) {
|
||||
width: 120px;
|
||||
min-width: 120px;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.log-detail-dialog__multiline {
|
||||
padding: 10px 12px;
|
||||
border-radius: 6px;
|
||||
background: var(--el-fill-color-light);
|
||||
color: var(--el-text-color-regular);
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user