国标通道编辑支持仅保存修改的字段

This commit is contained in:
lin
2025-11-06 15:50:42 +08:00
parent f89dee6393
commit 01e72407ac
10 changed files with 198 additions and 66 deletions

76
web/src/utils/diff.js Normal file
View File

@@ -0,0 +1,76 @@
// utils/diff.js
// 返回 newObj 相对于 oldObj 的变化部分(新增/修改)。
// 可选 includeRemoved=true 时把被删除字段以 removedValue 标记返回。
// 使用示例: diff(oldObj, newObj) 或 diff(oldObj, newObj, { includeRemoved: true })
export function diff(oldObj, newObj, options = {}) {
const { includeRemoved = false, removedValue = null, comparator } = options
function isObject(v) {
return v && typeof v === 'object' && !Array.isArray(v) && !(v instanceof Date)
}
function isDate(v) {
return v instanceof Date
}
function equal(a, b) {
if (typeof comparator === 'function') return comparator(a, b)
if (isDate(a) && isDate(b)) return a.getTime() === b.getTime()
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length) return false
for (let i = 0; i < a.length; i++) if (!equal(a[i], b[i])) return false
return true
}
if (isObject(a) && isObject(b)) {
const aKeys = Object.keys(a)
const bKeys = Object.keys(b)
if (aKeys.length !== bKeys.length) return false
for (const k of aKeys) {
if (!Object.prototype.hasOwnProperty.call(b, k) || !equal(a[k], b[k])) return false
}
return true
}
return a === b
}
function inner(o, n) {
// Normalize undefined -> empty object for easier handling in object branch.
const oIsObj = isObject(o)
const nIsObj = isObject(n)
if (equal(o, n)) return undefined
if (oIsObj && nIsObj) {
const result = {}
const keys = new Set([...Object.keys(o || {}), ...Object.keys(n || {})])
for (const k of keys) {
console.log(k)
const hasO = Object.prototype.hasOwnProperty.call(o || {}, k)
const hasN = Object.prototype.hasOwnProperty.call(n || {}, k)
if (hasN) {
const sub = inner(hasO ? o[k] : undefined, n[k])
if (sub !== undefined) result[k] = sub
} else if (hasO && includeRemoved) {
// key existed before but removed now
result[k] = removedValue
}
}
return Object.keys(result).length ? result : undefined
}
if (Array.isArray(o) && Array.isArray(n)) {
return equal(o, n) ? undefined : n
}
if (isDate(n)) return n
// Different primitive or type change -> return new value
return n
}
const res = inner(oldObj ?? {}, newObj ?? {})
return res === undefined ? {} : res
}
export default diff

View File

@@ -248,6 +248,7 @@
import channelCode from './../dialog/channelCode'
import ChooseCivilCode from '../dialog/chooseCivilCode.vue'
import ChooseGroup from '../dialog/chooseGroup.vue'
import diff from '../../utils/diff'
export default {
name: 'CommonChannelEdit',
@@ -288,7 +289,7 @@ export default {
if (!this.dataForm.gbDeviceId) {
this.dataForm.gbDeviceId = ''
}
this.form = this.dataForm
this.form = window.structuredClone(this.dataForm)
this.getPaths()
}
},
@@ -309,8 +310,16 @@ export default {
this.form.gbDownloadSpeed = this.form.gbDownloadSpeedArray.join('/')
}
this.form.enableBroadcast = this.form.enableBroadcastForBool ? 1 : 0
// 判断哪些字段变化
let diffData = diff(this.dataForm, this.form)
diffData['gbId'] = this.form.gbId
console.log(diffData)
console.log(this.dataForm)
console.log(this.form)
if (this.form.gbId) {
this.$store.dispatch('commonChanel/update', this.form)
this.$store.dispatch('commonChanel/update', diffData)
.then(data => {
this.$message.success({
showClose: true,
@@ -368,6 +377,7 @@ export default {
if (data.gbDownloadSpeed) {
data.gbDownloadSpeedArray = data.gbDownloadSpeed.split('/')
}
this.dataForm = window.structuredClone(data)
this.form = data
this.$set(this.form, 'enableBroadcastForBool', this.form.enableBroadcast === 1)
this.getPaths()