feat: 添加部门管理功能、主题切换和多语言支持
refactor(dashboard): 重构用户管理页面和路由结构 feat(server): 实现部门管理API和RBAC增强功能 docs: 更新用户手册和管理员指南文档 style: 统一图标使用和组件命名规范 test: 添加部门服务和数据隔离测试用例 chore: 更新依赖和配置文件
This commit is contained in:
@@ -264,6 +264,132 @@ export class HierarchyService {
|
||||
logger.info(`[Hierarchy] Deleted department ${departmentId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* [BE-MT002-04-01] 设置部门负责人
|
||||
*/
|
||||
static async assignDepartmentManager(
|
||||
departmentId: string,
|
||||
tenantId: string,
|
||||
managerId: string,
|
||||
assignedBy: string
|
||||
): Promise<Department> {
|
||||
const department = await db('cf_department')
|
||||
.where('id', departmentId)
|
||||
.where('tenant_id', tenantId)
|
||||
.first();
|
||||
|
||||
if (!department) {
|
||||
throw new Error('部门不存在');
|
||||
}
|
||||
|
||||
const user = await db('cf_user')
|
||||
.where('id', managerId)
|
||||
.where('tenant_id', tenantId)
|
||||
.where('status', 'ACTIVE')
|
||||
.first();
|
||||
|
||||
if (!user) {
|
||||
throw new Error('用户不存在或未激活');
|
||||
}
|
||||
|
||||
await db('cf_department')
|
||||
.where('id', departmentId)
|
||||
.where('tenant_id', tenantId)
|
||||
.update({
|
||||
manager_id: managerId,
|
||||
updated_at: new Date(),
|
||||
});
|
||||
|
||||
const updatedDepartment = await db('cf_department')
|
||||
.where('id', departmentId)
|
||||
.where('tenant_id', tenantId)
|
||||
.first();
|
||||
|
||||
await this.clearHierarchyCache(tenantId);
|
||||
|
||||
await EventBusService.publish({
|
||||
type: 'hierarchy.department.manager_assigned',
|
||||
data: {
|
||||
departmentId,
|
||||
tenantId,
|
||||
managerId,
|
||||
assignedBy,
|
||||
timestamp: new Date(),
|
||||
}
|
||||
});
|
||||
|
||||
logger.info(`[Hierarchy] Assigned manager ${managerId} to department ${departmentId}`);
|
||||
|
||||
return updatedDepartment;
|
||||
}
|
||||
|
||||
/**
|
||||
* [BE-MT002-04-02] 获取部门负责人
|
||||
*/
|
||||
static async getDepartmentManager(departmentId: string, tenantId: string): Promise<any> {
|
||||
const department = await db('cf_department')
|
||||
.where('id', departmentId)
|
||||
.where('tenant_id', tenantId)
|
||||
.first();
|
||||
|
||||
if (!department || !department.manager_id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const manager = await db('cf_user')
|
||||
.where('id', department.manager_id)
|
||||
.where('tenant_id', tenantId)
|
||||
.select('id', 'username', 'email', 'role', 'status')
|
||||
.first();
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* [BE-MT002-04-03] 获取部门统计信息
|
||||
*/
|
||||
static async getDepartmentStats(departmentId: string, tenantId: string): Promise<any> {
|
||||
const department = await db('cf_department')
|
||||
.where('id', departmentId)
|
||||
.where('tenant_id', tenantId)
|
||||
.first();
|
||||
|
||||
if (!department) {
|
||||
throw new Error('部门不存在');
|
||||
}
|
||||
|
||||
const [userCount, shopCount, subDepartmentCount] = await Promise.all([
|
||||
db('cf_user')
|
||||
.where('department_id', departmentId)
|
||||
.where('tenant_id', tenantId)
|
||||
.count('id as count')
|
||||
.first(),
|
||||
|
||||
db('cf_shop')
|
||||
.where('department_id', departmentId)
|
||||
.where('tenant_id', tenantId)
|
||||
.count('id as count')
|
||||
.first(),
|
||||
|
||||
db('cf_department')
|
||||
.where('parent_id', departmentId)
|
||||
.where('tenant_id', tenantId)
|
||||
.count('id as count')
|
||||
.first(),
|
||||
]);
|
||||
|
||||
return {
|
||||
departmentId,
|
||||
departmentName: department.name,
|
||||
userCount: Number(userCount?.count || 0),
|
||||
shopCount: Number(shopCount?.count || 0),
|
||||
subDepartmentCount: Number(subDepartmentCount?.count || 0),
|
||||
managerId: department.manager_id,
|
||||
status: department.status,
|
||||
createdAt: department.created_at,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* [BE-MT002-05] 创建店铺
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user