diff --git a/backend/alembic/versions/dd9d72cfd3c4_003_upgrade_term_table.py b/backend/alembic/versions/dd9d72cfd3c4_003_upgrade_term_table.py
new file mode 100644
index 00000000..4eb2da4f
--- /dev/null
+++ b/backend/alembic/versions/dd9d72cfd3c4_003_upgrade_term_table.py
@@ -0,0 +1,35 @@
+"""003_Upgrade_Term_Table
+
+Revision ID: dd9d72cfd3c4
+Revises: 1c8bcc7e25c8
+Create Date: 2025-04-27 14:56:29.185812
+
+"""
+from alembic import op
+import sqlalchemy as sa
+import sqlmodel.sql.sqltypes
+
+
+# revision identifiers, used by Alembic.
+revision = 'dd9d72cfd3c4'
+down_revision = '1c8bcc7e25c8'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.alter_column('terms', 'id',
+ existing_type=sa.INTEGER(),
+ type_=sa.BigInteger(),
+ existing_nullable=False)
+ # ### end Alembic commands ###
+
+
+def downgrade():
+ # ### commands auto generated by Alembic - please adjust! ###
+ op.alter_column('terms', 'id',
+ existing_type=sa.BigInteger(),
+ type_=sa.INTEGER(),
+ existing_nullable=False)
+ # ### end Alembic commands ###
diff --git a/backend/apps/settings/api/terminology.py b/backend/apps/settings/api/terminology.py
index c7716d5a..62b6a1a3 100644
--- a/backend/apps/settings/api/terminology.py
+++ b/backend/apps/settings/api/terminology.py
@@ -1,5 +1,7 @@
-from fastapi import APIRouter
+from fastapi import APIRouter
+from sqlmodel import select
from apps.settings.models.setting_models import term_model
+from apps.settings.schemas.setting_schemas import term_schema_creator
from common.core.deps import SessionDep
from common.core.pagination import Paginator
from common.core.schemas import PaginatedResponse, PaginationParams
@@ -18,4 +20,49 @@ async def pager(
return await paginator.get_paginated_response(
model=term_model,
pagination=pagination,
- **filters)
\ No newline at end of file
+ **filters)
+
+
+@router.get("/{id}", response_model=term_model)
+async def get_terminology_by_id(
+ session: SessionDep,
+ id: int
+):
+ term = session.get(term_model, id)
+ return term
+
+@router.post("", response_model=term_model)
+async def add_terminology(
+ session: SessionDep,
+ creator: term_schema_creator
+):
+ terminology = term_model(**creator.model_dump())
+ session.add(terminology)
+ session.commit()
+ return terminology
+
+@router.put("", response_model=term_model)
+async def update_terminology(
+ session: SessionDep,
+ terminology: term_model
+):
+ terminology.id = int(terminology.id)
+ term = session.exec(select(term_model).where(term_model.id == terminology.id)).first()
+ update_data = terminology.model_dump(exclude_unset=True)
+ for field, value in update_data.items():
+ setattr(term, field, value)
+ session.add(term)
+ session.commit()
+ return terminology
+
+@router.delete("/{id}", response_model=term_model)
+async def delete_terminology(
+ session: SessionDep,
+ id: int
+):
+ term = session.exec(select(term_model).where(term_model.id == id)).first()
+ session.delete(term)
+ session.commit()
+ return {
+ "message": f"Terminology with ID {id} deleted successfully."
+ }
diff --git a/backend/apps/settings/models/setting_models.py b/backend/apps/settings/models/setting_models.py
index 83fc5a60..29de7c85 100644
--- a/backend/apps/settings/models/setting_models.py
+++ b/backend/apps/settings/models/setting_models.py
@@ -1,10 +1,10 @@
from sqlmodel import Field, SQLModel
+from common.core.models import SnowflakeBase
-class term_model(SQLModel, table=True):
+
+class term_model(SnowflakeBase, table=True):
__tablename__ = "terms"
-
- id: int = Field(primary_key=True, index=True)
term: str = Field(max_length=255)
definition: str = Field(max_length=255)
domain: str = Field(max_length=255)
diff --git a/backend/apps/settings/schemas/setting_schemas.py b/backend/apps/settings/schemas/setting_schemas.py
index a4b11401..01378647 100644
--- a/backend/apps/settings/schemas/setting_schemas.py
+++ b/backend/apps/settings/schemas/setting_schemas.py
@@ -1,7 +1,6 @@
from pydantic import BaseModel
-class term_schema(BaseModel):
- id: int
+class term_schema_creator(BaseModel):
term: str
definition: str
domain: str
diff --git a/backend/common/core/models.py b/backend/common/core/models.py
new file mode 100644
index 00000000..57718314
--- /dev/null
+++ b/backend/common/core/models.py
@@ -0,0 +1,33 @@
+from pydantic import field_validator
+from sqlmodel import BigInteger, SQLModel, Field
+from typing import Optional
+
+from common.utils.snowflake import snowflake
+
+class SnowflakeBase(SQLModel):
+ id: Optional[int] = Field(
+ default_factory=snowflake.generate_id,
+ primary_key=True,
+ sa_type=BigInteger(),
+ index=True,
+ nullable=False
+ )
+
+ @field_validator("id", mode="before")
+ def validate_id(cls, v):
+ if isinstance(v, str):
+ if not v:
+ return None
+ try:
+ return int(v)
+ except ValueError:
+ raise ValueError("Invalid bigint string")
+ elif isinstance(v, int):
+ return v
+ raise TypeError("BigInt must be int or string")
+
+
+ class Config:
+ json_encoders = {
+ int: lambda v: str(v) if v > 2**53-1 else v
+ }
\ No newline at end of file
diff --git a/backend/common/utils/snowflake.py b/backend/common/utils/snowflake.py
new file mode 100644
index 00000000..5f75e8fa
--- /dev/null
+++ b/backend/common/utils/snowflake.py
@@ -0,0 +1,57 @@
+import time
+import threading
+class SnowflakeGenerator:
+ def __init__(self, worker_id=0, datacenter_id=0):
+ self.worker_id = worker_id
+ self.datacenter_id = datacenter_id
+ self.sequence = 0
+ self.last_timestamp = -1
+ self.lock = threading.Lock()
+
+ self.worker_id_bits = 5
+ self.datacenter_id_bits = 5
+ self.max_worker_id = -1 ^ (-1 << self.worker_id_bits)
+ self.max_datacenter_id = -1 ^ (-1 << self.datacenter_id_bits)
+ self.sequence_bits = 12
+
+ self.worker_id_shift = self.sequence_bits
+ self.datacenter_id_shift = self.sequence_bits + self.worker_id_bits
+ self.timestamp_left_shift = self.sequence_bits + self.worker_id_bits + self.datacenter_id_bits
+ self.sequence_mask = -1 ^ (-1 << self.sequence_bits)
+
+ if self.worker_id > self.max_worker_id or self.worker_id < 0:
+ raise ValueError(f"worker ID can't be greater than {self.max_worker_id} or less than 0")
+ if self.datacenter_id > self.max_datacenter_id or self.datacenter_id < 0:
+ raise ValueError(f"datacenter ID can't be greater than {self.max_datacenter_id} or less than 0")
+
+ def _current_time(self):
+ return int(time.time() * 1000)
+
+ def _wait_next_millis(self, last_timestamp):
+ timestamp = self._current_time()
+ while timestamp <= last_timestamp:
+ timestamp = self._current_time()
+ return timestamp
+
+ def generate_id(self):
+ with self.lock:
+ timestamp = self._current_time()
+
+ if timestamp < self.last_timestamp:
+ raise ValueError("Clock moved backwards. Refusing to generate ID")
+
+ if timestamp == self.last_timestamp:
+ self.sequence = (self.sequence + 1) & self.sequence_mask
+ if self.sequence == 0:
+ timestamp = self._wait_next_millis(self.last_timestamp)
+ else:
+ self.sequence = 0
+
+ self.last_timestamp = timestamp
+
+ return ((timestamp << self.timestamp_left_shift) |
+ (self.datacenter_id << self.datacenter_id_shift) |
+ (self.worker_id << self.worker_id_shift) |
+ self.sequence)
+
+snowflake = SnowflakeGenerator(worker_id=1)
\ No newline at end of file
diff --git a/backend/scripts/alembic/exec.sh b/backend/scripts/alembic/exec.sh
new file mode 100755
index 00000000..35381fd5
--- /dev/null
+++ b/backend/scripts/alembic/exec.sh
@@ -0,0 +1 @@
+alembic upgrade head
\ No newline at end of file
diff --git a/backend/scripts/prestart.sh b/backend/scripts/prestart.sh
old mode 100644
new mode 100755
diff --git a/backend/scripts/tests-start.sh b/backend/scripts/tests-start.sh
old mode 100644
new mode 100755
diff --git a/frontend/auto-imports.d.ts b/frontend/auto-imports.d.ts
index 76e1ee65..21b8307c 100644
--- a/frontend/auto-imports.d.ts
+++ b/frontend/auto-imports.d.ts
@@ -7,4 +7,5 @@
export {}
declare global {
const ElMessage: typeof import('element-plus/es')['ElMessage']
+ const ElMessageBox: typeof import('element-plus/es')['ElMessageBox']
}
diff --git a/frontend/src/api/setting.ts b/frontend/src/api/setting.ts
new file mode 100644
index 00000000..45dc7de5
--- /dev/null
+++ b/frontend/src/api/setting.ts
@@ -0,0 +1,9 @@
+import { request } from '@/utils/request'
+
+export const termApi = {
+ pager: (pageNumber: number, pageSize: number) => request.get(`/settings/terminology/pager/${pageNumber}/${pageSize}`),
+ add: (data: any) => request.post('/settings/terminology', data),
+ edit: (data: any) => request.put('/settings/terminology', data),
+ delete: (id: number) => request.delete(`/settings/terminology/${id}`),
+ query: (id: number) => request.get(`/settings/terminology/${id}`)
+}
\ No newline at end of file
diff --git a/frontend/src/utils/request.ts b/frontend/src/utils/request.ts
index a9a34309..f6df087d 100644
--- a/frontend/src/utils/request.ts
+++ b/frontend/src/utils/request.ts
@@ -91,11 +91,10 @@ class HttpService {
}
// Handle business logic
- if (response.data?.success !== true) {
+ /* if (response.data?.success !== true) {
return Promise.reject(response.data)
- }
-
- return response.data.data
+ } */
+ return response.data
},
async (error: AxiosError) => {
const config = error.config as FullRequestConfig & { __retryCount?: number }
diff --git a/frontend/src/views/setting/Professional.vue b/frontend/src/views/setting/Professional.vue
index 0dbc0076..1db27fba 100644
--- a/frontend/src/views/setting/Professional.vue
+++ b/frontend/src/views/setting/Professional.vue
@@ -23,7 +23,7 @@