Initial commit: One Pipe System
完整的管理系统,包含账户管理、卡片管理、套餐管理、财务管理等功能模块。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
489
src/views/system/permission/index.vue
Normal file
489
src/views/system/permission/index.vue
Normal file
@@ -0,0 +1,489 @@
|
||||
<template>
|
||||
<ArtTableFullScreen>
|
||||
<div class="permission-page" id="table-full-screen">
|
||||
<!-- 搜索栏 -->
|
||||
<ArtSearchBar
|
||||
v-model:filter="searchForm"
|
||||
:items="searchFormItems"
|
||||
@reset="handleReset"
|
||||
@search="handleSearch"
|
||||
></ArtSearchBar>
|
||||
|
||||
<ElCard shadow="never" class="art-table-card">
|
||||
<!-- 表格头部 -->
|
||||
<ArtTableHeader
|
||||
:columnList="columnOptions"
|
||||
v-model:columns="columnChecks"
|
||||
@refresh="handleRefresh"
|
||||
>
|
||||
<template #left>
|
||||
<ElButton @click="showDialog('add')">新增权限</ElButton>
|
||||
</template>
|
||||
</ArtTableHeader>
|
||||
|
||||
<!-- 表格 -->
|
||||
<ArtTable
|
||||
ref="tableRef"
|
||||
row-key="ID"
|
||||
:data="permissionList"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
:default-expand-all="false"
|
||||
:marginTop="10"
|
||||
:show-pagination="false"
|
||||
>
|
||||
<template #default>
|
||||
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
|
||||
</template>
|
||||
</ArtTable>
|
||||
|
||||
<!-- 新增/编辑对话框 -->
|
||||
<ElDialog
|
||||
v-model="dialogVisible"
|
||||
:title="dialogType === 'add' ? '新增权限' : '编辑权限'"
|
||||
width="600px"
|
||||
align-center
|
||||
>
|
||||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="100px">
|
||||
<ElFormItem label="权限名称" prop="perm_name">
|
||||
<ElInput v-model="form.perm_name" placeholder="请输入权限名称" />
|
||||
</ElFormItem>
|
||||
<ElFormItem label="权限标识" prop="perm_code">
|
||||
<ElInput v-model="form.perm_code" placeholder="请输入权限标识,如:user:add" />
|
||||
</ElFormItem>
|
||||
<ElFormItem label="权限类型" prop="perm_type">
|
||||
<ElSelect v-model="form.perm_type" placeholder="请选择权限类型" style="width: 100%">
|
||||
<ElOption
|
||||
v-for="option in PERMISSION_TYPE_OPTIONS"
|
||||
:key="option.value"
|
||||
:label="option.label"
|
||||
:value="option.value"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="父级权限" prop="parent_id">
|
||||
<ElTreeSelect
|
||||
v-model="form.parent_id"
|
||||
:data="permissionTreeOptions"
|
||||
placeholder="请选择父级权限(可选)"
|
||||
clearable
|
||||
check-strictly
|
||||
:render-after-expand="false"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</ElFormItem>
|
||||
<ElFormItem v-if="form.perm_type === PermissionType.MENU" label="菜单路径" prop="url">
|
||||
<ElInput v-model="form.url" placeholder="请输入菜单路径,如:/system/user" />
|
||||
</ElFormItem>
|
||||
<ElFormItem label="适用端口" prop="platform">
|
||||
<ElSelect v-model="form.platform" placeholder="请选择适用端口" style="width: 100%">
|
||||
<ElOption label="全部" value="all" />
|
||||
<ElOption label="Web后台" value="web" />
|
||||
<ElOption label="H5端" value="h5" />
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem label="排序序号" prop="sort">
|
||||
<ElInputNumber v-model="form.sort" :min="0" :max="9999" style="width: 100%" />
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<ElButton @click="dialogVisible = false">取消</ElButton>
|
||||
<ElButton type="primary" @click="handleSubmit" :loading="submitLoading"
|
||||
>提交</ElButton
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</ElDialog>
|
||||
</ElCard>
|
||||
</div>
|
||||
</ArtTableFullScreen>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { h } from 'vue'
|
||||
import {
|
||||
ElMessage,
|
||||
ElMessageBox,
|
||||
ElTag,
|
||||
ElSwitch,
|
||||
type FormInstance,
|
||||
type FormRules
|
||||
} from 'element-plus'
|
||||
import { PermissionService } from '@/api/modules'
|
||||
import type { Permission, CreatePermissionParams } from '@/types/api'
|
||||
import type { SearchFormItem } from '@/types'
|
||||
import { formatDateTime } from '@/utils/business/format'
|
||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
|
||||
import {
|
||||
CommonStatus,
|
||||
getStatusText,
|
||||
PermissionType,
|
||||
PERMISSION_TYPE_OPTIONS,
|
||||
PERMISSION_TYPE_SELECT_OPTIONS,
|
||||
getPermissionTypeText,
|
||||
getPermissionTypeTag,
|
||||
STATUS_SELECT_OPTIONS
|
||||
} from '@/config/constants'
|
||||
|
||||
defineOptions({ name: 'Permission' })
|
||||
|
||||
// 搜索表单初始值
|
||||
const initialSearchState = {
|
||||
perm_name: '',
|
||||
perm_code: '',
|
||||
perm_type: undefined as number | undefined,
|
||||
status: undefined as number | undefined
|
||||
}
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({ ...initialSearchState })
|
||||
|
||||
// 搜索表单配置
|
||||
const searchFormItems: SearchFormItem[] = [
|
||||
{
|
||||
label: '权限名称',
|
||||
prop: 'perm_name',
|
||||
type: 'input',
|
||||
config: {
|
||||
clearable: true,
|
||||
placeholder: '请输入权限名称'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '权限标识',
|
||||
prop: 'perm_code',
|
||||
type: 'input',
|
||||
config: {
|
||||
clearable: true,
|
||||
placeholder: '请输入权限标识'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '权限类型',
|
||||
prop: 'perm_type',
|
||||
type: 'select',
|
||||
options: PERMISSION_TYPE_SELECT_OPTIONS,
|
||||
config: {
|
||||
clearable: true,
|
||||
placeholder: '请选择'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '状态',
|
||||
prop: 'status',
|
||||
type: 'select',
|
||||
options: STATUS_SELECT_OPTIONS,
|
||||
config: {
|
||||
clearable: true,
|
||||
placeholder: '请选择'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
// 列配置
|
||||
const columnOptions = [
|
||||
{ label: '权限名称', prop: 'perm_name' },
|
||||
{ label: '权限标识', prop: 'perm_code' },
|
||||
{ label: '权限类型', prop: 'perm_type' },
|
||||
{ label: '菜单路径', prop: 'url' },
|
||||
{ label: '排序', prop: 'sort' },
|
||||
{ label: '状态', prop: 'status' },
|
||||
{ label: '创建时间', prop: 'CreatedAt' },
|
||||
{ label: '操作', prop: 'operation' }
|
||||
]
|
||||
|
||||
// 权限列表
|
||||
const permissionList = ref<Permission[]>([])
|
||||
|
||||
const tableRef = ref()
|
||||
const dialogVisible = ref(false)
|
||||
const detailDialogVisible = ref(false)
|
||||
const dialogType = ref('add')
|
||||
const currentRow = ref<Permission | null>(null)
|
||||
const currentPermissionId = ref<number>(0)
|
||||
const submitLoading = ref(false)
|
||||
|
||||
// 表单引用和数据
|
||||
const formRef = ref<FormInstance>()
|
||||
const form = reactive<CreatePermissionParams>({
|
||||
perm_name: '',
|
||||
perm_code: '',
|
||||
perm_type: PermissionType.MENU,
|
||||
parent_id: undefined,
|
||||
url: '',
|
||||
platform: 'all',
|
||||
sort: 0
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const rules = reactive<FormRules>({
|
||||
perm_name: [{ required: true, message: '请输入权限名称', trigger: 'blur' }],
|
||||
perm_code: [
|
||||
{ required: true, message: '请输入权限标识', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^[a-zA-Z0-9:_-]+$/,
|
||||
message: '权限标识只能包含字母、数字、冒号、下划线和连字符',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
perm_type: [{ required: true, message: '请选择权限类型', trigger: 'change' }]
|
||||
})
|
||||
|
||||
// 权限树选项(用于选择父级权限)
|
||||
const permissionTreeOptions = ref<any[]>([])
|
||||
|
||||
// 动态列配置
|
||||
const { columnChecks, columns } = useCheckedColumns(() => [
|
||||
{
|
||||
prop: 'perm_name',
|
||||
label: '权限名称',
|
||||
minWidth: 200
|
||||
},
|
||||
{
|
||||
prop: 'perm_code',
|
||||
label: '权限标识',
|
||||
width: 200
|
||||
},
|
||||
{
|
||||
prop: 'perm_type',
|
||||
label: '权限类型',
|
||||
width: 120,
|
||||
formatter: (row: any) => {
|
||||
return h(ElTag, { type: getPermissionTypeTag(row.perm_type) }, () =>
|
||||
getPermissionTypeText(row.perm_type)
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'url',
|
||||
label: '菜单路径',
|
||||
width: 180
|
||||
},
|
||||
{
|
||||
prop: 'sort',
|
||||
label: '排序',
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
prop: 'status',
|
||||
label: '状态',
|
||||
width: 100,
|
||||
formatter: (row: any) => {
|
||||
return h(ElSwitch, {
|
||||
modelValue: row.status,
|
||||
activeValue: CommonStatus.ENABLED,
|
||||
inactiveValue: CommonStatus.DISABLED,
|
||||
activeText: getStatusText(CommonStatus.ENABLED),
|
||||
inactiveText: getStatusText(CommonStatus.DISABLED),
|
||||
inlinePrompt: true,
|
||||
'onUpdate:modelValue': (val: number) => handleStatusChange(row, val)
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
prop: 'CreatedAt',
|
||||
label: '创建时间',
|
||||
width: 180,
|
||||
formatter: (row: any) => formatDateTime(row.CreatedAt)
|
||||
},
|
||||
{
|
||||
prop: 'operation',
|
||||
label: '操作',
|
||||
width: 160,
|
||||
fixed: 'right',
|
||||
formatter: (row: any) => {
|
||||
return h('div', { style: 'display: flex; gap: 8px;' }, [
|
||||
h(ArtButtonTable, {
|
||||
type: 'edit',
|
||||
onClick: () => showDialog('edit', row)
|
||||
}),
|
||||
h(ArtButtonTable, {
|
||||
type: 'delete',
|
||||
onClick: () => deletePermission(row)
|
||||
})
|
||||
])
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
// 获取权限列表
|
||||
const getPermissionList = async () => {
|
||||
try {
|
||||
const response = await PermissionService.getPermissions(searchForm)
|
||||
if (response.code === 0) {
|
||||
permissionList.value = response.data.items || []
|
||||
// 构建权限树选项
|
||||
buildPermissionTreeOptions()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 构建权限树选项
|
||||
const buildPermissionTreeOptions = () => {
|
||||
const buildTree = (list: Permission[]): any[] => {
|
||||
return list.map((item) => ({
|
||||
value: item.ID,
|
||||
label: item.perm_name,
|
||||
children: item.children ? buildTree(item.children) : undefined
|
||||
}))
|
||||
}
|
||||
permissionTreeOptions.value = buildTree(permissionList.value)
|
||||
}
|
||||
|
||||
// 搜索
|
||||
const handleSearch = () => {
|
||||
getPermissionList()
|
||||
}
|
||||
|
||||
// 重置
|
||||
const handleReset = () => {
|
||||
Object.assign(searchForm, { ...initialSearchState })
|
||||
getPermissionList()
|
||||
}
|
||||
|
||||
// 刷新表格
|
||||
const handleRefresh = () => {
|
||||
getPermissionList()
|
||||
}
|
||||
|
||||
// 显示对话框
|
||||
const showDialog = (type: string, row?: any) => {
|
||||
dialogVisible.value = true
|
||||
dialogType.value = type
|
||||
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
|
||||
if (type === 'edit' && row) {
|
||||
currentRow.value = row
|
||||
currentPermissionId.value = row.ID
|
||||
Object.assign(form, {
|
||||
perm_name: row.perm_name,
|
||||
perm_code: row.perm_code,
|
||||
perm_type: row.perm_type,
|
||||
parent_id: row.parent_id,
|
||||
url: row.url || '',
|
||||
platform: row.platform || 'all',
|
||||
sort: row.sort || 0
|
||||
})
|
||||
} else {
|
||||
currentPermissionId.value = 0
|
||||
resetForm()
|
||||
}
|
||||
}
|
||||
|
||||
// 删除权限
|
||||
const deletePermission = (row: Permission) => {
|
||||
// 检查是否有子权限
|
||||
if (row.children && row.children.length > 0) {
|
||||
ElMessage.warning('该权限下存在子权限,请先删除子权限')
|
||||
return
|
||||
}
|
||||
|
||||
ElMessageBox.confirm(`确定删除权限 ${row.perm_name} 吗?`, '删除确认', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'error'
|
||||
})
|
||||
.then(async () => {
|
||||
try {
|
||||
await PermissionService.deletePermission(row.ID)
|
||||
ElMessage.success('删除成功')
|
||||
getPermissionList()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// 用户取消删除
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return
|
||||
|
||||
await formRef.value.validate(async (valid) => {
|
||||
if (valid) {
|
||||
submitLoading.value = true
|
||||
try {
|
||||
if (dialogType.value === 'add') {
|
||||
await PermissionService.createPermission(form)
|
||||
ElMessage.success('新增成功')
|
||||
} else {
|
||||
await PermissionService.updatePermission(currentPermissionId.value, form)
|
||||
ElMessage.success('修改成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
formRef.value.resetFields()
|
||||
getPermissionList()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
Object.assign(form, {
|
||||
perm_name: '',
|
||||
perm_code: '',
|
||||
perm_type: PermissionType.MENU,
|
||||
parent_id: undefined,
|
||||
url: '',
|
||||
platform: 'all',
|
||||
sort: 0
|
||||
})
|
||||
}
|
||||
|
||||
// 获取父级权限名称
|
||||
const getParentPermissionName = (parentId?: number | null) => {
|
||||
if (!parentId) return ''
|
||||
|
||||
const findPermission = (list: Permission[], id: number): string | null => {
|
||||
for (const item of list) {
|
||||
if (item.ID === id) return item.perm_name
|
||||
if (item.children) {
|
||||
const found = findPermission(item.children, id)
|
||||
if (found) return found
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
return findPermission(permissionList.value, parentId) || ''
|
||||
}
|
||||
|
||||
// 状态切换
|
||||
const handleStatusChange = async (row: any, newStatus: number) => {
|
||||
const oldStatus = row.status
|
||||
// 先更新UI
|
||||
row.status = newStatus
|
||||
try {
|
||||
await PermissionService.updatePermission(row.ID, { status: newStatus })
|
||||
ElMessage.success('状态切换成功')
|
||||
} catch (error) {
|
||||
// 切换失败,恢复原状态
|
||||
row.status = oldStatus
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载时获取权限列表
|
||||
onMounted(() => {
|
||||
getPermissionList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.permission-page {
|
||||
// 权限管理页面样式
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user