日志记录修改

This commit is contained in:
luojiaquan
2026-09-30 16:57:44 +08:00
parent 02c281fd07
commit 903d19cad1
9 changed files with 794 additions and 101 deletions
@@ -0,0 +1,133 @@
<template>
<el-dialog
:model-value="modelValue"
@update:model-value="$emit('update:modelValue', $event)"
:title="`业务日志 - ${customerName || ''}`"
width="900px"
append-to-body
@open="handleOpen"
>
<div style="margin-bottom: 10px; color: #909399; font-size: 13px;">
客户编码:{{ customerCode || '-' }}
<span style="margin-left: 16px;">共 {{ logList.length }} 条日志(按操作时间倒序)</span>
</div>
<el-table v-loading="loading" :data="logList" border size="small" row-key="logId" :empty-text="'暂无业务日志'">
<el-table-column type="expand">
<template #default="scope">
<div style="padding: 8px 16px; background: #fafafa;">
<div v-if="!scope.row.changes || !scope.row.changes.length" style="color:#909399;">无字段明细</div>
<el-table v-else :data="scope.row.changes" border size="small">
<el-table-column label="字段" prop="fieldLabel" width="180" align="center" />
<el-table-column label="修改前" align="center">
<template #default="cell">
<span :style="{ color: cell.row.oldValue === '' ? '#909399' : '' }">{{ cell.row.oldValue === '' ? '(空)' : cell.row.oldValue }}</span>
</template>
</el-table-column>
<el-table-column label="修改后" align="center">
<template #default="cell">
<span :style="{ color: cell.row.newValue === '' ? '#909399' : '' }">{{ cell.row.newValue === '' ? '(空)' : cell.row.newValue }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
</el-table-column>
<el-table-column label="模块" align="center" width="92">
<template #default="scope">
<el-tag :type="moduleTagType(scope.row.bizModule)" size="small" effect="plain">{{ moduleLabel(scope.row.bizModule) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="76">
<template #default="scope">
<el-tag :type="opTagType(scope.row.operationType)" size="small">{{ opLabel(scope.row.operationType) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="对象" align="center" width="150" show-overflow-tooltip>
<template #default="scope">
<span :title="scope.row.bizName">{{ scope.row.bizName || '客户档案' }}</span>
</template>
</el-table-column>
<el-table-column label="操作人" align="center" width="130">
<template #default="scope">{{ scope.row.createByName || scope.row.createBy || '-' }}</template>
</el-table-column>
<el-table-column label="操作时间" align="center" width="160">
<template #default="scope">{{ fmtTime(scope.row.createTime) }}</template>
</el-table-column>
<el-table-column label="变更摘要" align="center">
<template #default="scope">
<span>{{ rowSummary(scope.row) }}</span>
</template>
</el-table-column>
</el-table>
<template #footer>
<el-button @click="$emit('update:modelValue', false)">关 闭</el-button>
</template>
</el-dialog>
</template>
<script setup>
import { listCustomerLog } from "@/api/customersuppliermanagement/customerinfo/customer.js"
const { proxy } = getCurrentInstance()
const props = defineProps({
modelValue: { type: Boolean, default: false },
customerId: { type: [Number, String], default: null },
customerName: { type: String, default: '' },
customerCode: { type: String, default: '' }
})
defineEmits(['update:modelValue'])
const loading = ref(false)
const logList = ref([])
const MODULE_META = {
main: { label: '客户档案', tag: '' },
company: { label: '公司主体', tag: 'success' },
contact: { label: '联系人', tag: 'warning' },
attachment: { label: '附件', tag: 'info' },
priceset: { label: '绑定套餐', tag: 'danger' }
}
const OP_META = {
'1': { label: '新建', tag: 'success' },
'2': { label: '修改', tag: 'warning' },
'3': { label: '删除', tag: 'danger' }
}
const moduleLabel = (m) => MODULE_META[m]?.label || '客户档案'
const moduleTagType = (m) => MODULE_META[m]?.tag ?? ''
const opLabel = (op) => OP_META[op]?.label || op
const opTagType = (op) => OP_META[op]?.tag || 'info'
const fmtTime = (t) => t ? proxy.parseTime(t, '{y}-{m}-{d} {h}:{i}:{s}') : '-'
const changeSummary = (changes) => {
if (!changes || !changes.length) return '-'
return changes.slice(0, 3).map(c => c.fieldLabel).join('、') + (changes.length > 3 ? ` 等${changes.length}项` : '')
}
const rowSummary = (row) => {
const mod = moduleLabel(row.bizModule)
const obj = row.bizName ? `「${row.bizName}」` : ''
if (row.operationType === '1') {
return `新建${mod}${obj},录入 ${row.changes?.length || 0} 项信息`
}
if (row.operationType === '2') {
return changeSummary(row.changes)
}
return `${mod}${obj}被删除`
}
const handleOpen = async () => {
if (!props.customerId) return
loading.value = true
try {
const res = await listCustomerLog(props.customerId)
logList.value = res.data || []
} finally {
loading.value = false
}
}
</script>
@@ -10,6 +10,7 @@
</div>
<div class="head-code">客户编码:{{ form.customerCode || '保存后可维护子表数据' }}</div>
<div class="head-right">
<el-button v-if="!isAdd" icon="Document" v-hasPermi="['customersupplier:customerinfo:query']" @click="logOpen = true">日 志</el-button>
<el-button @click="goBack">取 消</el-button>
<el-button v-if="isAdd" type="primary" :loading="saving" v-hasPermi="['customersupplier:customerinfo:add']" @click="submitForm">保 存</el-button>
<el-button v-else type="primary" :loading="saving" v-hasPermi="['customersupplier:customerinfo:edit']" @click="submitForm">保 存</el-button>
@@ -711,6 +712,14 @@
</div>
</template>
</el-dialog>
<!-- 客户业务操作日志弹窗 -->
<customer-log-dialog
v-model="logOpen"
:customer-id="form.customerId"
:customer-name="form.customerName"
:customer-code="form.customerCode"
/>
</div>
</template>
@@ -719,6 +728,7 @@ import {
listCustomer, getCustomer, addCustomer, updateCustomer,
delCustomerCompany, delCustomerContact
} from '@/api/customersuppliermanagement/customerinfo/customer.js'
import CustomerLogDialog from '../components/CustomerLogDialog.vue'
import {
listCustomerPriceSet, listPriceSetOption,
saveCustomerPriceSet, delCustomerPriceSet
@@ -740,6 +750,7 @@ const { ensureProducts, findProduct } = useProducts()
const pageLoading = ref(false)
const saving = ref(false)
const activeTab = ref('base')
const logOpen = ref(false)
const customerId = computed(() => route.query.customerId ? Number(route.query.customerId) : null)
const isAdd = computed(() => !customerId.value)
@@ -197,61 +197,19 @@
/>
<!-- 客户业务操作日志弹窗 -->
<el-dialog v-model="logOpen" :title="`业务日志 - ${logCustomer.customerName || ''}`" width="820px" append-to-body>
<div style="margin-bottom: 10px; color: #909399; font-size: 13px;">
客户编码:{{ logCustomer.customerCode || '-' }}
<span style="margin-left: 16px;">共 {{ logList.length }} 条日志(按操作时间倒序)</span>
</div>
<el-table v-loading="logLoading" :data="logList" border size="small" row-key="logId" :empty-text="'暂无业务日志'">
<el-table-column type="expand">
<template #default="scope">
<div style="padding: 8px 16px; background: #fafafa;">
<div v-if="!scope.row.changes || !scope.row.changes.length" style="color:#909399;">无字段明细</div>
<el-table v-else :data="scope.row.changes" border size="small">
<el-table-column label="字段" prop="fieldLabel" width="180" align="center" />
<el-table-column label="修改前" align="center">
<template #default="cell">
<span :style="{ color: cell.row.oldValue === '' ? '#909399' : '' }">{{ cell.row.oldValue === '' ? '(空)' : cell.row.oldValue }}</span>
</template>
</el-table-column>
<el-table-column label="修改后" align="center">
<template #default="cell">
<span :style="{ color: cell.row.newValue === '' ? '#909399' : '' }">{{ cell.row.newValue === '' ? '(空)' : cell.row.newValue }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
</el-table-column>
<el-table-column label="操作类型" align="center" width="90">
<template #default="scope">
<el-tag :type="opTagType(scope.row.operationType)" size="small">{{ opLabel(scope.row.operationType) }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作人" align="center" width="150">
<template #default="scope">{{ scope.row.createByName || scope.row.createBy || '-' }}</template>
</el-table-column>
<el-table-column label="操作时间" align="center" width="170">
<template #default="scope">{{ fmtTime(scope.row.createTime) }}</template>
</el-table-column>
<el-table-column label="变更字段" align="center">
<template #default="scope">
<span v-if="scope.row.operationType === '1'">新建客户,录入 {{ scope.row.changes?.length || 0 }} 项信息</span>
<span v-else-if="scope.row.operationType === '2'">{{ changeSummary(scope.row.changes) }}</span>
<span v-else style="color:#f56c6c;">客户被删除</span>
</template>
</el-table-column>
</el-table>
<template #footer>
<el-button @click="logOpen = false">关 闭</el-button>
</template>
</el-dialog>
<customer-log-dialog
v-model="logOpen"
:customer-id="logCustomer.customerId"
:customer-name="logCustomer.customerName"
:customer-code="logCustomer.customerCode"
/>
</div>
</template>
<script setup name="Customer">
import { listCustomer, delCustomer, listCustomerLog } from "@/api/customersuppliermanagement/customerinfo/customer.js"
import { listCustomer, delCustomer } from "@/api/customersuppliermanagement/customerinfo/customer.js"
import { useProducts, parseProductCodes } from '@/components/ProductSelect/useProducts'
import CustomerLogDialog from './components/CustomerLogDialog.vue'
import { useColumnSettings } from '@/utils/columnSettings'
const { proxy } = getCurrentInstance()
@@ -423,30 +381,8 @@ function handleExport() {
/** ========== 客户业务操作日志 ========== */
const logOpen = ref(false)
const logLoading = ref(false)
const logList = ref([])
const logCustomer = ref({})
const OP_META = {
'1': { label: '新建', tag: 'success' },
'2': { label: '修改', tag: 'warning' },
'3': { label: '删除', tag: 'danger' }
}
function opLabel(type) {
return OP_META[type]?.label || '未知'
}
function opTagType(type) {
return OP_META[type]?.tag || 'info'
}
function fmtTime(t) {
return t ? proxy.parseTime(t, '{y}-{m}-{d} {h}:{i}:{s}') : '-'
}
/** 修改日志的变更字段摘要 */
function changeSummary(changes) {
if (!changes || !changes.length) return '-'
return changes.map(c => c.fieldLabel).join('、')
}
/** 打开业务日志弹窗(操作列传 row;工具栏按钮取勾选行) */
function handleViewLog(row) {
const target = (row && row.customerId) ? row : selectedRows.value[0]
@@ -455,14 +391,7 @@ function handleViewLog(row) {
return
}
logCustomer.value = { customerId: target.customerId, customerName: target.customerName, customerCode: target.customerCode }
logList.value = []
logOpen.value = true
logLoading.value = true
listCustomerLog(target.customerId).then(res => {
logList.value = res.data || []
}).finally(() => {
logLoading.value = false
})
}
getList()