实现原料逻辑删除功能

- 为fabrics表添加is_deleted字段用于标记删除状态
- 修改delete_raw方法实现逻辑删除而非物理删除
- 更新所有查询语句过滤已删除的原料数据
- 更新库存视图过滤已删除的原料和相关记录
- 保留历史数据,支持数据恢复

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-27 19:09:16 +08:00
parent fa70f62099
commit 6322cb0caa
6 changed files with 42 additions and 30 deletions

View File

@@ -145,6 +145,10 @@ class DatabaseManager:
pass pass
# 添加逻辑删除字段 # 添加逻辑删除字段
try:
conn.execute("ALTER TABLE fabrics ADD COLUMN is_deleted INTEGER DEFAULT 0")
except:
pass
try: try:
conn.execute("ALTER TABLE fabric_stock_in ADD COLUMN is_deleted INTEGER DEFAULT 0") conn.execute("ALTER TABLE fabric_stock_in ADD COLUMN is_deleted INTEGER DEFAULT 0")
except: except:
@@ -223,8 +227,9 @@ class DatabaseManager:
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabric_consumption_date ON fabric_consumption(consume_date)') conn.execute('CREATE INDEX IF NOT EXISTS idx_fabric_consumption_date ON fabric_consumption(consume_date)')
# 添加库存计算视图 # 添加库存计算视图
conn.execute('DROP VIEW IF EXISTS fabric_stock_view')
conn.execute(''' conn.execute('''
CREATE VIEW IF NOT EXISTS fabric_stock_view AS CREATE VIEW fabric_stock_view AS
SELECT SELECT
f.model, f.model,
f.category, f.category,
@@ -238,13 +243,16 @@ class DatabaseManager:
LEFT JOIN ( LEFT JOIN (
SELECT model, SUM(quantity) as total_in SELECT model, SUM(quantity) as total_in
FROM fabric_stock_in FROM fabric_stock_in
WHERE is_deleted IS NULL OR is_deleted = 0
GROUP BY model GROUP BY model
) stock_in ON f.model = stock_in.model ) stock_in ON f.model = stock_in.model
LEFT JOIN ( LEFT JOIN (
SELECT model, SUM(consume_quantity) as total_consumed SELECT model, SUM(consume_quantity) as total_consumed
FROM fabric_consumption FROM fabric_consumption
WHERE is_deleted IS NULL OR is_deleted = 0
GROUP BY model GROUP BY model
) consumption ON f.model = consumption.model ) consumption ON f.model = consumption.model
WHERE f.is_deleted IS NULL OR f.is_deleted = 0
''') ''')
# 初始化默认密码 # 初始化默认密码
@@ -285,7 +293,7 @@ def get_fabric_categories(db_path):
cursor = conn.execute(""" cursor = conn.execute("""
SELECT DISTINCT category SELECT DISTINCT category
FROM fabrics FROM fabrics
WHERE category IS NOT NULL AND category != '' WHERE category IS NOT NULL AND category != '' AND (is_deleted IS NULL OR is_deleted = 0)
ORDER BY category ORDER BY category
""") """)
categories = set() categories = set()
@@ -307,7 +315,7 @@ def get_fabric_types_by_category(db_path, category):
cursor = conn.execute(""" cursor = conn.execute("""
SELECT DISTINCT fabric_type SELECT DISTINCT fabric_type
FROM fabrics FROM fabrics
WHERE category = ? AND fabric_type IS NOT NULL AND fabric_type != '' WHERE category = ? AND fabric_type IS NOT NULL AND fabric_type != '' AND (is_deleted IS NULL OR is_deleted = 0)
ORDER BY fabric_type ORDER BY fabric_type
""", (category,)) """, (category,))
@@ -327,7 +335,7 @@ def get_fabric_models_by_category_type(db_path, category, fabric_type):
cursor = conn.execute(""" cursor = conn.execute("""
SELECT model, color, unit SELECT model, color, unit
FROM fabrics FROM fabrics
WHERE category = ? OR category = ? OR category LIKE ? WHERE (category = ? OR category = ? OR category LIKE ?) AND (is_deleted IS NULL OR is_deleted = 0)
ORDER BY model ORDER BY model
""", (category, f"{category}-{fabric_type}", f"{category}-{fabric_type}-%")) """, (category, f"{category}-{fabric_type}", f"{category}-{fabric_type}-%"))

View File

@@ -263,7 +263,7 @@ class FabricManager(QMainWindow):
if fabric_model: if fabric_model:
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT width, gsm FROM fabrics WHERE model = ?", (fabric_model,)) cursor = conn.execute("SELECT width, gsm FROM fabrics WHERE model = ? AND (is_deleted IS NULL OR is_deleted = 0)", (fabric_model,))
fabric_info = cursor.fetchone() fabric_info = cursor.fetchone()
if fabric_info and fabric_info[0] and fabric_info[1]: if fabric_info and fabric_info[0] and fabric_info[1]:
width, gsm = fabric_info width, gsm = fabric_info

View File

@@ -659,7 +659,7 @@ class GarmentEditDialog(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, unit FROM fabrics WHERE model = ?", "SELECT category, fabric_type, unit FROM fabrics WHERE model = ? AND (is_deleted IS NULL OR is_deleted = 0)",
(base_model,) (base_model,)
) )
row_db = cursor.fetchone() row_db = cursor.fetchone()

View File

@@ -412,7 +412,7 @@ class FabricManager(QMainWindow):
if fabric_model: if fabric_model:
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT width, gsm FROM fabrics WHERE model = ?", (fabric_model,)) cursor = conn.execute("SELECT width, gsm FROM fabrics WHERE model = ? AND (is_deleted IS NULL OR is_deleted = 0)", (fabric_model,))
fabric_info = cursor.fetchone() fabric_info = cursor.fetchone()
if fabric_info and fabric_info[0] and fabric_info[1]: if fabric_info and fabric_info[0] and fabric_info[1]:
width, gsm = fabric_info width, gsm = fabric_info

View File

@@ -112,13 +112,13 @@ class RawMaterialEditDialog(QDialog):
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
# 加载类目 # 加载类目
cursor = conn.execute("SELECT DISTINCT category FROM fabrics WHERE category IS NOT NULL AND category != ''") cursor = conn.execute("SELECT DISTINCT category FROM fabrics WHERE category IS NOT NULL AND category != '' AND (is_deleted IS NULL OR is_deleted = 0)")
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({"布料", "辅料", "其他"})
self.edit_major_category.addItems(sorted(majors)) self.edit_major_category.addItems(sorted(majors))
# 加载供应商 # 加载供应商
cursor = conn.execute("SELECT DISTINCT supplier FROM fabrics WHERE supplier IS NOT NULL AND supplier != '' ORDER BY supplier") cursor = conn.execute("SELECT DISTINCT supplier FROM fabrics WHERE supplier IS NOT NULL AND supplier != '' AND (is_deleted IS NULL OR is_deleted = 0) ORDER BY supplier")
suppliers = [row[0] for row in cursor.fetchall()] suppliers = [row[0] for row in cursor.fetchall()]
self.edit_supplier.addItems(suppliers) self.edit_supplier.addItems(suppliers)
except: except:
@@ -129,7 +129,7 @@ class RawMaterialEditDialog(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, supplier, color, width, gsm, unit, retail_price, bulk_price FROM fabrics WHERE model = ?", "SELECT category, fabric_type, supplier, color, width, gsm, unit, retail_price, bulk_price FROM fabrics WHERE model = ? AND (is_deleted IS NULL OR is_deleted = 0)",
(self.model,) (self.model,)
) )
row = cursor.fetchone() row = cursor.fetchone()
@@ -456,7 +456,7 @@ class RawMaterialLibraryDialog(QDialog):
"""加载主类目""" """加载主类目"""
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT DISTINCT category FROM fabrics WHERE category IS NOT NULL AND category != ''") cursor = conn.execute("SELECT DISTINCT category FROM fabrics WHERE category IS NOT NULL AND category != '' AND (is_deleted IS NULL OR is_deleted = 0)")
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({"布料", "辅料", "其他"})
@@ -473,7 +473,7 @@ class RawMaterialLibraryDialog(QDialog):
"""加载添加界面的主类目""" """加载添加界面的主类目"""
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT DISTINCT category FROM fabrics WHERE category IS NOT NULL AND category != ''") cursor = conn.execute("SELECT DISTINCT category FROM fabrics WHERE category IS NOT NULL AND category != '' AND (is_deleted IS NULL OR is_deleted = 0)")
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({"布料", "辅料", "其他"})
@@ -502,11 +502,11 @@ 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 fabric_type FROM fabrics WHERE fabric_type IS NOT NULL AND fabric_type != ''") cursor = conn.execute("SELECT DISTINCT fabric_type FROM fabrics WHERE fabric_type IS NOT NULL AND fabric_type != '' AND (is_deleted IS NULL OR is_deleted = 0)")
subs = [row[0] for row in cursor.fetchall() if row[0]] subs = [row[0] for row in cursor.fetchall() if row[0]]
self.sub_combo.addItems(sorted(subs)) self.sub_combo.addItems(sorted(subs))
else: else:
cursor = conn.execute("SELECT DISTINCT fabric_type FROM fabrics WHERE category = ? AND fabric_type IS NOT NULL AND fabric_type != ''", (major,)) cursor = conn.execute("SELECT DISTINCT fabric_type FROM fabrics WHERE category = ? AND fabric_type IS NOT NULL AND fabric_type != '' AND (is_deleted IS NULL OR is_deleted = 0)", (major,))
subs = [row[0] for row in cursor.fetchall() if row[0]] subs = [row[0] for row in cursor.fetchall() if row[0]]
self.sub_combo.addItems(sorted(subs)) self.sub_combo.addItems(sorted(subs))
except: except:
@@ -519,7 +519,7 @@ class RawMaterialLibraryDialog(QDialog):
"""加载供应商列表""" """加载供应商列表"""
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
cursor = conn.execute("SELECT DISTINCT supplier FROM fabrics WHERE supplier IS NOT NULL AND supplier != '' ORDER BY supplier") cursor = conn.execute("SELECT DISTINCT supplier FROM fabrics WHERE supplier IS NOT NULL AND supplier != '' AND (is_deleted IS NULL OR is_deleted = 0) ORDER BY supplier")
suppliers = [row[0] for row in cursor.fetchall()] suppliers = [row[0] for row in cursor.fetchall()]
self.supplier_combo.blockSignals(True) self.supplier_combo.blockSignals(True)
@@ -543,6 +543,9 @@ class RawMaterialLibraryDialog(QDialog):
params = [] params = []
conditions = [] conditions = []
# 过滤已删除的原料
conditions.append("(is_deleted IS NULL OR is_deleted = 0)")
# 类目过滤 # 类目过滤
major = self.major_combo.currentText() major = self.major_combo.currentText()
sub = self.sub_combo.currentText() sub = self.sub_combo.currentText()
@@ -643,12 +646,13 @@ class RawMaterialLibraryDialog(QDialog):
self.refresh_filters_and_table() self.refresh_filters_and_table()
def delete_raw(self, model): def delete_raw(self, model):
"""删除原料""" """逻辑删除原料"""
reply = QMessageBox.question(self, "确认", f"删除 '{model}'") reply = QMessageBox.question(self, "确认", f"确定要删除 '{model}' 吗?\n\n此操作将标记删除该原料,不会影响历史数据。")
if reply == QMessageBox.Yes: if reply == QMessageBox.Yes:
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
conn.execute("DELETE FROM fabrics WHERE model=?", (model,)) # 逻辑删除设置is_deleted=1
conn.execute("UPDATE fabrics SET is_deleted=1, updated_at=CURRENT_TIMESTAMP WHERE model=?", (model,))
conn.commit() conn.commit()
self.load_table() self.load_table()
QMessageBox.information(self, "成功", "删除完成") QMessageBox.information(self, "成功", "删除完成")

View File

@@ -58,10 +58,10 @@ class StockInDialog(QDialog):
try: try:
with self.get_conn() as conn: with self.get_conn() as conn:
# 查询面料基础信息 # 查询面料基础信息
query = "SELECT model, color, supplier, unit FROM fabrics" query = "SELECT model, color, supplier, unit FROM fabrics WHERE (is_deleted IS NULL OR is_deleted = 0)"
params = [] params = []
if keyword: if keyword:
query += " WHERE model LIKE ? OR color LIKE ?" query += " AND (model LIKE ? OR color LIKE ?)"
params = ["%" + keyword + "%", "%" + keyword + "%"] params = ["%" + keyword + "%", "%" + keyword + "%"]
query += " ORDER BY timestamp DESC" query += " ORDER BY timestamp DESC"
cursor = conn.execute(query, params) cursor = conn.execute(query, params)