Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions backend/app/api/v1/module_system/tenant/model.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-

from typing import Optional
from typing import Optional, List, TYPE_CHECKING
from sqlalchemy import Boolean, String
from sqlalchemy.orm import Mapped, mapped_column, validates
from sqlalchemy.orm import Mapped, mapped_column, validates, relationship

from app.core.base_model import ModelMixin

Expand All @@ -15,6 +15,7 @@ class TenantModel(ModelMixin):
__table_args__ = ({'comment': '租户表'})

name: Mapped[Optional[str]] = mapped_column(String(64), nullable=True, default='', comment='租户名称')
code: Mapped[Optional[str]] = mapped_column(String(20), nullable=True, default='', comment='租户编码')
status: Mapped[bool] = mapped_column(Boolean(), default=True, nullable=False, comment="是否启用(True:启用 False:禁用)")

@validates('name')
Expand All @@ -23,3 +24,13 @@ def validate_name(self, key: str, name: str) -> str:
if not name or not name.strip():
raise ValueError('名称不能为空')
return name

@validates('code')
def validate_code(self, key: str, code: str) -> str:
"""验证编码格式校验"""
if not code or not code.strip():
raise ValueError('编码不能为空')
if not code.isalnum():
raise ValueError('编码只能包含字母和数字')
return code

7 changes: 4 additions & 3 deletions backend/app/api/v1/module_system/tenant/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@

class TenantCreateSchema(BaseModel):
"""新增模型"""
name: str = Field(..., max_length=50, description='租户名称')
name: str = Field(..., max_length=64, description='租户名称')
code: Optional[str] = Field(default=None, max_length=20, description='租户编码')
status: bool = Field(True, description="是否启用(True:启用 False:禁用)")
description: Optional[str] = Field(default=None, max_length=255, description="描述")

@field_validator('name')
@field_validator('name')
@classmethod
def _validate_name(cls, v: str) -> str:
v = v.strip()
Expand All @@ -26,7 +27,7 @@ def _after_validation(self):
核心业务规则校验
"""
# 长度校验:名称最小长度
if len(self.name) < 2 or len(self.name) > 50:
if len(self.name) < 2 or len(self.name) > 64:
raise ValueError('名称长度必须在2-50个字符之间')
# 格式校验:名称只能包含字母、数字、下划线和中划线
if not self.name.isalnum() and not all(c in '-_' for c in self.name):
Expand Down
1 change: 1 addition & 0 deletions backend/templates/python/model.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{% if table.sub %}
from sqlalchemy.orm import relationship
{% endif %}
from typing import Optional
from sqlalchemy.orm import Mapped, mapped_column

from app.core.base_model import CreatorMixin
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/api/module_system/tenant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ export interface ObjTable {
index?: number;
id?: number;
name?: string;
code?: string;
status?: boolean;
description?: string;
created_at?: string;
Expand All @@ -108,6 +109,7 @@ export interface ObjTable {
export interface ObjForm {
id?: number;
name?: string;
code?: string;
status?: boolean;
description?: string;
}
12 changes: 12 additions & 0 deletions frontend/src/components/WangEditor/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
* 项目地址:https://gitee.com/youlaiorg/vue3-element-admin
*
* 在使用时,请保留此注释,感谢您对开源的支持!
*
* 修改:此版本返回纯文本格式,使用 editor.getText() 获取内容
-->

<template>
Expand All @@ -24,6 +26,7 @@
:default-config="editorConfig"
mode="simple"
@on-created="handleCreated"
@on-change="handleChange"
/>
</div>
</template>
Expand Down Expand Up @@ -92,6 +95,15 @@ const handleCreated = (editor: any) => {
editorRef.value = editor;
};

// 处理内容变化 - 获取纯文本而不是HTML
const handleChange = (editor: any) => {
editorRef.value = editor;
if (editorRef.value) {
const text = editorRef.value.getText();
modelValue.value = text;
}
};

// 组件销毁时,也及时销毁编辑器,重要!
onBeforeUnmount(() => {
const editor = editorRef.value;
Expand Down
16 changes: 14 additions & 2 deletions frontend/src/views/module_system/tenant/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
</template>
</el-table-column>
<el-table-column v-if="tableColumns.find((col) => col.prop === 'name')?.show" label="名称" prop="name" min-width="140" />
<el-table-column v-if="tableColumns.find((col) => col.prop === 'code')?.show" label="编码" prop="code" min-width="140" />
<el-table-column v-if="tableColumns.find((col) => col.prop === 'status')?.show" label="状态" prop="status" min-width="120">
<template #default="scope">
<el-tag :type="scope.row.status ? 'success' : 'info'">
Expand Down Expand Up @@ -192,6 +193,9 @@
<el-descriptions-item label="名称" :span="2">
{{ detailFormData.name }}
</el-descriptions-item>
<el-descriptions-item label="编码" :span="2">
{{ detailFormData.code }}
</el-descriptions-item>
<el-descriptions-item label="状态" :span="2">
<el-tag :type="detailFormData.status ? 'success' : 'danger'">
{{ detailFormData.status ? '启用' : '停用' }}
Expand All @@ -215,7 +219,10 @@
<template v-else>
<el-form ref="dataFormRef" :model="formData" :rules="rules" label-suffix=":" label-width="auto" label-position="right">
<el-form-item label="名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入名称" :maxlength="50" />
<el-input v-model="formData.name" placeholder="请输入名称" :maxlength="64" />
</el-form-item>
<el-form-item label="编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入编码" :maxlength="20" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
Expand Down Expand Up @@ -259,7 +266,7 @@

<script setup lang="ts">
defineOptions({
name: "Example",
name: "Tenant",
inheritAttrs: false,
});

Expand Down Expand Up @@ -293,6 +300,7 @@ const tableColumns = ref([
{ prop: 'selection', label: '选择框', show: true },
{ prop: 'index', label: '序号', show: true },
{ prop: 'name', label: '名称', show: true },
{ prop: 'code', label: '编码', show: true },
{ prop: 'status', label: '状态', show: true },
{ prop: 'description', label: '描述', show: true },
{ prop: 'created_at', label: '创建时间', show: true },
Expand All @@ -304,6 +312,7 @@ const tableColumns = ref([
// 仅用于导出字段的列(排除非数据列及嵌套对象列)
const exportColumns = [
{ prop: 'name', label: '名称' },
{ prop: 'code', label: '编码' },
{ prop: 'status', label: '状态' },
{ prop: 'description', label: '描述' },
{ prop: 'created_at', label: '创建时间' },
Expand Down Expand Up @@ -366,6 +375,7 @@ const queryFormData = reactive<ObjPageQuery>({
const formData = reactive<ObjForm>({
id: undefined,
name: '',
code: '',
status: true,
description: undefined,
})
Expand All @@ -380,6 +390,7 @@ const dialogVisible = reactive({
// 表单验证规则
const rules = reactive({
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
code: [{ required: true, message: "请输入编码", trigger: "blur" }],
status: [{ required: true, message: "请选择状态", trigger: "blur" }],
});

Expand Down Expand Up @@ -446,6 +457,7 @@ async function handleResetQuery() {
const initialFormData: ObjForm = {
id: undefined,
name: '',
code: '',
status: true,
description: '',
}
Expand Down