Skip to content

Commit 126157c

Browse files
committed
feat: 新增目标房型节点
1 parent 897e048 commit 126157c

File tree

6 files changed

+200
-179
lines changed

6 files changed

+200
-179
lines changed

__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
from .node_mappings import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
66

7-
WEB_DIRECTORY = "./web"
7+
# WEB_DIRECTORY = "./web"
88

99
print(f"{blue}ComfyUI Baikong Buying: {green}Loaded nodes successfully.{color_end}")
1010

11-
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
11+
# __all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
12+
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"]

node_mappings.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88
node_module_mappings = {
99
'node_housing_decision': 'BK_HousingDecision',
10-
'node_table_preview': 'BK_Table_Preview',
11-
'node_district_info': 'BK_District_Info'
10+
'node_housing_calc': 'BK_HousingCalc',
11+
'node_housing_info': 'BK_HousingInfo'
1212
}
1313

1414
imported_classes = {}
@@ -29,6 +29,6 @@
2929

3030
NODE_DISPLAY_NAME_MAPPINGS = {
3131
"BK_HousingDecision": "BK Housing Decision",
32-
"BK_Table_Preview": "BK Table Preview",
33-
"BK_District_Info": "BK District Info"
32+
"BK_HousingCalc": "BK Housing Calc",
33+
"BK_HousingInfo": "BK Housing Info"
3434
}

nodes/node_housing_calc.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import torch
4+
import pandas as pd
5+
import numpy as np
6+
from PIL import Image
7+
import json
8+
from io import StringIO
9+
import matplotlib.pyplot as plt
10+
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
11+
from matplotlib.font_manager import FontProperties
12+
import os
13+
14+
# Tensor to PIL
15+
16+
17+
def tensor2pil(image):
18+
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
19+
20+
# Convert PIL to Tensor
21+
22+
23+
def pil2tensor(image):
24+
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
25+
26+
27+
class BK_HousingCalc:
28+
29+
@classmethod
30+
def INPUT_TYPES(s):
31+
return {
32+
"required": {
33+
"csv": ("CSV",),
34+
},
35+
"optional": {
36+
"sort_by": ("STRING", {
37+
"default": "房屋总价,得房率",
38+
"multiline": False,
39+
}),
40+
"sort_direction": (["正序", "倒序"], {"default": "正序"}),
41+
},
42+
"hidden": {
43+
"unique_id": "UNIQUE_ID",
44+
"extra_pnginfo": "EXTRA_PNGINFO",
45+
},
46+
}
47+
48+
RETURN_TYPES = ("STRING", "STRING", "IMAGE")
49+
RETURN_NAMES = ("JSON", "CSV", "IMAGE")
50+
FUNCTION = "exec"
51+
OUTPUT_NODE = True
52+
CATEGORY = "⭐️ Baikong"
53+
DESCRIPTION = "使用 Table 预览数据,并输出 csv、json 两种格式的结果" Excel"
54+
55+
def json_to_table(self, json_data):
56+
57+
# 将 JSON 数据转换为 DataFrame
58+
df = pd.json_normalize(json_data)
59+
60+
# 填充缺失值为 "-"
61+
df.fillna("-", inplace=True)
62+
63+
return df
64+
65+
def create_table_image(self, df):
66+
# 设置更高的 DPI 值来提高清晰度
67+
plt.rcParams['figure.dpi'] = 200
68+
69+
# 调整高度计算方式,减小系数
70+
rows = len(df) + 1 # +1 是为了包含表头
71+
fig, ax = plt.subplots(
72+
figsize=(15, max(4, rows * 0.25)), dpi=200)
73+
ax.axis('tight')
74+
ax.axis('off')
75+
76+
# 获取字体文件路径
77+
font_dir = os.path.join(os.path.dirname(
78+
os.path.dirname(os.path.realpath(__file__))), "fonts")
79+
font_path = os.path.join(font_dir, "AlibabaPuHuiTi-3-45-Light.ttf")
80+
font_prop = FontProperties(fname=font_path)
81+
82+
# 创建表格时应用字体
83+
table = ax.table(cellText=df.values,
84+
colLabels=df.columns,
85+
cellLoc='center',
86+
loc='center')
87+
88+
# 调整表格样式并应用字体
89+
table.auto_set_font_size(False)
90+
table.set_fontsize(9)
91+
92+
# 为每个单元格设置字体
93+
for cell in table._cells.values():
94+
cell.set_text_props(fontproperties=font_prop)
95+
cell.set_edgecolor('black')
96+
cell.set_linewidth(0.5)
97+
98+
# 自动调整布局以确保表格完全显示
99+
plt.tight_layout()
100+
101+
# 将图表转换为图片时保持高 DPI
102+
canvas = FigureCanvas(fig)
103+
canvas.draw()
104+
105+
# 获取更高分辨率的图像数据
106+
s, (width, height) = canvas.print_to_buffer()
107+
image = Image.frombytes("RGBA", (width, height), s)
108+
image = image.convert('RGB')
109+
plt.close(fig)
110+
111+
return image
112+
113+
def exec(self, csv, sort_by="", sort_direction="正序", unique_id=None, extra_pnginfo=None):
114+
if unique_id is not None and extra_pnginfo is not None:
115+
df = pd.read_csv(StringIO(csv))
116+
117+
# 填充缺失值为 "-"
118+
df.fillna("-", inplace=True)
119+
120+
# 处理排序
121+
if sort_by.strip():
122+
# 将排序字段拆分为列表
123+
sort_columns = [col.strip() for col in sort_by.split(',')]
124+
# 验证所有排序列是否存在
125+
valid_columns = [
126+
col for col in sort_columns if col in df.columns]
127+
128+
if valid_columns:
129+
# 根据选择的方向确定升序还是降序
130+
ascending = True if sort_direction == "正序" else False
131+
# 如果是多列排序,创建相同长度的 ascending 列表
132+
if len(valid_columns) > 1:
133+
ascending = [ascending] * len(valid_columns)
134+
135+
df = df.sort_values(by=valid_columns, ascending=ascending)
136+
print(f"[BK_Table_Preview] ○ Sorted by {
137+
valid_columns} in {sort_direction} order")
138+
else:
139+
print(
140+
f"[BK_Table_Preview] ⚠️ Warning: No valid column names found in {sort_by}")
141+
142+
# 将表格转换为 JSON 格式
143+
json_output = df.to_json(
144+
orient='records', force_ascii=False)
145+
146+
# 将 DataFrame 转换为 CSV 字符串
147+
csv_output = df.to_csv(index=False)
148+
149+
# 创建表格图片
150+
table_image = self.create_table_image(df)
151+
# 转换为 tensor
152+
table_tensor = pil2tensor(table_image)
153+
154+
# print(f"[BK_Table_Preview] ○ INPUT {df}")
155+
156+
return (json.dumps(json.loads(json_output),
157+
ensure_ascii=False,
158+
indent=2),
159+
csv_output,
160+
table_tensor)

nodes/node_district_info.py renamed to nodes/node_housing_info.py

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,50 @@
22

33
import pandas as pd
44
import json
5+
from io import StringIO
56

6-
class BK_District_Info:
7+
class BK_HousingInfo:
78

89
@classmethod
910
def INPUT_TYPES(s):
1011
return {
1112
"required": {},
1213
"optional": {
14+
"pipeline": ("CSV",),
1315
"小区名称": ("STRING",{"default": "滨运锦绣里",}),
14-
"房屋总价": ("INT", {"default": 4000000, "min": 0, "max": 99999999999}),
16+
"房屋总价": ("INT", {"default": 4200000, "min": 0, "max": 99999999999}),
1517
"室": ("INT", {"default": 3, "min": 0, "max": 20}),
1618
"厅": ("INT", {"default": 2, "min": 0, "max": 10}),
1719
"卫": ("INT", {"default": 2, "min": 0, "max": 10}),
18-
"建筑面积": ("FLOAT", {"default": 100.0, "min": 0, "max": 1000, "step": 0.01}),
19-
"得房率": ("INT", {"default": 80, "min": 0, "max": 200, "step": 1}),
20-
"当前楼层": ("INT", {"default": 4, "min": 0, "max": 100}),
21-
"总楼层": ("INT", {"default": 8, "min": 0, "max": 100}),
20+
"建筑面积": ("FLOAT", {"default": 110.0, "min": 0, "max": 1000, "step": 0.01}),
21+
"得房率": ("INT", {"default": 91, "min": 0, "max": 200, "step": 1}),
22+
"当前楼层": ("INT", {"default": 16, "min": 0, "max": 100}),
23+
"总楼层": ("INT", {"default": 17, "min": 0, "max": 100}),
24+
"装修标准": ("INT", {"default": 4000, "min": 0, "max": 99999999999}),
2225
"房屋权属": (["商品房","公房","经济适用房","其他",],{"default": "商品房"}),
2326
"楼房类型": (["塔楼", "板楼", "高层", "小高层", "超高层"],{"default": "塔楼"}),
2427
"房屋用途": (["普通住宅","商业类","别墅","四合院","车位","其他",],{"default": "普通住宅"}),
2528
"房屋类型": (["新房","二手房"],{"default": "新房"}),
2629
"装修": (["精装修","无"],{"default": "精装修"}),
2730
"交房时间": ("STRING",{"default": "2024-11",}),
28-
"物业费": ("FLOAT", {"default": 3.0, "min": 0, "max": 100, "step": 0.01}),
31+
"物业费": ("FLOAT", {"default": 5.5, "min": 0, "max": 100, "step": 0.01}),
32+
"容积率": ("FLOAT", {"default": 2.2, "min": 0, "max": 100, "step": 0.01}),
33+
"总户数": ("INT", {"default": 1500, "min": 0, "max": 5000}),
2934
}
3035
}
36+
3137
RETURN_TYPES = ("CSV", )
3238
RETURN_NAMES = ("CSV", )
3339
FUNCTION = "exec"
3440
OUTPUT_NODE = True
3541
CATEGORY = "⭐️ Baikong"
36-
DESCRIPTION = "预览 Excel"
42+
DESCRIPTION = "目标房产的基础信息"
3743

38-
def exec(self, 房屋总价, , , , 建筑面积, 小区名称=None, 得房率=None,
39-
当前楼层=None, 总楼层=None, 房屋用途=None, 房屋权属=None, 楼房类型=None,
40-
房屋类型=None, 装修=None, 交房时间=None, 物业费=None):
44+
def exec(self, pipeline=None, 房屋总价=None, =None, =None, =None, 建筑面积=None,
45+
小区名称=None, 得房率=None, 当前楼层=None, 总楼层=None, 装修标准=None, 房屋用途=None,
46+
房屋权属=None, 楼房类型=None, 房屋类型=None, 装修=None, 交房时间=None, 物业费=None,
47+
容积率=None, 总户数=None):
4148

42-
# 创建一个字典来存储输入数据
4349
data = {
4450
"小区名称": 小区名称 or "-",
4551
"房屋总价": f"{房屋总价/10000:.2f}万元",
@@ -48,21 +54,28 @@ def exec(self, 房屋总价, 室, 厅, 卫, 建筑面积, 小区名称=None, 得
4854
"得房率": f"{得房率}%" or "-",
4955
"套内面积": f"{建筑面积*得房率/100:.2f}m²" or "-",
5056
"楼层": f"{当前楼层}/{总楼层}" or "-",
57+
"装修标准": f"{装修标准}元/m²" or "-",
5158
"交房时间": 交房时间 or "-",
5259
"物业费(月)": f"{物业费}元/m²" or "-",
5360
"物业费(年)": f"{物业费*建筑面积*12:.2f}元" or "-",
5461
"房屋用途": 房屋用途 or "-",
5562
"楼房类型": 楼房类型 or "-",
5663
"房屋类型": 房屋类型 or "-",
57-
"装修": 装修 or "-"
64+
"装修": 装修 or "-",
65+
"容积率": 容积率 or "-",
66+
"总户数": 总户数 or "-"
5867
}
5968

60-
# 将数据转换为 DataFrame
61-
df = pd.DataFrame([data])
69+
current_df = pd.DataFrame([data])
70+
71+
if pipeline is not None:
72+
pipeline_df = pd.read_csv(StringIO(pipeline))
73+
combined_df = pd.concat([pipeline_df, current_df], ignore_index=True)
74+
else:
75+
combined_df = current_df
6276

63-
result = df.to_csv(index=False, encoding='utf-8')
77+
result = combined_df.to_csv(index=False, encoding='utf-8')
6478

65-
print(f"[BK_District_Info] ○ INPUT {result}")
79+
print(f"[BK_District_Info] ○ INPUT {小区名称}-{}{}{}")
6680

67-
# 返回 DataFrame 作为 CSV 格式
68-
return (result,)
81+
return (result,)

0 commit comments

Comments
 (0)