admin user and ui panel
This commit is contained in:
@@ -81,7 +81,7 @@ export class AdminUsersService {
|
||||
orderBy: orderBy as Prisma.AdminUserOrderByWithRelationInput,
|
||||
skip,
|
||||
take,
|
||||
include: { userType: true, branch: true },
|
||||
include: { userType: true, branch: true, avatarFile: true },
|
||||
}),
|
||||
this.prisma.adminUser.count({ where: where as Prisma.AdminUserWhereInput }),
|
||||
]);
|
||||
@@ -90,7 +90,11 @@ export class AdminUsersService {
|
||||
}
|
||||
|
||||
/** Legacy field names preserved; the password hash is never exposed. */
|
||||
private toRow(u: Prisma.AdminUserGetPayload<{ include: { userType: true; branch: true } }>) {
|
||||
private toRow(
|
||||
u: Prisma.AdminUserGetPayload<{
|
||||
include: { userType: true; branch: true; avatarFile: true };
|
||||
}>,
|
||||
) {
|
||||
return {
|
||||
id: u.id,
|
||||
name: u.fullName,
|
||||
@@ -106,27 +110,45 @@ export class AdminUsersService {
|
||||
active: u.isActive ? 1 : -1,
|
||||
is_active: u.isActive,
|
||||
caj: u.createdAt,
|
||||
// Sales-agent fields (ReagentCustomer.vue) — set only for role=SALES_EXPERT,
|
||||
// null for every other admin. Same shapes admin-customers.service.ts used
|
||||
// when this data still lived on Customer, so the form binds unchanged.
|
||||
address: u.address,
|
||||
store_name: u.storeName,
|
||||
pasazh_name: u.pasazhName,
|
||||
mcode: u.memberCode,
|
||||
image_id: u.avatarFileId,
|
||||
image: u.avatarFile ? { id: u.avatarFile.id, image: u.avatarFile.url } : null,
|
||||
};
|
||||
}
|
||||
|
||||
async findOne(id: string) {
|
||||
const u = await this.prisma.adminUser.findUnique({
|
||||
where: { id },
|
||||
include: { userType: true, branch: true },
|
||||
include: { userType: true, branch: true, avatarFile: true },
|
||||
});
|
||||
if (!u) throw new NotFoundException('کاربر یافت نشد');
|
||||
return this.toRow(u);
|
||||
}
|
||||
|
||||
/** Legacy `POST users`. */
|
||||
/**
|
||||
* Legacy `POST users`.
|
||||
*
|
||||
* `role` is REQUIRED — it used to default to SALES_EXPERT whenever the
|
||||
* caller omitted it, which silently turned every admin created without an
|
||||
* explicit role into a sales agent regardless of the access level ("نوع
|
||||
* کاربری") actually chosen. UserCreate.vue now always sends one.
|
||||
*/
|
||||
async create(data: Record<string, unknown>) {
|
||||
const fullName = String(data.name ?? data.fname ?? '').trim();
|
||||
const mobile = String(data.mobile ?? '').trim();
|
||||
const password = String(data.password ?? '');
|
||||
const role = data.role as AdminRole | undefined;
|
||||
|
||||
if (!fullName) throw new BadRequestException('نام الزامی است');
|
||||
if (!mobile) throw new BadRequestException('موبایل الزامی است');
|
||||
if (!password) throw new BadRequestException('رمز عبور الزامی است');
|
||||
if (!role) throw new BadRequestException('نقش کاربر الزامی است');
|
||||
|
||||
const existing = await this.prisma.adminUser.findUnique({ where: { mobile } });
|
||||
if (existing) throw new BadRequestException('این شماره موبایل قبلاً ثبت شده است');
|
||||
@@ -136,7 +158,7 @@ export class AdminUsersService {
|
||||
fullName,
|
||||
mobile,
|
||||
passwordHash: await bcrypt.hash(password, 10),
|
||||
role: (data.role as AdminRole) ?? AdminRole.SALES_EXPERT,
|
||||
role,
|
||||
userTypeId: data.ut !== undefined && data.ut !== null ? Number(data.ut) : null,
|
||||
branchId: (data.branch_id as string) || null,
|
||||
wagePercent:
|
||||
@@ -144,8 +166,15 @@ export class AdminUsersService {
|
||||
? new Prisma.Decimal(String(data.percent))
|
||||
: null,
|
||||
isActive: data.is_active !== undefined ? Boolean(data.is_active) : true,
|
||||
// Sales-agent-only fields (ReagentCustomer.vue); undefined for every
|
||||
// other role, which Prisma leaves at column default (null).
|
||||
address: (data.address as string) || null,
|
||||
storeName: (data.store_name as string) || null,
|
||||
pasazhName: (data.pasazh_name as string) || null,
|
||||
memberCode: (data.mcode as string) || null,
|
||||
avatarFileId: (data.image_id as string) || null,
|
||||
},
|
||||
include: { userType: true, branch: true },
|
||||
include: { userType: true, branch: true, avatarFile: true },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -180,11 +209,21 @@ export class AdminUsersService {
|
||||
data.percent === null ? null : new Prisma.Decimal(String(data.percent));
|
||||
}
|
||||
if (data.is_active !== undefined) patch.isActive = Boolean(data.is_active);
|
||||
if (data.address !== undefined) patch.address = (data.address as string) || null;
|
||||
if (data.store_name !== undefined) patch.storeName = (data.store_name as string) || null;
|
||||
if (data.pasazh_name !== undefined) patch.pasazhName = (data.pasazh_name as string) || null;
|
||||
if (data.mcode !== undefined) patch.memberCode = (data.mcode as string) || null;
|
||||
if (data.image_id !== undefined) {
|
||||
// legacy sent '' to mean "avatar removed"
|
||||
patch.avatarFile = data.image_id
|
||||
? { connect: { id: String(data.image_id) } }
|
||||
: { disconnect: true };
|
||||
}
|
||||
|
||||
return this.prisma.adminUser.update({
|
||||
where: { id },
|
||||
data: patch,
|
||||
include: { userType: true, branch: true },
|
||||
include: { userType: true, branch: true, avatarFile: true },
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user