Browse Source

增加calendar_info表的color字段

maxiaolong 1 day ago
parent
commit
021ca0f122

+ 0 - 92
app/config/config copy.py_bak

@@ -1,92 +0,0 @@
-import os
-import platform
-
-class Config:
-    """Base configuration class"""
-    SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
-    JSON_AS_ASCII = False
-    
-    # Platform specific configurations
-    PLATFORM = platform.system().lower()
-    
-    # File paths
-    if PLATFORM == 'windows':
-        FILE_PATH = os.environ.get('FILE_PATH') or 'C:/temp/'
-    elif PLATFORM == 'linux':
-        FILE_PATH = os.environ.get('FILE_PATH') or '/tmp/'
-    
-    # Upload configurations
-    UPLOAD_FOLDER = f"{FILE_PATH}resource_uploads/"
-    ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'xlsx', 'xls', 'csv'}
-    
-    # MinIO configurations - 原配置
-    """
-    MINIO_HOST = os.environ.get('MINIO_HOST') or 'minio.citupro.com'
-    MINIO_USER = os.environ.get('MINIO_USER') or 'default-user'
-    MINIO_PASSWORD = os.environ.get('MINIO_PASSWORD') or 'default-password'
-    MINIO_SECURE = True
-    """
-    
-    # MinIO configurations - 新配置
-    MINIO_HOST = '192.168.3.143:9000'
-    MINIO_USER = 'citu-dataops-acc-key'
-    MINIO_PASSWORD = 'citu-dataops-secret-key'
-    MINIO_SECURE = False  # 内网环境,设置为 False
-    
-    # Bucket configurations - 原配置
-    """
-    BUCKET_NAME = os.environ.get('BUCKET_NAME') or 'dev'
-    if PLATFORM == 'windows':
-        PREFIX = 'dataops-test'
-    elif PLATFORM == 'linux':
-        PREFIX = 'dataops'
-    """
-    
-    # Bucket configurations - 新配置
-    BUCKET_NAME = 'dataops-test'
-    PREFIX = ''  # 由于 bucket_name 已经包含了所需信息,PREFIX 可以置空
-    
-    # 新增端口配置基类设置
-    PORT = 5500  # 默认端口
-
-    # 修改后(PostgreSQL配置)
-     
-    # SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:citupgdba@192.168.3.143:5432/dataops'
-    # 本地开发环境
-    SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:dataOps@192.168.3.143:5432/dataops'
-    SQLALCHEMY_ENGINE_OPTIONS = {
-        'pool_pre_ping': True,
-        'pool_recycle': 300,
-        'pool_size': 10,
-        'max_overflow': 20
-    } 
-   
-    # 修改后(PostgreSQL配置)
-
-
-    # Neo4j配置段
-     
-
-    NEO4J_URI = "bolt://192.168.3.143:7687"
-    NEO4J_HTTP_URI = "http://192.168.3.143:7474"
-    NEO4J_USER = "neo4j"
-    NEO4J_PASSWORD = "cituneo4j"
-    NEO4J_ENCRYPTED = False  # 内网环境可关闭加密 
-
-  
-class DevelopmentConfig(Config):
-    """Development configuration"""
-    DEBUG = True
-    PORT = 5500  # 开发环境保持5500
-
-class ProductionConfig(Config):
-    """Production configuration"""
-    DEBUG = False
-    PORT = 80  # 生产环境使用标准HTTP端口
-
-# Configuration dictionary
-config = {
-    'development': DevelopmentConfig,
-    'production': ProductionConfig,
-    'default': DevelopmentConfig
-} 

+ 53 - 9
app/core/data_parse/calendar.py

@@ -54,6 +54,9 @@ class CalendarInfo(db.Model):
     # 忌 (text)
     ji = db.Column(db.Text, nullable=True, comment='忌')
     
+    # 颜色 (varchar(10))
+    color = db.Column(db.String(10), nullable=True, comment='颜色')
+    
     def __init__(self, **kwargs):
         super().__init__(**kwargs)
     
@@ -77,7 +80,8 @@ class CalendarInfo(db.Model):
             'jishen': self.jishen,
             'yi': self.yi,
             'xiongshen': self.xiongshen,
-            'ji': self.ji
+            'ji': self.ji,
+            'color': self.color
         }
     
     def to_json(self) -> str:
@@ -108,16 +112,34 @@ class CalendarInfo(db.Model):
             except ValueError:
                 yangli = None
         
+        # 从wuxing字段中判断五行元素并设置对应的颜色值
+        wuxing = data.get('wuxing', '') or ''
+        color = data.get('color')  # 先获取字典中的color值
+        
+        # 如果字典中没有color值,则根据wuxing字段判断五行元素设置颜色
+        if not color:
+            if '金' in wuxing:
+                color = '白'
+            elif '水' in wuxing:
+                color = '黑'
+            elif '木' in wuxing:
+                color = '绿'
+            elif '火' in wuxing:
+                color = '红'
+            elif '土' in wuxing:
+                color = '黄'
+        
         return cls(
             yangli=yangli,  # type: ignore
             yinli=data.get('yinli'),  # type: ignore
-            wuxing=data.get('wuxing'),  # type: ignore
+            wuxing=wuxing,  # type: ignore
             chongsha=data.get('chongsha'),  # type: ignore
             baiji=data.get('baiji'),  # type: ignore
             jishen=data.get('jishen'),  # type: ignore
             yi=data.get('yi'),  # type: ignore
             xiongshen=data.get('xiongshen'),  # type: ignore
-            ji=data.get('ji')  # type: ignore
+            ji=data.get('ji'),  # type: ignore
+            color=color  # type: ignore
         )
 
 
@@ -338,7 +360,8 @@ class CalendarService:
                     (CalendarInfo.jishen.contains(keyword)) |
                     (CalendarInfo.yi.contains(keyword)) |
                     (CalendarInfo.xiongshen.contains(keyword)) |
-                    (CalendarInfo.ji.contains(keyword))
+                    (CalendarInfo.ji.contains(keyword)) |
+                    (CalendarInfo.color.contains(keyword))
                 ).limit(limit).all()
         else:
             # 使用Flask-SQLAlchemy的db.session
@@ -350,7 +373,8 @@ class CalendarService:
                 (CalendarInfo.jishen.contains(keyword)) |
                 (CalendarInfo.yi.contains(keyword)) |
                 (CalendarInfo.xiongshen.contains(keyword)) |
-                (CalendarInfo.ji.contains(keyword))
+                (CalendarInfo.ji.contains(keyword)) |
+                (CalendarInfo.color.contains(keyword))
             ).limit(limit).all()
     
     def fetch_calendar_from_api(self, yangli_date: date) -> Optional[dict]:
@@ -425,17 +449,35 @@ class CalendarService:
                 print(f"无效的日期格式: {yangli_str}")
                 return None
             
+            # 从wuxing字段中判断五行元素并设置对应的颜色值
+            wuxing = api_data.get('wuxing', '') or ''
+            color = api_data.get('color')  # 先获取API中的color值
+            
+            # 如果API中没有color值,则根据wuxing字段判断五行元素设置颜色
+            if not color:
+                if '金' in wuxing:
+                    color = '白'
+                elif '水' in wuxing:
+                    color = '黑'
+                elif '木' in wuxing:
+                    color = '绿'
+                elif '火' in wuxing:
+                    color = '红'
+                elif '土' in wuxing:
+                    color = '黄'
+            
             # 创建CalendarInfo对象
             calendar_info = CalendarInfo(
                 yangli=yangli_date,  # type: ignore
                 yinli=api_data.get('yinli', ''),  # type: ignore
-                wuxing=api_data.get('wuxing'),  # type: ignore
+                wuxing=wuxing,  # type: ignore
                 chongsha=api_data.get('chongsha'),  # type: ignore
                 baiji=api_data.get('baiji'),  # type: ignore
                 jishen=api_data.get('jishen'),  # type: ignore
                 yi=api_data.get('yi'),  # type: ignore
                 xiongshen=api_data.get('xionshen'),  # type: ignore  # 注意API返回的是xionshen
-                ji=api_data.get('ji')  # type: ignore
+                ji=api_data.get('ji'),  # type: ignore
+                color=color  # type: ignore
             )
             
             # 保存到数据库
@@ -525,7 +567,8 @@ def get_calendar_by_date(yangli_date: str, engine=None) -> dict:
                     "jishen": calendar_info.jishen,
                     "yi": calendar_info.yi,
                     "xiongshen": calendar_info.xiongshen,
-                    "ji": calendar_info.ji
+                    "ji": calendar_info.ji,
+                    "color": calendar_info.color
                 }
             }
         else:
@@ -555,7 +598,8 @@ def get_calendar_by_date(yangli_date: str, engine=None) -> dict:
                             "jishen": saved_calendar.jishen,
                             "yi": saved_calendar.yi,
                             "xiongshen": saved_calendar.xiongshen,
-                            "ji": saved_calendar.ji
+                            "ji": saved_calendar.ji,
+                            "color": saved_calendar.color
                         }
                     }
                 else:

+ 24 - 0
database/add_color_field_to_calendar_info.sql

@@ -0,0 +1,24 @@
+-- 为calendar_info表添加color字段的迁移脚本
+-- 执行时间: 2025-01-20
+
+BEGIN;
+
+-- 添加color字段到calendar_info表
+ALTER TABLE public.calendar_info 
+ADD COLUMN color varchar(10);
+
+-- 添加字段注释
+COMMENT ON COLUMN public.calendar_info.color IS '颜色';
+
+-- 可选:设置默认值(根据需要取消注释)
+-- UPDATE public.calendar_info SET color = 'default' WHERE color IS NULL;
+
+COMMIT;
+
+-- 验证字段是否成功添加
+SELECT column_name, data_type, character_maximum_length, is_nullable 
+FROM information_schema.columns 
+WHERE table_name = 'calendar_info' 
+  AND table_schema = 'public' 
+  AND column_name = 'color';
+

+ 4 - 1
database/create_calendar_info.sql

@@ -10,7 +10,8 @@ create table public.calendar_info
     jishen    text,
     yi        text,
     xiongshen text,
-    ji        text
+    ji        text,
+    color     varchar(10)
 );
 
 comment on table public.calendar_info is '黄历信息表';
@@ -35,5 +36,7 @@ comment on column public.calendar_info.xiongshen is '凶神宜忌';
 
 comment on column public.calendar_info.ji is '忌';
 
+comment on column public.calendar_info.color is '颜色';
+
 
 

+ 11 - 0
docs/每日签运需求.txt

@@ -0,0 +1,11 @@
+每日签运小程序
+1. 微信小程序注册登录(微信号,手机)
+2. 日历展示每日签运。阅读过的有标记。没阅读过的保持空白。 
+3. 每日签运推荐颜色。阅读过的标记也可以用同一种颜色标记。 
+	金:白      #FAFAFA
+	水:黑      #212121
+	木:绿      #43A047
+	火:红      #F44336
+	土:黄      #FDD835
+4. 每日手账。可以记录简短文字,不超过500字。 纯文本。 (可以语音录入)
+5. 日历中点击某一天,可以查看当日签运,可以查看当日手账。  

+ 2 - 1
test_calendar_basic.py

@@ -50,7 +50,8 @@ def test_calendar_info_creation():
             'jishen': '官日 六仪 益後 月德合 除神 玉堂 鸣犬',
             'yi': '祭祀 出行 扫舍 馀事勿取',
             'xiongshen': '月建 小时 土府 月刑 厌对 招摇 五离',
-            'ji': '诸事不宜'
+            'ji': '诸事不宜',
+            'color': 'purple'
         }
         
         # 使用from_dict方法创建对象

+ 295 - 0
test_calendar_color_mapping.py

@@ -0,0 +1,295 @@
+"""
+测试黄历信息数据模型的五行颜色映射功能
+"""
+
+import sys
+import os
+from datetime import date
+
+# 添加项目路径到sys.path
+sys.path.append(os.path.dirname(os.path.abspath(__file__)))
+
+from app.core.data_parse.calendar import CalendarInfo, CalendarService
+
+
+def test_wuxing_color_mapping():
+    """测试五行颜色映射功能"""
+    print("=== 测试五行颜色映射功能 ===")
+    
+    # 测试数据:包含不同五行元素的wuxing字段
+    test_cases = [
+        {
+            'name': '金元素测试',
+            'data': {
+                'yangli': '2025-01-20',
+                'yinli': '腊月二十一',
+                'wuxing': '井泉水 金 建执位',  # 包含"金"
+            },
+            'expected_color': '白'
+        },
+        {
+            'name': '水元素测试',
+            'data': {
+                'yangli': '2025-01-21',
+                'yinli': '腊月二十二',
+                'wuxing': '井泉水 建执位',  # 包含"水"
+            },
+            'expected_color': '黑'
+        },
+        {
+            'name': '木元素测试',
+            'data': {
+                'yangli': '2025-01-22',
+                'yinli': '腊月二十三',
+                'wuxing': '大林木 除执位',  # 包含"木"
+            },
+            'expected_color': '绿'
+        },
+        {
+            'name': '火元素测试',
+            'data': {
+                'yangli': '2025-01-23',
+                'yinli': '腊月二十四',
+                'wuxing': '山头火 满执位',  # 包含"火"
+            },
+            'expected_color': '红'
+        },
+        {
+            'name': '土元素测试',
+            'data': {
+                'yangli': '2025-01-24',
+                'yinli': '腊月二十五',
+                'wuxing': '大驿土 平执位',  # 包含"土"
+            },
+            'expected_color': '黄'
+        },
+        {
+            'name': '无五行元素测试',
+            'data': {
+                'yangli': '2025-01-25',
+                'yinli': '腊月二十六',
+                'wuxing': '建执位',  # 不包含五行元素
+            },
+            'expected_color': None
+        },
+        {
+            'name': '预设颜色测试',
+            'data': {
+                'yangli': '2025-01-26',
+                'yinli': '腊月二十七',
+                'wuxing': '井泉水 金 建执位',  # 包含"金",但已有预设颜色
+                'color': '紫'  # 预设颜色
+            },
+            'expected_color': '紫'  # 应该保持预设颜色,不被覆盖
+        }
+    ]
+    
+    for test_case in test_cases:
+        print(f"\n--- {test_case['name']} ---")
+        
+        # 使用from_dict方法创建对象
+        calendar_info = CalendarInfo.from_dict(test_case['data'])
+        
+        print(f"输入wuxing: {test_case['data'].get('wuxing', 'None')}")
+        print(f"预设color: {test_case['data'].get('color', 'None')}")
+        print(f"实际color: {calendar_info.color}")
+        print(f"期望color: {test_case['expected_color']}")
+        
+        # 验证结果
+        if calendar_info.color == test_case['expected_color']:
+            print("✅ 测试通过")
+        else:
+            print("❌ 测试失败")
+            return False
+    
+    print("\n✅ 所有五行颜色映射测试通过!")
+    return True
+
+
+def test_save_calendar_from_api_color_mapping():
+    """测试CalendarService.save_calendar_from_api方法的颜色映射功能"""
+    print("\n=== 测试save_calendar_from_api颜色映射功能 ===")
+    
+    # 创建服务实例(不连接数据库)
+    service = CalendarService()
+    
+    # 模拟API数据
+    api_test_cases = [
+        {
+            'name': 'API金元素测试',
+            'api_data': {
+                'yangli': '2025-01-20',
+                'yinli': '腊月二十一',
+                'wuxing': '白腊金 成执位',  # 包含"金"
+                'chongsha': '冲兔',
+                'baiji': '甲不开仓',
+                'jishen': '天德',
+                'yi': '祭祀',
+                'xionshen': '天刑',
+                'ji': '嫁娶'
+            },
+            'expected_color': '白'
+        },
+        {
+            'name': 'API火元素测试',
+            'api_data': {
+                'yangli': '2025-01-21',
+                'yinli': '腊月二十二',
+                'wuxing': '山头火 收执位',  # 包含"火"
+                'chongsha': '冲龙',
+                'baiji': '乙不栽种',
+                'jishen': '月德',
+                'yi': '开光',
+                'xionshen': '天火',
+                'ji': '安葬'
+            },
+            'expected_color': '红'
+        },
+        {
+            'name': 'API预设颜色测试',
+            'api_data': {
+                'yangli': '2025-01-22',
+                'yinli': '腊月二十三',
+                'wuxing': '大林木 开执位',  # 包含"木"
+                'color': '蓝',  # API中已有颜色值
+                'chongsha': '冲蛇',
+                'baiji': '丙不修灶',
+                'jishen': '天喜',
+                'yi': '求嗣',
+                'xionshen': '月刑',
+                'ji': '破土'
+            },
+            'expected_color': '蓝'  # 应该保持API中的颜色,不被覆盖
+        }
+    ]
+    
+    for test_case in api_test_cases:
+        print(f"\n--- {test_case['name']} ---")
+        
+        try:
+            # 模拟save_calendar_from_api中的颜色逻辑
+            api_data = test_case['api_data']
+            wuxing = api_data.get('wuxing', '') or ''
+            color = api_data.get('color')  # 先获取API中的color值
+            
+            # 如果API中没有color值,则根据wuxing字段判断五行元素设置颜色
+            if not color:
+                if '金' in wuxing:
+                    color = '白'
+                elif '水' in wuxing:
+                    color = '黑'
+                elif '木' in wuxing:
+                    color = '绿'
+                elif '火' in wuxing:
+                    color = '红'
+                elif '土' in wuxing:
+                    color = '黄'
+            
+            print(f"输入wuxing: {wuxing}")
+            print(f"API预设color: {api_data.get('color', 'None')}")
+            print(f"计算得出color: {color}")
+            print(f"期望color: {test_case['expected_color']}")
+            
+            # 验证结果
+            if color == test_case['expected_color']:
+                print("✅ 测试通过")
+            else:
+                print("❌ 测试失败")
+                return False
+                
+        except Exception as e:
+            print(f"❌ 测试异常: {e}")
+            return False
+    
+    print("\n✅ 所有save_calendar_from_api颜色映射测试通过!")
+    return True
+
+
+def test_edge_cases():
+    """测试边界情况"""
+    print("\n=== 测试边界情况 ===")
+    
+    test_cases = [
+        {
+            'name': '空wuxing字段测试',
+            'data': {
+                'yangli': '2025-01-27',
+                'yinli': '腊月二十八',
+                'wuxing': '',  # 空字符串
+            },
+            'expected_color': None
+        },
+        {
+            'name': 'None wuxing字段测试',
+            'data': {
+                'yangli': '2025-01-28',
+                'yinli': '腊月二十九',
+                # 没有wuxing字段
+            },
+            'expected_color': None
+        },
+        {
+            'name': '含有五行字符但非五行元素测试',
+            'data': {
+                'yangli': '2025-01-29',
+                'yinli': '腊月三十',
+                'wuxing': '建执位 满执位',  # 不包含任何五行元素
+            },
+            'expected_color': None
+        }
+    ]
+    
+    for test_case in test_cases:
+        print(f"\n--- {test_case['name']} ---")
+        
+        calendar_info = CalendarInfo.from_dict(test_case['data'])
+        
+        print(f"输入wuxing: {test_case['data'].get('wuxing', 'None')}")
+        print(f"实际color: {calendar_info.color}")
+        print(f"期望color: {test_case['expected_color']}")
+        
+        if calendar_info.color == test_case['expected_color']:
+            print("✅ 测试通过")
+        else:
+            print("❌ 测试失败")
+            return False
+    
+    print("\n✅ 所有边界情况测试通过!")
+    return True
+
+
+def main():
+    """主测试函数"""
+    print("开始测试黄历信息五行颜色映射功能...\n")
+    
+    try:
+        # 运行所有测试
+        test1_passed = test_wuxing_color_mapping()
+        test2_passed = test_save_calendar_from_api_color_mapping()
+        test3_passed = test_edge_cases()
+        
+        if test1_passed and test2_passed and test3_passed:
+            print("\n🎉 所有五行颜色映射测试通过!")
+            print("\n五行颜色映射规则:")
+            print("- 金 → 白")
+            print("- 水 → 黑") 
+            print("- 木 → 绿")
+            print("- 火 → 红")
+            print("- 土 → 黄")
+            print("\n功能特性:")
+            print("- ✅ 自动从wuxing字段识别五行元素")
+            print("- ✅ 自动设置对应的颜色值")
+            print("- ✅ 保留API或字典中预设的颜色值")
+            print("- ✅ 处理边界情况(空值、无五行元素等)")
+            print("- ✅ from_dict和save_calendar_from_api都支持此功能")
+        else:
+            print("\n❌ 部分测试失败!")
+        
+    except Exception as e:
+        print(f"❌ 测试过程中发生错误: {e}")
+        import traceback
+        traceback.print_exc()
+
+
+if __name__ == "__main__":
+    main()

+ 8 - 4
test_calendar_model.py

@@ -26,7 +26,8 @@ def test_calendar_info_model():
         'jishen': '天德 月德 天喜',
         'yi': '祭祀 祈福 求嗣 开光',
         'xiongshen': '天刑 天火',
-        'ji': '嫁娶 安葬 开市 破土'
+        'ji': '嫁娶 安葬 开市 破土',
+        'color': 'red'
     }
     
     # 测试from_dict方法
@@ -65,7 +66,8 @@ def test_calendar_service():
         'jishen': '天德 月德 天喜',
         'yi': '祭祀 祈福 求嗣 开光',
         'xiongshen': '天刑 天火',
-        'ji': '嫁娶 安葬 开市 破土'
+        'ji': '嫁娶 安葬 开市 破土',
+        'color': 'blue'
     }
     
     # 测试数据创建(不实际保存到数据库)
@@ -89,7 +91,8 @@ def test_convenience_functions():
         'jishen': '天德 月德 天喜',
         'yi': '祭祀 祈福 求嗣 开光',
         'xiongshen': '天刑 天火',
-        'ji': '嫁娶 安葬 开市 破土'
+        'ji': '嫁娶 安葬 开市 破土',
+        'color': 'green'
     }
     
     # 测试create_calendar_info函数
@@ -119,7 +122,8 @@ def test_data_validation():
     # 测试必需字段
     required_data = {
         'yangli': '2025-01-19',
-        'yinli': '腊月二十'
+        'yinli': '腊月二十',
+        'color': 'yellow'
     }
     
     calendar_info = CalendarInfo.from_dict(required_data)

+ 36 - 0
test_wuxing_color_simple.py

@@ -0,0 +1,36 @@
+"""
+简单测试五行颜色自动推导功能
+"""
+
+import sys
+import os
+sys.path.append(os.path.dirname(os.path.abspath(__file__)))
+
+from app.core.data_parse.calendar import CalendarInfo
+
+def test_simple_wuxing_color():
+    """简单测试五行颜色推导"""
+    print("=== 简单测试五行颜色推导 ===")
+    
+    # 测试没有预设颜色,只根据wuxing推导
+    test_data = {
+        'yangli': '2025-01-20',
+        'yinli': '腊月二十一',
+        'wuxing': '金'  # 只有五行元素,没有预设颜色
+    }
+    
+    calendar_info = CalendarInfo.from_dict(test_data)
+    print(f"输入wuxing: {test_data['wuxing']}")
+    print(f"推导出的color: {calendar_info.color}")
+    print(f"期望color: 白")
+    
+    if calendar_info.color == '白':
+        print("✅ 五行颜色推导测试通过!")
+        return True
+    else:
+        print("❌ 五行颜色推导测试失败!")
+        return False
+
+if __name__ == "__main__":
+    test_simple_wuxing_color()
+