import { Provide, Inject } from "@midwayjs/core"; import { InjectRepository } from "@midwayjs/sequelize"; import { Repository } from "sequelize-typescript"; import { Op, UniqueConstraintError, fn, col } from "sequelize"; import { Context } from "@midwayjs/koa"; import Customer from "../entity/customer.entity"; import CustomerDepartment from "../entity/customer_department.entity"; import CustomerAccount from "../entity/customer_account.entity"; import SysUserRole from "../entity/sysUserRole.entity"; import SysRole from "../entity/sysRole.entity"; @Provide() export class CustomerService { @InjectRepository(Customer) customerModel!: Repository; @InjectRepository(CustomerDepartment) customerDepModel!: Repository; @InjectRepository(CustomerAccount) customerAccModel!: Repository; @InjectRepository(SysUserRole) userRoleModel!: Repository; @InjectRepository(SysRole) roleModel!: Repository; async list( query: { page?: any; pageSize?: any; keyword?: string; status?: number; salesmanId?: number }, ctx: Context ): Promise { const page = Number(query.page) || 1; const pageSize = Number(query.pageSize) || 10; const where: any = {}; if (query.keyword) { where[Op.or] = [ { customerName: { [Op.like]: `%${query.keyword}%` } }, { contactPerson: { [Op.like]: `%${query.keyword}%` } }, { contactPhone: { [Op.like]: `%${query.keyword}%` } } ]; } if (query.status !== undefined) { where.status = query.status; } if (query.salesmanId) { where.salesmanId = query.salesmanId; } const isAdmin = await this.isAdmin(ctx.state.user.userId); if (!isAdmin) { where.salesmanId = ctx.state.user.userId; } const { count, rows } = await this.customerModel.findAndCountAll({ where, limit: pageSize, offset: (page - 1) * pageSize, order: [["created_at", "DESC"]] }); return { code: 200, message: "获取客户列表成功", data: { list: rows, total: count, page: Number(page), pageSize: Number(pageSize) } }; } async detail(id: number, ctx: Context): Promise { const record = await this.customerModel.findByPk(id); if (!record) { return { code: 404, message: "客户不存在", data: null }; } const isAdmin = await this.isAdmin(ctx.state.user.userId); if (!isAdmin && record.salesmanId !== ctx.state.user.userId) { return { code: 403, message: "无权限访问该客户", data: null }; } return { code: 200, message: "获取客户详情成功", data: record }; } private async isAdmin(userId: number): Promise { const userRoles = await this.userRoleModel.findAll({ where: { userId }, include: [SysRole] }); return userRoles.some((ur) => { const role = (ur as any).role as SysRole; return role && role.roleCode === "ADMIN"; }); } public async generateCustomerNo(retry: number = 0): Promise { const now = new Date(); const offsetMs = now.getTime() + 8 * 60 * 60 * 1000; const dateLocal = new Date(offsetMs); const yyyy = dateLocal.getUTCFullYear(); const mm = String(dateLocal.getUTCMonth() + 1).padStart(2, "0"); const dd = String(dateLocal.getUTCDate()).padStart(2, "0"); const yyyymmdd = `${yyyy}${mm}${dd}`; const lastRecord = await this.customerModel.findOne({ where: { customerNo: { [Op.like]: `KH${yyyymmdd}%` } }, order: [["customer_no", "DESC"]] }); let newSeq = 1; if (lastRecord) { const lastNo = lastRecord.customerNo; const seqStr = lastNo.slice(-3); const seq = parseInt(seqStr, 10) || 0; newSeq = seq + 1; } const newSeqStr = String(newSeq).padStart(3, "0"); const result = `KH${yyyymmdd}${newSeqStr}`; const exists = await this.customerModel.findOne({ where: { customerNo: result } }); if (exists) { if (retry < 1) { return this.generateCustomerNo(retry + 1); } else { throw new Error("客户编号生成冲突,请重试"); } } return result; } async create(data: any, ctx: Context): Promise { const isAdmin = await this.isAdmin(ctx.state.user.userId); if (!isAdmin) { data.salesmanId = ctx.state.user.userId; } try { data.customerNo = await this.generateCustomerNo(); const created = await this.customerModel.create(data); return { code: 200, message: "创建客户成功", data: created.toJSON() }; } catch (err: any) { if (err instanceof UniqueConstraintError && err.errors?.some((e) => e.path === "customer_no" || e.path === "uk_customer_no")) { try { data.customerNo = await this.generateCustomerNo(); const created = await this.customerModel.create(data); return { code: 200, message: "创建客户成功", data: created.toJSON() }; } catch (_e) { return { code: 400, message: "客户编号冲突,请重试", data: null }; } } throw err; } } async update(id: number, data: any, ctx: Context): Promise { const record = await this.customerModel.findByPk(id); if (!record) { return { code: 404, message: "客户不存在", data: null }; } const isAdmin = await this.isAdmin(ctx.state.user.userId); if (!isAdmin && record.salesmanId !== ctx.state.user.userId) { return { code: 403, message: "无权限操作该客户", data: null }; } delete data.customerNo; delete data.createdAt; delete data.updatedAt; if (!isAdmin) { delete data.salesmanId; } await record.update(data); return { code: 200, message: "更新客户成功", data: record }; } async delete(id: number, ctx: Context): Promise { const record = await this.customerModel.findByPk(id); if (!record) { return { code: 404, message: "客户不存在", data: null }; } const isAdmin = await this.isAdmin(ctx.state.user.userId); if (!isAdmin && record.salesmanId !== ctx.state.user.userId) { return { code: 403, message: "无权限操作该客户", data: null }; } const hasDep = await this.customerDepModel.findOne({ where: { customerId: id }, limit: 1 }); const hasAcc = await this.customerAccModel.findOne({ where: { customerId: id }, limit: 1 }); if (hasDep || hasAcc) { return { code: 400, message: "该客户存在关联的部门或账号,无法删除,请先删除关联数据", data: null }; } await record.destroy(); return { code: 200, message: "删除客户成功", data: null }; } async updateStatus(id: number, status: number, ctx: Context): Promise { const record = await this.customerModel.findByPk(id); if (!record) { return { code: 404, message: "客户不存在", data: null }; } const isAdmin = await this.isAdmin(ctx.state.user.userId); if (!isAdmin && record.salesmanId !== ctx.state.user.userId) { return { code: 403, message: "无权限操作该客户", data: null }; } await record.update({ status }); return { code: 200, message: "更新客户状态成功", data: null }; } async getSimpleList(ctx: Context): Promise { const userId = ctx.state.user.userId; const isAdmin = await this.isAdmin(userId); const where: any = {}; if (!isAdmin) { where.salesmanId = userId; } const rows = await this.customerModel.findAll({ where, attributes: ["id", "customerNo", "customerName", "status"], order: [["created_at", "DESC"]] }); return { code: 200, message: "获取客户选项成功", data: rows.map((r) => r.toJSON()) }; } async getStats(ctx: Context): Promise { const userId = ctx.state.user.userId; const isAdmin = await this.isAdmin(userId); const where: any = {}; if (!isAdmin) { where.salesmanId = userId; } const total = await this.customerModel.count({ where }); const statusRows = await this.customerModel.findAll({ where, attributes: ["status", [fn("COUNT", col("id")), "count"]], group: ["status"], raw: true }); const levelRows = await this.customerModel.findAll({ where, attributes: ["customer_level", [fn("COUNT", col("id")), "count"]], group: ["customer_level"], raw: true }); const statusCounts: Record = {}; for (const row of statusRows as any[]) { if (row.status !== null && row.status !== undefined) { statusCounts[row.status] = Number(row.count) || 0; } } const levelCounts: Record = {}; for (const row of levelRows as any[]) { if (row.customer_level) { levelCounts[row.customer_level] = Number(row.count) || 0; } } return { code: 200, message: "获取客户统计成功", data: { total, statusCounts, levelCounts } }; } }