This commit is contained in:
2025-12-23 00:30:36 +08:00
parent 192c05707a
commit 033a1acef3
16 changed files with 2870 additions and 1342 deletions

342
database.py Normal file
View File

@@ -0,0 +1,342 @@
"""
数据库连接和初始化模块
"""
import sqlite3
import os
from datetime import datetime
def get_db_connection(db_path):
"""获取数据库连接"""
return sqlite3.connect(db_path, timeout=30)
class DatabaseManager:
"""数据库管理类"""
def __init__(self, db_path):
self.db_path = db_path
self.init_db()
def get_conn(self):
"""获取数据库连接"""
return get_db_connection(self.db_path)
def init_db(self):
"""初始化数据库表结构"""
try:
with self.get_conn() as conn:
# 原料表
conn.execute('''
CREATE TABLE IF NOT EXISTS fabrics (
model TEXT PRIMARY KEY,
category TEXT DEFAULT '未分类',
supplier TEXT,
color TEXT,
width REAL,
gsm REAL,
retail_price REAL,
bulk_price REAL,
unit TEXT DEFAULT '',
timestamp TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
# 为fabrics表添加索引
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabrics_category ON fabrics(category)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabrics_supplier ON fabrics(supplier)')
# 衣服款号表
conn.execute('''
CREATE TABLE IF NOT EXISTS garments (
style_number TEXT PRIMARY KEY,
image_path TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
# 衣服材料用量表
conn.execute('''
CREATE TABLE IF NOT EXISTS garment_materials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
style_number TEXT,
category TEXT,
fabric_type TEXT,
usage_per_piece REAL,
unit TEXT DEFAULT '',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (style_number) REFERENCES garments(style_number)
)
''')
# 为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_category ON garment_materials(category)')
# 添加新字段(如果不存在)
try:
conn.execute("ALTER TABLE garment_materials ADD COLUMN fabric_type TEXT")
except:
pass
try:
conn.execute("ALTER TABLE fabrics ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE fabrics ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE garments ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE garments ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE garment_materials ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE garment_materials ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE admin_settings ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE admin_settings ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE fabric_stock_in ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE fabric_stock_in ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE fabric_consumption ADD COLUMN created_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
try:
conn.execute("ALTER TABLE fabric_consumption ADD COLUMN updated_at DATETIME DEFAULT CURRENT_TIMESTAMP")
except:
pass
# 管理员设置表
conn.execute('''
CREATE TABLE IF NOT EXISTS admin_settings (
key TEXT PRIMARY KEY,
value TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
# 原料入库表
conn.execute('''
CREATE TABLE IF NOT EXISTS fabric_stock_in (
id INTEGER PRIMARY KEY AUTOINCREMENT,
model TEXT,
quantity REAL,
unit TEXT,
purchase_date TEXT,
note TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (model) REFERENCES fabrics(model)
)
''')
# 为fabric_stock_in表添加索引
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabric_stock_in_model ON fabric_stock_in(model)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabric_stock_in_date ON fabric_stock_in(purchase_date)')
# 原料消耗表
conn.execute('''
CREATE TABLE IF NOT EXISTS fabric_consumption (
id INTEGER PRIMARY KEY AUTOINCREMENT,
style_number TEXT,
model TEXT,
single_usage REAL,
quantity_made INTEGER,
loss_rate REAL,
consume_quantity REAL,
consume_date TEXT,
unit TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (style_number) REFERENCES garments(style_number),
FOREIGN KEY (model) REFERENCES fabrics(model)
)
''')
# 为fabric_consumption表添加索引
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabric_consumption_style ON fabric_consumption(style_number)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabric_consumption_model ON fabric_consumption(model)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_fabric_consumption_date ON fabric_consumption(consume_date)')
# 添加库存计算视图
conn.execute('''
CREATE VIEW IF NOT EXISTS fabric_stock_view AS
SELECT
f.model,
f.category,
f.supplier,
f.color,
f.unit,
COALESCE(stock_in.total_in, 0) as total_stock_in,
COALESCE(consumption.total_consumed, 0) as total_consumed,
COALESCE(stock_in.total_in, 0) - COALESCE(consumption.total_consumed, 0) as current_stock
FROM fabrics f
LEFT JOIN (
SELECT model, SUM(quantity) as total_in
FROM fabric_stock_in
GROUP BY model
) stock_in ON f.model = stock_in.model
LEFT JOIN (
SELECT model, SUM(consume_quantity) as total_consumed
FROM fabric_consumption
GROUP BY model
) consumption ON f.model = consumption.model
''')
# 初始化默认密码
if not self.get_setting("admin_password"):
conn.execute("INSERT INTO admin_settings (key, value) VALUES ('admin_password', ?)", ("123456",))
if not self.get_setting("user_password"):
conn.execute("INSERT INTO admin_settings (key, value) VALUES ('user_password', ?)", ("123456",))
conn.commit()
except Exception as e:
raise Exception(f"无法初始化数据库:{str(e)}")
def get_setting(self, key):
"""获取设置值"""
try:
with self.get_conn() as conn:
cursor = conn.execute("SELECT value FROM admin_settings WHERE key = ?", (key,))
row = cursor.fetchone()
return row[0] if row else None
except:
return None
def set_setting(self, key, value):
"""设置配置值"""
try:
with self.get_conn() as conn:
conn.execute("INSERT OR REPLACE INTO admin_settings (key, value) VALUES (?, ?)", (key, value))
conn.commit()
return True
except Exception:
return False
def get_fabric_categories(db_path):
"""获取所有面料类目"""
try:
with get_db_connection(db_path) as conn:
cursor = conn.execute("""
SELECT DISTINCT
CASE
WHEN category LIKE '%-%' THEN SUBSTR(category, 1, INSTR(category, '-') - 1)
ELSE category
END as major_category
FROM fabrics
WHERE category IS NOT NULL AND category != ''
ORDER BY major_category
""")
categories = set()
for row in cursor.fetchall():
if row[0] and row[0].strip():
categories.add(row[0])
# 添加默认类目
categories.update(["布料", "辅料", "其他"])
return sorted(categories)
except:
return ["布料", "辅料", "其他"]
def get_fabric_types_by_category(db_path, category):
"""根据类目获取面料类型"""
try:
with get_db_connection(db_path) as conn:
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}-%", category))
types = []
for row in cursor.fetchall():
if row[0] and row[0] != '默认类型':
types.append(row[0])
return types
except:
return []
def get_fabric_models_by_category_type(db_path, category, fabric_type):
"""根据类目和类型获取面料型号"""
try:
with get_db_connection(db_path) as conn:
cursor = conn.execute("""
SELECT model, color, unit
FROM fabrics
WHERE category = ? OR category = ? OR category LIKE ?
ORDER BY model
""", (category, f"{category}-{fabric_type}", f"{category}-{fabric_type}-%"))
models = []
for row in cursor.fetchall():
model, color, unit = row
display_text = model
if color and color.strip():
display_text = f"{model}-{color}"
models.append((display_text, model, unit))
return models
except:
return []
def get_password(db_path, password_type):
"""获取密码设置"""
try:
with get_db_connection(db_path) as conn:
cursor = conn.execute(
"SELECT value FROM admin_settings WHERE key = ?",
(f"{password_type}_password",)
)
row = cursor.fetchone()
return row[0] if row else "123456"
except:
return "123456"
def update_password(db_path, password_type, new_password):
"""更新密码"""
try:
with get_db_connection(db_path) as conn:
conn.execute(
"UPDATE admin_settings SET value = ?, updated_at = CURRENT_TIMESTAMP WHERE key = ?",
(new_password, f"{password_type}_password")
)
conn.commit()
return True
except:
return False