diff --git a/client/src/api/customerBuilding.ts b/client/src/api/customerBuilding.ts
index f89a5b7..eb3e215 100644
--- a/client/src/api/customerBuilding.ts
+++ b/client/src/api/customerBuilding.ts
@@ -7,6 +7,7 @@ export interface CustomerBuildingInfo {
basicInfo?: string;
purpose?: string;
floorCount?: number;
+ floorDownCount?: number;
createdAt: string;
}
@@ -30,6 +31,7 @@ export interface CustomerBuildingCreateParams {
basicInfo?: string;
purpose?: string;
floorCount?: number;
+ floorDownCount?: number;
}
export interface CustomerBuildingUpdateParams {
@@ -38,6 +40,7 @@ export interface CustomerBuildingUpdateParams {
basicInfo?: string;
purpose?: string;
floorCount?: number;
+ floorDownCount?: number;
}
export const customerBuildingApi = {
diff --git a/client/src/views/customer/topology/index.vue b/client/src/views/customer/topology/index.vue
index 091afb4..6d96d1d 100644
--- a/client/src/views/customer/topology/index.vue
+++ b/client/src/views/customer/topology/index.vue
@@ -145,8 +145,11 @@
-
-
+
+
+
+
+
@@ -176,7 +179,12 @@
-
+
@@ -237,6 +245,7 @@ const formData = reactive({
buildingName: '',
purpose: '',
floorCount: undefined as number | undefined,
+ floorDownCount: undefined as number | undefined,
basicInfo: '',
roomCode: '',
roomName: '',
@@ -263,6 +272,21 @@ const buildingOptions = computed<{ label: string; value: number }[]>(() => {
const departmentOptions = ref<{ label: string; value: number }[]>([]);
const departmentLoading = ref(false);
+const floorOptions = computed<{ label: string; value: string }[]>(() => {
+ const root = treeData.value[0];
+ const building = root?.children?.find((n) => n.type === 'building' && n.data.id === formData.buildingId);
+ const up = building?.data?.floorCount ?? 0;
+ const down = building?.data?.floorDownCount ?? 0;
+ const opts: { label: string; value: string }[] = [];
+ for (let i = down; i >= 1; i--) {
+ opts.push({ label: `负${i}层`, value: String(-i) });
+ }
+ for (let i = 1; i <= up; i++) {
+ opts.push({ label: `${i}层`, value: String(i) });
+ }
+ return opts;
+});
+
const formRules = computed(() => {
if (modalType.value === 'building') {
return {
@@ -293,7 +317,8 @@ function descFor(data: TreeNode): string {
if (data.type === 'building') {
const b: CustomerBuildingInfo = data.data;
if (b.purpose) parts.push(b.purpose);
- if (b.floorCount != null) parts.push(`共${b.floorCount}层`);
+ if (b.floorCount != null) parts.push(`地上${b.floorCount}层`);
+ if (b.floorDownCount != null && b.floorDownCount > 0) parts.push(`地下${b.floorDownCount}层`);
if (b.basicInfo) parts.push(b.basicInfo);
} else if (data.type === 'room') {
const r: CustomerRoomInfo = data.data;
@@ -407,6 +432,7 @@ function handleEditBuilding(node: TreeNode) {
formData.buildingName = b.buildingName;
formData.purpose = b.purpose || '';
formData.floorCount = b.floorCount;
+ formData.floorDownCount = b.floorDownCount;
formData.basicInfo = b.basicInfo || '';
modalVisible.value = true;
}
@@ -451,6 +477,7 @@ function resetForm() {
formData.buildingName = '';
formData.purpose = '';
formData.floorCount = undefined;
+ formData.floorDownCount = undefined;
formData.basicInfo = '';
formData.roomCode = '';
formData.roomName = '';
@@ -474,12 +501,13 @@ async function handleSubmit() {
let res: any;
if (modalType.value === 'building') {
const payload = {
- customerId: formData.customerId,
- buildingName: formData.buildingName,
- purpose: formData.purpose,
- floorCount: formData.floorCount,
- basicInfo: formData.basicInfo,
- };
+ customerId: formData.customerId,
+ buildingName: formData.buildingName,
+ purpose: formData.purpose,
+ floorCount: formData.floorCount,
+ floorDownCount: formData.floorDownCount,
+ basicInfo: formData.basicInfo,
+ };
if (isEdit.value && editId.value != null) {
res = await customerBuildingApi.update(editId.value, payload);
} else {
diff --git a/database/migrations/20261008_building_floordown_count.sql b/database/migrations/20261008_building_floordown_count.sql
new file mode 100644
index 0000000..9ae197f
--- /dev/null
+++ b/database/migrations/20261008_building_floordown_count.sql
@@ -0,0 +1,5 @@
+-- 客户建筑信息表增加地下楼层数 floordown_count(INT,默认0)
+-- 语义:floor_count 为地上楼层数,floordown_count 为地下楼层数
+-- 幂等:ADD COLUMN IF NOT EXISTS 重复执行安全
+ALTER TABLE customer_building
+ ADD COLUMN IF NOT EXISTS floordown_count INT DEFAULT 0;
\ No newline at end of file
diff --git a/server/src/dto/customer_building.dto.ts b/server/src/dto/customer_building.dto.ts
index 45ec416..7141101 100644
--- a/server/src/dto/customer_building.dto.ts
+++ b/server/src/dto/customer_building.dto.ts
@@ -13,6 +13,7 @@ export class CustomerBuildingCreateDTO {
@IsOptional() @IsString() @MaxLength(2000) @Matches(/^[^<>]*$/) basicInfo?: string;
@IsOptional() @IsString() @MaxLength(128) @Matches(/^[^<>]*$/) purpose?: string;
@IsOptional() @IsInt() @Min(0) floorCount?: number;
+ @IsOptional() @IsInt() @Min(0) floorDownCount?: number;
}
export class CustomerBuildingUpdateDTO {
@@ -21,4 +22,5 @@ export class CustomerBuildingUpdateDTO {
@IsOptional() @IsString() @MaxLength(2000) @Matches(/^[^<>]*$/) basicInfo?: string;
@IsOptional() @IsString() @MaxLength(128) @Matches(/^[^<>]*$/) purpose?: string;
@IsOptional() @IsInt() @Min(0) floorCount?: number;
+ @IsOptional() @IsInt() @Min(0) floorDownCount?: number;
}
\ No newline at end of file
diff --git a/server/src/entity/customer_building.entity.ts b/server/src/entity/customer_building.entity.ts
index 1fa5b13..9c3f500 100644
--- a/server/src/entity/customer_building.entity.ts
+++ b/server/src/entity/customer_building.entity.ts
@@ -26,9 +26,12 @@ export default class CustomerBuilding extends Model {
@Column({ type: DataType.STRING(128), comment: "用途" })
purpose!: string;
- @Column({ type: DataType.INTEGER, field: "floor_count", comment: "层数" })
+ @Column({ type: DataType.INTEGER, field: "floor_count", comment: "地上楼层数" })
floorCount!: number;
+ @Column({ type: DataType.INTEGER, field: "floordown_count", comment: "地下楼层数", defaultValue: 0 })
+ floorDownCount!: number;
+
@BelongsTo(() => Customer)
customer!: Customer;