hldy_vue/src/views/synchronization/directive/directiveopelog/components/DirectiveOpeLogInfoCompare.vue

307 lines
7.9 KiB
Vue
Raw Normal View History

<template>
<a-spin :spinning="loading">
<div class="container2">
<a-row>
<a-col :span="24">
<a-table :dataSource="tableData" :columns="columns" :pagination="false" bordered size="small"
:rowClassName="setRowClassName">
<template #bodyCell="{ column, record }">
<!-- 旧数据 -->
<template v-if="column.dataIndex === 'oldValue'">
<template v-if="isImageField(record, column.dataIndex) && record.oldValue">
<JImageUpload :value="getFieldValue(record, column.dataIndex)" disabled />
</template>
<template v-else-if="record.fieldKey === 'mp3File' && record.oldValue">
<audio controls style="width: 200px; height: 30px;">
<source :src="getFileAccessHttpUrl(getFullUrl(record.oldValue))" type="audio/mpeg">
</audio>
</template>
<template v-else-if="record.fieldKey === 'mp4File' && record.oldValue">
<video controls style="width: 200px; max-height: 150px;">
<source :src="getFileAccessHttpUrl(getFullUrl(record.oldValue))" type="video/mp4">
</video>
</template>
<template v-else>
<span>{{ record[column.dataIndex] || '-' }}</span>
</template>
</template>
<!-- 新数据 -->
<template v-else-if="column.dataIndex === 'newValue'">
<template v-if="isImageField(record, column.dataIndex) && record.newValue">
<JImageUpload :value="getFieldValue(record, column.dataIndex)" disabled />
</template>
<template v-else-if="record.fieldKey === 'mp3File' && record.newValue">
<audio controls style="width: 200px; height: 30px;">
<source :src="getFileAccessHttpUrl(getFullUrl(record.newValue))" type="audio/mpeg">
</audio>
</template>
<template v-else-if="record.fieldKey === 'mp4File' && record.newValue">
<video controls style="width: 200px; max-height: 150px;">
<source :src="getFileAccessHttpUrl(getFullUrl(record.newValue))" type="video/mp4">
</video>
</template>
<template v-else>
<span>{{ record[column.dataIndex] || '-' }}</span>
</template>
</template>
</template>
</a-table>
</a-col>
</a-row>
</div>
</a-spin>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted } from 'vue';
import { Tag } from 'ant-design-vue';
import JImageUpload from '/@/components/Form/src/jeecg/components/JImageUpload.vue';
import { list } from '../DirectiveOpeLogInfo.api';
import { getFileAccessHttpUrl } from '/@/utils/common/compUtils';
const loading = ref(false);
const oldData = ref<Record<string, any>>({});
const newData = ref<Record<string, any>>({});
// 字段映射,用于显示中文名称
const fieldLabels: Record<string, string> = {
instructionTagName: '分类标签',
categoryName: '服务类别',
typeName: '服务类型',
directiveName: '服务指令',
tollPrice: '收费价格(元)',
comPrice: '提成价格(元)',
cycleType_dictText: '周期类型',
serviceContent: '服务说明',
serviceDuration: '服务时长(分钟)',
mp3File: '语音文件',
mp4File: '视频文件',
previewFile: '预览图片(大)',
previewFileSmall: '预览图片(小)',
immediateFile: '即时指令图片',
immediateFileFocus: '即时指令焦点图片',
};
// 需要显示的字段顺序
const displayFields = [
'instructionTagName',
'categoryName',
'typeName',
'directiveName',
'cycleType_dictText',
'tollPrice',
'comPrice',
'serviceDuration',
'previewFile',
'previewFileSmall',
'mp3File',
'mp4File',
'immediateFile',
'immediateFileFocus',
'serviceContent',
];
// 表格列定义
const columns = computed(() => [
{
title: '字段',
dataIndex: 'field',
key: 'field',
ellipsis: false
},
{
title: '旧数据',
dataIndex: 'oldValue',
key: 'oldValue',
width: '45%',
ellipsis: false
},
{
title: '新数据',
dataIndex: 'newValue',
key: 'newValue',
width: '45%',
ellipsis: false
}
]);
// 表格数据
const tableData = computed(() => {
return displayFields.map(field => {
// 修正:正确处理字段值
let oldValue = oldData.value[field];
let newValue = newData.value[field];
return {
key: field,
field: fieldLabels[field] || field,
fieldKey: field,
oldValue: oldValue,
newValue: newValue,
// 为了在模板中方便访问,添加原始字段
[field]: newValue,
// 添加原始数据的引用
oldDataRef: oldData,
newDataRef: newData
};
});
});
// 判断是否为图片字段
const isImageField = (record: any, columnDataIndex: string) => {
const imageFields = [
'previewFile',
'previewFileSmall',
'immediateFile',
'immediateFileFocus'
];
if (columnDataIndex == 'field') {
return false
} else {
return imageFields.includes(record.fieldKey);
}
};
// 获取字段值
const getFieldValue = (record: any, columnDataIndex: string) => {
if (columnDataIndex === 'oldValue') {
return record.oldValue;
} else if (columnDataIndex === 'newValue') {
return record.newValue;
} else if (columnDataIndex === 'field') {
return record.field;
}
return '';
};
// 获取完整的文件URL
const getFullUrl = (url: string) => {
if (!url) return '';
if (url.startsWith('http')) {
return url;
}
const baseUrl = '';
return baseUrl + url;
};
// 设置行类名,高亮显示有差异的行
const setRowClassName = (record: any) => {
if (record.oldValue !== record.newValue && record.fieldKey !== 'createTime') {
return 'highlight-row';
}
return '';
};
async function init(record_: any) {
try {
loading.value = true;
const data = await list({ 'pkId': record_.id });
if (data && data.records && data.records.length >= 2) {
const oldRecord = data.records.find((item: any) => item.dataType === '1');
const newRecord = data.records.find((item: any) => item.dataType === '2');
if (oldRecord) {
oldData.value = { ...oldRecord };
}
if (newRecord) {
newData.value = { ...newRecord };
}
} else if (data && data.records && data.records.length === 1) {
const record = data.records[0];
if (record.dataType === '1') {
oldData.value = { ...record };
newData.value = {};
} else if (record.dataType === '2') {
oldData.value = {};
newData.value = { ...record };
}
}
} catch (error) {
} finally {
loading.value = false;
}
}
defineExpose({
init
});
</script>
<style lang="less" scoped>
.container2 {
padding: 16px;
background: #fff;
}
:deep(.ant-table-cell) {
padding: 8px 12px !important;
}
// 高亮行样式
:deep(.highlight-row) {
background-color: #f0f9ff !important; // 浅蓝色背景,表示有变更
&:hover {
background-color: #e6f7ff !important;
}
}
// 差异高亮样式
:deep(.ant-table-row) {
.ant-table-cell {
&:nth-child(2),
// 旧数据列
&:nth-child(3) {
// 新数据列
.ant-image,
.ant-upload-list-item {
border: 1px solid #e8e8e8;
border-radius: 4px;
}
}
}
&.highlight-row {
.ant-table-cell {
&:nth-child(2),
// 旧数据列
&:nth-child(3) {
// 新数据列
background-color: #fff1f0 !important; // 差异数据浅红色背景
}
}
}
}
// 媒体文件样式调整
audio,
video {
vertical-align: middle;
background: #f5f5f5;
border-radius: 4px;
}
audio {
min-width: 200px;
}
video {
min-width: 200px;
min-height: 100px;
}
// 标签样式
.ant-tag {
margin: 0;
border: none;
font-size: 12px;
line-height: 20px;
}
</style>