| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- from app.api.v1.module_system.auth.schema import AuthSchema
- from app.core.exceptions import CustomException
- from app.core.logger import log
- from .crud import PointsCRUD, PointsRecordCRUD
- from .enums import PointsChangeTypeEnum, BusinessTypeEnum
- from .schema import PointsCreateSchema, PointsRecordOutSchema, PointsUpdateSchema, PointsOutSchema, PointsChangeSchema
- class PointsService:
- """积分服务层"""
- @classmethod
- async def create_points_service(
- cls, auth: AuthSchema, data: PointsCreateSchema
- ) -> PointsOutSchema:
- """
- 创建积分账户
- """
- crud = PointsCRUD(auth)
-
- # 检查租户是否已存在积分账户
- existing_points = await crud.get_by_tenant_id(data.tenant_id)
-
- if existing_points:
- raise CustomException(msg="租户已存在积分账户")
- points = await crud.create(data.model_dump(exclude_unset=True), skip_tenant_id=True)
- return PointsOutSchema.model_validate(points)
- @classmethod
- async def get_points_service(cls, auth: AuthSchema) -> PointsOutSchema:
- """
- 查询租户积分
- """
- crud = PointsCRUD(auth)
- points = await crud.get_by_tenant_id(auth.tenant_id)
- if not points:
- raise CustomException(msg="积分账户不存在")
-
- return PointsOutSchema.model_validate(points)
- @classmethod
- async def update_points_service(
- cls, auth: AuthSchema, data: PointsUpdateSchema
- ) -> PointsOutSchema:
- """
- 更新积分
- """
- change_data = PointsChangeSchema(
- points=data.points,
- change_type=PointsChangeTypeEnum.ADD.value,
- business_type=BusinessTypeEnum.RECHARGE.value,
- remark="后台充值"
- )
- return await cls.change_points_service(auth, change_data)
- @classmethod
- async def add_points_service(
- cls, auth: AuthSchema, data: PointsChangeSchema
- ) -> PointsOutSchema:
- """
- 增加积分
- """
- crud = PointsCRUD(auth)
- points = await crud.get_by_tenant_id(auth.tenant_id)
- if not points:
- raise CustomException(msg="积分账户不存在")
- # 计算新的积分余额
- new_points = points.points + data.points
- # 更新积分
- points.points = new_points
- await auth.db.flush()
- await auth.db.refresh(points)
- # 记录积分变动
- record_crud = PointsRecordCRUD(auth)
- await record_crud.create({
- "tenant_id": auth.tenant_id,
- "enterprise_id": data.enterprise_id,
- "employee_id": data.employee_id,
- "points": data.points,
- "balance": new_points,
- "type": PointsChangeTypeEnum.ADD.value,
- "business_type": data.business_type,
- "business_id": data.business_id,
- "remark": data.remark
- })
- log.info(f"增加积分成功: 租户={auth.tenant_id}, 增加={data.points}, 余额={new_points}")
- return PointsOutSchema.model_validate(points)
- @classmethod
- async def deduct_points_service(
- cls, auth: AuthSchema, data: PointsChangeSchema
- ) -> PointsOutSchema:
- """
- 扣除积分
- """
- crud = PointsCRUD(auth)
- points = await crud.get_by_tenant_id(auth.tenant_id)
- if not points:
- raise CustomException(msg="积分账户不存在")
- if points.points < data.points:
- raise CustomException(msg="积分不足")
- # 计算新的积分余额
- new_points = points.points - data.points
- # 更新积分
- points.points = new_points
- await auth.db.flush()
- await auth.db.refresh(points)
- # 记录积分变动
- record_crud = PointsRecordCRUD(auth)
- await record_crud.create({
- "tenant_id": auth.tenant_id,
- "enterprise_id": data.enterprise_id,
- "employee_id": data.employee_id,
- "points": data.points,
- "balance": new_points,
- "type": PointsChangeTypeEnum.DEDUCT.value,
- "business_type": data.business_type,
- "business_id": data.business_id,
- "remark": data.remark
- })
- log.info(f"扣除积分成功: 租户={auth.tenant_id}, 扣除={data.points}, 余额={new_points}")
- return PointsOutSchema.model_validate(points)
- @classmethod
- async def check_points_service(cls, auth: AuthSchema, change_data: PointsChangeSchema) -> bool:
- """
- 检查积分余额
- """
- crud = PointsCRUD(auth)
- points = await crud.get_by_tenant_id(auth.tenant_id)
- return points.points >= change_data.points
- @classmethod
- async def change_points_service(
- cls, auth: AuthSchema, data: PointsChangeSchema
- ) -> PointsOutSchema:
- """
- 通用积分变动
- """
- if data.change_type == PointsChangeTypeEnum.ADD.value:
- return await cls.add_points_service(auth, data)
- elif data.change_type == PointsChangeTypeEnum.DEDUCT.value:
- return await cls.deduct_points_service(auth, data)
- else:
- raise CustomException(msg="无效的积分变动类型")
- @classmethod
- async def list_record_service(
- cls,
- auth: AuthSchema,
- page_no: int = 1,
- page_size: int = 20,
- search: dict | None = None,
- ) -> dict:
- """
- 查询积分记录
- """
- crud = PointsRecordCRUD(auth)
- offset = (page_no - 1) * page_size
- return await crud.page(
- offset=offset,
- limit=page_size,
- order_by=[{"id": "desc"}],
- search=search or {},
- out_schema=PointsRecordOutSchema
- )
|