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;