数据库异动:https://huzlblog.com/zhishi/1032
主要实现对比两个json的不同点
Show组件:
<template>表格清单:
<el-dialog
:model-value="modelValue"
@update:model-value="$emit('update:modelValue', $event)"
:title="`数据变更详情 - ID: ${safeData.auditID || '无'}`"
width="80%"
top="5vh"
>
<!-- 调试信息 -->
<el-alert
v-if="debugMode"
title="调试信息"
type="info"
class="mb-4"
:closable="false"
>
<pre>接收到的props: {{ JSON.stringify(props.auditItem, null, 2) }}</pre>
<pre>标准化后数据: {{ JSON.stringify(safeData, null, 2) }}</pre>
</el-alert>
<el-descriptions :column="2" border>
<el-descriptions-item label="表名">
{{ safeData.tableName || "无" }}
</el-descriptions-item>
<el-descriptions-item label="主键">
{{ safeData.primaryKeyValue || "无" }}
</el-descriptions-item>
<el-descriptions-item label="操作时间">
{{ formatTime(safeData.changeTime) }}
</el-descriptions-item>
<el-descriptions-item label="操作人">
{{ safeData.changedBy || "无" }}
</el-descriptions-item>
</el-descriptions>
<el-table
width="100%"
:data="formatToTableData(parsedOldData, parsedNewData)"
border
highlight-current-row
>
<el-table-column prop="key" label="字段名" width="180" />
<el-table-column label="旧值">
<template #default="{ row }">
<span :class="{ 'diff-modified': row.hasChange }">
{{ row.oldValue ?? "无" }}
</span>
</template>
</el-table-column>
<el-table-column label="新值">
<template #default="{ row }">
<span :class="{ 'diff-added': row.hasChange }">
{{ row.newValue ?? "无" }}
</span>
</template>
</el-table-column>
</el-table>
<template #footer>
<el-button @click="debugMode = !debugMode">
{{ debugMode ? "隐藏调试" : "显示调试" }}
</el-button>
<el-button @click="$emit('update:modelValue', false)">关闭</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { computed, ref } from "vue";
import dayjs from "dayjs";
const props = defineProps({
modelValue: Boolean,
auditItem: {
type: Object,
default: () => ({}), // 默认空对象而非null
},
});
const emit = defineEmits(["update:modelValue"]);
const debugMode = ref(false);
// 安全数据访问(兼容大小写和空值)
const safeData = computed(() => {
return {
auditID: props.auditItem?.auditID ?? props.auditItem?.AuditID,
tableName: props.auditItem?.tableName ?? props.auditItem?.TableName,
operationType:
props.auditItem?.operationType ?? props.auditItem?.OperationType,
primaryKeyValue:
props.auditItem?.primaryKeyValue ?? props.auditItem?.PrimaryKeyValue,
oldData: props.auditItem?.oldData ?? props.auditItem?.OldData,
newData: props.auditItem?.newData ?? props.auditItem?.NewData,
changeTime: props.auditItem?.changeTime ?? props.auditItem?.ChangeTime,
changedBy: props.auditItem?.changedBy ?? props.auditItem?.ChangedBy,
};
});
// 格式化时间
const formatTime = (time) => {
return time ? dayjs(time).format("YYYY-MM-DD HH:mm:ss") : "无时间信息";
};
const parseJsonData = (data) => {
if (!data) return null;
try {
// 处理已经是对象的情况
if (typeof data === "object") return data;
// 处理JSON字符串
let parsed = JSON.parse(data);
// 处理可能是双重JSON字符串的情况
while (typeof parsed === "string") {
parsed = JSON.parse(parsed);
}
// 提取数组中的第一个对象
if (Array.isArray(parsed)) {
return parsed.length > 0 ? parsed[0] : {};
}
return parsed;
} catch (error) {
console.error("JSON解析失败:", error, "原始数据:", data);
return {
error: "数据解析失败",
rawData: data,
};
}
};
// 计算属性
const parsedOldData = computed(() => {
const result = parseJsonData(safeData.value.oldData);
console.log("旧数据解析结果:", result);
return result;
});
const parsedNewData = computed(() => {
const result = parseJsonData(safeData.value.newData);
console.log("新数据解析结果:", result);
return result;
});
// 转换数据函数(增加变更检测)
const formatToTableData = (oldData, newData) => {
const allKeys = new Set([
...Object.keys(oldData || {}),
...Object.keys(newData || {}),
]);
return Array.from(allKeys).map((key) => ({
key,
oldValue: oldData?.[key],
newValue: newData?.[key],
hasChange: !isEqual(oldData?.[key], newData?.[key]),
}));
};
// 简单对象比较
const isEqual = (a, b) => {
return JSON.stringify(a) === JSON.stringify(b);
};
</script>
<style>
.diff-modified {
background-color: #f5705c;
text-decoration: line-through;
padding: 10px;
}
.diff-added {
background-color: #9cf048;
padding: 10px;
}
</style>
<template>实现效果:
<div class="app-container">
<el-table
v-loading="listLoading"
width="100%"
border
ref="tableSortRef"
:data="list"
>
<el-table-column prop="auditID" label="ID" width="80" />
<el-table-column prop="tableName" label="表名" />
<el-table-column label="操作类型" width="100">
<template #default="{ row }">
<el-tag :type="getOperationTypeColor(row.operationType)">
{{ getOperationTypeText(row.operationType) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="primaryKeyValue" label="主键" />
<el-table-column prop="changedBy" label="操作人" />
<el-table-column prop="changeTime" label="操作时间" />
<el-table-column label="操作" width="120">
<template #default="scope">
<el-button size="small" @click="showDetail(scope.row)" :icon="View">
详情
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-if="total > 0"
v-model:total="total"
v-model:page="queryForm.startIndex"
v-model:limit="queryForm.pageSize"
@pagination="fetchData"
/>
<show v-model="dialogVisible" :audit-item="selectedItem" />
</div>
</template>
<script>
import apiService from "@/api/ApiService";
import dayjs from "dayjs";
export default defineComponent({
setup() {
const state = reactive({
tableSortRef: null,
list: [],
listLoading: true,
layout: "total, sizes, prev, pager, next, jumper",
total: 0,
dialogVisible: false,
selectedItem: null,
queryForm: {
startIndex: 1,
pageSize: 20,
},
});
// 修复方法1:使用scope.row
const showDetail = (rowData) => {
console.log("行数据:", rowData);
state.selectedItem = JSON.parse(JSON.stringify(rowData)); // 深拷贝
state.dialogVisible = true;
};
const queryData = () => {
state.queryForm.startIndex = 1;
fetchData();
};
const fetchData = async () => {
state.listLoading = true;
try {
const res = await apiService.getList(
"/tableChangeAudit/get",
state.queryForm
);
console.log("data", JSON.stringify(res.data.data));
state.list = res.data.data;
if (state.queryForm.startIndex == 1) state.total = res.data.total;
} catch (err) {
console.error(err);
} finally {
state.listLoading = false;
}
};
onMounted(() => {
state["tableSortRef"].doLayout();
fetchData();
});
const getOperationTypeText = (type) => {
const map = { I: "新增", U: "修改", D: "删除" };
return map[type] || type;
};
const getOperationTypeColor = (type) => {
const colors = { I: "success", U: "warning", D: "danger" };
return colors[type] || "";
};
return {
...toRefs(state),
queryData,
fetchData,
showDetail,
getOperationTypeText,
getOperationTypeColor,
};
},
});
</script>
<style scoped>
.audit-log-container {
padding: 20px;
}
</style>
- 本文标题: 数据异动不同点对比
- 文章分类:【VueJS】
- 非特殊说明,本文版权归【胡同里的砖头】个人博客 所有,转载请注明出处.
- 上一篇:数据库异动记录