blog-admin-web/src/views/system/SystemConfig.vue
灌糖包子 a4f7db415e
权限系统重构:
- 角色模型改为 permissions 字段,移除 methods/includeUri/excludeUri
- 角色管理页面支持权限树选择,保存时只传最上级权限
- /common/verifyToken 返回 permissions,存入 vuex
- 新增 v-permission 指令,所有操作按钮和菜单均按权限控制显示
- 菜单按 list 权限过滤
- 各业务页面按钮加权限指令
- 角色管理列表只显示名称/描述/时间,不显示权限列,权限必选
2026-04-02 20:38:14 +08:00

134 lines
4.3 KiB
Vue

<template>
<div>
<el-form inline :model="search" @submit.prevent>
<el-form-item label="配置项">
<el-input placeholder="名称/描述" v-model="search.name" />
</el-form-item>
</el-form>
<div class="btn-container">
<el-button type="primary" @click="add" v-permission="'config:save'">添加</el-button>
<div class="search-btn">
<el-button type="primary" @click="loadData" icon="Search">搜索</el-button>
<el-button @click="reset" icon="RefreshLeft">重置</el-button>
</div>
</div>
<el-table class="table-container" :data="systemConfigData" v-loading="loading" stripe>
<el-table-column type="expand">
<template #default="scope">
<pre style="margin:0 10px;">{{ JSON.stringify(scope.row.value, null, ' ') }}</pre>
</template>
</el-table-column>
<el-table-column prop="name" label="配置项名称" />
<el-table-column prop="description" label="配置项描述" />
<el-table-column prop="isPublic" label="是否公开" >
<template #default="scope">
{{ scope.row.isPublic ? '是' : '否' }}
</template>
</el-table-column>
<el-table-column prop="createdAt" label="创建时间" >
<template #default="scope">
{{ datetimeFormat(scope.row.createdAt) }}
</template>
</el-table-column>
<el-table-column prop="updatedAt" label="更新时间" >
<template #default="scope">
{{ datetimeFormat(scope.row.updatedAt) }}
</template>
</el-table-column>
<el-table-column label="操作" >
<template #default="scope">
<el-button link icon="Edit" @click="update(scope.row)" title="修改" v-permission="'config:save'"></el-button>
<el-button link type="danger" icon="Delete" @click="remove(scope.row)" title="删除" v-permission="'config:delete'"></el-button>
</template>
</el-table-column>
</el-table>
<el-dialog v-model="addModal" :title="modalTitle" >
<system-config-add ref="addForm" :formData="formData" />
<template #footer>
<span class="dialog-footer">
<el-button @click="addModal = false">取消</el-button>
<el-button type="primary" @click="save" :loading="modalLoading">确定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import moment from 'moment'
import http from '@/utils/http'
import SystemConfigAdd from './SystemConfigAdd.vue'
import { SystemConfigModel } from '@/model/system/system-config'
const modalLoading = ref(false)
const loading = ref(false)
const search = ref<{name?: string}>({})
const systemConfigData = ref<SystemConfigModel[]>([])
const addModal = ref(false)
const modalTitle = ref('')
const formData = ref<SystemConfigModel>({
name: '',
value: '',
description: '',
isPublic: false
})
const addForm = ref<InstanceType<typeof SystemConfigAdd>>()
function reset() {
search.value = {}
loadData()
}
async function loadData() {
loading.value = true
systemConfigData.value = await http.get('/system/config/list', {params: search.value})
loading.value = false
}
function add() {
formData.value = {
name: '',
value: '',
description: '',
isPublic: false
}
modalTitle.value = '新增配置项'
addModal.value = true
}
function update(row: SystemConfigModel) {
const data = Object.assign({}, row)
data.value = JSON.stringify(data.value, null, ' ')
formData.value = data
modalTitle.value = '修改配置项'
addModal.value = true
}
async function save() {
addForm.value?.configForm?.validate(async (valid: boolean) => {
if (!valid) return
modalLoading.value = true
await http.post<SystemConfigModel, any>('/system/config/save', formData.value)
modalLoading.value = false
addModal.value = false
ElMessage.success("保存成功")
loadData()
})
}
function remove(row: SystemConfigModel) {
ElMessageBox.confirm(`是否确认删除 ${row.name} 配置项?`, '确认删除', {type: 'warning'}).then(async () => {
await http.delete<{params: {id: string}}, any>('/system/config/delete', {params: {id: row._id}})
ElMessage.success('删除成功')
loadData()
})
}
function datetimeFormat(dateStr: string) {
return dateStr ? moment(dateStr).format('YYYY-MM-DD HH:mm:ss') : null
}
loadData()
</script>