1
0
forked from erp-dev/erp

feat: shipment patch

This commit is contained in:
2026-04-02 18:07:06 +08:00
parent d36d9c1d9c
commit 1be840a8c2
14 changed files with 979 additions and 72 deletions

View File

@@ -0,0 +1,74 @@
import json
from django.core.management.base import BaseCommand, CommandError
from basic_info import models as basic_models
from basic_info.services import EmployeeUserProvisioningService
class Command(BaseCommand):
help = "快速创建系统用户并绑定 Employee适合人工脚本或 MCP 调用。"
def add_arguments(self, parser):
parser.add_argument("--username", required=True, help="用户名")
parser.add_argument("--password", required=True, help="密码")
parser.add_argument("--display-name", required=True, help="员工显示名称")
parser.add_argument("--merchant-id", type=int, required=True, help="商户 ID")
parser.add_argument("--email", default="", help="邮箱(可选)")
parser.add_argument("--mobile", default="", help="手机号(可选)")
parser.add_argument("--area", default="", help="地区(可选)")
parser.add_argument("--description", default="", help="描述(可选)")
parser.add_argument(
"--status",
default=basic_models.EmployeeStatusEnum.ACTIVE,
help="员工状态枚举文本,默认 在职",
)
parser.add_argument("--role-id", type=int, default=None, help="角色 ID可选")
parser.add_argument(
"--json",
action="store_true",
help="以 JSON 输出结果,适合脚本或 MCP 调用",
)
def handle(self, *args, **options):
try:
result = EmployeeUserProvisioningService.quick_create_employee_user(
username=options["username"],
password=options["password"],
display_name=options["display_name"],
merchant_id=options["merchant_id"],
email=options["email"],
mobile=options["mobile"],
area=options["area"],
description=options["description"],
status=options["status"],
role_id=options["role_id"],
)
except ValueError as exc:
if options["json"]:
self.stdout.write(
json.dumps(
{"ok": False, "error": str(exc)},
ensure_ascii=False,
)
)
return
raise CommandError(str(exc))
payload = {
"ok": True,
"result": result.to_dict(),
}
if options["json"]:
self.stdout.write(json.dumps(payload, ensure_ascii=False))
return
user_payload = payload["result"]["user"]
employee_payload = payload["result"]["employee"]
self.stdout.write(self.style.SUCCESS("创建成功"))
self.stdout.write(
f"user: id={user_payload['id']} username={user_payload['username']} role_id={user_payload['role_id']}"
)
self.stdout.write(
f"employee: id={employee_payload['id']} name={employee_payload['name']} merchant={employee_payload['merchant']} status={employee_payload['status']}"
)

View File

@@ -1,6 +1,13 @@
from dataclasses import dataclass
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.db import transaction
from django.db.models import Q
from . import models as basic_models
User = get_user_model()
class CustomerVisibilityService:
@staticmethod
@@ -79,3 +86,88 @@ class MerchantSettingService:
@staticmethod
def get_setting(merchant: basic_models.Merchant, key: basic_models.MerchantSettingKeyEnum):
return basic_models.MerchantSetting.objects.get(merchant=merchant, key=key)
@dataclass
class QuickCreateEmployeeUserResult:
user: object
employee: basic_models.Employee
role_id: int | None
def to_dict(self) -> dict:
return {
"user": {
"id": self.user.id,
"username": self.user.username,
"display_name": self.employee.name,
"role_id": self.role_id,
},
"employee": {
"id": self.employee.id,
"name": self.employee.name,
"status": self.employee.status,
"merchant": self.employee.merchant_id,
},
}
class EmployeeUserProvisioningService:
@staticmethod
def quick_create_employee_user(
*,
username: str,
password: str,
display_name: str,
merchant_id: int,
email: str | None = None,
mobile: str | None = None,
area: str | None = None,
description: str | None = None,
status: int | None = None,
role_id: int | None = None,
) -> QuickCreateEmployeeUserResult:
username = (username or "").strip()
if not username:
raise ValueError("用户名不能为空")
if User.objects.filter(username=username).exists():
raise ValueError("用户名已存在")
merchant = basic_models.Merchant.objects.filter(id=merchant_id).first()
if merchant is None:
raise ValueError("商户不存在")
group = None
if role_id is not None:
group = Group.objects.filter(id=role_id).first()
if group is None:
raise ValueError("角色不存在")
status_value = status or basic_models.EmployeeStatusEnum.ACTIVE
with transaction.atomic():
user = User.objects.create_user(
username=username,
password=password,
email=(email or "").strip(),
)
user.first_name = display_name
user.save(update_fields=["first_name"])
if group is not None:
user.groups.add(group)
employee = basic_models.Employee.objects.create(
merchant=merchant,
sys_user=user,
name=display_name,
mobile=(mobile or "").strip(),
area=(area or "").strip(),
description=(description or "").strip(),
status=status_value,
)
return QuickCreateEmployeeUserResult(
user=user,
employee=employee,
role_id=group.id if group is not None else None,
)