Commit 640f1611 by 李宁

1

1 parent d3641432
...@@ -2,7 +2,10 @@ ...@@ -2,7 +2,10 @@
"permissions": { "permissions": {
"allow": [ "allow": [
"Bash(grep -E \"\\.(js|vue|html)$\")", "Bash(grep -E \"\\.(js|vue|html)$\")",
"Bash(npm install axios)" "Bash(npm install axios)",
"Bash(tree src/)",
"Bash(npm run build)",
"Bash(npm run build-only)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []
......
...@@ -13,6 +13,11 @@ const handleLogin = (username: string, role: 'admin' | 'viewer') => { ...@@ -13,6 +13,11 @@ const handleLogin = (username: string, role: 'admin' | 'viewer') => {
isLoggedIn.value = true isLoggedIn.value = true
} }
if(isLoggedIn){
let name = JSON.parse(localStorage.getItem('pcUserInfo')).nickname||''
handleLogin( name, 'admin')
}
// 登出处理 // 登出处理
const handleLogout = () => { const handleLogout = () => {
localStorage.removeItem('pcUserInfo') localStorage.removeItem('pcUserInfo')
......
import request from '../../request' import request from '../../request'
/**
* 查询人员列表
*/
export function queryAllPerson(data) {
return request({
url: '/compass/api/personnel/list',
data,
})
}
/** /**
* 添加人员 * 查询角色列表
*/ */
export function addNewPerson(data) { export function queryRoleList(data) {
let url = '/compass/api/personnel/create'
if(data.id){
url = '/compass/api/personnel/update'
}
return request({ return request({
url: url, url: '/crm/getRoleList',
method: 'GET',
data, data,
}) })
} }
/**
* 删除人员
*/
export function deletePerson(data) {
return request({
url: '/compass/api/personnel/delete',
data,
})
}
/** /**
* 批量导入工维人员 * 创建和修改角色
*/ */
export function importGwPerson(data) { export function createOrUpdateRole(data) {
return request({ let url = '/crm/createRole'
url: '/compass/api/personnel/import-maintenance-preview', if(data.roleId){
data, url = '/crm/updateRole'
}) }
}
/**
* 批量导入营销人员
*/
export function importYxPerson(data) {
return request({ return request({
url: '/compass/api/marketing/import-preview', url,
data, data,
}) })
} }
...@@ -18,7 +18,7 @@ service.interceptors.request.use( ...@@ -18,7 +18,7 @@ service.interceptors.request.use(
if (localStorage.pcUserInfo) { if (localStorage.pcUserInfo) {
let userInfo = JSON.parse(localStorage.pcUserInfo); let userInfo = JSON.parse(localStorage.pcUserInfo);
config.headers["x-access-token"] = userInfo.token config.headers["token"] = userInfo.token
} }
return config; return config;
......
...@@ -222,7 +222,7 @@ const generateCaptcha = async () => { ...@@ -222,7 +222,7 @@ const generateCaptcha = async () => {
} }
// 倒计时逻辑 // 倒计时逻辑
let countdownTimer: NodeJS.Timeout | null = null let countdownTimer: number | null = null
const startCountdown = () => { const startCountdown = () => {
countdown.value = 60 countdown.value = 60
......
...@@ -143,7 +143,7 @@ const props = withDefaults(defineProps<Props>(), { ...@@ -143,7 +143,7 @@ const props = withDefaults(defineProps<Props>(), {
roleId: '', roleId: '',
roles: () => [], roles: () => [],
expandedIds: () => new Set(), expandedIds: () => new Set(),
accountType: '' accountType: undefined
}) })
const emit = defineEmits<{ const emit = defineEmits<{
......
<template> <template>
<div class="space-y-1"> <div class="space-y-1">
<div <div
:class="`permission-tree-node flex items-center gap-2 p-2 rounded ${level > 0 ? 'ml-6' : ''}`" :class="`permission-tree-node flex items-center gap-2 p-2 rounded ${level > 0 ? 'ml-6' : ''}`">
>
<!-- 展开/收起按钮 --> <!-- 展开/收起按钮 -->
<button <button
v-if="hasChildren" v-if="hasChildren"
...@@ -27,18 +26,18 @@ ...@@ -27,18 +26,18 @@
<div class="flex-1"> <div class="flex-1">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span class="text-neutral-900">{{ permission.name }}</span> <span class="text-neutral-900">{{ permission.name }}</span>
<el-tag <!-- <el-tag
type="info" type="info"
effect="plain" effect="plain"
size="small" size="small"
class="text-xs" class="text-xs"
> >
{{ permission.code }} {{ permission.code }}
</el-tag> </el-tag> -->
</div> </div>
<p v-if="permission.description" class="text-xs text-neutral-500 mt-1"> <!-- <p v-if="permission.description" class="text-xs text-neutral-500 mt-1">
{{ permission.description }} {{ permission.description }}
</p> </p> -->
</div> </div>
</div> </div>
......
...@@ -23,44 +23,28 @@ ...@@ -23,44 +23,28 @@
:data="filteredRoles" :data="filteredRoles"
style="width: 100%" style="width: 100%"
:header-cell-style="{ backgroundColor: '#f3f4f6', color: '#374151', fontWeight: '500', borderBottom: '1px solid #e5e7eb' }" :header-cell-style="{ backgroundColor: '#f3f4f6', color: '#374151', fontWeight: '500', borderBottom: '1px solid #e5e7eb' }"
:row-style="{ borderBottom: '1px solid rgb(243 244 246)' }" :row-style="{ borderBottom: '1px solid rgb(243 244 246)' }">
> <el-table-column prop="roleName" label="角色名称" min-width="120">
<el-table-column prop="name" label="角色名称" min-width="120">
<template #default="{ row }">
<span class="text-neutral-900">{{ row.name }}</span>
</template>
</el-table-column>
<el-table-column prop="permissionIds" label="权限数量" min-width="100">
<template #default="{ row }"> <template #default="{ row }">
<el-tag <span class="text-neutral-900">{{ row.roleName }}</span>
type="info"
effect="plain"
size="small"
class="bg-neutral-50"
>
{{ row.permissionIds.length }} 个权限
</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="status" label="状态" min-width="80"> <el-table-column prop="status" label="状态" min-width="80">
<template #default="{ row }"> <template #default="{ row }">
<el-tag <el-tag
:type="row.status === '启用' ? 'success' : 'info'" :type="row.status == 1 ? 'success' : 'info'"
effect="plain" effect="plain"
size="small" size="small"
> >
{{ row.status }} {{ row.status==1?'启用':'停用' }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间" min-width="150"> <el-table-column prop="createTime" label="创建时间" min-width="150">
<template #default="{ row }"> <template #default="{ row }">
<span class="text-neutral-600">{{ row.createTime || '-' }}</span> <span class="text-neutral-600">{{ $utils.detailTime(row.createTime)}}</span>
</template> </template>
</el-table-column> </el-table-column>
...@@ -191,11 +175,32 @@ ...@@ -191,11 +175,32 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from 'vue' import { ref,onMounted, computed, watch ,getCurrentInstance} from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue' import { Plus } from '@element-plus/icons-vue'
import PermissionTreeNode from './PermissionTreeNode.vue' import PermissionTreeNode from './PermissionTreeNode.vue'
const { $api,$utils } = getCurrentInstance()!.appContext.config.globalProperties
onMounted(() => {
// 初始化数据
handleFilter()
})
const handleFilter = async () => {
try {
const response = await $api.queryRoleList({});
if (response.c === 0) {
filteredRoles.value = response.d
ElMessage.success('查询成功');
} else {
ElMessage.error(response.msg || '查询失败');
}
} catch (error) {
ElMessage.error('查询失败: ' + error.message);
}
}
// 类型定义 // 类型定义
export interface Permission { export interface Permission {
id: string id: string
...@@ -211,7 +216,8 @@ export interface Role { ...@@ -211,7 +216,8 @@ export interface Role {
name: string name: string
description?: string description?: string
level: RoleLevel level: RoleLevel
permissionIds: string[] permissionIds?: string[]
permissions?: string[]
status: RoleStatus status: RoleStatus
createTime?: string createTime?: string
} }
...@@ -242,6 +248,7 @@ const roleName = ref('') ...@@ -242,6 +248,7 @@ const roleName = ref('')
const roleDescription = ref('') const roleDescription = ref('')
const selectedPermissions = ref<string[]>([]) const selectedPermissions = ref<string[]>([])
const roleLevel = ref<'地市级' | '区县级' | '一线人员'>('区县级')
const roleStatusEnabled = ref(true) const roleStatusEnabled = ref(true)
// 权限树展开状态 // 权限树展开状态
...@@ -254,9 +261,12 @@ const topLevelPermissions = computed(() => ...@@ -254,9 +261,12 @@ const topLevelPermissions = computed(() =>
props.permissions.filter(p => !p.parentId) props.permissions.filter(p => !p.parentId)
) )
const filteredRoles = computed(() => const filteredRoles = ref([])
props.roles.filter(role => role.name !== '地市主管理员')
) // 获取角色的权限ID列表,兼容不同的字段名
const getRolePermissionIds = (role: Role): string[] => {
return role.permissionIds || role.permissions || []
}
...@@ -278,7 +288,7 @@ const handleOpenEditDialog = (role: Role) => { ...@@ -278,7 +288,7 @@ const handleOpenEditDialog = (role: Role) => {
roleName.value = role.name roleName.value = role.name
roleDescription.value = role.description || '' roleDescription.value = role.description || ''
selectedPermissions.value = [...role.permissionIds] selectedPermissions.value = [...getRolePermissionIds(role)]
roleStatusEnabled.value = role.status === '启用' roleStatusEnabled.value = role.status === '启用'
expandedPermissions.value = new Set(props.permissions.filter(p => !p.parentId).map(p => p.id)) expandedPermissions.value = new Set(props.permissions.filter(p => !p.parentId).map(p => p.id))
isDialogOpen.value = true isDialogOpen.value = true
...@@ -299,7 +309,7 @@ const handleSave = () => { ...@@ -299,7 +309,7 @@ const handleSave = () => {
const roleData = { const roleData = {
name: roleName.value.trim(), name: roleName.value.trim(),
description: roleDescription.value.trim(), description: roleDescription.value.trim(),
level: roleLevel.value,
permissionIds: selectedPermissions.value, permissionIds: selectedPermissions.value,
status: roleStatus.value status: roleStatus.value
} }
......
...@@ -336,7 +336,7 @@ import { Plus, Building2, Search } from 'lucide-vue-next' ...@@ -336,7 +336,7 @@ import { Plus, Building2, Search } from 'lucide-vue-next'
import OrganizationTree from './OrganizationTree.vue' import OrganizationTree from './OrganizationTree.vue'
// 类型定义 // 类型定义
interface User { export interface User {
id: string id: string
username: string username: string
realName: string realName: string
...@@ -378,7 +378,7 @@ interface UserManagementProps { ...@@ -378,7 +378,7 @@ interface UserManagementProps {
const props = defineProps<UserManagementProps>() const props = defineProps<UserManagementProps>()
const emit = defineEmits<{ const emit = defineEmits<{
addUser: [user: Omit<User, 'id' | 'createTime'>] addUser: [user: Omit<User, 'id' | 'createTime' | 'creatorId'>]
updateUser: [id: string, updates: Partial<User>] updateUser: [id: string, updates: Partial<User>]
}>() }>()
...@@ -398,7 +398,7 @@ const formData = ref({ ...@@ -398,7 +398,7 @@ const formData = ref({
realName: '', realName: '',
phone: '', phone: '',
accountType: '', accountType: '一线人员' as '地市级' | '区县级' | '一线人员',
organizationId: '', organizationId: '',
roleId: '', roleId: '',
isActive: true isActive: true
...@@ -502,7 +502,7 @@ const handleOpenAddDialog = () => { ...@@ -502,7 +502,7 @@ const handleOpenAddDialog = () => {
realName: '', realName: '',
phone: '', phone: '',
accountType: '', accountType: '一线人员' as '地市级' | '区县级' | '一线人员',
organizationId: '', organizationId: '',
roleId: '', roleId: '',
isActive: true isActive: true
...@@ -517,7 +517,7 @@ const handleOpenEditDialog = (user: User) => { ...@@ -517,7 +517,7 @@ const handleOpenEditDialog = (user: User) => {
realName: user.realName, realName: user.realName,
phone: user.phone || '', phone: user.phone || '',
accountType: user.accountType || '', accountType: user.accountType || '一线人员',
organizationId: user.organizationId, organizationId: user.organizationId,
roleId: user.roleId, roleId: user.roleId,
isActive: user.status === '正常' isActive: user.status === '正常'
......
...@@ -13,8 +13,11 @@ import App from './App.vue' ...@@ -13,8 +13,11 @@ import App from './App.vue'
import router from './router' import router from './router'
// 引入 API 接口和工具方法 // 引入 API 接口和工具方法
// @ts-ignore
import api from './assets/js/api/interface/index.js' import api from './assets/js/api/interface/index.js'
// @ts-ignore
import stores from './assets/js/stores/index.js' import stores from './assets/js/stores/index.js'
// @ts-ignore
import commonUtils from './assets/js/const/common.js' import commonUtils from './assets/js/const/common.js'
const app = createApp(App) const app = createApp(App)
......
<template>
<div class="min-h-screen bg-gray-50 p-6">
<div class="max-w-7xl mx-auto">
<h1 class="text-2xl font-bold text-gray-900 mb-6">角色管理测试页面</h1>
<RoleManagement
:roles="roles"
:permissions="permissions"
@add-role="handleAddRole"
@update-role="handleUpdateRole"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import RoleManagement, { type Role, type Permission } from '@/components/RoleManagement.vue'
import { ElMessage } from 'element-plus'
// 测试数据
const roles = ref<Role[]>([
{
id: 'role-001',
name: '区县全权管理员',
description: '拥有区县级别的所有管理权限,可以管理订单、用户和业务规则',
level: '区县级',
permissions: [
'order',
'order:view',
'order:complete',
'order:reward',
'order:approve',
'business',
'business:view',
'business:create',
'business:edit',
'system',
'system:role',
'system:role:view',
'system:role:create',
'system:role:edit',
'system:account',
'system:account:view',
'system:account:create',
'system:account:edit'
],
status: '启用',
createTime: '2025-10-20 09:00:00'
},
{
id: 'role-002',
name: '订单管理员',
description: '负责订单的日常管理和处理',
level: '一线人员',
permissions: ['order', 'order:view', 'order:complete', 'order:reward', 'order:approve'],
status: '启用',
createTime: '2025-10-20 09:30:00'
},
{
id: 'role-003',
name: '业务规则管理员',
description: '负责业务规则的配置和维护',
level: '区县级',
permissions: ['business', 'business:view', 'business:create', 'business:edit'],
status: '启用',
createTime: '2025-10-20 10:00:00'
}
])
const permissions = ref<Permission[]>([
{
id: 'order',
name: '订单管理',
code: 'order',
description: '订单相关的所有权限',
children: [
{
id: 'order:view',
name: '查看订单',
code: 'order:view',
description: '查看订单列表和详情',
parentId: 'order'
},
{
id: 'order:complete',
name: '填写办结信息',
code: 'order:complete',
description: '填写CRM订单编号和办理备注',
parentId: 'order'
},
{
id: 'order:reward',
name: '填写酬金金额',
code: 'order:reward',
description: '填写和修改实际发放酬金',
parentId: 'order'
},
{
id: 'order:approve',
name: '审核',
code: 'order:approve',
description: '审核通过或驳回订单',
parentId: 'order'
}
]
},
{
id: 'business',
name: '业务规则管理',
code: 'business',
description: '业务规则相关权限',
children: [
{
id: 'business:view',
name: '查看业务规则',
code: 'business:view',
description: '查看业务规则列表',
parentId: 'business'
},
{
id: 'business:create',
name: '创建业务规则',
code: 'business:create',
description: '创建新的业务规则',
parentId: 'business'
},
{
id: 'business:edit',
name: '编辑业务规则',
code: 'business:edit',
description: '修改和停用业务规则',
parentId: 'business'
}
]
},
{
id: 'system',
name: '系统管理',
code: 'system',
description: '系统管理相关权限',
children: [
{
id: 'system:role',
name: '角色管理',
code: 'system:role',
description: '角色管理相关权限',
parentId: 'system',
children: [
{
id: 'system:role:view',
name: '查看角色',
code: 'system:role:view',
description: '查看角色列表',
parentId: 'system:role'
},
{
id: 'system:role:create',
name: '创建角色',
code: 'system:role:create',
description: '创建新角色',
parentId: 'system:role'
},
{
id: 'system:role:edit',
name: '编辑角色',
code: 'system:role:edit',
description: '编辑角色信息和权限',
parentId: 'system:role'
}
]
},
{
id: 'system:account',
name: '账号管理',
code: 'system:account',
description: '账号管理相关权限',
parentId: 'system',
children: [
{
id: 'system:account:view',
name: '查看账号',
code: 'system:account:view',
description: '查看账号列表',
parentId: 'system:account'
},
{
id: 'system:account:create',
name: '创建账号',
code: 'system:account:create',
description: '创建新账号',
parentId: 'system:account'
},
{
id: 'system:account:edit',
name: '编辑账号',
code: 'system:account:edit',
description: '编辑账号信息',
parentId: 'system:account'
}
]
}
]
}
])
// 事件处理
const handleAddRole = (roleData: Omit<Role, 'id' | 'createTime'>) => {
const newRole: Role = {
id: `role-${Date.now()}`,
...roleData,
permissions: roleData.permissionIds || roleData.permissions || [],
createTime: new Date().toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
})
}
roles.value.push(newRole)
ElMessage.success('角色创建成功')
console.log('新增角色:', newRole)
}
const handleUpdateRole = (roleId: string, updates: Partial<Role>) => {
const roleIndex = roles.value.findIndex(role => role.id === roleId)
if (roleIndex !== -1) {
roles.value[roleIndex] = { ...roles.value[roleIndex], ...updates } as Role
ElMessage.success('角色更新成功')
console.log('更新角色:', roleId, updates)
}
}
</script>
<style scoped>
/* 测试页面样式 */
</style>
...@@ -10,6 +10,7 @@ export default defineConfig({ ...@@ -10,6 +10,7 @@ export default defineConfig({
vue(), vue(),
// vueDevTools(), // vueDevTools(),
], ],
base: './',
resolve: { resolve: {
alias: { alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)) '@': fileURLToPath(new URL('./src', import.meta.url))
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!