feat(config): 增强配置历史管理并统一数据库时间
- 新增 dao.Now() 函数获取数据库毫秒精度时间,避免多实例时钟偏差 - 增量同步查询增加上界(updated_at <= upperBound)防止竞态条件 - 配置创建、更新、删除、回滚统一使用数据库时间替代 time.Now() - 配置历史新增 operate 字段记录操作类型(update/delete/rollback) - 删除配置和回滚操作前增加历史快照记录 - 新增 DeleteHistory 接口支持手动删除单条历史记录 - 移除 GetHistory 的 Limit(5) 限制,返回完整历史列表 - 删除应用时同步更新关联配置的 updated_at 以便增量同步识别 - version 字段改为必填,前后端同步增加校验规则 - 前端历史列表增加操作类型列、删除按钮及表格最大高度限制 - 数据库表结构 datetime 升级为 datetime(3) 支持毫秒精度
This commit is contained in:
@@ -51,3 +51,10 @@ export function rollbackConfig(id) {
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteConfigHistory(id) {
|
||||
return request({
|
||||
url: `/admin/config/history/delete/${id}`,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -62,9 +62,17 @@
|
||||
></el-pagination>
|
||||
|
||||
<el-dialog title="变更历史" :visible.sync="historyVisible" width="900px">
|
||||
<el-table :data="historyList" border stripe>
|
||||
<el-table :data="historyList" border stripe max-height="500">
|
||||
<el-table-column prop="id" label="ID" width="60"></el-table-column>
|
||||
<el-table-column prop="createdBy" label="操作人" width="100"></el-table-column>
|
||||
<el-table-column label="操作类型" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.operate === 'delete'" style="color: #F56C6C">删除</span>
|
||||
<span v-else-if="scope.row.operate === 'rollback'">回滚</span>
|
||||
<span v-else-if="scope.row.operate === 'update'">更新</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作时间" width="180">
|
||||
<template slot-scope="scope">
|
||||
{{ formatTime(scope.row.createdAt) }}
|
||||
@@ -73,7 +81,8 @@
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click="viewHistoryContent(scope.row)">查看内容</el-button>
|
||||
<el-button type="text" @click="handleRollback(scope.row)">回滚到此版本</el-button>
|
||||
<el-button v-if="scope.row.operate !== 'delete'" type="text" @click="handleRollback(scope.row)">回滚到此版本</el-button>
|
||||
<el-button type="text" style="color: #F56C6C" @click="handleDeleteHistory(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -133,7 +142,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getConfigList, deleteConfig, getConfigHistory, rollbackConfig, getConfig } from '../../api/config'
|
||||
import { getConfigList, deleteConfig, getConfigHistory, rollbackConfig, getConfig, deleteConfigHistory } from '../../api/config'
|
||||
import { getClientListByConfig } from '../../api/client'
|
||||
import request from '../../api/request'
|
||||
|
||||
@@ -313,6 +322,15 @@ export default {
|
||||
this.historyVisible = true
|
||||
} catch (e) {}
|
||||
},
|
||||
async handleDeleteHistory(row) {
|
||||
try {
|
||||
await this.$confirm('确定删除这条历史记录?删除后不可恢复。')
|
||||
await deleteConfigHistory(row.id)
|
||||
this.$message.success('删除成功')
|
||||
const res = await getConfigHistory(row.originId)
|
||||
this.historyList = res.data || []
|
||||
} catch (e) {}
|
||||
},
|
||||
async viewHistoryContent(row) {
|
||||
this.currentHistory = row
|
||||
const historyContent = row.contents || ''
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<el-option v-for="p in profiles" :key="p.value" :label="p.label" :value="p.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="版本">
|
||||
<el-form-item label="版本" prop="version">
|
||||
<el-input v-model="form.version" placeholder="latest"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="配置格式">
|
||||
@@ -66,6 +66,7 @@ export default {
|
||||
},
|
||||
rules: {
|
||||
env: [{ required: true, message: '请选择环境', trigger: 'change' }],
|
||||
version: [{ required: true, message: '请输入版本', trigger: 'blur' }],
|
||||
contents: [{ required: true, message: '请输入配置内容', trigger: 'blur' }]
|
||||
},
|
||||
groups: [],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-card>
|
||||
<div slot="header">编辑配置</div>
|
||||
<el-form :model="form" ref="form" label-width="100px" v-loading="loading">
|
||||
<el-form :model="form" :rules="rules" ref="form" label-width="100px" v-loading="loading">
|
||||
<el-form-item label="配置名称">
|
||||
<el-input v-model="form.name" disabled></el-input>
|
||||
</el-form-item>
|
||||
@@ -11,7 +11,7 @@
|
||||
<el-form-item label="所属应用">
|
||||
<el-input :value="form.appNames" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="版本">
|
||||
<el-form-item label="版本" prop="version">
|
||||
<el-input v-model="form.version"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="配置内容">
|
||||
@@ -32,6 +32,9 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
rules: {
|
||||
version: [{ required: true, message: '请输入版本', trigger: 'blur' }]
|
||||
},
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
@@ -50,6 +53,7 @@ export default {
|
||||
},
|
||||
async handleSubmit() {
|
||||
try {
|
||||
await this.$refs.form.validate()
|
||||
await updateConfig(this.form)
|
||||
this.$message.success('保存成功')
|
||||
if (this.form.appId) {
|
||||
|
||||
@@ -57,9 +57,17 @@
|
||||
></el-pagination>
|
||||
|
||||
<el-dialog title="变更历史" :visible.sync="historyVisible" width="900px">
|
||||
<el-table :data="historyList" border stripe>
|
||||
<el-table :data="historyList" border stripe max-height="500">
|
||||
<el-table-column prop="id" label="ID" width="60"></el-table-column>
|
||||
<el-table-column prop="createdBy" label="操作人" width="100"></el-table-column>
|
||||
<el-table-column label="操作类型" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.operate === 'delete'" style="color: #F56C6C">删除</span>
|
||||
<span v-else-if="scope.row.operate === 'rollback'">回滚</span>
|
||||
<span v-else-if="scope.row.operate === 'update'">更新</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作时间" width="180">
|
||||
<template slot-scope="scope">
|
||||
{{ formatTime(scope.row.createdAt) }}
|
||||
@@ -68,7 +76,8 @@
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click="viewHistoryContent(scope.row)">查看内容</el-button>
|
||||
<el-button type="text" @click="handleRollback(scope.row)">回滚到此版本</el-button>
|
||||
<el-button v-if="scope.row.operate !== 'delete'" type="text" @click="handleRollback(scope.row)">回滚到此版本</el-button>
|
||||
<el-button type="text" style="color: #F56C6C" @click="handleDeleteHistory(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -128,7 +137,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getConfigList, deleteConfig, getConfigHistory, rollbackConfig, getConfig } from '../../api/config'
|
||||
import { getConfigList, deleteConfig, getConfigHistory, rollbackConfig, getConfig, deleteConfigHistory } from '../../api/config'
|
||||
import { getClientListByConfig } from '../../api/client'
|
||||
import request from '../../api/request'
|
||||
|
||||
@@ -299,6 +308,15 @@ export default {
|
||||
this.historyVisible = true
|
||||
} catch (e) {}
|
||||
},
|
||||
async handleDeleteHistory(row) {
|
||||
try {
|
||||
await this.$confirm('确定删除这条历史记录?删除后不可恢复。')
|
||||
await deleteConfigHistory(row.id)
|
||||
this.$message.success('删除成功')
|
||||
const res = await getConfigHistory(row.originId)
|
||||
this.historyList = res.data || []
|
||||
} catch (e) {}
|
||||
},
|
||||
async viewHistoryContent(row) {
|
||||
this.currentHistory = row
|
||||
const historyContent = row.contents || ''
|
||||
|
||||
Reference in New Issue
Block a user