diff --git a/backend/dvadmin/system/views/login.py b/backend/dvadmin/system/views/login.py
index da39cf2..c51ed64 100644
--- a/backend/dvadmin/system/views/login.py
+++ b/backend/dvadmin/system/views/login.py
@@ -28,6 +28,13 @@ from dvadmin.utils.validator import CustomValidationError
logger = logging.getLogger(__name__)
+def _is_supplier_portal_role_key(role_key: str) -> bool:
+ """供应商端登录:允许 role.key 为 supplier 或 supplier_*(如 supplier_quote)。"""
+ if not role_key:
+ return False
+ return role_key == "supplier" or role_key.startswith("supplier_")
+
+
class CaptchaView(APIView):
authentication_classes = []
permission_classes = []
@@ -143,7 +150,7 @@ class LoginSerializer(TokenObtainPairSerializer):
class SupplierLoginSerializer(TokenObtainPairSerializer):
"""
供应商登录的序列化器
- 复用 LoginSerializer 的验证逻辑,额外校验 role.key = 'supplier'
+ 复用 LoginSerializer 的验证逻辑,额外校验 role.key 为 supplier 或 supplier_*(如 supplier_quote)
"""
captcha = serializers.CharField(
max_length=6, required=False, allow_null=True, allow_blank=True
@@ -189,10 +196,10 @@ class SupplierLoginSerializer(TokenObtainPairSerializer):
# 必须重置用户名为username,否则使用邮箱手机号登录会提示密码错误
attrs['username'] = user.username
- # 校验用户角色是否为供应商
+ # 校验用户角色是否为供应商(含 supplier_quote 等 supplier_*)
user_roles = user.role.all()
role_keys = [r.key for r in user_roles]
- if 'supplier' not in role_keys:
+ if not any(_is_supplier_portal_role_key(k) for k in role_keys):
raise CustomValidationError("该账号不是供应商账号,请使用采购方入口登录")
try:
diff --git a/web/src/views/pisadmin/dashboard/index.vue b/web/src/views/pisadmin/dashboard/index.vue
index d8b8a64..e1a8d04 100644
--- a/web/src/views/pisadmin/dashboard/index.vue
+++ b/web/src/views/pisadmin/dashboard/index.vue
@@ -8,7 +8,7 @@
-
+
@@ -27,6 +27,10 @@ const { buyer, supplier } = storeToRefs(store);
const currentRole = ref('buyer');
+/** 供应商侧仪表盘:角色标识为 supplier_*(如 supplier_quote),兼容历史值 supplier */
+const isSupplierDashboardRole = (role: string) =>
+ role === 'supplier' || /^supplier_/.test(role);
+
const hasBuyerRole = computed(() => !!buyer.value);
const hasSupplierRole = computed(() => !!supplier.value);
const hasBothRoles = computed(() => hasBuyerRole.value && hasSupplierRole.value);
@@ -46,10 +50,10 @@ onMounted(() => {
});
// 如果只有采购方权限,默认 buyer
-// 如果只有供应商权限,默认 supplier
+// 如果只有供应商权限,默认 supplier_*(当前为 supplier_quote)
// 初始化时确保 currentRole 与可用角色匹配
if (!hasBuyerRole.value && hasSupplierRole.value) {
- currentRole.value = 'supplier';
+ currentRole.value = 'supplier_quote';
}
// 如果后端返回了数据但 currentRole 不匹配角色,则默认 buyer
@@ -61,13 +65,13 @@ if (hasBuyerRole.value && !hasBothRoles.value) {
watch([hasBuyerRole, hasSupplierRole], () => {
if (hasBothRoles.value) {
// 双方角色,默认 buyer
- if (currentRole.value !== 'buyer' && currentRole.value !== 'supplier') {
+ if (currentRole.value !== 'buyer' && !isSupplierDashboardRole(currentRole.value)) {
currentRole.value = 'buyer';
}
} else if (hasBuyerRole.value) {
currentRole.value = 'buyer';
} else if (hasSupplierRole.value) {
- currentRole.value = 'supplier';
+ currentRole.value = 'supplier_quote';
}
});