编辑款式下拉框修复

This commit is contained in:
2025-12-23 12:35:07 +08:00
parent 033a1acef3
commit 58605b1f92
7 changed files with 399 additions and 228 deletions

View File

@@ -32,6 +32,7 @@ class DatabaseManager:
CREATE TABLE IF NOT EXISTS fabrics ( CREATE TABLE IF NOT EXISTS fabrics (
model TEXT PRIMARY KEY, model TEXT PRIMARY KEY,
category TEXT DEFAULT '未分类', category TEXT DEFAULT '未分类',
fabric_type TEXT,
supplier TEXT, supplier TEXT,
color TEXT, color TEXT,
width REAL, width REAL,
@@ -47,6 +48,7 @@ class DatabaseManager:
# 为fabrics表添加索引 # 为fabrics表添加索引
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabrics_category ON fabrics(category)') conn.execute('CREATE INDEX IF NOT EXISTS idx_fabrics_category ON fabrics(category)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabrics_fabric_type ON fabrics(fabric_type)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabrics_supplier ON fabrics(supplier)') conn.execute('CREATE INDEX IF NOT EXISTS idx_fabrics_supplier ON fabrics(supplier)')
# 衣服款号表 # 衣服款号表
@@ -66,6 +68,7 @@ class DatabaseManager:
style_number TEXT, style_number TEXT,
category TEXT, category TEXT,
fabric_type TEXT, fabric_type TEXT,
model TEXT,
usage_per_piece REAL, usage_per_piece REAL,
unit TEXT DEFAULT '', unit TEXT DEFAULT '',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP, created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
@@ -77,12 +80,21 @@ class DatabaseManager:
# 为garment_materials表添加索引 # 为garment_materials表添加索引
conn.execute('CREATE INDEX IF NOT EXISTS idx_garment_materials_style ON garment_materials(style_number)') conn.execute('CREATE INDEX IF NOT EXISTS idx_garment_materials_style ON garment_materials(style_number)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_garment_materials_category ON garment_materials(category)') conn.execute('CREATE INDEX IF NOT EXISTS idx_garment_materials_category ON garment_materials(category)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_garment_materials_model ON garment_materials(model)')
# 添加新字段(如果不存在) # 添加新字段(如果不存在)
try: try:
conn.execute("ALTER TABLE garment_materials ADD COLUMN fabric_type TEXT") conn.execute("ALTER TABLE garment_materials ADD COLUMN fabric_type TEXT")
except: except:
pass pass
try:
conn.execute("ALTER TABLE garment_materials ADD COLUMN model TEXT")
except:
pass
try:
conn.execute("ALTER TABLE fabrics ADD COLUMN fabric_type TEXT")
except:
pass
try: try:
conn.execute("ALTER TABLE fabrics ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP") conn.execute("ALTER TABLE fabrics ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except: except:
@@ -132,6 +144,21 @@ class DatabaseManager:
except: except:
pass pass
# 数据迁移将fabrics表中category字段的"类目-类型"格式拆分成两个字段
try:
cursor = conn.execute("SELECT model, category FROM fabrics WHERE category LIKE '%-%' AND (fabric_type IS NULL OR fabric_type = '')")
rows = cursor.fetchall()
for model, category in rows:
if '-' in category:
parts = category.split('-', 1)
new_category = parts[0]
new_fabric_type = parts[1]
conn.execute("UPDATE fabrics SET category = ?, fabric_type = ? WHERE model = ?",
(new_category, new_fabric_type, model))
conn.commit()
except:
pass
# 管理员设置表 # 管理员设置表
conn.execute(''' conn.execute('''
CREATE TABLE IF NOT EXISTS admin_settings ( CREATE TABLE IF NOT EXISTS admin_settings (
@@ -246,14 +273,10 @@ def get_fabric_categories(db_path):
try: try:
with get_db_connection(db_path) as conn: with get_db_connection(db_path) as conn:
cursor = conn.execute(""" cursor = conn.execute("""
SELECT DISTINCT SELECT DISTINCT category
CASE
WHEN category LIKE '%-%' THEN SUBSTR(category, 1, INSTR(category, '-') - 1)
ELSE category
END as major_category
FROM fabrics FROM fabrics
WHERE category IS NOT NULL AND category != '' WHERE category IS NOT NULL AND category != ''
ORDER BY major_category ORDER BY category
""") """)
categories = set() categories = set()
for row in cursor.fetchall(): for row in cursor.fetchall():
@@ -272,19 +295,15 @@ def get_fabric_types_by_category(db_path, category):
try: try:
with get_db_connection(db_path) as conn: with get_db_connection(db_path) as conn:
cursor = conn.execute(""" cursor = conn.execute("""
SELECT DISTINCT SELECT DISTINCT fabric_type
CASE
WHEN category LIKE '%-%' THEN SUBSTR(category, INSTR(category, '-') + 1)
ELSE '默认类型'
END as fabric_type
FROM fabrics FROM fabrics
WHERE category LIKE ? OR category = ? WHERE category = ? AND fabric_type IS NOT NULL AND fabric_type != ''
ORDER BY fabric_type ORDER BY fabric_type
""", (f"{category}-%", category)) """, (category,))
types = [] types = []
for row in cursor.fetchall(): for row in cursor.fetchall():
if row[0] and row[0] != '默认类型': if row[0] and row[0].strip():
types.append(row[0]) types.append(row[0])
return types return types
except: except:

Binary file not shown.

View File

@@ -177,12 +177,17 @@ class FabricManager(QMainWindow):
text = f"款号: {style_number}\n生产件数: {qty}\n损耗率: {self.loss_input.value()}%\n\n" text = f"款号: {style_number}\n生产件数: {qty}\n损耗率: {self.loss_input.value()}%\n\n"
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT category, fabric_type, usage_per_piece, unit FROM garment_materials WHERE style_number = ? ORDER BY id", (style_number,)) cursor = conn.execute("SELECT category, fabric_type, model, usage_per_piece, unit FROM garment_materials WHERE style_number = ? ORDER BY id", (style_number,))
for category, fabric_type, usage, unit in cursor.fetchall(): for category, fabric_type, model, usage, unit in cursor.fetchall():
if usage: if usage:
total = usage * qty * (1 + loss) total = usage * qty * (1 + loss)
# 显示材料名称(如果有类型则显示类目-类型,否则只显示类目 # 显示材料名称:优先显示型号,否则显示类目-类型,最后只显示类目
material_name = f"{category}-{fabric_type}" if fabric_type else category if model:
material_name = model
elif fabric_type:
material_name = f"{category}-{fabric_type}" if category else fabric_type
else:
material_name = category or "未命名材料"
text += f"{material_name}\n单件: {usage:.3f} {unit}\n总用量: {total:.3f} {unit}\n\n" text += f"{material_name}\n单件: {usage:.3f} {unit}\n总用量: {total:.3f} {unit}\n\n"
except Exception as e: except Exception as e:
text += "计算失败: " + str(e) text += "计算失败: " + str(e)
@@ -332,6 +337,7 @@ class FabricManager(QMainWindow):
CREATE TABLE IF NOT EXISTS fabrics ( CREATE TABLE IF NOT EXISTS fabrics (
model TEXT PRIMARY KEY, model TEXT PRIMARY KEY,
category TEXT DEFAULT '未分类', category TEXT DEFAULT '未分类',
fabric_type TEXT,
supplier TEXT, supplier TEXT,
color TEXT, color TEXT,
width REAL, width REAL,
@@ -356,6 +362,7 @@ class FabricManager(QMainWindow):
style_number TEXT, style_number TEXT,
category TEXT, category TEXT,
fabric_type TEXT, fabric_type TEXT,
model TEXT,
usage_per_piece REAL, usage_per_piece REAL,
unit TEXT DEFAULT '' unit TEXT DEFAULT ''
) )
@@ -364,6 +371,30 @@ class FabricManager(QMainWindow):
# 添加fabric_type列如果不存在 # 添加fabric_type列如果不存在
try: try:
conn.execute("ALTER TABLE garment_materials ADD COLUMN fabric_type TEXT") conn.execute("ALTER TABLE garment_materials ADD COLUMN fabric_type TEXT")
except:
pass
# 添加model列如果不存在
try:
conn.execute("ALTER TABLE garment_materials ADD COLUMN model TEXT")
except:
pass
# 添加fabrics表的fabric_type列如果不存在
try:
conn.execute("ALTER TABLE fabrics ADD COLUMN fabric_type TEXT")
except:
pass
# 数据迁移将fabrics表中category字段的"类目-类型"格式拆分成两个字段
try:
cursor = conn.execute("SELECT model, category FROM fabrics WHERE category LIKE '%-%' AND (fabric_type IS NULL OR fabric_type = '')")
rows = cursor.fetchall()
for model, category in rows:
if '-' in category:
parts = category.split('-', 1)
new_category = parts[0]
new_fabric_type = parts[1]
conn.execute("UPDATE fabrics SET category = ?, fabric_type = ? WHERE model = ?",
(new_category, new_fabric_type, model))
conn.commit()
except: except:
pass # 列已存在 pass # 列已存在

View File

@@ -41,14 +41,22 @@ class SearchableComboBox(QComboBox):
def addItem(self, text, userData=None): def addItem(self, text, userData=None):
"""添加选项""" """添加选项"""
# 临时断开信号连接防止textChanged触发on_text_changed # 临时断开信号连接防止textChanged触发on_text_changed
try:
self.lineEdit().textChanged.disconnect() self.lineEdit().textChanged.disconnect()
except TypeError:
# 信号未连接或已被断开,忽略错误
pass
super().addItem(text, userData) super().addItem(text, userData)
if text not in self.all_items: if text not in self.all_items:
self.all_items.append(text) self.all_items.append(text)
self.all_data.append(userData) self.all_data.append(userData)
self.update_completer() self.update_completer()
# 重新连接信号 # 重新连接信号
try:
self.lineEdit().textChanged.connect(self.on_text_changed) self.lineEdit().textChanged.connect(self.on_text_changed)
except:
# 如果连接失败,忽略错误
pass
def addItems(self, texts): def addItems(self, texts):
"""批量添加选项""" """批量添加选项"""
@@ -66,14 +74,25 @@ class SearchableComboBox(QComboBox):
def reset_items(self): def reset_items(self):
"""重置所有选项""" """重置所有选项"""
# 临时断开信号连接防止textChanged触发on_text_changed # 临时断开信号连接防止textChanged触发on_text_changed
try:
self.lineEdit().textChanged.disconnect() self.lineEdit().textChanged.disconnect()
except TypeError:
# 信号未连接或已被断开,忽略错误
pass
self.is_filtering = True self.is_filtering = True
super().clear() super().clear()
for i, item in enumerate(self.all_items): for i, item in enumerate(self.all_items):
super().addItem(item, self.all_data[i] if i < len(self.all_data) else None) super().addItem(item, self.all_data[i] if i < len(self.all_data) else None)
self.is_filtering = False self.is_filtering = False
# 重新连接信号 # 重新连接信号
try:
self.lineEdit().textChanged.connect(self.on_text_changed) self.lineEdit().textChanged.connect(self.on_text_changed)
except:
# 如果连接失败,忽略错误
pass
# # 确保当前索引设置为0第一项
# if self.count() > 0:
# super().setCurrentIndex(0)
def update_completer(self): def update_completer(self):
"""更新自动完成列表""" """更新自动完成列表"""
@@ -111,6 +130,22 @@ class SearchableComboBox(QComboBox):
if filtered_items and self.hasFocus(): if filtered_items and self.hasFocus():
self.showPopup() self.showPopup()
def setDefaultText(self, text):
"""设置默认文本"""
# 临时断开信号连接防止textChanged触发on_text_changed
try:
self.lineEdit().textChanged.disconnect()
except TypeError:
# 信号未连接或已被断开,忽略错误
pass
self.lineEdit().setText(text)
self.update_completer()
# 重新连接信号
try:
self.lineEdit().textChanged.connect(self.on_text_changed)
except:
# 如果连接失败,忽略错误
pass
class GarmentLibraryDialog(QDialog): class GarmentLibraryDialog(QDialog):
"""服装库管理对话框""" """服装库管理对话框"""
@@ -355,40 +390,12 @@ class GarmentEditDialog(QDialog):
"""加载材料列表""" """加载材料列表"""
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT category, fabric_type, usage_per_piece, unit FROM garment_materials WHERE style_number = ? ORDER BY id", (self.style_number,)) cursor = conn.execute("SELECT category, fabric_type, model, usage_per_piece, unit FROM garment_materials WHERE style_number = ? ORDER BY id", (self.style_number,))
for category, fabric_type, usage, unit in cursor.fetchall(): for category, fabric_type, model, usage, unit in cursor.fetchall():
display_category = "" # 直接使用数据库中的三个字段
display_type = "" display_category = category or ""
display_model = "" display_type = fabric_type or ""
display_model = model or ""
# category字段可能存储型号或类目-类型组合
if category:
# 首先检查是否是型号在fabrics表中查找
fabric_cursor = conn.execute("SELECT category, model FROM fabrics WHERE model = ?", (category,))
fabric_row = fabric_cursor.fetchone()
if fabric_row:
# 是型号从fabrics表获取类目信息
fabric_category, model = fabric_row
display_model = model
if fabric_category and "-" in fabric_category:
parts = fabric_category.split("-", 1)
display_category = parts[0]
display_type = parts[1]
else:
display_category = fabric_category or ""
else:
# 不是型号,按类目-类型格式解析
if "-" in category:
parts = category.split("-", 1)
display_category = parts[0]
display_type = parts[1]
else:
display_category = category
# 如果有单独的fabric_type字段优先使用
if fabric_type:
display_type = fabric_type
self.add_material_row(display_category, display_type, usage or 0, unit or "", display_model) self.add_material_row(display_category, display_type, usage or 0, unit or "", display_model)
except Exception as e: except Exception as e:
@@ -408,32 +415,24 @@ class GarmentEditDialog(QDialog):
# 列0: 类目下拉框 # 列0: 类目下拉框
cat_combo = QComboBox() cat_combo = QComboBox()
cat_combo.setEditable(True) cat_combo.setEditable(False)
# 最后添加自定义选项 # 最后添加自定义选项
cat_combo.addItem("—— 自定义类目 ——") cat_combo.addItem("—— 自定义类目 ——")
# 先添加所有类目选项 # 先添加所有类目选项
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
# 只获取纯类目(提取"-"前面的部分)
cursor = conn.execute(""" cursor = conn.execute("""
SELECT DISTINCT SELECT DISTINCT category
CASE
WHEN category LIKE '%-%' THEN SUBSTR(category, 1, INSTR(category, '-') - 1)
ELSE category
END as major_category
FROM fabrics FROM fabrics
WHERE category IS NOT NULL AND category != '' WHERE category IS NOT NULL AND category != ''
ORDER BY major_category ORDER BY category
""") """)
categories = set() categories = set()
for cat_row in cursor.fetchall(): for cat_row in cursor.fetchall():
if cat_row[0] and cat_row[0].strip(): if cat_row[0] and cat_row[0].strip():
categories.add(cat_row[0]) categories.add(cat_row[0])
# 添加默认类目
categories.update(["布料", "辅料", "其他"])
for cat in sorted(categories): for cat in sorted(categories):
cat_combo.addItem(cat) cat_combo.addItem(cat)
except: except:
@@ -445,53 +444,57 @@ class GarmentEditDialog(QDialog):
if category: if category:
cat_combo.setCurrentText(category) cat_combo.setCurrentText(category)
else: else:
# 如果没有指定类目,默认选择第一个实际类目而不是"自定义类目" # 如果没有指定类目,默认选择"—— 自定义类目 ——"索引0
if cat_combo.count() > 1: print("没有指定类目,默认选择'—— 自定义类目 ——'索引0")
print(cat_combo.count())
print(cat_combo.currentIndex())
# 打印所有选项
for i in range(cat_combo.count()):
print(cat_combo.itemText(i))
cat_combo.setCurrentIndex(0) cat_combo.setCurrentIndex(0)
cat_combo.currentTextChanged.connect(lambda text, r=row: self.on_category_changed(text, r))
self.material_table.setCellWidget(row, 0, cat_combo) self.material_table.setCellWidget(row, 0, cat_combo)
# 列1: 类型下拉框 # 列1: 类型下拉框
type_combo = QComboBox() type_combo = QComboBox()
type_combo.setEditable(True) type_combo.setEditable(False)
# 最后添加选择提示
type_combo.addItem("—— 选择类型 ——")
# 先添加所有类型选项 # 先添加所有类型选项
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute(""" cursor = conn.execute("""
SELECT DISTINCT SELECT DISTINCT fabric_type
CASE
WHEN category LIKE '%-%' THEN SUBSTR(category, INSTR(category, '-') + 1)
ELSE '默认类型'
END as fabric_type
FROM fabrics FROM fabrics
WHERE category IS NOT NULL AND category != '' WHERE fabric_type IS NOT NULL AND fabric_type != ''
ORDER BY fabric_type ORDER BY fabric_type
""") """)
types = cursor.fetchall() types = cursor.fetchall()
for type_row in types: for type_row in types:
if type_row[0] and type_row[0] != '默认类型': if type_row[0] and type_row[0].strip():
type_combo.addItem(type_row[0]) type_combo.addItem(type_row[0])
except: except:
pass pass
# 最后添加选择提示
type_combo.addItem("—— 选择类型 ——")
if fabric_type: if fabric_type:
type_combo.setCurrentText(fabric_type) type_combo.setCurrentText(fabric_type)
else: else:
# 如果没有指定类型,默认选择第一个实际类型而不是"选择类型" # 如果没有指定类型,默认选择"—— 选择类型 ——"索引0
if type_combo.count() > 1: print("没有指定类型,默认选择'—— 选择类型 ——'索引0")
print(type_combo.count())
print(type_combo.currentIndex())
# 打印所有选项
for i in range(type_combo.count()):
print(type_combo.itemText(i))
type_combo.setCurrentIndex(0) type_combo.setCurrentIndex(0)
type_combo.currentTextChanged.connect(lambda text, r=row: self.on_type_changed(text, r))
self.material_table.setCellWidget(row, 1, type_combo) self.material_table.setCellWidget(row, 1, type_combo)
# 列2: 型号下拉框(支持模糊搜索) # 列2: 型号下拉框
model_combo = SearchableComboBox() model_combo = QComboBox()
model_combo.setEditable(False)
model_combo.addItem("—— 选择型号 ——") model_combo.addItem("—— 选择型号 ——")
# 初始化时加载所有型号 # 初始化时加载所有型号
@@ -513,10 +516,18 @@ class GarmentEditDialog(QDialog):
except Exception as e: except Exception as e:
pass pass
# 确保默认选中第一项("—— 选择型号 ——" if fabric_type:
model_combo.setCurrentText(fabric_type)
else:
# 如果没有指定类型,默认选择"—— 选择类型 ——"索引0
print("没有指定类型,默认选择'—— 选择类型 ——'索引0")
print(model_combo.count())
print(model_combo.currentIndex())
# 打印所有选项
for i in range(model_combo.count()):
print(model_combo.itemText(i))
model_combo.setCurrentIndex(0) model_combo.setCurrentIndex(0)
model_combo.currentTextChanged.connect(lambda text, r=row: self.on_model_selected(text, r))
self.material_table.setCellWidget(row, 2, model_combo) self.material_table.setCellWidget(row, 2, model_combo)
# 列3: 单件用量 # 列3: 单件用量
@@ -539,38 +550,37 @@ class GarmentEditDialog(QDialog):
self.material_table.setCellWidget(row, 5, del_btn) self.material_table.setCellWidget(row, 5, del_btn)
# 初始化类型和型号选项 # 初始化类型和型号选项
self.on_category_changed(cat_combo.currentText(), row) # self.on_category_changed(cat_combo.currentText(), row)
# 如果没有选择具体类目,初始化时显示全部型号 # 如果没有选择具体类目,初始化时显示全部型号
if cat_combo.currentText() == "—— 自定义类目 ——": # if cat_combo.currentText() == "—— 自定义类目 ——":
self.on_type_changed("—— 选择类型 ——", row) # self.on_type_changed("—— 选择类型 ——", row)
# 如果有指定的型号,需要在初始化完成后设置 # 如果有指定的型号,需要在初始化完成后设置
if model: # if model:
# 先设置类型(如果有的话) # # 先设置类型(如果有的话)
if fabric_type: # if fabric_type:
type_combo.setCurrentText(fabric_type) # type_combo.setCurrentText(fabric_type)
self.on_type_changed(fabric_type, row) # self.on_type_changed(fabric_type, row)
# 然后设置型号 - 使用SearchableComboBox的setCurrentText方法
model_combo = self.material_table.cellWidget(row, 2)
if isinstance(model_combo, SearchableComboBox):
# 确保型号在选项列表中
found = False
for i in range(model_combo.count()):
item_data = model_combo.itemData(i)
item_text = model_combo.itemText(i)
if item_data == model or item_text == model:
model_combo.setCurrentIndex(i)
found = True
break
# 如果没找到直接设置文本SearchableComboBox支持
if not found:
model_combo.setCurrentText(model)
# # 然后设置型号
# model_combo = self.material_table.cellWidget(row, 2)
# if model_combo:
# # 确保型号在选项列表中
# found = False
# for i in range(model_combo.count()):
# item_data = model_combo.itemData(i)
# item_text = model_combo.itemText(i)
# if item_data == model or item_text == model:
# model_combo.setCurrentIndex(i)
# found = True
# break
cat_combo.currentTextChanged.connect(lambda text, r=row: self.on_category_changed(text, r))
type_combo.currentTextChanged.connect(lambda text, r=row: self.on_type_changed(text, r))
model_combo.currentTextChanged.connect(lambda text, r=row: self.on_model_selected(text, r))
def on_category_changed(self, category_text, row): def on_category_changed(self, category_text, row):
"""当类目改变时,更新类型下拉框""" """当类目改变时,更新类型下拉框"""
print("on_category_changed", category_text, row)
type_combo = self.material_table.cellWidget(row, 1) type_combo = self.material_table.cellWidget(row, 1)
model_combo = self.material_table.cellWidget(row, 2) model_combo = self.material_table.cellWidget(row, 2)
@@ -578,46 +588,50 @@ class GarmentEditDialog(QDialog):
type_combo.clear() type_combo.clear()
type_combo.addItem("—— 选择类型 ——") type_combo.addItem("—— 选择类型 ——")
# 重新初始化型号下拉框,显示所有型号 # 重新初始化型号下拉框,显示所有型号阻止信号防止触发on_model_selected
model_combo.blockSignals(True)
model_combo.clear() model_combo.clear()
model_combo.addItem("—— 选择型号 ——") model_combo.addItem("—— 选择型号 ——")
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
# 加载所有类型 # 加载所有类型
if category_text and category_text != "—— 自定义类目 ——":
# 如果选择了具体类目,则过滤
cursor = conn.execute(""" cursor = conn.execute("""
SELECT DISTINCT SELECT DISTINCT fabric_type
CASE
WHEN category LIKE '%-%' THEN SUBSTR(category, INSTR(category, '-') + 1)
ELSE '默认类型'
END as fabric_type
FROM fabrics FROM fabrics
WHERE category IS NOT NULL AND category != '' WHERE category = ? AND fabric_type IS NOT NULL AND fabric_type != ''
ORDER BY fabric_type
""", (category_text,))
else:
# 加载所有类型
cursor = conn.execute("""
SELECT DISTINCT fabric_type
FROM fabrics
WHERE fabric_type IS NOT NULL AND fabric_type != ''
ORDER BY fabric_type ORDER BY fabric_type
""") """)
# 如果选择了具体类目,则过滤
if category_text and category_text != "—— 自定义类目 ——":
cursor = conn.execute("""
SELECT DISTINCT
CASE
WHEN category LIKE '%-%' THEN SUBSTR(category, INSTR(category, '-') + 1)
ELSE '默认类型'
END as fabric_type
FROM fabrics
WHERE category LIKE ? OR category = ?
ORDER BY fabric_type
""", (f"{category_text}-%", category_text))
types = cursor.fetchall() types = cursor.fetchall()
for type_row in types: for type_row in types:
if type_row[0] and type_row[0] != '默认类型': if type_row[0] and type_row[0].strip():
type_combo.addItem(type_row[0]) type_combo.addItem(type_row[0])
# 连接类型改变事件 # 连接类型改变事件
type_combo.currentTextChanged.connect(lambda text, r=row: self.on_type_changed(text, r)) type_combo.currentTextChanged.connect(lambda text, r=row: self.on_type_changed(text, r))
# 加载所有型号到型号下拉框 # 加载该类目下的所有型号到型号下拉框
if category_text and category_text != "—— 自定义类目 ——":
# 如果选择了具体类目,则只加载该类目下的型号
cursor = conn.execute("""
SELECT DISTINCT model, color, unit
FROM fabrics
WHERE category = ?
ORDER BY model
""", (category_text,))
else:
# 如果是自定义类目,加载所有型号
cursor = conn.execute(""" cursor = conn.execute("""
SELECT DISTINCT model, color, unit SELECT DISTINCT model, color, unit
FROM fabrics FROM fabrics
@@ -636,20 +650,84 @@ class GarmentEditDialog(QDialog):
model_combo.setCurrentIndex(0) model_combo.setCurrentIndex(0)
except Exception as e: except Exception as e:
pass pass
finally:
# 恢复信号
model_combo.blockSignals(False)
def on_type_changed(self, type_text, row): def on_type_changed(self, type_text, row):
"""当类型改变时,更新型号下拉框""" """当类型改变时,更新类目和型号下拉框"""
print("on_type_changed", type_text, row)
cat_combo = self.material_table.cellWidget(row, 0) cat_combo = self.material_table.cellWidget(row, 0)
model_combo = self.material_table.cellWidget(row, 2) model_combo = self.material_table.cellWidget(row, 2)
# 重新初始化型号下拉框,显示所有型号 if not model_combo:
if hasattr(model_combo, 'clear'): return
# 如果选择了具体类型,自动选中该类型对应的类目
if cat_combo and type_text and type_text != "—— 选择类型 ——":
try:
with self.get_conn() as conn:
# 查询该类型对应的类目
cursor = conn.execute("""
SELECT DISTINCT category
FROM fabrics
WHERE fabric_type = ? AND category IS NOT NULL AND category != ''
ORDER BY category
LIMIT 1
""", (type_text,))
row = cursor.fetchone()
if row and row[0]:
category = row[0].strip()
# 在类目下拉框中查找并选中该类目
index = cat_combo.findText(category)
if index >= 0:
cat_combo.blockSignals(True)
cat_combo.setCurrentIndex(index)
cat_combo.blockSignals(False)
except Exception as e:
pass
# 重新初始化型号下拉框,显示该类型下的所有型号
model_combo.blockSignals(True)
model_combo.clear() model_combo.clear()
model_combo.addItem("—— 选择型号 ——") model_combo.addItem("—— 选择型号 ——")
# 始终显示所有型号,不进行过滤 # 根据类型和类目过滤型号
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
# 获取当前选择的类目(可能已经更新)
category_text = cat_combo.currentText() if cat_combo else ""
# 构建查询条件
if type_text and type_text != "—— 选择类型 ——":
# 如果选择了具体类型
if category_text and category_text != "—— 自定义类目 ——":
# 同时根据类目和类型过滤
cursor = conn.execute("""
SELECT DISTINCT model, color, unit
FROM fabrics
WHERE category = ? AND fabric_type = ?
ORDER BY model
""", (category_text, type_text))
else:
# 只根据类型过滤
cursor = conn.execute("""
SELECT DISTINCT model, color, unit
FROM fabrics
WHERE fabric_type = ?
ORDER BY model
""", (type_text,))
else:
# 如果没有选择类型,根据类目过滤(如果有类目)
if category_text and category_text != "—— 自定义类目 ——":
cursor = conn.execute("""
SELECT DISTINCT model, color, unit
FROM fabrics
WHERE category = ?
ORDER BY model
""", (category_text,))
else:
# 显示所有型号
cursor = conn.execute(""" cursor = conn.execute("""
SELECT DISTINCT model, color, unit SELECT DISTINCT model, color, unit
FROM fabrics FROM fabrics
@@ -663,22 +741,55 @@ class GarmentEditDialog(QDialog):
if color and color.strip(): if color and color.strip():
display_text = f"{model}-{color}" display_text = f"{model}-{color}"
model_combo.addItem(display_text, model) model_combo.addItem(display_text, model)
# 确保默认选中第一项("—— 选择型号 ——"
model_combo.setCurrentIndex(0)
except Exception as e: except Exception as e:
pass pass
# 确保默认选中第一项("—— 选择型号 ——"
model_combo.setCurrentIndex(0)
model_combo.blockSignals(False)
def on_model_selected(self, model_text, row): def on_model_selected(self, model_text, row):
"""当型号选择时,自动设置单位并填充类目和类型""" """当型号选择时,自动设置单位并填充类目和类型"""
if not model_text or model_text == "—— 选择型号 ——": print("on_model_selected", model_text, row)
return # 先获取所有需要的控件
cat_combo = self.material_table.cellWidget(row, 0) cat_combo = self.material_table.cellWidget(row, 0)
type_combo = self.material_table.cellWidget(row, 1) type_combo = self.material_table.cellWidget(row, 1)
model_combo = self.material_table.cellWidget(row, 2) model_combo = self.material_table.cellWidget(row, 2)
unit_combo = self.material_table.cellWidget(row, 4) unit_combo = self.material_table.cellWidget(row, 4)
if not model_text or model_text == "—— 选择型号 ——":
# 获取当前类目和类型下的所有型号,阻止信号防止死循环
model_combo.blockSignals(True)
try:
model_combo.clear()
model_combo.addItem("—— 选择型号 ——")
try:
with self.get_conn() as conn:
if cat_combo.currentText() != "—— 自定义类目 ——" and type_combo.currentText() != "—— 选择类型 ——":
cursor = conn.execute("SELECT DISTINCT model, color, unit FROM fabrics WHERE category = ? AND fabric_type = ? ORDER BY model", (cat_combo.currentText(), type_combo.currentText()))
elif cat_combo.currentText() != "—— 自定义类目 ——" and type_combo.currentText() == "—— 选择类型 ——":
cursor = conn.execute("SELECT DISTINCT model, color, unit FROM fabrics WHERE category = ? ORDER BY model", (cat_combo.currentText(),))
else:
cursor = conn.execute("SELECT DISTINCT model, color, unit FROM fabrics ORDER BY model")
models = cursor.fetchall()
for model_row in models:
model, color, unit = model_row
# 显示格式:型号-颜色(如果有颜色的话)
display_text = model
if color and color.strip():
display_text = f"{model}-{color}"
model_combo.addItem(display_text, model)
except Exception as e:
pass
model_combo.setCurrentIndex(0)
finally:
# 恢复信号
model_combo.blockSignals(False)
return
# 获取选中项的数据 # 获取选中项的数据
current_index = model_combo.currentIndex() current_index = model_combo.currentIndex()
if current_index > 0: if current_index > 0:
@@ -686,36 +797,48 @@ class GarmentEditDialog(QDialog):
if model: if model:
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT category, unit FROM fabrics WHERE model = ?", (model,)) cursor = conn.execute("SELECT category, fabric_type, unit FROM fabrics WHERE model = ?", (model,))
row_db = cursor.fetchone() row_db = cursor.fetchone()
if row_db: if row_db:
category, unit = row_db category, fabric_type, unit = row_db
# 自动填充单位 # 自动填充单位
if unit: if unit:
unit_combo.setCurrentText(unit) unit_combo.setCurrentText(unit)
# 自动填充类目和类型 # 自动填充类目和类型,阻止信号以避免触发默认更新逻辑
if category: if category:
# 解析类目信息,可能是"类目-类型"格式或单独的类目 # 阻止类目类型和型号的信号,避免触发默认更新逻辑
if '-' in category: cat_combo.blockSignals(True)
parts = category.split('-', 1) type_combo.blockSignals(True)
cat_text = parts[0] model_combo.blockSignals(True)
type_text = parts[1] if len(parts) > 1 else ""
# 设置类目 # 设置类目
cat_combo.setCurrentText(cat_text) cat_combo.setCurrentText(category)
# 更新类型下拉框选项 # 更新类型下拉框选项(直接调用,不会触发信号因为已经阻止了)
self.on_category_changed(cat_text, row) self.on_category_changed(category, row)
# 重新阻止信号因为on_category_changed在finally中恢复了信号
# 这可以防止死循环
model_combo.blockSignals(True)
# 重新设置选中的型号因为on_category_changed会清空并重新加载型号下拉框
# 查找并选中对应的型号
for i in range(model_combo.count()):
item_data = model_combo.itemData(i)
if item_data == model:
model_combo.setCurrentIndex(i)
break
# 设置类型 # 设置类型
if type_text: if fabric_type:
type_combo.setCurrentText(type_text) type_combo.setCurrentText(fabric_type)
else:
# 只有类目,没有类型 # 恢复信号
cat_combo.setCurrentText(category) cat_combo.blockSignals(False)
self.on_category_changed(category, row) type_combo.blockSignals(False)
model_combo.blockSignals(False)
except: except:
pass pass
@@ -764,11 +887,9 @@ class GarmentEditDialog(QDialog):
usage = usage_widget.value() usage = usage_widget.value()
unit = unit_widget.currentText().strip() or "" unit = unit_widget.currentText().strip() or ""
# 分别存储类目、类型和型号信息 # 分别存储类目、类型和型号到对应字段
material_identifier = final_model if final_model else (f"{category}-{fabric_type}" if fabric_type else category) conn.execute("INSERT INTO garment_materials (style_number, category, fabric_type, model, usage_per_piece, unit) VALUES (?, ?, ?, ?, ?, ?)",
(style_number, category, fabric_type, final_model, usage, unit))
conn.execute("INSERT INTO garment_materials (style_number, category, fabric_type, usage_per_piece, unit) VALUES (?, ?, ?, ?, ?)",
(style_number, material_identifier, fabric_type, usage, unit))
conn.commit() conn.commit()
QMessageBox.information(self, "成功", "保存完成") QMessageBox.information(self, "成功", "保存完成")

13
main.py
View File

@@ -335,12 +335,17 @@ class FabricManager(QMainWindow):
text = f"款号: {style_number}\n生产件数: {qty}\n损耗率: {self.loss_input.value()}%\n\n" text = f"款号: {style_number}\n生产件数: {qty}\n损耗率: {self.loss_input.value()}%\n\n"
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT category, fabric_type, usage_per_piece, unit FROM garment_materials WHERE style_number = ? ORDER BY id", (style_number,)) cursor = conn.execute("SELECT category, fabric_type, model, usage_per_piece, unit FROM garment_materials WHERE style_number = ? ORDER BY id", (style_number,))
for category, fabric_type, usage, unit in cursor.fetchall(): for category, fabric_type, model, usage, unit in cursor.fetchall():
if usage: if usage:
total = usage * qty * (1 + loss) total = usage * qty * (1 + loss)
# 显示材料名称(如果有类型则显示类目-类型,否则只显示类目 # 显示材料名称:优先显示型号,否则显示类目-类型,最后只显示类目
material_name = f"{category}-{fabric_type}" if fabric_type else category if model:
material_name = model
elif fabric_type:
material_name = f"{category}-{fabric_type}" if category else fabric_type
else:
material_name = category or "未命名材料"
text += f"{material_name}\n单件: {usage:.3f} {unit}\n总用量: {total:.3f} {unit}\n\n" text += f"{material_name}\n单件: {usage:.3f} {unit}\n总用量: {total:.3f} {unit}\n\n"
except Exception as e: except Exception as e:
text += "计算失败: " + str(e) text += "计算失败: " + str(e)

View File

@@ -76,17 +76,22 @@ class PurchaseOrderDialog(QDialog):
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute(''' cursor = conn.execute('''
SELECT category, fabric_type, usage_per_piece, unit SELECT category, fabric_type, model, usage_per_piece, unit
FROM garment_materials FROM garment_materials
WHERE style_number = ? AND usage_per_piece > 0 WHERE style_number = ? AND usage_per_piece > 0
ORDER BY id ORDER BY id
''', (self.style_number,)) ''', (self.style_number,))
rows = cursor.fetchall() rows = cursor.fetchall()
for category, fabric_type, usage_per_piece, unit in rows: for category, fabric_type, model, usage_per_piece, unit in rows:
total_usage = usage_per_piece * self.quantity * (1 + self.loss_rate) total_usage = usage_per_piece * self.quantity * (1 + self.loss_rate)
# 显示材料名称(如果有类型则显示类目-类型,否则只显示类目 # 显示材料名称:优先显示型号,否则显示类目-类型,最后只显示类目
material_name = f"{category}-{fabric_type}" if fabric_type else category if model:
material_name = model
elif fabric_type:
material_name = f"{category}-{fabric_type}" if category else fabric_type
else:
material_name = category or "未命名材料"
text += f"材料:{material_name}\n" text += f"材料:{material_name}\n"
text += f" 单件用量:{usage_per_piece:.3f} {unit}\n" text += f" 单件用量:{usage_per_piece:.3f} {unit}\n"
text += f" 总需采购:{total_usage:.3f} {unit}\n\n" text += f" 总需采购:{total_usage:.3f} {unit}\n\n"

View File

@@ -246,7 +246,7 @@ class RawMaterialLibraryDialog(QDialog):
"""加载主类目""" """加载主类目"""
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT DISTINCT CASE WHEN category LIKE '%-%' THEN SUBSTR(category, 1, INSTR(category, '-') - 1) ELSE category END FROM fabrics") cursor = conn.execute("SELECT DISTINCT category FROM fabrics WHERE category IS NOT NULL AND category != ''")
majors = set(row[0] for row in cursor.fetchall() if row[0]) majors = set(row[0] for row in cursor.fetchall() if row[0])
majors.update({"布料", "辅料", "其他"}) majors.update({"布料", "辅料", "其他"})
@@ -263,7 +263,7 @@ class RawMaterialLibraryDialog(QDialog):
"""加载添加界面的主类目""" """加载添加界面的主类目"""
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT DISTINCT CASE WHEN category LIKE '%-%' THEN SUBSTR(category, 1, INSTR(category, '-') - 1) ELSE category END FROM fabrics") cursor = conn.execute("SELECT DISTINCT category FROM fabrics WHERE category IS NOT NULL AND category != ''")
majors = set(row[0] for row in cursor.fetchall() if row[0]) majors = set(row[0] for row in cursor.fetchall() if row[0])
majors.update({"布料", "辅料", "其他"}) majors.update({"布料", "辅料", "其他"})
@@ -292,20 +292,12 @@ class RawMaterialLibraryDialog(QDialog):
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
if major in ("全部类目", ""): if major in ("全部类目", ""):
cursor = conn.execute("SELECT DISTINCT category FROM fabrics WHERE category LIKE '%-%'") cursor = conn.execute("SELECT DISTINCT fabric_type FROM fabrics WHERE fabric_type IS NOT NULL AND fabric_type != ''")
subs = set() subs = [row[0] for row in cursor.fetchall() if row[0]]
for row in cursor.fetchall():
cat = row[0]
if '-' in cat:
subs.add(cat.split('-', 1)[1])
self.sub_combo.addItems(sorted(subs)) self.sub_combo.addItems(sorted(subs))
else: else:
cursor = conn.execute("SELECT category FROM fabrics WHERE category LIKE ? OR category = ?", (major + "-%", major)) cursor = conn.execute("SELECT DISTINCT fabric_type FROM fabrics WHERE category = ? AND fabric_type IS NOT NULL AND fabric_type != ''", (major,))
subs = set() subs = [row[0] for row in cursor.fetchall() if row[0]]
for row in cursor.fetchall():
cat = row[0]
if '-' in cat:
subs.add(cat.split('-', 1)[1])
self.sub_combo.addItems(sorted(subs)) self.sub_combo.addItems(sorted(subs))
except: except:
pass pass
@@ -337,7 +329,7 @@ class RawMaterialLibraryDialog(QDialog):
"""加载原料表格数据""" """加载原料表格数据"""
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
query = "SELECT category, model, supplier, color, width, gsm, unit, retail_price, bulk_price FROM fabrics" query = "SELECT category, fabric_type, model, supplier, color, width, gsm, unit, retail_price, bulk_price FROM fabrics"
params = [] params = []
conditions = [] conditions = []
@@ -346,11 +338,11 @@ class RawMaterialLibraryDialog(QDialog):
sub = self.sub_combo.currentText() sub = self.sub_combo.currentText()
if major != "全部类目" and major: if major != "全部类目" and major:
if sub != "全部类型" and sub: if sub != "全部类型" and sub:
conditions.append("category = ?") conditions.append("category = ? AND fabric_type = ?")
params.append(major + "-" + sub) params.append(major)
params.append(sub)
else: else:
conditions.append("(category LIKE ? OR category = ?)") conditions.append("category = ?")
params.append(major + "-%")
params.append(major) params.append(major)
# 供应商过滤 # 供应商过滤
@@ -377,9 +369,9 @@ class RawMaterialLibraryDialog(QDialog):
self.table.setRowCount(len(rows)) self.table.setRowCount(len(rows))
self.table.clearContents() self.table.clearContents()
for row_idx, (category, model, supplier, color, width, gsm, unit, retail, bulk) in enumerate(rows): for row_idx, (category, fabric_type, model, supplier, color, width, gsm, unit, retail, bulk) in enumerate(rows):
major = category.split('-', 1)[0] if '-' in category else category major = category or ""
sub = category.split('-', 1)[1] if '-' in category else "" sub = fabric_type or ""
self.table.setItem(row_idx, 0, QTableWidgetItem(major)) self.table.setItem(row_idx, 0, QTableWidgetItem(major))
self.table.setItem(row_idx, 1, QTableWidgetItem(sub)) self.table.setItem(row_idx, 1, QTableWidgetItem(sub))
@@ -433,16 +425,16 @@ class RawMaterialLibraryDialog(QDialog):
"""编辑原料""" """编辑原料"""
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT category, supplier, color, width, gsm, unit, retail_price, bulk_price FROM fabrics WHERE model = ?", (model,)) cursor = conn.execute("SELECT category, fabric_type, supplier, color, width, gsm, unit, retail_price, bulk_price FROM fabrics WHERE model = ?", (model,))
row = cursor.fetchone() row = cursor.fetchone()
if not row: if not row:
QMessageBox.warning(self, "提示", "原料不存在或已被删除") QMessageBox.warning(self, "提示", "原料不存在或已被删除")
return return
category, supplier, color, width, gsm, unit, retail, bulk = row category, fabric_type, supplier, color, width, gsm, unit, retail, bulk = row
major = category.split('-', 1)[0] if '-' in category else category major = category or ""
sub = category.split('-', 1)[1] if '-' in category else "" sub = fabric_type or ""
self.add_major_category.setCurrentText(major) self.add_major_category.setCurrentText(major)
self.add_sub_category.setText(sub) self.add_sub_category.setText(sub)
@@ -493,10 +485,8 @@ class RawMaterialLibraryDialog(QDialog):
if "胸杯" in sub: if "胸杯" in sub:
major = "辅料" major = "辅料"
if major and sub: category = major or ""
category = major + "-" + sub fabric_type = sub or ""
else:
category = sub or major
supplier = self.add_supplier.currentText().strip() supplier = self.add_supplier.currentText().strip()
color = self.add_color.text().strip() color = self.add_color.text().strip()
@@ -506,9 +496,9 @@ class RawMaterialLibraryDialog(QDialog):
with self.get_conn() as conn: with self.get_conn() as conn:
conn.execute(''' conn.execute('''
INSERT OR REPLACE INTO fabrics INSERT OR REPLACE INTO fabrics
(model, category, supplier, color, width, gsm, retail_price, bulk_price, unit, timestamp) (model, category, fabric_type, supplier, color, width, gsm, retail_price, bulk_price, unit, timestamp)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (model, category, supplier, color, ''', (model, category, fabric_type, supplier, color,
self.add_width.value() or None, self.add_gsm.value() or None, self.add_width.value() or None, self.add_gsm.value() or None,
self.add_retail.value() or None, self.add_bulk.value() or None, self.add_retail.value() or None, self.add_bulk.value() or None,
unit, datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) unit, datetime.now().strftime('%Y-%m-%d %H:%M:%S')))