mengchang 2 meses atrás
pai
commit
3e53d1543d

+ 48 - 0
tools/deduction_ratio.csv

@@ -0,0 +1,48 @@
+option_id,itemText,factor
+100039,正常开机,0.0
+100043,无法开机,0.4
+100029,外壳完美,0.0
+100034,外壳缺失/裂缝/孔变形/翘起/刻字,0.18
+100339,全新机未拆封(质检时会进行拆封),0.0
+100341,外壳有细微划痕,0.05
+100342,外壳有磕碰掉漆,0.1
+100408,机身有弯曲,0.2
+100069,屏幕外观完美,0.0
+100335,屏幕有细微划痕,0.03
+100336,屏幕有划伤/屏幕气泡/脱胶,0.12
+100337,屏幕有碎裂或磨损,0.3
+100411,屏幕有硬划痕(指甲划过划痕表面有停顿感),0.08
+100533,屏幕较明显划痕,0.08
+100534,屏幕裂痕/小缺角/脱胶进灰,0.25
+100085,显示完美,无任何异常,0.0
+100092,显示异常(漏液/错乱/闪屏/屏生线/亮度坏),0.3
+100331,显示轻微泛黄/亮点/亮斑(有其中一项),0.05
+100332,显示有亮坏点/亮斑/色斑,0.07
+100333,显示有透图/透字,0.15
+100535,屏幕全花屏/无法显示,0.5
+100329,个人账号无法退出,0.2
+100330,个人账号可退出,0.0
+100344,机器无维修痕迹,0.0
+100346,屏幕维修(更换非原厂屏等),0.25
+100381,电池维修(电池有更换),0.04
+100382,维修前摄像头(前摄像头有更换),0.06
+100383,维修后摄像头(后摄像头有更换),0.08
+100384,主板维修/扩容,0.4
+100410,维修后壳/其他零件,0.03
+100529,更换电池/摄像头/外壳/其他配件,0.1
+100530,更换原厂屏,0.15
+100370,电池健康度<80%,0.05
+100555,展示机/资源机/官换机,0.1
+100560,已开启丢失模式,0.6
+100398,WiFi/蓝牙连接正常,0.0
+100399,WiFi/蓝牙连接异常,0.1
+100402,面容/指纹功能正常,0.0
+100403,面容/指纹功能异常,0.15
+100392,触摸正常,0.0
+100394,触摸异常(延迟/失灵),0.3
+100395,拍摄正常,0.0
+100397,拍摄异常(抖动/模糊/不对焦/分层/颠倒),0.15
+100400,通话正常,0.0
+100401,通话异常,0.25
+100495,转轴开合正常,0.0
+100496,转轴开合异常,0.15

+ 61 - 0
tools/gen_koujian.py

@@ -0,0 +1,61 @@
+import csv
+
+# 所有评估项数据:[valueId, 评估项文本, 扣减比例]
+deduction_data = [
+    ["option_id", "itemText", "factor"],  # 表头
+    [100039, "正常开机", 0.00],
+    [100043, "无法开机", 0.40],
+    [100029, "外壳完美", 0.00],
+    [100034, "外壳缺失/裂缝/孔变形/翘起/刻字", 0.18],
+    [100339, "全新机未拆封(质检时会进行拆封)", 0.00],
+    [100341, "外壳有细微划痕", 0.05],
+    [100342, "外壳有磕碰掉漆", 0.10],
+    [100408, "机身有弯曲", 0.20],
+    [100069, "屏幕外观完美", 0.00],
+    [100335, "屏幕有细微划痕", 0.03],
+    [100336, "屏幕有划伤/屏幕气泡/脱胶", 0.12],
+    [100337, "屏幕有碎裂或磨损", 0.30],
+    [100411, "屏幕有硬划痕(指甲划过划痕表面有停顿感)", 0.08],
+    [100533, "屏幕较明显划痕", 0.08],
+    [100534, "屏幕裂痕/小缺角/脱胶进灰", 0.25],
+    [100085, "显示完美,无任何异常", 0.00],
+    [100092, "显示异常(漏液/错乱/闪屏/屏生线/亮度坏)", 0.30],
+    [100331, "显示轻微泛黄/亮点/亮斑(有其中一项)", 0.05],
+    [100332, "显示有亮坏点/亮斑/色斑", 0.07],
+    [100333, "显示有透图/透字", 0.15],
+    [100535, "屏幕全花屏/无法显示", 0.50],
+    [100329, "个人账号无法退出", 0.20],
+    [100330, "个人账号可退出", 0.00],
+    [100344, "机器无维修痕迹", 0.00],
+    [100346, "屏幕维修(更换非原厂屏等)", 0.25],
+    [100381, "电池维修(电池有更换)", 0.04],
+    [100382, "维修前摄像头(前摄像头有更换)", 0.06],
+    [100383, "维修后摄像头(后摄像头有更换)", 0.08],
+    [100384, "主板维修/扩容", 0.40],
+    [100410, "维修后壳/其他零件", 0.03],
+    [100529, "更换电池/摄像头/外壳/其他配件", 0.10],
+    [100530, "更换原厂屏", 0.15],
+    [100370, "电池健康度<80%", 0.05],
+    [100555, "展示机/资源机/官换机", 0.10],
+    [100560, "已开启丢失模式", 0.60],
+    [100398, "WiFi/蓝牙连接正常", 0.00],
+    [100399, "WiFi/蓝牙连接异常", 0.10],
+    [100402, "面容/指纹功能正常", 0.00],
+    [100403, "面容/指纹功能异常", 0.15],
+    [100392, "触摸正常", 0.00],
+    [100394, "触摸异常(延迟/失灵)", 0.30],
+    [100395, "拍摄正常", 0.00],
+    [100397, "拍摄异常(抖动/模糊/不对焦/分层/颠倒)", 0.15],
+    [100400, "通话正常", 0.00],
+    [100401, "通话异常", 0.25],
+    [100495, "转轴开合正常", 0.00],
+    [100496, "转轴开合异常", 0.15]
+]
+
+# 写入CSV文件(utf-8-sig编码解决Excel中文乱码,保留2位小数)
+with open("deduction_ratio.csv", "w", encoding="utf-8-sig", newline="") as f:
+    writer = csv.writer(f)
+    writer.writerows(deduction_data)
+
+print("✅ CSV文件生成成功!文件名称:deduction_ratio.csv")
+print("📌 特性:utf-8-sig编码(Excel打开无乱码)、含表头、扣减比例保留2位小数")

+ 81 - 0
tools/import_deduction_ratio.py

@@ -0,0 +1,81 @@
+import pymysql
+import pandas as pd
+import time
+from pymysql.err import OperationalError, ProgrammingError, DataError
+
+# -------------------------- 你的配置信息(已保留,无需修改) --------------------------
+DB_CONFIG = {
+    "host": "127.0.0.1",    # 数据库地址,本地一般是127.0.0.1
+    "port": 3306,           # 数据库端口,默认3306
+    "user": "root",         # 数据库用户名
+    "password": "root",   # 数据库密码
+    "database": "recycle",  # 替换为price_option_factor表所在的数据库名
+    "charset": "utf8mb4"
+}
+CSV_FILE_PATH = "deduction_ratio.csv"  # CSV文件路径,若不在同目录则写绝对路径
+# ---------------------------------------------------------------------------------------
+
+def insert_csv_to_mysql():
+    # 1. 读取CSV文件,仅保留需要的option_id和factor字段
+    try:
+        df = pd.read_csv(CSV_FILE_PATH, usecols=["option_id", "factor"])
+        # 转换数据类型(匹配数据库字段,option_id为bigint,factor为decimal)
+        df["option_id"] = df["option_id"].astype(int)
+        df["factor"] = df["factor"].astype(float)
+        if df.empty:
+            print("CSV文件中无有效数据,无需插入")
+            return
+    except FileNotFoundError:
+        print(f"错误:未找到CSV文件,路径为{CSV_FILE_PATH}")
+        return
+    except Exception as e:
+        print(f"读取CSV文件失败:{str(e)}")
+        return
+
+    # 生成当前时间(MySQL datetime格式:YYYY-MM-DD HH:MM:SS),同批次数据时间一致
+    current_time = time.strftime("%Y-%m-%d %H:%M:%S")
+    # ✅ 修复:普通元组通过索引取值(0=option_id,1=factor),这是报错的核心解决点
+    data_list = [
+        (row[0], row[1], current_time, current_time) 
+        for row in df.itertuples(index=False, name=None)
+    ]
+
+    # 2. 连接数据库并批量插入数据
+    conn = None
+    cursor = None
+    try:
+        # 建立数据库连接
+        conn = pymysql.connect(**DB_CONFIG)
+        cursor = conn.cursor()
+
+        # 插入SQL语句:新增create_time、update_time字段手动写入
+        insert_sql = """
+        INSERT INTO price_option_factor (option_id, factor, create_time, update_time)
+        VALUES (%s, %s, %s, %s)
+        """
+        # 批量执行插入(效率高于单条插入)
+        cursor.executemany(insert_sql, data_list)
+        # 提交事务
+        conn.commit()
+        print(f"成功插入{cursor.rowcount}条数据到price_option_factor表,时间统一为:{current_time}")
+
+    except OperationalError:
+        print("数据库连接失败:请检查host/port/user/password/database是否正确")
+    except ProgrammingError as e:
+        print(f"SQL执行错误:表不存在或字段名错误,详情:{str(e)}")
+    except DataError:
+        print("数据类型错误:CSV中的数据超出数据库字段的取值范围(如factor超出decimal(5,4))")
+    except Exception as e:
+        # 出错时回滚事务
+        if conn:
+            conn.rollback()
+        print(f"插入数据失败:{str(e)}")
+    finally:
+        # 关闭游标和连接(无论是否出错都执行)
+        if cursor:
+            cursor.close()
+        if conn:
+            conn.close()
+
+if __name__ == "__main__":
+    insert_csv_to_mysql()

+ 8 - 3
tools/import_release_option_clean.py

@@ -33,13 +33,18 @@ def main():
         reader = csv.DictReader(f)
 
         for row in reader:
+            step_id = row["step_id"].strip()
+            if step_id == "1":
+                continue
             step_name = row["step_name"].strip()
+            option_key_id = int(row["option_key_id"].strip())
             option_key_name = row["option_key_name"].strip()
+            option_id = int(row["option_id"].strip())
             option_name = row["option_name"].strip()
 
             # ---- step ----
             if step_name not in step_map:
-                step_id = gen_id()
+                # step_id = gen_id()
                 step_map[step_name] = step_id
             else:
                 step_id = step_map[step_name]
@@ -47,13 +52,13 @@ def main():
             # ---- option_key ----
             key = (step_name, option_key_name)
             if key not in option_key_map:
-                option_key_id = gen_id()
+                # option_key_id = gen_id()
                 option_key_map[key] = option_key_id
             else:
                 option_key_id = option_key_map[key]
 
             # ---- option ----
-            option_id = gen_id()
+            # option_id = gen_id()
 
             cur.execute("""
                 INSERT INTO release_option

+ 96 - 0
tools/import_step1_attr.py

@@ -0,0 +1,96 @@
+import csv
+import pymysql
+import time
+from datetime import datetime
+
+# ====== DB CONFIG ======
+DB = {
+    "host": "127.0.0.1",
+    "port": 3306,
+    "user": "root",
+    "password": "root",
+    "database": "recycle",
+    "charset": "utf8mb4"
+}
+
+CSV_FILE = "t_chx_release_option.csv"
+
+
+def gen_id():
+    """简单生成唯一ID(你后期可换成雪花)"""
+    return int(time.time() * 1000)
+
+
+def main():
+    conn = pymysql.connect(**DB)
+    cur = conn.cursor()
+
+    # ====== 内存映射(保证同名只生成一个ID)======
+    step_map = {}        # step_name -> step_id
+    option_key_map = {}  # (step_name, option_key_name) -> option_key_id
+
+    with open(CSV_FILE, encoding="gb18030") as f:
+        reader = csv.DictReader(f)
+
+        for row in reader:
+            step_id = row["step_id"].strip()
+            if step_id != "1":
+                continue
+            step_name = row["step_name"].strip()
+            option_key_id = int(row["option_key_id"].strip())
+            option_key_name = row["option_key_name"].strip()
+            option_id = int(row["option_id"].strip())
+            option_name = row["option_name"].strip()
+
+            # ---- step ----
+            if step_name not in step_map:
+                # step_id = gen_id()
+                step_map[step_name] = step_id
+            else:
+                step_id = step_map[step_name]
+
+            # ---- option_key ----
+            key = (step_name, option_key_name)
+            if key not in option_key_map:
+                # option_key_id = gen_id()
+                option_key_map[key] = option_key_id
+            else:
+                option_key_id = option_key_map[key]
+
+            # ---- option ----
+            # option_id = gen_id()
+            is_default = 0
+            is_base_price_attr = 0
+            if option_key_name == "容量":
+                is_base_price_attr = 1
+            cur.execute("""
+                INSERT INTO step1_attr
+                (
+                    step,attr_key,attr_name,value_id,value_name,
+                    is_default,is_normal,required,is_multi,sort_order,is_base_price_attr,
+                    create_time,
+                    update_time
+                )
+                VALUES
+                (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
+            """, (
+                1,
+                step_name,
+                option_key_name,
+                option_id,
+                option_name,
+                is_default,
+                1,1,0,0,is_base_price_attr,
+                datetime.now(),
+                datetime.now()
+            ))
+
+    conn.commit()
+    cur.close()
+    conn.close()
+
+    print("✅ release_option 规范化导入完成")
+
+
+if __name__ == "__main__":
+    main()