Bootstrap

通义灵码2.0 AI 程序员体验:优化与问题解决的全过程

在这里插入图片描述

通义灵码2.0 AI 程序员体验:优化与问题解决的全过程


🌟 嗨,我是LucianaiB

🌍 总有人间一两风,填我十万八千梦。

🚀 路漫漫其修远兮,吾将上下而求索。


前言

随着AI技术的发展,越来越多的开发工具开始结合智能化功能,极大地提高了开发效率。通义灵码2.0是阿里云推出的一款智能编程助手,专注于为程序员提供AI辅助编程功能。通过通义灵码2.0,开发者能够在项目的各个阶段获得更加智能的支持,从代码生成、问题诊断到性能优化,都能通过AI程序员获得高效的帮助。

在这次体验中,我深入体验了通义灵码2.0的功能,包括项目初始化、界面优化、调试过程以及与AI的交互。接下来,我将通过实际操作,详细记录这个过程中遇到的情况,并与通义灵码1.0进行对比。

快速获取通义灵码 2.0

打开我们的pycharm,点击我们左侧的拓展按钮,在搜索框中输入TONGYI Lingma回车搜索就能看到我们的通义灵码插件,我们点击获取,默认下载的就是最新版本的,即通义灵码 2.0 ,如果之前下载了的,我们点击更新就行了。
image.png

1. 项目初始化

首先,我们进入项目初始化阶段。启动过程中,程序界面简洁而清晰,初始化过程流畅。下图展示了项目启动时的运行过程:

项目初始化时的运行过程

在该阶段,AI已经在后台自动加载了必要的配置文件,并准备好为后续的开发过程提供支持。

2. 设计优化与科技感添加

接下来,我将界面进行了优化,目标是提升整体的科技感。在优化的过程中,我希望能够增加一些视觉效果,让界面更具未来感。优化后的界面如下:

优化后界面

左侧可以找到各项操作的位置,并且底部加入了一键同意功能,极大提高了操作的便捷性。

3. 调整背景与细节

为了进一步增强科技感,我将背景进行了虚拟化处理,达到更科幻的效果:

背景虚拟化调整

虽然背景的变化符合要求,但整体的科技感还不够强烈。于是我通过与AI进行交流,提出希望能进一步添加一些科技元素。

4. 科技感增强

AI响应迅速,并建议我加入CSS动画、过渡效果以及一些更具未来感的UI组件。AI的建议和修改说明都非常清晰:

AI修改说明

经过调整后,界面变得更加符合科技感需求。再次运行后,界面的效果更加炫酷,用户体验也大大提升:

最终效果

5. 错误调试与AI帮助

尽管优化效果令人满意,但在运行过程中仍然出现了一个报错问题。这时,我将错误信息提交给AI程序员:

报错信息

AI程序员不仅及时反馈了解决方案,还帮助我解决了问题:

AI帮助解决问题

6. 通义灵码单元测试 Agent 对比人工单测效率和效果

在实际开发过程中,单元测试是确保代码质量的重要环节。相比传统的人工单测,通义灵码2.0的单元测试 Agent 提供了更高效的自动化测试功能。AI不仅能够根据代码生成测试用例,还能实时分析测试结果,并给出修改建议。人工单测往往需要消耗大量的时间来编写测试用例和调试,而AI程序员通过智能分析,能够在短时间内自动完成这一过程,提高了工作效率,并减少了人工错误。

7. 通义灵码 2.0 和 1.0 对比

通义灵码2.0相比1.0版本有了显著的提升,尤其在用户体验和功能的智能化方面。以下是我对比的几个关键点:

  • 界面设计与交互性:2.0在UI界面的科技感和未来感设计上做得更加出色。相比1.0版本,2.0的UI组件更加灵活,CSS动画和过渡效果使得界面显得更加炫酷和现代化。

  • 问题诊断与解决:2.0的智能诊断功能更加精确,不仅能够处理代码错误,还能根据上下文提供更加精准的优化建议。而1.0的诊断功能相对基础,常常需要人工干预才能找到问题根源。

  • 代码生成与优化建议:2.0在代码生成和优化方面更加智能,能够根据开发者的需求自动调整代码结构,并且给出详细的优化方案,极大提升了编程效率。而1.0则更多依赖开发者的手动调整。

通过以上对比,通义灵码2.0明显提升了开发效率和智能化程度,是对1.0的一次重要升级。

对通义灵码AI程序员的评价

image.png


代码结构与组织

  模块化设计:代码结构清晰,功能模块划分合理。HTML模板直接嵌入到Python文件中,虽然不是最佳实践(通常建议将HTML模板分离到独立文件中),但在小型项目中可以接受。
  路由定义:Flask路由定义明确,包括主页、获取运势和静态文件服务,满足了基本需求。

功能实现
  运势计算逻辑:
使用生肖和出生日期来计算运势,逻辑简单但有趣。
运势等级通过随机生成的方式确定,增加了趣味性,但也可以考虑更复杂的算法以提高预测的“科学性”或娱乐性。
  前端交互:
前端页面设计精美,使用了Tailwind CSS进行样式布局,并添加了许多动画效果,提升了用户体验。
表单验证和提交处理逻辑完善,确保用户输入的有效性。
运势结果显示部分设计美观,信息丰富,包括总体运势、事业运、感情运等多方面内容。

用户体验
  视觉效果:页面背景图片和科技感元素的加入使得整体界面非常吸引人,特别是蛇年主题的设计,突出了节日氛围。
  交互反馈:按钮点击后的加载状态、结果展示时的淡入动画等细节处理得当,增强了用户的互动体验。

技术实现
  安全性:代码中对用户输入进行了初步验证,防止了无效数据的提交,但仍需进一步加强安全措施,如防止SQL注入、XSS攻击等。
  性能优化:对于小型应用来说,当前性能足够,但如果扩展为更大规模的应用,可能需要考虑缓存机制、异步处理等方式提升性能。

总结
  通义灵码AI程序员在短时间内能够编写出功能完整、界面美观且具有一定趣味性的运势预测应用,展示了其良好的编程能力和创造力。代码质量较高,符合现代Web开发的最佳实践。如果希望进一步提升,可以考虑以下几点:
分离前后端代码:将HTML模板移至独立文件,便于维护和管理。
  增强安全性:增加更多的安全防护措施,确保应用的安全性。
  优化算法:改进运势计算逻辑,使其更加复杂或有趣,提升用户体验。
  响应式设计:确保页面在不同设备上的显示效果一致,提升移动端用户体验。
  总体而言,通义灵码AI程序员的表现令人满意,具备较强的开发能力。

总结

通义灵码2.0为我的编程过程提供了强大的支持,无论是项目初始化、界面优化,还是调试问题,都能依靠AI的智能辅助来提升开发效率。与通义灵码1.0相比,2.0在用户体验、功能智能化以及问题诊断方面都有了显著的提升。整个体验让我更加期待未来AI在编程中的应用,尤其是其在用户体验和问题解决上的巨大潜力。

代码

from flask import Flask, render_template_string, request, jsonify, send_from_directory
import random
import os

app = Flask(__name__)

# HTML模板(直接嵌入到Python文件中)
HTML_TEMPLATE = '''
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>蛇年运势预测</title>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
    <style>
        body {
            background: url('/static/蛇迎新春.png') center center fixed;
            background-size: cover;
            color: #333;
            font-family: 'Arial', sans-serif;
        }
        .container {
            background-color: rgba(255, 255, 255, 0.8);
            padding: 40px;
            border-radius: 20px;
            box-shadow: 0 15px 30px rgba(0,0,0,0.15);
            backdrop-filter: blur(3px);
            position: relative;
            z-index: 1;
            border: 2px solid #d81e06;
            background-image: 
                linear-gradient(45deg, #d81e06 12px, transparent 0),
                linear-gradient(-45deg, #d81e06 12px, transparent 0);
            background-position: top left, top right;
            background-repeat: no-repeat;
            background-size: 30px 30px;
        }
        .container::before,
        .container::after {
            content: '';
            position: absolute;
            width: 30px;
            height: 30px;
            bottom: 0;
            border: 2px solid #d81e06;
        }
        .container::before {
            left: 0;
            border-width: 0 0 2px 2px;
        }
        .container::after {
            right: 0;
            border-width: 0 2px 2px 0;
        }
        h1 {
            color: #d81e06;
            text-align: center;
            font-size: 2.5em;
            margin-bottom: 30px;
            position: relative;
            padding-bottom: 15px;
        }
        h1::after {
            content: '';
            position: absolute;
            bottom: 0;
            left: 50%;
            transform: translateX(-50%);
            width: 100px;
            height: 3px;
            background: linear-gradient(90deg, transparent, #d81e06, transparent);
        }
        .input-section {
            text-align: center;
            margin: 30px 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 25px;
            width: 100%;
            max-width: 600px;
            margin: 0 auto;
        }
        .name-input {
            position: relative;
            margin-bottom: 30px;
            width: 100%;
            max-width: 400px;
            margin: 0 auto 30px;
        }
        .name-input::after {
            content: '';
            position: absolute;
            bottom: -10px;
            left: 0;
            width: 100%;
            height: 1px;
            background: linear-gradient(90deg, transparent, rgba(216,30,6,0.2), transparent);
        }
        .name-input label {
            position: absolute;
            left: 15px;
            top: -10px;
            background: white;
            padding: 0 5px;
            color: #666;
            font-size: 14px;
            z-index: 1;
        }
        .name-input input {
            width: 100%;
            padding: 15px;
            border: 2px solid #eee;
            border-radius: 8px;
            font-size: 16px;
            transition: all 0.3s ease;
        }
        .date-inputs {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 30px;
            width: 100%;
            background: rgba(255, 255, 255, 0.9);
            padding: 30px;
            border-radius: 15px;
            box-shadow: 0 5px 15px rgba(0,0,0,0.05);
            margin: 20px 0;
            border: 1px solid rgba(216,30,6,0.3);
            position: relative;
        }
        .date-inputs::before {
            content: '生辰信息';
            position: absolute;
            top: -12px;
            left: 20px;
            background: white;
            padding: 0 10px;
            color: #d81e06;
            font-weight: bold;
            font-size: 14px;
        }
        .input-group {
            position: relative;
            padding: 5px;
        }
        .input-group label {
            font-size: 14px;
            color: #666;
            font-weight: 500;
            margin-bottom: 8px;
            display: block;
        }
        .input-group input {
            width: 100%;
            padding: 12px 15px;
            border: 2px solid rgba(216,30,6,0.2);
            border-radius: 8px;
            font-size: 16px;
            transition: all 0.3s ease;
            background-color: white;
            height: 45px;
        }
        .input-group input:focus {
            outline: none;
            border-color: #d81e06;
            box-shadow: 0 0 10px rgba(216,30,6,0.1);
        }
        input[type="number"] {
            -moz-appearance: textfield;
            appearance: textfield;
            width: 100%;
        }
        input[type="number"]::-webkit-outer-spin-button,
        input[type="number"]::-webkit-inner-spin-button {
            -webkit-appearance: none;
            margin: 0;
        }
        select {
            cursor: pointer;
            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%23666' viewBox='0 0 16 16'%3E%3Cpath d='M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E");
            background-repeat: no-repeat;
            background-position: calc(100% - 12px) center;
            padding-right: 35px;
        }
        select:invalid {
            color: #999;
        }
        option {
            color: #333;
        }
        button {
            background: linear-gradient(45deg, #d81e06, #ff4b2b);
            color: white;
            border: none;
            border-radius: 25px;
            padding: 15px 50px;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s ease;
            margin-top: 30px;
            min-width: 250px;
            text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
            box-shadow: 0 5px 15px rgba(216,30,6,0.3);
            position: relative;
            overflow: hidden;
        }
        button::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(
                90deg,
                transparent,
                rgba(255,255,255,0.2),
                transparent
            );
            transition: 0.5s;
        }
        button:hover::before {
            left: 100%;
        }
        button:active {
            transform: translateY(1px);
            box-shadow: 0 3px 10px rgba(216,30,6,0.3);
        }
        button:disabled {
            background: #cccccc;
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }
        .result {
            background-color: rgba(255, 255, 255, 0.85);
            backdrop-filter: blur(3px);
            padding: 30px;
            border-radius: 15px;
            margin-top: 30px;
            border: 1px solid rgba(216,30,6,0.2);
            position: relative;
            animation: fadeIn 0.5s ease;
        }
        @keyframes fadeIn {
            from { 
                opacity: 0; 
                transform: translateY(20px);
            }
            to { 
                opacity: 1;
                transform: translateY(0);
            }
        }
        .result h2 {
            color: #d81e06;
            text-align: center;
            margin-bottom: 25px;
            font-size: 1.8em;
        }
        .result p {
            margin: 15px 0;
            padding: 12px;
            border-radius: 8px;
            background-color: rgba(255,255,255,0.7);
            border-left: 3px solid #d81e06;
            transition: all 0.3s ease;
        }
        .result p:hover {
            transform: translateX(5px);
            background-color: rgba(255,255,255,0.9);
        }
        .special-note {
            background: linear-gradient(45deg, rgba(216,30,6,0.1), rgba(255,75,43,0.1));
            border: 2px dashed #d81e06;
            padding: 20px;
            border-radius: 12px;
            text-align: center;
            margin-top: 25px;
            position: relative;
            overflow: hidden;
        }
        .special-note::before {
            content: '🎊';
            position: absolute;
            left: 20px;
            top: 50%;
            transform: translateY(-50%);
            font-size: 24px;
        }
        .special-note::after {
            content: '🎊';
            position: absolute;
            right: 20px;
            top: 50%;
            transform: translateY(-50%);
            font-size: 24px;
        }
        .snake-border {
            position: relative;
            border: 2px solid #d81e06;
            padding: 40px;
            margin: 20px 0;
            border-radius: 15px;
        }
        .snake-border::before {
            content: "🐍";
            position: absolute;
            top: -15px;
            left: 20px;
            background: white;
            padding: 0 10px;
            font-size: 24px;
        }
        .snake-decoration {
            text-align: center;
            margin: 15px 0;
            font-size: 28px;
            background: linear-gradient(45deg, #d81e06, #ff4b2b);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            animation: slither 3s infinite ease-in-out;
        }
        @keyframes slither {
            0% { transform: translateX(-10px); }
            50% { transform: translateX(10px); }
            100% { transform: translateX(-10px); }
        }
        /* 添加科技感元素 */
        .tech-background {
            background: radial-gradient(circle, rgba(255, 255, 255, 0.1), rgba(0, 0, 0, 0));
            backdrop-filter: blur(10px);
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: -1;
        }
        .tech-border {
            border: 2px solid #d81e06;
            border-radius: 20px;
            padding: 20px;
            box-shadow: 0 0 30px rgba(216, 30, 6, 0.5);
        }
        .tech-button {
            background: linear-gradient(45deg, #ff4b2b, #d81e06);
            border: none;
            border-radius: 25px;
            padding: 15px 50px;
            font-size: 18px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s ease;
            margin-top: 30px;
            min-width: 250px;
            text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
            box-shadow: 0 5px 15px rgba(216, 30, 6, 0.3);
            position: relative;
            overflow: hidden;
        }
        .tech-button::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(
                90deg,
                transparent,
                rgba(255,255,255,0.2),
                transparent
            );
            transition: 0.5s;
        }
        .tech-button:hover::before {
            left: 100%;
        }
        .tech-button:active {
            transform: translateY(1px);
            box-shadow: 0 3px 10px rgba(216, 30, 6, 0.3);
        }
        .tech-button:disabled {
            background: #cccccc;
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }
        .tech-result {
            background-color: rgba(255, 255, 255, 0.85);
            backdrop-filter: blur(3px);
            padding: 30px;
            border-radius: 15px;
            margin-top: 30px;
            border: 1px solid rgba(216, 30, 6, 0.2);
            position: relative;
            animation: fadeIn 0.5s ease;
        }
        .tech-result h2 {
            color: #d81e06;
            text-align: center;
            margin-bottom: 25px;
            font-size: 1.8em;
        }
        .tech-result p {
            margin: 15px 0;
            padding: 12px;
            border-radius: 8px;
            background-color: rgba(255,255,255,0.7);
            border-left: 3px solid #d81e06;
            transition: all 0.3s ease;
        }
        .tech-result p:hover {
            transform: translateX(5px);
            background-color: rgba(255,255,255,0.9);
        }
    </style>
</head>
<body class="bg-cover bg-center bg-no-repeat" style="background-image: url('/static/蛇迎新春.png');">
    <div class="tech-background"></div>
    <div class="container mx-auto p-10 bg-white bg-opacity-80 rounded-3xl shadow-lg relative z-10 border-2 border-d81e06">
        <h1 class="text-5xl text-center mb-10 relative pb-4 text-d81e06">
            ✨ 2025蛇年运势预测 ✨
            <span class="absolute bottom-0 left-1/2 transform -translate-x-1/2 w-24 h-1 bg-gradient-to-r from-transparent via-d81e06 to-transparent"></span>
        </h1>
        <div class="snake-decoration text-center mb-5 text-4xl bg-gradient-to-r from-d81e06 to-ff4b2b bg-clip-text text-transparent animate-slither">🐍 ~ ~ ~</div>
        <div class="tech-border relative border-2 border-d81e06 p-10 mb-5 rounded-2xl">
            <div class="input-section flex flex-col items-center gap-10 w-full max-w-2xl mx-auto">
                <div class="name-input relative mb-10 w-full max-w-lg mx-auto">
                    <label class="absolute left-4 top-2 bg-white px-2 text-gray-600 text-sm z-10">姓名</label>
                    <input type="text" id="name" placeholder="请输入您的姓名" autocomplete="off" class="w-full px-4 py-3 border-2 border-gray-300 rounded-lg text-lg transition-all duration-300">
                </div>
                <div class="date-inputs grid grid-cols-3 gap-10 w-full bg-white bg-opacity-90 p-10 rounded-xl shadow-md border border-d81e06 relative">
                    <span class="absolute top-0 left-5 bg-white px-3 text-d81e06 font-bold text-sm">生辰信息</span>
                    <div class="input-group relative p-2">
                        <label class="text-gray-600 font-medium mb-2 block">出生年份</label>
                        <input type="text" id="birth-year" placeholder="如:1990" maxlength="4" autocomplete="off" oninput="validateNumber(this, 1920, 2024, 4)" class="w-full px-4 py-3 border-2 border-gray-200 rounded-lg text-lg transition-all duration-300 bg-white h-11">
                    </div>
                    <div class="input-group relative p-2">
                        <label class="text-gray-600 font-medium mb-2 block">出生月份</label>
                        <input type="text" id="birth-month" placeholder="如:1-12" maxlength="2" autocomplete="off" oninput="validateNumber(this, 1, 12, 2)" class="w-full px-4 py-3 border-2 border-gray-200 rounded-lg text-lg transition-all duration-300 bg-white h-11">
                    </div>
                    <div class="input-group relative p-2">
                        <label class="text-gray-600 font-medium mb-2 block">出生日期</label>
                        <input type="text" id="birth-day" placeholder="如:1-31" maxlength="2" autocomplete="off" oninput="validateNumber(this, 1, 31, 2)" class="w-full px-4 py-3 border-2 border-gray-200 rounded-lg text-lg transition-all duration-300 bg-white h-11">
                    </div>
                </div>
                <button onclick="getFortune()" class="tech-button">
                    <span class="absolute top-0 left-0 w-full h-full bg-gradient-to-r from-transparent via-white to-transparent transition-all duration-500"></span>
                    查看运势
                </button>
            </div>
        </div>
        <div id="result" class="tech-result bg-white bg-opacity-85 backdrop-filter backdrop-blur-md p-10 rounded-xl mt-10 border border-d81e06 relative animate-fadeIn"></div>
    </div>

    <script>
        function validateNumber(input, min, max, maxLength) {
            input.value = input.value.replace(/[^\d]/g, '').slice(0, maxLength);
            input.value = input.value.replace(/[^\d]/g, '').slice(0, maxLength);
            let value = parseInt(input.value);
            if (input.value.length === maxLength || value > max) {
                if (value < min) {
                    input.value = min.toString();
                } else if (value > max) {
                    input.value = max.toString();
                }
            }
            validateDate();
        }

        function validateDate() {
            const year = parseInt(document.getElementById('birth-year').value);
            const month = parseInt(document.getElementById('birth-month').value);
            const dayInput = document.getElementById('birth-day');
            const day = parseInt(dayInput.value);

            if (isNaN(year) || isNaN(month) || isNaN(day)) return;

            let maxDays = 31;
            if ([4, 6, 9, 11].includes(month)) {
                maxDays = 30;
            } else if (month === 2) {
                maxDays = (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) ? 29 : 28;
            }

            if (day > maxDays) {
                dayInput.value = maxDays.toString();
            }
        }

        function getFortune() {
            const year = document.getElementById('birth-year').value;
            const month = document.getElementById('birth-month').value;
            const day = document.getElementById('birth-day').value;
            const name = document.getElementById('name').value;
            
            if (!year || !month || !day || !name) {
                alert('请填写完整信息!');
                return;
            }

            if (year.length !== 4 || parseInt(year) < 1920 || parseInt(year) > 2024) {
                alert('请输入有效的出生年份!');
                return;
            }

            const button = document.querySelector('.tech-button');
            button.disabled = true;
            button.innerHTML = '正在测算...';
            
            fetch('/get_fortune', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    name: name,
                    birth_year: year,
                    birth_month: month,
                    birth_day: day
                })
            })
            .then(response => response.json())
            .then(data => {
                const resultDiv = document.getElementById('result');
                resultDiv.style.display = 'block';
                resultDiv.innerHTML = `
                    <div class="snake-decoration text-center mb-5 text-4xl bg-gradient-to-r from-d81e06 to-ff4b2b bg-clip-text text-transparent animate-slither">🐍 ~ ~ ~</div>
                    <h2 class="text-3xl text-center mb-5 text-d81e06">🌟 ${name}的蛇年运势预测 🌟</h2>
                    <div class="zodiac-info">
                        ${getZodiacInfo(data.zodiac_sign, data.is_snake_year)}
                    </div>
                    <p class="mb-3 p-3 rounded-lg bg-white bg-opacity-70 border-l-4 border-d81e06 transition-all duration-300 hover:translate-x-1 hover:bg-opacity-90">总体运势:${getEmoji(data.overall)} ${data.overall}</p>
                    <p class="mb-3 p-3 rounded-lg bg-white bg-opacity-70 border-l-4 border-d81e06 transition-all duration-300 hover:translate-x-1 hover:bg-opacity-90">事业运:${getEmoji(data.career)} ${data.career}</p>
                    <p class="mb-3 p-3 rounded-lg bg-white bg-opacity-70 border-l-4 border-d81e06 transition-all duration-300 hover:translate-x-1 hover:bg-opacity-90">感情运:${getEmoji(data.love)} ${data.love}</p>
                    <p class="mb-3 p-3 rounded-lg bg-white bg-opacity-70 border-l-4 border-d81e06 transition-all duration-300 hover:translate-x-1 hover:bg-opacity-90">财运:${getEmoji(data.wealth)} ${data.wealth}</p>
                    <p class="mb-3 p-3 rounded-lg bg-white bg-opacity-70 border-l-4 border-d81e06 transition-all duration-300 hover:translate-x-1 hover:bg-opacity-90">健康运:${getEmoji(data.health)} ${data.health}</p>
                    <p class="mb-3 p-3 rounded-lg bg-white bg-opacity-70 border-l-4 border-d81e06 transition-all duration-300 hover:translate-x-1 hover:bg-opacity-90">🔮 幸运数字:${data.lucky_numbers.join('、')}</p>
                    <p class="mb-3 p-3 rounded-lg bg-white bg-opacity-70 border-l-4 border-d81e06 transition-all duration-300 hover:translate-x-1 hover:bg-opacity-90">🎨 幸运颜色:${data.lucky_colors.join('、')}</p>
                    <p class="mb-3 p-3 rounded-lg bg-white bg-opacity-70 border-l-4 border-d81e06 transition-all duration-300 hover:translate-x-1 hover:bg-opacity-90">🌿 开运方位:${data.lucky_directions.join('、')}</p>
                    ${data.is_snake_year ? '<p class="special-note bg-gradient-to-r from-d81e06 to-ff4b2b bg-clip-text text-transparent border-2 border-dashed border-d81e06 p-5 rounded-3xl text-center mt-5 relative overflow-hidden">🎊 恭喜您!2024年是您的本命年!要记得戴红色饰品以旺运避凶!🎊</p>' : ''}
                `;
                
                button.disabled = false;
                button.innerHTML = '查看运势';
            })
            .catch(error => {
                console.error('Error:', error);
                alert('获取运势失败,请重试!');
                button.disabled = false;
                button.innerHTML = '查看运势';
            });
        }
        
        function getEmoji(fortune) {
            const emojis = {
                '大吉': '🐍',
                '吉': '✨',
                '中平': '⭐',
                '小凶': '☁️',
                '大凶': '⚡'
            };
            return emojis[fortune] || '🌟';
        }
        
        function getZodiacInfo(zodiacSign, isSnakeYear) {
            const baseInfo = `您的生肖属相:${zodiacSign}`;
            if (isSnakeYear) {
                return `${baseInfo}<br>🎊 2024年是您的本命年 🎊<br>
                    <span style="color: #d81e06">温馨提示:本命年要特别注意趋吉避凶,建议佩戴红色饰品,助您好运连连!</span>`;
            }
            return baseInfo;
        }
    </script>
</body>
</html>
'''

def calculate_fortune(birth_year, birth_month, birth_day, name):
    # 定义运势等级
    luck_levels = ["大吉", "吉", "中平", "小凶", "大凶"]

    # 计算生肖
    zodiac_year = (int(birth_year) - 4) % 12
    zodiac_signs = ["鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"]
    zodiac_sign = zodiac_signs[zodiac_year]
    is_snake_year = (zodiac_year == 5)

    # 根据月日调整运势权重
    month_weight = (int(birth_month) * int(birth_day)) % 5

    # 生成运势
    fortune = {
        "zodiac_sign": zodiac_sign,
        "is_snake_year": is_snake_year,
        "overall": luck_levels[(month_weight + int(birth_day)) % 5],
        "career": luck_levels[(month_weight + int(birth_month)) % 5],
        "love": luck_levels[(month_weight + int(birth_year) % 5) % 5],
        "wealth": luck_levels[(month_weight + sum(map(int, str(birth_day)))) % 5],
        "health": luck_levels[(month_weight + sum(map(int, str(birth_month)))) % 5],
        "lucky_numbers": random.sample(range(1, 50), 3),
        "lucky_colors": random.sample(["红色", "黄色", "青色", "紫色", "金色", "银色"], 2),
        "lucky_directions": random.sample(["东", "南", "西", "北", "东南", "西南", "东北", "西北"], 2)
    }

    return fortune

@app.route('/')
def index():
    return render_template_string(HTML_TEMPLATE)

@app.route('/get_fortune', methods=['POST'])
def get_fortune():
    data = request.get_json()
    birth_year = data.get('birth_year')
    birth_month = data.get('birth_month')
    birth_day = data.get('birth_day')
    name = data.get('name')

    fortune_result = calculate_fortune(birth_year, birth_month, birth_day, name)
    return jsonify(fortune_result)

# 添加静态文件路由
@app.route('/static/<path:filename>')
def serve_static(filename):
    return send_from_directory('static', filename)

if __name__ == '__main__':
    # 确保static目录存在
    if not os.path.exists('static'):
        os.makedirs('static')
    # 如果图片不在static目录中,将其复制到static目录
    if not os.path.exists('static/蛇迎新春.png') and os.path.exists('蛇迎新春.png'):
        import shutil
        shutil.copy('蛇迎新春.png', 'static/蛇迎新春.png')

    app.run(debug=True)

嗨,我是LucianaiB。如果你觉得我的分享有价值,不妨通过以下方式表达你的支持:👍 点赞来表达你的喜爱,📁 关注以获取我的最新消息,💬 评论与我交流你的见解。我会继续努力,为你带来更多精彩和实用的内容。

点击这里👉LucianaiB ,获取最新动态,⚡️ 让信息传递更加迅速。

;