Initial commit
- Add mymath.py with multiply and divide functions - Add SmartVoyage travel assistant project - Add .gitignore for Python cache files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.idea/
|
||||
logs/
|
||||
*.log
|
||||
139
SmartVoyage/a2a_server/order_server.py
Normal file
139
SmartVoyage/a2a_server/order_server.py
Normal file
@@ -0,0 +1,139 @@
|
||||
import asyncio
|
||||
import uuid
|
||||
from platform import system
|
||||
|
||||
from langchain_openai import ChatOpenAI
|
||||
from mcp import ClientSession
|
||||
from mcp.client.streamable_http import streamablehttp_client
|
||||
from langchain_mcp_adapters.tools import load_mcp_tools
|
||||
from langchain.agents import create_tool_calling_agent, AgentExecutor
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
from python_a2a import AgentCard, AgentSkill, run_server, TaskStatus, TaskState, A2AServer, A2AClient, Message, \
|
||||
TextContent, MessageRole, Task
|
||||
|
||||
from SmartVoyage.create_logger import logger
|
||||
from SmartVoyage.config import Config
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 初始化LLM
|
||||
llm = ChatOpenAI(
|
||||
model=conf.model_name,
|
||||
base_url=conf.base_url,
|
||||
api_key=conf.api_key,
|
||||
temperature=0.1
|
||||
)
|
||||
async def order_tickets(query):
|
||||
try:
|
||||
async with streamablehttp_client('http://127.0.0.1:8003/mcp') as (read,write,_):
|
||||
async with ClientSession(read,write) as session:
|
||||
try:
|
||||
await session.initialize()
|
||||
tools=await load_mcp_tools(session)
|
||||
|
||||
prompt=ChatPromptTemplate.from_messages([
|
||||
( 'system',
|
||||
"你是一个票务预定助手,能够调用工具来完成火车票、飞机票或演出票的预定你需要仔细分析工具需要的参数,然后从用户提供的信息中提取信息。如果用户提供的信息不足以提取到调用工具所有必要参数,则向用户追问,以获取该信息。不能自己编撰参数。"),
|
||||
('human','{input}'),
|
||||
('placeholder','{agent_scratchpad}'),
|
||||
])
|
||||
agent=create_tool_calling_agent(llm,tools,prompt)
|
||||
agent_executor=AgentExecutor(agent=agent,tools=tools,verbose=True)
|
||||
response = await agent_executor.ainvoke({"input": query})
|
||||
|
||||
return {"status": "success", "message": f"{response['output']}"}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"票务 MCP 测试出错:{str(e)}")
|
||||
return {"status": "error", "message": f"票务 MCP 查询出错:{str(e)}"}
|
||||
except Exception as e:
|
||||
logger.error(f"连接或会话初始化时发生错误: {e}")
|
||||
return {"status": "error", "message": "连接或会话初始化时发生错误"}
|
||||
# Agent 卡片定义
|
||||
agent_card = AgentCard(
|
||||
name="TicketOrderAssistant",
|
||||
description="通过MCP提供票务预定服务的助手",
|
||||
url="http://localhost:5007",
|
||||
version="1.0.4",
|
||||
capabilities={"streaming": True, "memory": True},
|
||||
skills=[
|
||||
AgentSkill(
|
||||
name="execute ticket order",
|
||||
description="根据客户端提供的输入执行票务预定,返回执行结果",
|
||||
examples=["北京 到 上海 2025-11-15 火车票 二等座 1张",
|
||||
"上海 到 北京 2025-12-11 飞机票 公务舱 2张"]
|
||||
)
|
||||
]
|
||||
)
|
||||
class TicketOrderServer(A2AServer):
|
||||
def __init__(self):
|
||||
super().__init__(agent_card=agent_card)
|
||||
self.llm = llm
|
||||
self.ticket_client = A2AClient("http://localhost:5006")
|
||||
|
||||
# 处理任务:提取输入,查询余票,调用MCP,结果输出
|
||||
def handle_task(self, task):
|
||||
# 1 提取输入
|
||||
content = (task.message or {}).get("content", {}) # 从消息中获取内容
|
||||
# 提取conversation,即客户端发起的任务中的query语句
|
||||
conversation = content.get("text", "") if isinstance(content, dict) else ""
|
||||
logger.info(f"对话历史及用户问题: {conversation}")
|
||||
|
||||
try:
|
||||
# 2 调用票务查询agent查询余票
|
||||
message_ticket = Message(content=TextContent(text=conversation), role=MessageRole.USER)
|
||||
task_ticket = Task(id="task-" + str(uuid.uuid4()), message=message_ticket.to_dict())
|
||||
|
||||
# 发送任务并获取最终结果
|
||||
ticket_result_task = asyncio.run(self.ticket_client.send_task_async(task_ticket))
|
||||
logger.info(f"原始响应: {ticket_result_task}")
|
||||
|
||||
# 处理结果:未查到余票信息时,则返回提示信息
|
||||
if ticket_result_task.status.state != 'completed':
|
||||
required_message = ticket_result_task.status.message['content']['text']
|
||||
logger.info(f'余票未查到:{required_message}')
|
||||
task.status = TaskStatus(state=TaskState.INPUT_REQUIRED,
|
||||
message={"role": "agent", "content": {"text": required_message}})
|
||||
return task
|
||||
# 处理结果:查到余票信息时,进行订票
|
||||
ticket_result = ticket_result_task.artifacts[0]["parts"][0]["text"]
|
||||
logger.info(f"余票信息: {ticket_result}")
|
||||
|
||||
# 3 调用MCP订票
|
||||
order_result = asyncio.run(order_tickets(conversation + '\n余票信息:' + ticket_result))
|
||||
logger.info(f"MCP 返回: {order_result}")
|
||||
|
||||
# 4 结果输出
|
||||
data = order_result.get("message", '')
|
||||
logger.info(f"订票结果: {data}")
|
||||
# 检查响应状态
|
||||
if order_result.get("status") == "success":
|
||||
result = '余票信息:' + ticket_result + '\n订票结果:' + data
|
||||
# 设置任务产物为文本部分,并设置任务状态为完成
|
||||
task.artifacts = [{"parts": [{"type": "text", "text": result}]}]
|
||||
task.status = TaskStatus(state=TaskState.COMPLETED)
|
||||
else:
|
||||
# 设置任务状态为失败,添加错误信息
|
||||
task.status = TaskStatus(state=TaskState.FAILED,
|
||||
message={"role": "agent", "content": {"text": data}})
|
||||
return task
|
||||
except Exception as e: # 捕获异常
|
||||
logger.error(f"查询失败: {str(e)}")
|
||||
|
||||
# 设置任务状态为失败,添加错误信息
|
||||
task.status = TaskStatus(state=TaskState.FAILED,
|
||||
message={"role": "agent", "content": {"text": f"查询失败: {str(e)} 请重试或提供更多细节。"}})
|
||||
return task
|
||||
if __name__ == "__main__":
|
||||
# 创建并运行服务器
|
||||
# 实例化票务查询服务器
|
||||
ticket_server = TicketOrderServer()
|
||||
# 打印服务器信息
|
||||
print("\n=== 服务器信息 ===")
|
||||
print(f"名称: {ticket_server.agent_card.name}")
|
||||
print(f"描述: {ticket_server.agent_card.description}")
|
||||
print("\n技能:")
|
||||
for skill in ticket_server.agent_card.skills:
|
||||
print(f"- {skill.name}: {skill.description}")
|
||||
# 运行服务器
|
||||
run_server(ticket_server, host="127.0.0.1", port=5007)
|
||||
273
SmartVoyage/a2a_server/ticket_server.py
Normal file
273
SmartVoyage/a2a_server/ticket_server.py
Normal file
@@ -0,0 +1,273 @@
|
||||
import json
|
||||
import asyncio
|
||||
|
||||
from mcp import ClientSession
|
||||
from mcp.client.streamable_http import streamablehttp_client
|
||||
from python_a2a import A2AServer, run_server, AgentCard, AgentSkill, TaskStatus, TaskState
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
from datetime import datetime
|
||||
import pytz
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
from SmartVoyage.create_logger import logger
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 初始化LLM
|
||||
llm = ChatOpenAI(
|
||||
model=conf.model_name,
|
||||
base_url=conf.base_url,
|
||||
api_key=conf.api_key,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
|
||||
# 数据表 schema
|
||||
table_schema_string = """ # 定义票务表SQL schema字符串,用于Prompt上下文
|
||||
CREATE TABLE train_tickets (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键,自增,唯一标识每条记录',
|
||||
departure_city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '出发城市(如“北京”)',
|
||||
arrival_city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '到达城市(如“上海”)',
|
||||
departure_time DATETIME NOT NULL COMMENT '出发时间(如“2025-08-12 07:00:00”)',
|
||||
arrival_time DATETIME NOT NULL COMMENT '到达时间(如“2025-08-12 11:30:00”)',
|
||||
train_number VARCHAR(20) NOT NULL COMMENT '火车车次(如“G1001”)',
|
||||
seat_type VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '座位类型(如“二等座”)',
|
||||
total_seats INT NOT NULL COMMENT '总座位数(如 1000)',
|
||||
remaining_seats INT NOT NULL COMMENT '剩余座位数(如 50)',
|
||||
price DECIMAL(10, 2) NOT NULL COMMENT '票价(如 553.50)',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间,自动记录插入时间',
|
||||
UNIQUE KEY unique_train (departure_time, train_number)
|
||||
) COMMENT='火车票信息表';
|
||||
|
||||
-- 机票表
|
||||
CREATE TABLE flight_tickets (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键,自增,唯一标识每条记录',
|
||||
departure_city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '出发城市(如“北京”)',
|
||||
arrival_city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '到达城市(如“上海”)',
|
||||
departure_time DATETIME NOT NULL COMMENT '出发时间(如“2025-08-12 08:00:00”)',
|
||||
arrival_time DATETIME NOT NULL COMMENT '到达时间(如“2025-08-12 10:30:00”)',
|
||||
flight_number VARCHAR(20) NOT NULL COMMENT '航班号(如“CA1234”)',
|
||||
cabin_type VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '舱位类型(如“经济舱”)',
|
||||
total_seats INT NOT NULL COMMENT '总座位数(如 200)',
|
||||
remaining_seats INT NOT NULL COMMENT '剩余座位数(如 10)',
|
||||
price DECIMAL(10, 2) NOT NULL COMMENT '票价(如 1200.00)',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间,自动记录插入时间',
|
||||
UNIQUE KEY unique_flight (departure_time, flight_number)
|
||||
) COMMENT='航班机票信息表';
|
||||
|
||||
-- 演唱会票表
|
||||
CREATE TABLE concert_tickets (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键,自增,唯一标识每条记录',
|
||||
artist VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '艺人名称(如“周杰伦”)',
|
||||
city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '举办城市(如“上海”)',
|
||||
venue VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '场馆(如“上海体育场”)',
|
||||
start_time DATETIME NOT NULL COMMENT '开始时间(如“2025-08-12 19:00:00”)',
|
||||
end_time DATETIME NOT NULL COMMENT '结束时间(如“2025-08-12 22:00:00”)',
|
||||
ticket_type VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '票类型(如“VIP”)',
|
||||
total_seats INT NOT NULL COMMENT '总座位数(如 5000)',
|
||||
remaining_seats INT NOT NULL COMMENT '剩余座位数(如 100)',
|
||||
price DECIMAL(10, 2) NOT NULL COMMENT '票价(如 880.00)',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间,自动记录插入时间',
|
||||
UNIQUE KEY unique_concert (start_time, artist, ticket_type)
|
||||
) COMMENT='演唱会门票信息表';
|
||||
"""
|
||||
|
||||
# 生成SQL的提示词
|
||||
sql_prompt = ChatPromptTemplate.from_template(
|
||||
"""
|
||||
系统提示:你是一个专业的票务SQL生成器,需要从对话历史(含用户的问题)中提取用户的意图以及关键信息,然后基于train_tickets、flight_tickets、concert_tickets表生成SELECT语句。
|
||||
根据对话历史:
|
||||
1. 提取用户的意图,意图有3种(train: 火车/高铁, flight: 机票, concert: 演唱会),输出:{{"type": "train/flight/concert"}};如果无法识别意图,或者意图不在这3种内,则模仿最后1个示例回复即可。
|
||||
2. 根据用户的意图,生成对应表的 SELECT 语句,仅查询指定字段:
|
||||
- train_tickets: id, departure_city, arrival_city, departure_time, arrival_time, train_number, seat_type, price, remaining_seats
|
||||
- flight_tickets: id, departure_city, arrival_city, departure_time, arrival_time, flight_number, cabin_type, price, remaining_seats
|
||||
- concert_tickets: id, artist, city, venue, start_time, end_time, ticket_type, price, remaining_seats
|
||||
3. 如果用户在查询票务信息时,缺少必要信息,则输出:{{"status": "input_required", "message": "请提供票务类型(如火车票、机票、演唱会)和必要信息(如城市、日期)。"}} ,如示例所示;如果对话历史中信息齐全,则输出纯SQL即可。
|
||||
其中,每种意图必要的信息有:
|
||||
- flight/train: 【departure_city (出发城市), arrival_city (到达城市), date (日期)】 或 【train_number/flight_number (车次)】
|
||||
- concert: city (城市), artist (艺人), date (日期)。
|
||||
4. 按要求输出两行数据或一行数据即可,不需要输出其他内容。
|
||||
|
||||
|
||||
示例:
|
||||
- 对话: user: 火车票 北京 上海 2025-07-31 硬卧
|
||||
输出:
|
||||
{{"type": "train"}}
|
||||
SELECT id, departure_city, arrival_city, departure_time, arrival_time, train_number, seat_type, price, remaining_seats FROM train_tickets WHERE departure_city = '北京' AND arrival_city = '上海' AND DATE(departure_time) = '2025-07-31' AND seat_type = '硬卧'
|
||||
|
||||
- 对话: user: 机票 上海 广州 2025-09-11 头等舱
|
||||
输出:
|
||||
{{"type": "flight"}}
|
||||
SELECT id, departure_city, arrival_city, departure_time, arrival_time, flight_number, cabin_type, price, remaining_seats FROM flight_tickets WHERE departure_city = '上海' AND arrival_city = '广州' AND DATE(departure_time) = '2025-09-11' AND cabin_type = '头等舱'
|
||||
|
||||
- 对话: user: 演唱会 北京 刀郎 2025-08-23 看台
|
||||
输出:
|
||||
{{"type": "concert"}}
|
||||
SELECT id, artist, city, venue, start_time, end_time, ticket_type, price, remaining_seats FROM concert_tickets WHERE city = '北京' AND artist = '刀郎' AND DATE(start_time) = '2025-08-23' AND ticket_type = '看台'
|
||||
|
||||
- 对话: user: 火车票
|
||||
输出:
|
||||
{{"status": "input_required", "message": "请提供票务类型(如火车票、机票、演唱会)和必要信息(如城市、日期)。"}}
|
||||
|
||||
- 对话: user: 你好
|
||||
输出:
|
||||
{{"status": "input_required", "message": "请提供票务类型(如火车票、机票、演唱会)和必要信息(如城市、日期)。"}}
|
||||
|
||||
表结构:{table_schema_string}
|
||||
对话历史: {conversation}
|
||||
当前日期: {current_date} (Asia/Shanghai)
|
||||
"""
|
||||
)
|
||||
# 定义查询函数
|
||||
async def get_ticket_info(sql):
|
||||
try:
|
||||
# 启动 MCP server,通过streamable建立连接
|
||||
async with streamablehttp_client("http://127.0.0.1:8001/mcp") as (read, write, _):
|
||||
# 使用读写通道创建 MCP 会话
|
||||
async with ClientSession(read, write) as session:
|
||||
try:
|
||||
await session.initialize()
|
||||
# 工具调用
|
||||
result = await session.call_tool("query_tickets", {"sql": sql})
|
||||
result_data = json.loads(result) if isinstance(result, str) else result
|
||||
logger.info(f"票务查询结果:{result_data}")
|
||||
return result_data.content[0].text
|
||||
except Exception as e:
|
||||
logger.error(f"票务 MCP 测试出错:{str(e)}")
|
||||
return {"status": "error", "message": f"票务 MCP 查询出错:{str(e)}"}
|
||||
except Exception as e:
|
||||
logger.error(f"连接或会话初始化时发生错误: {e}")
|
||||
return {"status": "error", "message": "连接或会话初始化时发生错误"}
|
||||
agent_card = AgentCard(
|
||||
name="TicketQueryAssistant",
|
||||
description="基于 LangChain 提供票务查询服务的助手",
|
||||
url="http://localhost:5006",
|
||||
version="1.0.4",
|
||||
capabilities={"streaming": True, "memory": True},
|
||||
skills=[
|
||||
AgentSkill(
|
||||
name="execute ticket query",
|
||||
description="根据客户端提供的输入执行票务查询,返回数据库结果,支持自然语言输入",
|
||||
examples=["火车票 北京 上海 2025-07-31 硬卧", "机票 北京 上海 2025-07-31 经济舱",
|
||||
"演唱会 北京 刀郎 2025-08-23 看台"]
|
||||
)
|
||||
]
|
||||
)
|
||||
class TicketQueryServer(A2AServer):
|
||||
def __init__(self):
|
||||
super().__init__(agent_card=agent_card)
|
||||
self.llm = llm
|
||||
self.sql_prompt = sql_prompt
|
||||
self.schema = table_schema_string
|
||||
|
||||
# 定义生成SQL查询方法,输入对话历史,返回SQL或追问JSON
|
||||
def generate_sql_query(self, conversation: str) -> dict:
|
||||
try:
|
||||
# 组装链
|
||||
chain = self.sql_prompt | self.llm
|
||||
# 调用链
|
||||
current_date = datetime.now(pytz.timezone('Asia/Shanghai')).strftime('%Y-%m-%d') # 获取当前日期,格式化为字符串
|
||||
output = chain.invoke({"conversation": conversation, "current_date": current_date, "table_schema_string": self.schema}).content.strip()
|
||||
logger.info(f"原始 LLM 输出: {output}")
|
||||
|
||||
# 处理结果,返回字典
|
||||
lines = output.split('\n')
|
||||
type_line = lines[0].strip()
|
||||
if type_line.startswith('```json'): # 检查是否以```json开头
|
||||
type_line = lines[1].strip() # 取下一行为类型行
|
||||
sql_lines = lines[3:-1] if lines[-1].strip() == '```' else lines[3:] # 提取SQL行,跳过代码块标记
|
||||
else:
|
||||
sql_lines = lines[1:] if len(lines) > 1 else [] # 取剩余行为SQL行
|
||||
|
||||
# 提取 type 和 SQL
|
||||
if type_line.startswith('{"type":'): # 如果以{"type":开头
|
||||
query_type = json.loads(type_line)["type"] # 解析并提取类型
|
||||
sql_query = ' '.join([line.strip() for line in sql_lines if line.strip() and not line.startswith('```')]) # 连接SQL行,过滤空行和代码块
|
||||
logger.info(f"分类类型: {query_type}, 生成的 SQL: {sql_query}")
|
||||
return {"status": "sql", "type": query_type, "sql": sql_query} # 返回SQL状态字典,包括类型
|
||||
elif type_line.startswith('{"status": "input_required"'): # 检查是否为追问JSON
|
||||
return json.loads(type_line)
|
||||
else: # 无效格式
|
||||
logger.error(f"无效的 LLM 输出格式: {output}")
|
||||
return {"status": "input_required", "message": "无法解析查询类型或SQL,请提供更明确的信息。"} # 返回默认追问
|
||||
except Exception as e:
|
||||
logger.error(f"SQL 生成失败: {str(e)}")
|
||||
return {"status": "input_required", "message": "查询无效,请提供查询票务的相关信息。"} # 返回追问JSON
|
||||
def handle_task(self, task):
|
||||
# 1 提取输入
|
||||
content = (task.message or {}).get("content", {}) # 从消息中获取内容
|
||||
# 提取conversation,即客户端发起的任务中的query语句
|
||||
conversation = content.get("text", "") if isinstance(content, dict) else ""
|
||||
logger.info(f"对话历史及用户问题: {conversation}")
|
||||
|
||||
try:
|
||||
# 2 基于用户问题生成SQL查询
|
||||
gen_result = self.generate_sql_query(conversation)
|
||||
# 检查是否需要追问,如果是则添加追问消息后返回任务
|
||||
if gen_result["status"] == "input_required":
|
||||
task.status = TaskStatus(state=TaskState.INPUT_REQUIRED,
|
||||
message={"role": "agent", "content": {"text": gen_result["message"]}})
|
||||
return task
|
||||
|
||||
# 否则则提取SQL查询,并进行MCP调用
|
||||
sql_query = gen_result["sql"]
|
||||
query_type = gen_result["type"]
|
||||
logger.info(f"执行 SQL 查询: {sql_query} (类型: {query_type})")
|
||||
|
||||
# 3 调用MCP
|
||||
ticket_result = asyncio.run(get_ticket_info(sql_query))
|
||||
|
||||
# 4 格式化结果
|
||||
response = json.loads(ticket_result) if isinstance(ticket_result, str) else ticket_result
|
||||
logger.info(f"MCP 返回: {response}")
|
||||
# 检查响应状态
|
||||
if response.get("status") == "success":
|
||||
data = response.get("data", []) # 提取数据列表
|
||||
response_text = "" # 初始化响应文本
|
||||
for d in data: # 遍历每个数据项
|
||||
if query_type == "train": # 火车票类型
|
||||
response_text += f"{d['departure_city']} 到 {d['arrival_city']} {d['departure_time']}: 车次 {d['train_number']},{d['seat_type']},票价 {d['price']}元,剩余 {d['remaining_seats']} 张\n" # 格式化火车票文本
|
||||
elif query_type == "flight": # 机票类型
|
||||
response_text += f"{d['departure_city']} 到 {d['arrival_city']} {d['departure_time']}: 航班 {d['flight_number']},{d['cabin_type']},票价 {d['price']}元,剩余 {d['remaining_seats']} 张\n" # 格式化机票文本
|
||||
elif query_type == "concert": # 演唱会类型
|
||||
response_text += f"{d['city']} {d['start_time']}: {d['artist']} 演唱会,{d['ticket_type']},场地 {d['venue']},票价 {d['price']}元,剩余 {d['remaining_seats']} 张\n" # 格式化演唱会文本
|
||||
if not response_text: # 检查文本是否为空
|
||||
response_text = "无结果。如果需要其他日期,请补充。"
|
||||
# 设置任务产物为文本部分,并设置任务状态为完成
|
||||
task.artifacts = [{"parts": [{"type": "text", "text": response_text}]}]
|
||||
task.status = TaskStatus(state=TaskState.COMPLETED)
|
||||
elif response.get("status") == "no_data":
|
||||
response_text = response.get("message", "请输出查询票务的详细信息。")
|
||||
|
||||
# 设置任务状态为输入所需,添加追问消息
|
||||
task.status = TaskStatus(state=TaskState.INPUT_REQUIRED,
|
||||
message={"role": "agent", "content": {"text": response_text}})
|
||||
else:
|
||||
response_text = response.get("message", "查询失败,请重试或提供更多细节。")
|
||||
|
||||
# 设置任务状态为失败,添加错误信息
|
||||
task.status = TaskStatus(state=TaskState.FAILED,
|
||||
message={"role": "agent", "content": {"text": response_text}})
|
||||
return task
|
||||
except Exception as e: # 捕获异常
|
||||
logger.error(f"查询失败: {str(e)}")
|
||||
|
||||
# 设置任务状态为失败,添加错误信息
|
||||
task.status = TaskStatus(state=TaskState.FAILED,
|
||||
message={"role": "agent",
|
||||
"content": {"text": f"查询失败: {str(e)} 请重试或提供更多细节。"}})
|
||||
return task
|
||||
if __name__ == "__main__":
|
||||
# 创建并运行服务器
|
||||
# 实例化票务查询服务器
|
||||
ticket_server = TicketQueryServer()
|
||||
# 打印服务器信息
|
||||
print("\n=== 服务器信息 ===")
|
||||
print(f"名称: {ticket_server.agent_card.name}")
|
||||
print(f"描述: {ticket_server.agent_card.description}")
|
||||
print("\n技能:")
|
||||
for skill in ticket_server.agent_card.skills:
|
||||
print(f"- {skill.name}: {skill.description}")
|
||||
# 运行服务器
|
||||
run_server(ticket_server, host="127.0.0.1", port=5006)
|
||||
214
SmartVoyage/a2a_server/weather_server.py
Normal file
214
SmartVoyage/a2a_server/weather_server.py
Normal file
@@ -0,0 +1,214 @@
|
||||
import json
|
||||
import asyncio
|
||||
from mcp import ClientSession
|
||||
from mcp.client.streamable_http import streamablehttp_client
|
||||
from python_a2a import A2AServer, run_server, AgentCard, AgentSkill, TaskStatus, TaskState
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
from datetime import datetime
|
||||
import pytz
|
||||
|
||||
from SmartVoyage.create_logger import logger
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 初始化LLM
|
||||
llm = ChatOpenAI(
|
||||
model=conf.model_name,
|
||||
base_url=conf.base_url,
|
||||
api_key=conf.api_key,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
# 数据表 schema
|
||||
table_schema_string = """ # 定义天气数据表的SQL schema字符串,用于Prompt上下文
|
||||
CREATE TABLE IF NOT EXISTS weather_data (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
city VARCHAR(50) NOT NULL COMMENT '城市名称',
|
||||
fx_date DATE NOT NULL COMMENT '预报日期',
|
||||
sunrise TIME COMMENT '日出时间',
|
||||
sunset TIME COMMENT '日落时间',
|
||||
moonrise TIME COMMENT '月升时间',
|
||||
moonset TIME COMMENT '月落时间',
|
||||
moon_phase VARCHAR(20) COMMENT '月相名称',
|
||||
moon_phase_icon VARCHAR(10) COMMENT '月相图标代码',
|
||||
temp_max INT COMMENT '最高温度',
|
||||
temp_min INT COMMENT '最低温度',
|
||||
icon_day VARCHAR(10) COMMENT '白天天气图标代码',
|
||||
text_day VARCHAR(20) COMMENT '白天天气描述',
|
||||
icon_night VARCHAR(10) COMMENT '夜间天气图标代码',
|
||||
text_night VARCHAR(20) COMMENT '夜间天气描述',
|
||||
wind360_day INT COMMENT '白天风向360角度',
|
||||
wind_dir_day VARCHAR(20) COMMENT '白天风向',
|
||||
wind_scale_day VARCHAR(10) COMMENT '白天风力等级',
|
||||
wind_speed_day INT COMMENT '白天风速 (km/h)',
|
||||
wind360_night INT COMMENT '夜间风向360角度',
|
||||
wind_dir_night VARCHAR(20) COMMENT '夜间风向',
|
||||
wind_scale_night VARCHAR(10) COMMENT '夜间风力等级',
|
||||
wind_speed_night INT COMMENT '夜间风速 (km/h)',
|
||||
precip DECIMAL(5,1) COMMENT '降水量 (mm)',
|
||||
uv_index INT COMMENT '紫外线指数',
|
||||
humidity INT COMMENT '相对湿度 (%)',
|
||||
pressure INT COMMENT '大气压强 (hPa)',
|
||||
vis INT COMMENT '能见度 (km)',
|
||||
cloud INT COMMENT '云量 (%)',
|
||||
update_time DATETIME COMMENT '数据更新时间',
|
||||
UNIQUE KEY unique_city_date (city, fx_date)
|
||||
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='天气数据表';
|
||||
"""
|
||||
|
||||
# 生成SQL的提示词
|
||||
sql_prompt = ChatPromptTemplate.from_template(
|
||||
"""
|
||||
系统提示:你是一个专业的天气SQL生成器,需要从对话历史(含用户的问题)中提取关键信息,然后基于weather_data表生成SELECT语句。
|
||||
- 如果用户需要查天气,则至少需要城市和时间信息。如果对话历史中缺乏必要的信息,可以向其追问,输出格式为json格式,如示例所示;如果对话历史中信息齐全,则输出纯SQL即可。
|
||||
- 如果用户问与天气无关的问题,则模仿最后2个示例回复即可。
|
||||
|
||||
|
||||
示例:
|
||||
- 对话: user: 北京 2025-07-30
|
||||
输出: SELECT city, fx_date, temp_max, temp_min, text_day, text_night, humidity, wind_dir_day, precip FROM weather_data WHERE city = '北京' AND fx_date = '2025-07-30'
|
||||
- 对话: user: 上海未来3天的天气
|
||||
输出: SELECT city, fx_date, temp_max, temp_min, text_day, text_night, humidity, wind_dir_day, precip FROM weather_data WHERE city = '上海' AND fx_date BETWEEN '2025-07-30' AND '2025-08-01' ORDER BY fx_date
|
||||
- 对话: user: 北京的天气
|
||||
输出: {{"status": "input_required", "message": "请提供具体的需要查询的日期,例如 '2025-07-30'。"}}
|
||||
- 对话: user: 今天\nassistant: 请提供城市。\nuser: 北京
|
||||
输出: SELECT city, fx_date, temp_max, temp_min, text_day, text_night, humidity, wind_dir_day, precip FROM weather_data WHERE city = '北京' AND fx_date = '2025-07-30'
|
||||
- 对话: user: 北京明天的天气\nassistant: 多云。\nuser: 后天呢
|
||||
输出: SELECT city, fx_date, temp_max, temp_min, text_day, text_night, humidity, wind_dir_day, precip FROM weather_data WHERE city = '北京' AND fx_date = '2025-08-01'
|
||||
- 对话: user: 你好
|
||||
输出: {{"status": "input_required", "message": "请提供城市和日期,例如 '北京 2025-07-30'。"}}
|
||||
- 对话: user: 今天有什么好吃的
|
||||
输出: {{"status": "input_required", "message": "请提供天气相关查询,包括城市和日期。"}}
|
||||
|
||||
weather_data表结构:{table_schema_string}
|
||||
对话历史: {conversation}
|
||||
当前日期: {current_date} (Asia/Shanghai)
|
||||
"""
|
||||
)
|
||||
async def get_weather(sql):
|
||||
try:
|
||||
# 启动 MCP server,通过streamable建立连接
|
||||
async with streamablehttp_client("http://127.0.0.1:8002/mcp") as (read, write, _):
|
||||
# 使用读写通道创建 MCP 会话
|
||||
async with ClientSession(read, write) as session:
|
||||
try:
|
||||
await session.initialize()
|
||||
# 工具调用
|
||||
result = await session.call_tool("query_weather", {"sql": sql})
|
||||
result_data = json.loads(result) if isinstance(result, str) else result
|
||||
logger.info(f"天气查询结果:{result_data}")
|
||||
return result_data.content[0].text
|
||||
except Exception as e:
|
||||
logger.error(f"天气 MCP 测试出错:{str(e)}")
|
||||
return {"status": "error", "message": f"天气 MCP 查询出错:{str(e)}"}
|
||||
except Exception as e:
|
||||
logger.error(f"连接或会话初始化时发生错误: {e}")
|
||||
return {"status": "error", "message": "连接或会话初始化时发生错误"}
|
||||
# Agent卡片定义
|
||||
agent_card = AgentCard(
|
||||
name="WeatherQueryAssistant",
|
||||
description="基于LangChain提供天气查询服务的助手",
|
||||
url="http://localhost:5005",
|
||||
version="1.0.0",
|
||||
capabilities={"streaming": True, "memory": True}, # 设置能力:支持流式和内存
|
||||
skills=[ # 定义技能列表
|
||||
AgentSkill(
|
||||
name="execute weather query",
|
||||
description="执行天气查询,返回天气数据库结果,支持自然语言输入",
|
||||
examples=["北京 2025-07-30 天气", "上海未来5天", "今天天气如何"]
|
||||
)
|
||||
]
|
||||
)
|
||||
class WeatherQueryServer(A2AServer):
|
||||
def __init__(self):
|
||||
super().__init__(agent_card=agent_card)
|
||||
self.llm=llm
|
||||
self.sql_prompt=sql_prompt
|
||||
self.schema=table_schema_string
|
||||
|
||||
def generate_sql_query(self,conversation:str) -> dict:
|
||||
try:
|
||||
chain=self.sql_prompt|self.llm
|
||||
|
||||
current_date=datetime.now(pytz.timezone(('Asia/Shanghai')).strftime('%Y-%m-%d'))
|
||||
output=chain.invoke({"conversation": conversation, "current_date": current_date, "table_schema_string": self.schema}).content.strip()
|
||||
logger.info(f'原始LLM输出:{output}')
|
||||
if output.startswith('{'):
|
||||
return json.loads(output)
|
||||
return {'status':'sql','sql':output}
|
||||
except Exception as e:
|
||||
logger.error(f'SQL生成失败:{str(e)}')
|
||||
return {'status':'input_required','message':'查询无效,请提供城市和日期。'}
|
||||
def handle_task(self, task):
|
||||
# 1 提取输入
|
||||
content = (task.message or {}).get("content", {}) # 从消息中获取内容
|
||||
# 提取conversation,即客户端发起的任务中的query语句
|
||||
conversation = content.get("text", "") if isinstance(content, dict) else ""
|
||||
logger.info(f"对话历史及用户问题: {conversation}")
|
||||
|
||||
try:
|
||||
# 2 基于用户问题生成SQL查询
|
||||
gen_result = self.generate_sql_query(conversation)
|
||||
# 检查是否需要追问,如果是则添加追问消息后返回任务
|
||||
if gen_result["status"] == "input_required":
|
||||
# 追问逻辑,这里是指在无法正常生成sql时,设置任务状态为输入所需,添加追问消息
|
||||
task.status = TaskStatus(state=TaskState.INPUT_REQUIRED,
|
||||
message={"role": "agent", "content": {"text": gen_result["message"]}})
|
||||
return task
|
||||
|
||||
# 否则则提取SQL查询,并进行MCP调用
|
||||
sql_query = gen_result["sql"] #
|
||||
logger.info(f"生成的SQL查询: {sql_query}")
|
||||
|
||||
# 3 调用MCP
|
||||
weather_result = asyncio.run(get_weather(sql_query))
|
||||
|
||||
# 4 格式化结果
|
||||
response = json.loads(weather_result) if isinstance(weather_result, str) else weather_result
|
||||
logger.info(f"MCP 返回: {response}")
|
||||
# 检查响应状态
|
||||
if response.get("status") == "success":
|
||||
data = response.get("data", []) # 提取数据列表
|
||||
response_text = "\n".join([f"{d['city']} {d['fx_date']}: {d['text_day']}(夜间 {d['text_night']}),温度 {d['temp_min']}-{d['temp_max']}°C,湿度 {d['humidity']}%,风向 {d['wind_dir_day']},降水 {d['precip']}mm" for d in data]) # 格式化每个数据项为友好文本,连接成多行
|
||||
|
||||
# 设置任务产物为文本部分,并设置任务状态为完成
|
||||
task.artifacts = [{"parts": [{"type": "text", "text": response_text}]}]
|
||||
task.status = TaskStatus(state=TaskState.COMPLETED)
|
||||
elif response.get("status") == "no_data":
|
||||
response_text = response.get("message", "请重新输入查询的城市和日期。")
|
||||
|
||||
# 设置任务状态为输入所需,添加追问消息
|
||||
task.status = TaskStatus(state=TaskState.INPUT_REQUIRED,
|
||||
message={"role": "agent", "content": {"text": response_text}})
|
||||
else:
|
||||
response_text = response.get("message", "查询失败,请重试或提供更多细节。")
|
||||
|
||||
# 设置任务状态为失败,添加错误信息
|
||||
task.status = TaskStatus(state=TaskState.FAILED,
|
||||
message={"role": "agent", "content": {"text": response_text}})
|
||||
|
||||
return task
|
||||
except Exception as e: # 捕获异常
|
||||
logger.error(f"查询失败: {str(e)}")
|
||||
|
||||
# 设置任务状态为失败,添加错误信息
|
||||
task.status = TaskStatus(state=TaskState.FAILED,
|
||||
message={"role": "agent",
|
||||
"content": {"text": f"查询失败: {str(e)} 请重试或提供更多细节。"}})
|
||||
return task
|
||||
if __name__ == "__main__":
|
||||
# 创建并运行服务器
|
||||
# 实例化天气查询服务器
|
||||
weather_server = WeatherQueryServer()
|
||||
# 打印服务器信息
|
||||
print("\n=== 服务器信息 ===")
|
||||
print(f"名称: {weather_server.agent_card.name}")
|
||||
print(f"描述: {weather_server.agent_card.description}")
|
||||
print("\n技能:")
|
||||
for skill in weather_server.agent_card.skills:
|
||||
print(f"- {skill.name}: {skill.description}")
|
||||
# 运行服务器
|
||||
run_server(weather_server, host="127.0.0.1", port=5005)
|
||||
26
SmartVoyage/config.py
Normal file
26
SmartVoyage/config.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import os
|
||||
|
||||
# 项目根目录
|
||||
project_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')
|
||||
|
||||
|
||||
#定义配置文件
|
||||
class Config:
|
||||
def __init__(self):
|
||||
# 大模型配置
|
||||
self.base_url = 'https://api.deepseek.com'
|
||||
self.api_key = 'sk-2a9f2aeb2ebb44aa8b5d396a133f6586'
|
||||
self.model_name = 'deepseek-chat'
|
||||
|
||||
# 数据库配置
|
||||
self.host = 'localhost'
|
||||
self.user = 'root'
|
||||
self.password = 'root'
|
||||
self.database = 'travel_rag'
|
||||
|
||||
# 日志配置
|
||||
self.log_file = os.path.join(project_root, 'SmartVoyage', 'logs/app.log')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(Config().log_file)
|
||||
36
SmartVoyage/create_logger.py
Normal file
36
SmartVoyage/create_logger.py
Normal file
@@ -0,0 +1,36 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
|
||||
|
||||
def setup_logger(name, log_file='logs/app.log'):
|
||||
# 创建日志文件夹
|
||||
os.makedirs(os.path.dirname(log_file), exist_ok=True)
|
||||
|
||||
# 获取日志记录器
|
||||
logger = logging.getLogger(name)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
# 防止重复输出的关键!
|
||||
logger.propagate = False
|
||||
|
||||
# 定义日志格式
|
||||
formatter = logging.Formatter('%(name)s - %(asctime)s - %(levelname)s - %(message)s')
|
||||
|
||||
# 创建控制台处理器
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setFormatter(formatter)
|
||||
console_handler.setLevel(logging.INFO) # 每个日志处理器可以单独设置日志级别,但是这个日志级别必须高于或等于处理器级别
|
||||
|
||||
# 创建文件处理器
|
||||
file_handler = logging.FileHandler(filename=log_file, encoding="utf-8", mode="a")
|
||||
file_handler.setFormatter(formatter)
|
||||
file_handler.setLevel(logging.DEBUG)
|
||||
|
||||
# 将处理器添加到日志记录器中
|
||||
if not logger.handlers: # 先进行判断,再进行添加。避免重复添加处理器
|
||||
logger.addHandler(console_handler)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
return logger
|
||||
logger = setup_logger('SmartVoage', Config().log_file)
|
||||
54
SmartVoyage/main.py
Normal file
54
SmartVoyage/main.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import asyncio
|
||||
import json
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
import pytz
|
||||
import re
|
||||
from python_a2a import AgentNetwork, TextContent, Message, MessageRole, Task
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
from SmartVoyage.create_logger import logger
|
||||
from SmartVoyage.main_prompts import SmartVoyagePrompts
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 初始化全局变量,用于模拟会话状态 这些变量替换了Streamlit的session_state
|
||||
messages = [] # 存储对话历史消息列表,每个元素为字典{"role": "user/assistant", "content": "消息内容"}
|
||||
agent_network = None # 代理网络实例
|
||||
llm = None # 大语言模型实例
|
||||
agent_urls = {} # 存储代理的URL信息字典
|
||||
conversation_history = "" # 存储整个对话历史字符串,用于意图识别
|
||||
|
||||
|
||||
# 初始化代理网络和相关组件 此部分在脚本启动时执行一次,模拟Streamlit的初始化
|
||||
def initialize_system():
|
||||
"""
|
||||
初始化系统组件,包括代理网络、路由器、LLM和会话状态
|
||||
核心逻辑:构建AgentNetwork,添加代理,创建路由器和LLM
|
||||
"""
|
||||
|
||||
global agent_network, llm, agent_urls, conversation_history
|
||||
# 存储代理URL信息,便于查看
|
||||
agent_urls = {
|
||||
"WeatherQueryAssistant": "http://localhost:5005", # 天气代理URL
|
||||
"TicketQueryAssistant": "http://localhost:5006", # 票务代理URL
|
||||
"TicketOrderAssistant": "http://localhost:5007" # 票务预定URL
|
||||
}
|
||||
# 创建代理网络
|
||||
network = AgentNetwork(name="旅行助手网络")
|
||||
network.add("WeatherQueryAssistant", "http://localhost:5005")
|
||||
network.add("TicketQueryAssistant", "http://localhost:5006")
|
||||
network.add("TicketOrderAssistant", "http://localhost:5007")
|
||||
agent_network = network
|
||||
|
||||
# 加载配置并创建LLM
|
||||
llm = ChatOpenAI(
|
||||
model=conf.model_name,
|
||||
api_key=conf.api_key,
|
||||
base_url=conf.base_url,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
# 初始化对话历史为空字符串
|
||||
conversation_history = ""
|
||||
81
SmartVoyage/main_prompts.py
Normal file
81
SmartVoyage/main_prompts.py
Normal file
@@ -0,0 +1,81 @@
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
|
||||
|
||||
class SmartVoyagePrompts:
|
||||
|
||||
# 定义意图识别提示模板
|
||||
@staticmethod
|
||||
def intent_prompt():
|
||||
return ChatPromptTemplate.from_template(
|
||||
"""
|
||||
系统提示:您是一个专业的旅行意图识别专家,基于用户查询和对话历史,识别其意图,用于调用专门的agent server来执行;为方便后续的agent server处理,可以基于对话历史对用户查询进行改写,使问题更明确。严格遵守规则:
|
||||
- 支持意图:['weather' (天气查询), 'flight' (机票查询), 'train' (高铁/火车票查询), 'concert' (演唱会票查询), 'order' (票务预定), 'attraction' (景点推荐)] 或其组合(如 ['weather', 'flight'])。如果意图超出范围,返回意图 'out_of_scope'。
|
||||
- 注意票务预定和票务查询要区分开,涉及到订票时则为order,只是查询则为flight、train或concert。
|
||||
- 如果意图为 'out_of_scope'时,此时不需要再进行查询改写,你可以直接根据用户问题进行回复,将回复答案写到follow_up_message中即可。
|
||||
- 在进行用户查询改写时,不要回答其问题,也不要修改其原意,只需要将对话历史中跟该查询相关的上下文信息取出来,然后整合到一起,使用户查询更明确即可,要仔细分析上下文信息,不要进行过度整合。如果用户查询跟对话历史无关,则输出原始查询。
|
||||
- 如果用户的意图很不明确或者有歧义,可以向其进行追问,将追问问题填充到follow_up_message中。
|
||||
- 输出严格为JSON:{{"intents": ["intent1", "intent2"], "user_queries": {{"intent1": "user_query1", "intent2": "user_query2"}}, "follow_up_message": "追问消息"}}。不要添加额外文本!
|
||||
|
||||
输出示例:
|
||||
{{"intents": ["weather"], "user_queries": {{"weather": "今天北京天气如何"}}, "follow_up_message": ""}}
|
||||
{{"intents": ["weather"], "user_queries": {{}}, "follow_up_message": "你问的是今天北京天气状况吗"}}
|
||||
{{"intents": ["weather", "flight"], "user_queries": {{"weather": "今天北京天气如何", "flight": "查询一下10月28日,从北京飞往杭州的机票"}}, "follow_up_message": ""}}
|
||||
{{"intents": ["out_of_scope"], "user_queries": {{}}, "follow_up_message": "你好,我是智能旅行助手,欢迎您向我提问"}}
|
||||
|
||||
当前日期:{current_date} (Asia/Shanghai)。
|
||||
对话历史:{conversation_history}
|
||||
用户查询:{query}
|
||||
""")
|
||||
|
||||
# 定义天气结果总结提示模板,用于LLM总结天气查询的原始响应
|
||||
@staticmethod
|
||||
def summarize_weather_prompt():
|
||||
return ChatPromptTemplate.from_template(
|
||||
"""
|
||||
系统提示:您是一位专业的天气预报员,以生动、准确的风格总结天气信息。基于查询和结果:
|
||||
- 核心描述点:城市、日期、温度范围、天气描述、湿度、风向、降水等。
|
||||
- 如果结果为空或者意思为需要补充数据,则委婉提示“未找到数据,请确认城市/日期”
|
||||
- 语气:专业预报,如“根据最新数据,北京2025-07-31的天气预报为...”。
|
||||
- 保持中文,100-150字。
|
||||
- 如果查询无关,返回“请提供天气相关查询。”
|
||||
|
||||
查询:{query}
|
||||
结果:{raw_response}
|
||||
""")
|
||||
|
||||
# 定义票务结果总结提示模板,用于LLM总结票务查询的原始响应
|
||||
@staticmethod
|
||||
def summarize_ticket_prompt():
|
||||
return ChatPromptTemplate.from_template(
|
||||
"""
|
||||
系统提示:您是一位专业的旅行顾问,以热情、精确的风格总结票务信息。基于查询和结果:
|
||||
- 核心描述点:出发/到达、时间、类型、价格、剩余座位等。
|
||||
- 如果结果为空或者意思为需要补充数据,则委婉提示“未找到数据,请确认或修改条件”
|
||||
- 语气:顾问式,如“为您推荐北京到上海的机票选项...”。
|
||||
- 保持中文,100-150字。
|
||||
- 如果查询无关,返回“请提供票务相关查询。”
|
||||
|
||||
|
||||
查询:{query}
|
||||
结果:{raw_response}
|
||||
""")
|
||||
|
||||
# 定义景点推荐提示模板,用于LLM直接生成景点推荐内容
|
||||
@staticmethod
|
||||
def attraction_prompt():
|
||||
return ChatPromptTemplate.from_template(
|
||||
"""
|
||||
系统提示:您是一位旅行专家,基于用户查询生成景点推荐。规则:
|
||||
- 推荐3-5个景点,包含描述、理由、注意事项。
|
||||
- 基于槽位:城市、偏好。
|
||||
|
||||
- 语气:热情推荐,如“推荐您在北京探索故宫...”。
|
||||
- 备注:内容生成,仅供参考。
|
||||
- 保持中文,150-250字。
|
||||
|
||||
查询:{query}
|
||||
""")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(SmartVoyagePrompts.intent_prompt())
|
||||
81
SmartVoyage/mcp_server/mcp_order_server.py
Normal file
81
SmartVoyage/mcp_server/mcp_order_server.py
Normal file
@@ -0,0 +1,81 @@
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
from SmartVoyage.create_logger import logger
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 创建FastMCP实例
|
||||
order_mcp = FastMCP(name="OrderTools",
|
||||
instructions="票务预定工具,通过调用API完成火车票、飞机票和演唱会票的预定。",
|
||||
log_level="ERROR",
|
||||
host="127.0.0.1", port=8003)
|
||||
|
||||
|
||||
@order_mcp.tool(
|
||||
name="order_train",
|
||||
description="根据时间、车次、座位类型、数量预定火车票"
|
||||
)
|
||||
def order_train(departure_date: str, train_number: str, seat_type: str, number: int) -> str:
|
||||
'''
|
||||
Args:
|
||||
departure_date (str): 出发日期,如 '2025-10-30'
|
||||
train_number (str): 火车车次,如 'G346'
|
||||
seat_type (str): 座位类型,如 '二等座'
|
||||
number (int): 订购张数
|
||||
'''
|
||||
logger.info(f"正在订购火车票: {departure_date}, {train_number}, {seat_type}, {number}")
|
||||
logger.info(f"恭喜,火车票预定成功!")
|
||||
return "恭喜,火车票预定成功!"
|
||||
@order_mcp.tool(
|
||||
name="order_flight",
|
||||
description="根据时间、班次、座位类型、数量预定飞机票"
|
||||
)
|
||||
def order_flight(departure_date: str, flight_number: str, seat_type: str, number: int) -> str:
|
||||
'''
|
||||
Args:
|
||||
departure_date (str): 出发日期,如 '2025-10-30'
|
||||
flight_number (str): 飞机班次,如 'CA6557'
|
||||
seat_type (str): 座位类型,如 '经济舱'
|
||||
number (int): 订购张数
|
||||
'''
|
||||
logger.info(f"正在订购飞机票: {departure_date}, {flight_number}, {seat_type}, {number}")
|
||||
logger.info(f"恭喜,飞机票预定成功!")
|
||||
return "恭喜,飞机票预定成功!"
|
||||
|
||||
|
||||
@order_mcp.tool(
|
||||
name="order_concert",
|
||||
description="根据时间、明星、场地、座位类型、数量预定演出票"
|
||||
)
|
||||
def order_concert(start_date: str, aritist: str, venue: str, seat_type: str, number: int) -> str:
|
||||
'''
|
||||
Args:
|
||||
start_date (str): 开始日期,如 '2025-10-30'
|
||||
aritist (str): 明星,如 '刀郎'
|
||||
venue (str): 场地,如 '上海体育馆'
|
||||
seat_type (str): 座位类型,如 '看台'
|
||||
number (int): 订购张数
|
||||
'''
|
||||
logger.info(f"正在订购演出票: {start_date}, {aritist}, {venue}, {seat_type}, {number}")
|
||||
logger.info(f"恭喜,演出票预定成功!")
|
||||
return "恭喜,演出票预定成功!"
|
||||
|
||||
# 创建票务预定MCP服务器
|
||||
def create_order_mcp_server():
|
||||
# 打印服务器信息
|
||||
logger.info("=== 票务预定MCP服务器信息 ===")
|
||||
logger.info(f"名称: {order_mcp.name}")
|
||||
logger.info(f"描述: {order_mcp.instructions}")
|
||||
|
||||
# 运行服务器
|
||||
try:
|
||||
print("服务器已启动,请访问 http://127.0.0.1:8003/mcp")
|
||||
order_mcp.run(transport="streamable-http") # 使用 streamable-http 传输方式
|
||||
except Exception as e:
|
||||
print(f"服务器启动失败: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 调用创建服务器函数
|
||||
create_order_mcp_server()
|
||||
77
SmartVoyage/mcp_server/mcp_ticket_server.py
Normal file
77
SmartVoyage/mcp_server/mcp_ticket_server.py
Normal file
@@ -0,0 +1,77 @@
|
||||
import mysql.connector
|
||||
import json
|
||||
from datetime import date, datetime, timedelta
|
||||
from decimal import Decimal
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
from SmartVoyage.create_logger import logger
|
||||
from SmartVoyage.utils.format import DateEncoder, default_encoder
|
||||
|
||||
conf = Config()
|
||||
|
||||
|
||||
# 票务服务类
|
||||
class TicketService: # 定义票务服务类,封装数据库操作逻辑
|
||||
def __init__(self): # 初始化方法,建立数据库连接
|
||||
# 连接数据库
|
||||
self.conn = mysql.connector.connect(
|
||||
host=conf.host,
|
||||
user=conf.user,
|
||||
password=conf.password,
|
||||
database=conf.database
|
||||
)
|
||||
# 定义执行SQL查询方法,输入SQL字符串,返回JSON字符串
|
||||
def execute_query(self, sql: str) -> str:
|
||||
try:
|
||||
cursor = self.conn.cursor(dictionary=True)
|
||||
cursor.execute(sql)
|
||||
results = cursor.fetchall()
|
||||
cursor.close()
|
||||
# 格式化结果
|
||||
for result in results: # 遍历每个结果字典
|
||||
for key, value in result.items():
|
||||
if isinstance(value, (date, datetime, timedelta, Decimal)): # 检查值是否为特殊类型
|
||||
result[key] = default_encoder(value) # 使用自定义编码器格式化该值
|
||||
# 序列化为JSON,如果有结果返回success,否则no_data;使用DateEncoder,非ASCII不转义
|
||||
return json.dumps({"status": "success", "data": results} if results else {"status": "no_data",
|
||||
"message": "未找到票务数据,请确认查询条件。"},
|
||||
cls=DateEncoder, ensure_ascii=False)
|
||||
except Exception as e:
|
||||
logger.error(f"票务查询错误: {str(e)}")
|
||||
# 返回错误JSON响应
|
||||
return json.dumps({"status": "error", "message": str(e)}, ensure_ascii=False)
|
||||
def create_ticket_mcp_server():
|
||||
# 创建FastMCP实例
|
||||
ticket_mcp = FastMCP(name="TicketTools",
|
||||
instructions="票务查询工具,基于 train_tickets, flight_tickets, concert_tickets 表。只支持查询。",
|
||||
log_level="ERROR",
|
||||
host="127.0.0.1", port=8001)
|
||||
|
||||
# 实例化票务服务对象
|
||||
service = TicketService()
|
||||
|
||||
@ticket_mcp.tool(
|
||||
name="query_tickets",
|
||||
description="查询票务数据,输入 SQL,如 'SELECT * FROM train_tickets WHERE departure_city = \"北京\" AND arrival_city = \"上海\"'"
|
||||
)
|
||||
def query_tickets(sql: str) -> str:
|
||||
logger.info(f"执行票务查询: {sql}")
|
||||
return service.execute_query(sql)
|
||||
|
||||
# 打印服务器信息
|
||||
logger.info("=== 票务MCP服务器信息 ===")
|
||||
logger.info(f"名称: {ticket_mcp.name}")
|
||||
logger.info(f"描述: {ticket_mcp.instructions}")
|
||||
|
||||
# 运行服务器
|
||||
try:
|
||||
print("服务器已启动,请访问 http://127.0.0.1:8001/mcp")
|
||||
ticket_mcp.run(transport="streamable-http") # 使用 streamable-http 传输方式
|
||||
except Exception as e:
|
||||
print(f"服务器启动失败: {e}")
|
||||
if __name__ == "__main__":
|
||||
# service = TicketService()
|
||||
# sql = "SELECT * FROM flight_tickets WHERE departure_city = '上海' AND arrival_city = '北京' AND DATE(departure_time) = '2026-4-15' AND cabin_type = '公务舱'"
|
||||
# print(service.execute_query(sql))
|
||||
create_ticket_mcp_server()
|
||||
72
SmartVoyage/mcp_server/mcp_weather_server.py
Normal file
72
SmartVoyage/mcp_server/mcp_weather_server.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import mysql.connector
|
||||
import json
|
||||
from datetime import date, datetime, timedelta
|
||||
from decimal import Decimal
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
from SmartVoyage.create_logger import logger
|
||||
from SmartVoyage.utils.format import DateEncoder, default_encoder
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 天气服务类
|
||||
class WeatherService: # 定义天气服务类,封装数据库操作逻辑
|
||||
def __init__(self):
|
||||
# 连接数据库
|
||||
self.conn = mysql.connector.connect(
|
||||
host=conf.host,
|
||||
user=conf.user,
|
||||
password=conf.password,
|
||||
database=conf.database
|
||||
)
|
||||
def execute_query(self,sql:str) -> str:
|
||||
try:
|
||||
cursor=self.conn.cursor(dictionary=True)
|
||||
cursor.execute(sql)
|
||||
results=cursor.fetchall()
|
||||
cursor.close()
|
||||
for result in results:
|
||||
for key,value in result.items():
|
||||
if isinstance(value,(date,datetime,timedelta,Decimal)):
|
||||
result[key]=default_encoder(value)
|
||||
return json.dumps({'status': 'success', 'data': results} if results else {"status": "no_data", "message": "未找到天气数据,请确认城市和日期。"}, cls=DateEncoder, ensure_ascii=False)
|
||||
except Exception as e:
|
||||
logger.error(f"天气查询错误: {str(e)}")
|
||||
# 返回错误JSON响应
|
||||
return json.dumps({"status": "error", "message": str(e)}, ensure_ascii=False)
|
||||
# 创建天气MCP服务器
|
||||
def create_weather_mcp_server():
|
||||
# 创建FastMCP实例
|
||||
weather_mcp = FastMCP(name="WeatherTools",
|
||||
instructions="天气查询工具,基于 weather_data 表。",
|
||||
log_level="ERROR",
|
||||
host="127.0.0.1", port=8002)
|
||||
|
||||
# 实例化天气服务对象
|
||||
service = WeatherService()
|
||||
|
||||
@weather_mcp.tool(
|
||||
name="query_weather",
|
||||
description="查询天气数据,输入 SQL,如 'SELECT * FROM weather_data WHERE city = \"北京\" AND fx_date = \"2025-07-30\"'"
|
||||
)
|
||||
def query_weather(sql: str) -> str:
|
||||
logger.info(f"执行天气查询: {sql}")
|
||||
return service.execute_query(sql)
|
||||
|
||||
# 打印服务器信息
|
||||
logger.info("=== 天气MCP服务器信息 ===")
|
||||
logger.info(f"名称: {weather_mcp.name}")
|
||||
logger.info(f"描述: {weather_mcp.instructions}")
|
||||
|
||||
# 运行服务器
|
||||
try:
|
||||
print("服务器已启动,请访问 http://127.0.0.1:8002/mcp")
|
||||
weather_mcp.run(transport="streamable-http") # 使用 streamable-http 传输方式
|
||||
except Exception as e:
|
||||
print(f"服务器启动失败: {e}")
|
||||
if __name__ == "__main__":
|
||||
# service = WeatherService()
|
||||
# sql = "SELECT * FROM weather_data WHERE city='上海' limit 2"
|
||||
# print(service.execute_query(sql))
|
||||
create_weather_mcp_server()
|
||||
34
SmartVoyage/mcp_server/practice_mcp.py
Normal file
34
SmartVoyage/mcp_server/practice_mcp.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import mysql.connector
|
||||
import json
|
||||
from datetime import datetime,date,timedelta
|
||||
from decimal import Decimal
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
from SmartVoyage.config import Config
|
||||
from SmartVoyage.create_logger import logger
|
||||
from SmartVoyage.utils.format import DateEncoder,default_encoder
|
||||
|
||||
config=Config()
|
||||
|
||||
#票务服务
|
||||
class TicketService:#定义票务服务类,封装数据库操作逻辑
|
||||
def __init__(self):#初始化方法,建立数据库连接
|
||||
#连接数据库
|
||||
self.conn=mysql.connector.connect(
|
||||
host=config.host,
|
||||
user=config.user,
|
||||
password=config.password,
|
||||
database=config.database
|
||||
)
|
||||
#定义执行sql查询方法,输入SQL字符串,返回JSON字符串
|
||||
def execute_query(self,sql:str) -> str:
|
||||
try:
|
||||
cursor=self.conn.cursor(dictionary=True)
|
||||
cursor.execute(sql)
|
||||
resultes=cursor.fetchall()
|
||||
cursor.close()
|
||||
#格式化结果
|
||||
for resulte in resultes:#遍历每个结果字典
|
||||
for key,value in resulte.items():
|
||||
if isinstance(value,(date,datetime,timedelta,Decimal)):#检查值是否是特殊类型
|
||||
resulte[key]=default_encoder(value)#使用自定义编码器格式化该值
|
||||
|
||||
121
SmartVoyage/sql/concert_tickets_202601251131.csv
Normal file
121
SmartVoyage/sql/concert_tickets_202601251131.csv
Normal file
@@ -0,0 +1,121 @@
|
||||
"id","artist","city","venue","start_time","end_time","ticket_type","total_seats","remaining_seats","price","created_at"
|
||||
1,刀郎,上海,上海体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",内场,403,403,880.00,"2025-07-27 16:05:50"
|
||||
2,张学友,广州,广州体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",看台,431,431,180.00,"2025-07-27 16:05:50"
|
||||
3,周杰伦,上海,上海体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",看台,418,418,50.00,"2025-07-27 16:05:50"
|
||||
4,五月天,上海,上海体育馆,"2025-08-03 20:11:00","2025-08-04 00:11:00",VIP,428,428,1280.00,"2025-07-27 16:05:50"
|
||||
5,刀郎,深圳,深圳体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",VIP,282,282,1080.00,"2025-07-27 16:05:50"
|
||||
7,五月天,北京,北京体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",看台,380,380,480.00,"2025-07-27 16:05:50"
|
||||
11,张学友,广州,广州体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",内场,305,305,680.00,"2025-07-27 16:05:50"
|
||||
12,张学友,上海,上海体育馆,"2025-08-02 20:55:00","2025-08-02 23:55:00",VIP,454,454,1080.00,"2025-07-27 16:05:50"
|
||||
13,周杰伦,北京,北京体育馆,"2025-08-15 20:27:00","2025-08-15 22:27:00",VIP,332,332,1080.00,"2025-07-27 16:05:50"
|
||||
16,五月天,上海,上海体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",内场,365,365,680.00,"2025-07-27 16:05:50"
|
||||
17,张学友,广州,广州体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",VIP,201,201,1080.00,"2025-07-27 16:05:50"
|
||||
18,刀郎,广州,广州体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",看台,388,388,280.00,"2025-07-27 16:05:50"
|
||||
22,周杰伦,广州,广州体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",VIP,257,257,1280.00,"2025-07-27 16:05:50"
|
||||
23,刀郎,深圳,深圳体育馆,"2025-08-17 20:58:00","2025-08-18 00:58:00",看台,216,216,280.00,"2025-07-27 16:05:50"
|
||||
25,周杰伦,广州,广州体育馆,"2025-08-19 21:51:00","2025-08-20 01:51:00",VIP,426,426,1080.00,"2025-07-27 16:05:50"
|
||||
27,刀郎,广州,广州体育馆,"2025-07-29 20:07:00","2025-07-29 23:07:00",看台,295,295,280.00,"2025-07-27 16:05:50"
|
||||
34,五月天,上海,上海体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",VIP,302,302,1080.00,"2025-07-27 16:05:50"
|
||||
35,五月天,深圳,深圳体育馆,"2025-08-03 21:45:00","2025-08-03 23:45:00",内场,420,420,880.00,"2025-07-27 16:05:50"
|
||||
43,周杰伦,广州,广州体育馆,"2025-08-26 22:00:00","2025-08-27 00:00:00",内场,360,360,680.00,"2025-07-27 16:05:50"
|
||||
44,周杰伦,广州,广州体育馆,"2025-08-02 20:41:00","2025-08-02 23:41:00",内场,399,399,880.00,"2025-07-27 16:05:50"
|
||||
46,刀郎,深圳,深圳体育馆,"2025-08-24 21:07:00","2025-08-25 01:07:00",内场,378,378,880.00,"2025-07-27 16:05:50"
|
||||
50,五月天,北京,北京体育馆,"2025-08-21 19:07:00","2025-08-21 21:07:00",内场,275,275,880.00,"2025-07-27 16:05:50"
|
||||
52,五月天,北京,北京体育馆,"2025-08-16 21:32:00","2025-08-17 00:32:00",内场,352,352,680.00,"2025-07-27 16:05:50"
|
||||
57,五月天,广州,广州体育馆,"2025-08-19 20:28:00","2025-08-20 00:28:00",内场,409,409,880.00,"2025-07-27 16:05:50"
|
||||
59,周杰伦,深圳,深圳体育馆,"2025-08-01 19:35:00","2025-08-01 21:35:00",内场,411,411,880.00,"2025-07-27 16:05:50"
|
||||
61,刀郎,上海,上海体育馆,"2025-08-25 19:37:00","2025-08-25 21:37:00",VIP,304,304,1280.00,"2025-07-27 16:05:50"
|
||||
63,五月天,广州,广州体育馆,"2025-08-06 20:54:00","2025-08-06 22:54:00",VIP,413,413,1280.00,"2025-07-27 16:05:50"
|
||||
67,五月天,上海,上海体育馆,"2025-08-16 20:08:00","2025-08-17 00:08:00",看台,382,382,180.00,"2025-07-27 16:05:50"
|
||||
69,周杰伦,广州,广州体育馆,"2025-08-15 21:36:00","2025-08-15 23:36:00",看台,449,449,50.00,"2025-07-27 16:05:50"
|
||||
70,五月天,广州,广州体育馆,"2025-08-19 21:50:00","2025-08-20 01:50:00",VIP,287,287,1080.00,"2025-07-27 16:05:50"
|
||||
71,刀郎,深圳,深圳体育馆,"2025-08-09 20:17:00","2025-08-09 22:17:00",看台,441,441,180.00,"2025-07-27 16:05:50"
|
||||
73,周杰伦,北京,北京体育馆,"2025-08-17 21:13:00","2025-08-18 00:13:00",看台,335,335,180.00,"2025-07-27 16:05:50"
|
||||
77,张学友,北京,北京体育馆,"2025-08-05 20:11:00","2025-08-05 23:11:00",VIP,251,251,1280.00,"2025-07-27 16:05:50"
|
||||
78,刀郎,深圳,深圳体育馆,"2025-08-01 21:04:00","2025-08-02 01:04:00",看台,232,232,280.00,"2025-07-27 16:05:50"
|
||||
79,五月天,广州,广州体育馆,"2025-08-04 20:35:00","2025-08-05 00:35:00",内场,253,253,880.00,"2025-07-27 16:05:50"
|
||||
80,刀郎,上海,上海体育馆,"2025-08-06 20:32:00","2025-08-07 00:32:00",VIP,489,489,1280.00,"2025-07-27 16:05:50"
|
||||
83,张学友,上海,上海体育馆,"2025-08-26 21:02:00","2025-08-27 00:00:00",内场,284,284,880.00,"2025-07-27 16:05:50"
|
||||
85,周杰伦,深圳,深圳体育馆,"2025-08-16 20:54:00","2025-08-17 00:54:00",看台,262,262,50.00,"2025-07-27 16:05:50"
|
||||
86,周杰伦,北京,北京体育馆,"2025-08-13 20:17:00","2025-08-13 22:17:00",看台,428,428,180.00,"2025-07-27 16:05:50"
|
||||
88,五月天,广州,广州体育馆,"2025-07-30 19:30:00","2025-07-30 23:30:00",看台,325,325,480.00,"2025-07-27 16:05:50"
|
||||
90,刀郎,北京,北京体育馆,"2025-08-23 20:04:00","2025-08-24 00:04:00",看台,222,222,180.00,"2025-07-27 16:05:50"
|
||||
91,周杰伦,上海,上海体育馆,"2025-08-01 21:59:00","2025-08-01 23:59:00",内场,300,300,680.00,"2025-07-27 16:05:50"
|
||||
98,刀郎,深圳,深圳体育馆,"2025-08-01 20:43:00","2025-08-02 00:43:00",看台,242,242,50.00,"2025-07-27 16:05:50"
|
||||
99,张学友,广州,广州体育馆,"2025-08-08 21:32:00","2025-08-09 01:32:00",内场,387,387,680.00,"2025-07-27 16:05:50"
|
||||
101,五月天,上海,上海体育馆,"2025-08-17 20:06:00","2025-08-18 00:06:00",VIP,445,445,1080.00,"2025-07-27 16:05:50"
|
||||
104,张学友,广州,广州体育馆,"2025-08-08 19:17:00","2025-08-08 23:17:00",VIP,459,459,1080.00,"2025-07-27 16:05:50"
|
||||
108,周杰伦,北京,北京体育馆,"2025-08-19 21:39:00","2025-08-20 01:39:00",VIP,272,272,1080.00,"2025-07-27 16:05:50"
|
||||
110,周杰伦,深圳,深圳体育馆,"2025-08-13 21:44:00","2025-08-14 00:44:00",VIP,351,351,1080.00,"2025-07-27 16:05:50"
|
||||
113,周杰伦,深圳,深圳体育馆,"2025-08-10 20:16:00","2025-08-10 23:16:00",VIP,369,369,1280.00,"2025-07-27 16:05:50"
|
||||
114,周杰伦,北京,北京体育馆,"2025-08-15 20:57:00","2025-08-15 23:57:00",看台,212,212,480.00,"2025-07-27 16:05:50"
|
||||
115,张学友,北京,北京体育馆,"2025-07-28 19:37:00","2025-07-28 21:37:00",VIP,222,222,1280.00,"2025-07-27 16:05:50"
|
||||
116,张学友,北京,北京体育馆,"2025-08-09 19:27:00","2025-08-09 23:27:00",内场,469,469,680.00,"2025-07-27 16:05:50"
|
||||
119,张学友,北京,北京体育馆,"2025-08-16 19:13:00","2025-08-16 22:13:00",内场,360,360,680.00,"2025-07-27 16:05:50"
|
||||
122,周杰伦,深圳,深圳体育馆,"2025-08-21 19:20:00","2025-08-21 21:20:00",内场,380,380,680.00,"2025-07-27 16:05:50"
|
||||
125,刀郎,北京,北京体育馆,"2025-08-11 20:33:00","2025-08-12 00:33:00",看台,490,490,280.00,"2025-07-27 16:05:50"
|
||||
130,张学友,广州,广州体育馆,"2025-07-29 20:30:00","2025-07-30 00:30:00",VIP,219,219,1280.00,"2025-07-27 16:05:50"
|
||||
131,刀郎,上海,上海体育馆,"2025-08-14 21:46:00","2025-08-14 23:46:00",VIP,475,475,1080.00,"2025-07-27 16:05:50"
|
||||
136,周杰伦,广州,广州体育馆,"2025-08-14 20:27:00","2025-08-14 22:27:00",看台,307,307,50.00,"2025-07-27 16:05:50"
|
||||
137,刀郎,上海,上海体育馆,"2025-08-03 21:28:00","2025-08-04 00:28:00",看台,294,294,480.00,"2025-07-27 16:05:50"
|
||||
139,周杰伦,深圳,深圳体育馆,"2025-08-08 19:08:00","2025-08-08 21:08:00",VIP,495,495,1280.00,"2025-07-27 16:05:50"
|
||||
141,周杰伦,广州,广州体育馆,"2025-08-03 21:38:00","2025-08-03 23:38:00",内场,210,210,680.00,"2025-07-27 16:05:50"
|
||||
144,五月天,北京,北京体育馆,"2025-08-14 22:01:00","2025-08-15 02:01:00",VIP,472,472,1280.00,"2025-07-27 16:05:50"
|
||||
149,张学友,北京,北京体育馆,"2025-07-29 22:00:00","2025-07-30 01:00:00",看台,461,461,180.00,"2025-07-27 16:05:50"
|
||||
152,刀郎,北京,北京体育馆,"2025-08-04 21:02:00","2025-08-05 00:02:00",VIP,467,467,1280.00,"2025-07-27 16:05:50"
|
||||
153,周杰伦,深圳,深圳体育馆,"2025-08-15 20:04:00","2025-08-15 22:04:00",VIP,292,292,1280.00,"2025-07-27 16:05:50"
|
||||
161,周杰伦,北京,北京体育馆,"2025-08-04 21:18:00","2025-08-04 23:18:00",看台,338,338,280.00,"2025-07-27 16:05:50"
|
||||
162,五月天,广州,广州体育馆,"2025-08-25 19:44:00","2025-08-25 21:44:00",内场,326,326,680.00,"2025-07-27 16:05:50"
|
||||
163,张学友,上海,上海体育馆,"2025-08-07 21:21:00","2025-08-08 00:21:00",VIP,400,400,1080.00,"2025-07-27 16:05:50"
|
||||
165,张学友,深圳,深圳体育馆,"2025-08-11 20:03:00","2025-08-11 22:03:00",看台,421,421,480.00,"2025-07-27 16:05:50"
|
||||
168,周杰伦,深圳,深圳体育馆,"2025-08-20 20:08:00","2025-08-20 23:08:00",VIP,236,236,1280.00,"2025-07-27 16:05:50"
|
||||
172,刀郎,广州,广州体育馆,"2025-08-06 19:09:00","2025-08-06 22:09:00",VIP,462,462,1080.00,"2025-07-27 16:05:50"
|
||||
174,刀郎,深圳,深圳体育馆,"2025-08-25 20:34:00","2025-08-25 22:34:00",看台,326,326,180.00,"2025-07-27 16:05:50"
|
||||
175,刀郎,深圳,深圳体育馆,"2025-08-26 21:35:00","2025-08-27 00:00:00",VIP,428,428,1280.00,"2025-07-27 16:05:50"
|
||||
177,五月天,上海,上海体育馆,"2025-07-29 20:39:00","2025-07-30 00:39:00",内场,232,232,680.00,"2025-07-27 16:05:50"
|
||||
179,周杰伦,深圳,深圳体育馆,"2025-08-02 20:45:00","2025-08-03 00:45:00",VIP,489,489,1280.00,"2025-07-27 16:05:50"
|
||||
180,周杰伦,深圳,深圳体育馆,"2025-07-28 19:29:00","2025-07-28 23:29:00",内场,287,287,880.00,"2025-07-27 16:05:50"
|
||||
183,周杰伦,上海,上海体育馆,"2025-08-22 20:01:00","2025-08-23 00:01:00",看台,463,463,280.00,"2025-07-27 16:05:50"
|
||||
190,周杰伦,北京,北京体育馆,"2025-08-01 21:52:00","2025-08-01 23:52:00",内场,231,231,880.00,"2025-07-27 16:05:50"
|
||||
191,五月天,广州,广州体育馆,"2025-08-05 20:13:00","2025-08-06 00:13:00",看台,352,352,50.00,"2025-07-27 16:05:50"
|
||||
199,张学友,北京,北京体育馆,"2025-08-14 20:47:00","2025-08-14 23:47:00",内场,338,338,880.00,"2025-07-27 16:05:50"
|
||||
201,周杰伦,上海,上海体育馆,"2025-08-17 19:21:00","2025-08-17 23:21:00",看台,310,310,480.00,"2025-07-27 16:05:50"
|
||||
205,刀郎,北京,北京体育馆,"2025-08-24 21:41:00","2025-08-25 00:41:00",看台,311,311,180.00,"2025-07-27 16:05:50"
|
||||
209,张学友,广州,广州体育馆,"2025-08-07 19:48:00","2025-08-07 23:48:00",看台,246,246,180.00,"2025-07-27 16:05:50"
|
||||
211,张学友,深圳,深圳体育馆,"2025-08-03 20:15:00","2025-08-03 22:15:00",看台,202,202,280.00,"2025-07-27 16:05:50"
|
||||
212,刀郎,深圳,深圳体育馆,"2025-08-25 21:53:00","2025-08-25 23:53:00",内场,300,300,680.00,"2025-07-27 16:05:50"
|
||||
215,刀郎,北京,北京体育馆,"2025-08-14 20:17:00","2025-08-14 22:17:00",看台,223,223,180.00,"2025-07-27 16:05:50"
|
||||
216,周杰伦,深圳,深圳体育馆,"2025-08-17 20:59:00","2025-08-17 22:59:00",看台,381,381,280.00,"2025-07-27 16:05:50"
|
||||
217,周杰伦,广州,广州体育馆,"2025-08-02 20:26:00","2025-08-03 00:26:00",内场,403,403,680.00,"2025-07-27 16:05:50"
|
||||
218,刀郎,深圳,深圳体育馆,"2025-07-31 19:06:00","2025-07-31 21:06:00",VIP,319,319,1280.00,"2025-07-27 16:05:50"
|
||||
221,刀郎,广州,广州体育馆,"2025-08-07 20:45:00","2025-08-07 22:45:00",VIP,465,465,1080.00,"2025-07-27 16:05:50"
|
||||
222,五月天,深圳,深圳体育馆,"2025-08-13 19:14:00","2025-08-13 22:14:00",VIP,479,479,1280.00,"2025-07-27 16:05:50"
|
||||
223,五月天,北京,北京体育馆,"2025-08-16 20:37:00","2025-08-16 23:37:00",VIP,494,494,1080.00,"2025-07-27 16:05:50"
|
||||
227,刀郎,广州,广州体育馆,"2025-07-27 21:04:00","2025-07-27 23:04:00",看台,296,296,280.00,"2025-07-27 16:05:50"
|
||||
228,五月天,深圳,深圳体育馆,"2025-08-15 20:09:00","2025-08-15 22:09:00",看台,233,233,280.00,"2025-07-27 16:05:50"
|
||||
229,刀郎,广州,广州体育馆,"2025-07-28 21:03:00","2025-07-29 00:03:00",看台,438,438,480.00,"2025-07-27 16:05:50"
|
||||
231,五月天,北京,北京体育馆,"2025-08-24 20:05:00","2025-08-25 00:05:00",看台,385,385,50.00,"2025-07-27 16:05:50"
|
||||
237,五月天,上海,上海体育馆,"2025-08-15 20:45:00","2025-08-15 23:45:00",看台,240,240,480.00,"2025-07-27 16:05:50"
|
||||
241,刀郎,上海,上海体育馆,"2025-07-31 19:54:00","2025-07-31 21:54:00",VIP,332,332,1080.00,"2025-07-27 16:05:50"
|
||||
244,张学友,上海,上海体育馆,"2025-07-31 21:52:00","2025-08-01 00:52:00",VIP,228,228,1080.00,"2025-07-27 16:05:50"
|
||||
252,五月天,深圳,深圳体育馆,"2025-08-25 21:54:00","2025-08-26 01:54:00",内场,257,257,880.00,"2025-07-27 16:05:50"
|
||||
258,周杰伦,上海,上海体育馆,"2025-08-22 19:04:00","2025-08-22 22:04:00",VIP,294,294,1280.00,"2025-07-27 16:05:50"
|
||||
259,张学友,上海,上海体育馆,"2025-08-05 21:32:00","2025-08-05 23:32:00",内场,430,430,680.00,"2025-07-27 16:05:50"
|
||||
262,张学友,深圳,深圳体育馆,"2025-08-04 21:26:00","2025-08-05 00:26:00",VIP,318,318,1280.00,"2025-07-27 16:05:50"
|
||||
266,五月天,北京,北京体育馆,"2025-08-17 21:34:00","2025-08-18 00:34:00",看台,216,216,180.00,"2025-07-27 16:05:50"
|
||||
268,刀郎,北京,北京体育馆,"2025-08-15 19:49:00","2025-08-15 21:49:00",内场,264,264,880.00,"2025-07-27 16:05:50"
|
||||
271,刀郎,广州,广州体育馆,"2025-08-17 21:02:00","2025-08-17 23:02:00",VIP,473,473,1280.00,"2025-07-27 16:05:50"
|
||||
272,张学友,北京,北京体育馆,"2025-08-04 21:37:00","2025-08-05 01:37:00",内场,272,272,680.00,"2025-07-27 16:05:50"
|
||||
276,周杰伦,北京,北京体育馆,"2025-08-17 21:22:00","2025-08-18 01:22:00",VIP,219,219,1080.00,"2025-07-27 16:05:50"
|
||||
279,张学友,上海,上海体育馆,"2025-07-29 19:14:00","2025-07-29 23:14:00",内场,256,256,880.00,"2025-07-27 16:05:50"
|
||||
283,五月天,北京,北京体育馆,"2025-08-22 20:39:00","2025-08-22 22:39:00",VIP,254,254,1080.00,"2025-07-27 16:05:50"
|
||||
285,张学友,深圳,深圳体育馆,"2025-08-07 19:59:00","2025-08-07 21:59:00",VIP,405,405,1280.00,"2025-07-27 16:05:50"
|
||||
287,张学友,上海,上海体育馆,"2025-08-18 20:47:00","2025-08-18 22:47:00",内场,317,317,680.00,"2025-07-27 16:05:50"
|
||||
288,刀郎,广州,广州体育馆,"2025-08-18 21:13:00","2025-08-19 00:13:00",看台,449,449,50.00,"2025-07-27 16:05:50"
|
||||
292,张学友,北京,北京体育馆,"2025-08-20 20:56:00","2025-08-20 23:56:00",VIP,314,314,1080.00,"2025-07-27 16:05:50"
|
||||
294,五月天,深圳,深圳体育馆,"2025-08-02 21:40:00","2025-08-03 01:40:00",看台,380,380,180.00,"2025-07-27 16:05:50"
|
||||
296,张学友,深圳,深圳体育馆,"2025-08-26 20:11:00","2025-08-26 23:11:00",内场,250,250,880.00,"2025-07-27 16:05:50"
|
||||
297,张学友,广州,广州体育馆,"2025-08-04 20:24:00","2025-08-04 22:24:00",内场,376,376,680.00,"2025-07-27 16:05:50"
|
||||
298,刀郎,深圳,深圳体育馆,"2025-08-24 20:17:00","2025-08-24 23:17:00",VIP,335,335,1280.00,"2025-07-27 16:05:50"
|
||||
299,周杰伦,广州,广州体育馆,"2025-08-06 19:55:00","2025-08-06 21:55:00",看台,224,224,180.00,"2025-07-27 16:05:50"
|
||||
306,刀郎,北京,北京体育馆,"2025-08-22 20:57:00","2025-08-22 23:57:00",VIP,488,488,1080.00,"2025-07-27 16:05:50"
|
||||
|
87
SmartVoyage/sql/create_table.sql
Normal file
87
SmartVoyage/sql/create_table.sql
Normal file
@@ -0,0 +1,87 @@
|
||||
DROP DATABASE IF EXISTS travel_rag;
|
||||
CREATE DATABASE travel_rag CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
USE travel_rag;
|
||||
|
||||
-- 火车票表
|
||||
CREATE TABLE train_tickets (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键,自增,唯一标识每条记录',
|
||||
departure_city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '出发城市(如“北京”)',
|
||||
arrival_city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '到达城市(如“上海”)',
|
||||
departure_time DATETIME NOT NULL COMMENT '出发时间(如“2025-08-12 07:00:00”)',
|
||||
arrival_time DATETIME NOT NULL COMMENT '到达时间(如“2025-08-12 11:30:00”)',
|
||||
train_number VARCHAR(20) NOT NULL COMMENT '火车车次(如“G1001”)',
|
||||
seat_type VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '座位类型(如“二等座”)',
|
||||
total_seats INT NOT NULL COMMENT '总座位数(如 1000)',
|
||||
remaining_seats INT NOT NULL COMMENT '剩余座位数(如 50)',
|
||||
price DECIMAL(10, 2) NOT NULL COMMENT '票价(如 553.50)',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间,自动记录插入时间',
|
||||
UNIQUE KEY unique_train (departure_time, train_number) -- 唯一约束,确保同一时间和车次不重复
|
||||
) COMMENT='火车票信息表';
|
||||
|
||||
-- 机票表
|
||||
CREATE TABLE flight_tickets (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键,自增,唯一标识每条记录',
|
||||
departure_city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '出发城市(如“北京”)',
|
||||
arrival_city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '到达城市(如“上海”)',
|
||||
departure_time DATETIME NOT NULL COMMENT '出发时间(如“2025-08-12 08:00:00”)',
|
||||
arrival_time DATETIME NOT NULL COMMENT '到达时间(如“2025-08-12 10:30:00”)',
|
||||
flight_number VARCHAR(20) NOT NULL COMMENT '航班号(如“CA1234”)',
|
||||
cabin_type VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '舱位类型(如“经济舱”)',
|
||||
total_seats INT NOT NULL COMMENT '总座位数(如 200)',
|
||||
remaining_seats INT NOT NULL COMMENT '剩余座位数(如 10)',
|
||||
price DECIMAL(10, 2) NOT NULL COMMENT '票价(如 1200.00)',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间,自动记录插入时间',
|
||||
UNIQUE KEY unique_flight (departure_time, flight_number) -- 唯一约束,确保同一时间和航班号不重复
|
||||
) COMMENT='航班机票信息表';
|
||||
|
||||
-- 演唱会票表
|
||||
CREATE TABLE concert_tickets (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键,自增,唯一标识每条记录',
|
||||
artist VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '艺人名称(如“周杰伦”)',
|
||||
city VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '举办城市(如“上海”)',
|
||||
venue VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '场馆(如“上海体育场”)',
|
||||
start_time DATETIME NOT NULL COMMENT '开始时间(如“2025-08-12 19:00:00”)',
|
||||
end_time DATETIME NOT NULL COMMENT '结束时间(如“2025-08-12 22:00:00”)',
|
||||
ticket_type VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '票类型(如“VIP”)',
|
||||
total_seats INT NOT NULL COMMENT '总座位数(如 5000)',
|
||||
remaining_seats INT NOT NULL COMMENT '剩余座位数(如 100)',
|
||||
price DECIMAL(10, 2) NOT NULL COMMENT '票价(如 880.00)',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间,自动记录插入时间',
|
||||
UNIQUE KEY unique_concert (start_time, artist, ticket_type) -- 唯一约束,确保同一时间、艺人和票类型不重复
|
||||
) COMMENT='演唱会门票信息表';
|
||||
|
||||
-- 天气数据表
|
||||
DROP TABLE IF EXISTS weather_data;
|
||||
CREATE TABLE IF NOT EXISTS weather_data (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
city VARCHAR(50) NOT NULL COMMENT '城市名称',
|
||||
fx_date DATE NOT NULL COMMENT '预报日期',
|
||||
sunrise TIME COMMENT '日出时间',
|
||||
sunset TIME COMMENT '日落时间',
|
||||
moonrise TIME COMMENT '月升时间',
|
||||
moonset TIME COMMENT '月落时间',
|
||||
moon_phase VARCHAR(20) COMMENT '月相名称',
|
||||
moon_phase_icon VARCHAR(10) COMMENT '月相图标代码',
|
||||
temp_max INT COMMENT '最高温度',
|
||||
temp_min INT COMMENT '最低温度',
|
||||
icon_day VARCHAR(10) COMMENT '白天天气图标代码',
|
||||
text_day VARCHAR(20) COMMENT '白天天气描述',
|
||||
icon_night VARCHAR(10) COMMENT '夜间天气图标代码',
|
||||
text_night VARCHAR(20) COMMENT '夜间天气描述',
|
||||
wind360_day INT COMMENT '白天风向360角度',
|
||||
wind_dir_day VARCHAR(20) COMMENT '白天风向',
|
||||
wind_scale_day VARCHAR(10) COMMENT '白天风力等级',
|
||||
wind_speed_day INT COMMENT '白天风速 (km/h)',
|
||||
wind360_night INT COMMENT '夜间风向360角度',
|
||||
wind_dir_night VARCHAR(20) COMMENT '夜间风向',
|
||||
wind_scale_night VARCHAR(10) COMMENT '夜间风力等级',
|
||||
wind_speed_night INT COMMENT '夜间风速 (km/h)',
|
||||
precip DECIMAL(5,1) COMMENT '降水量 (mm)',
|
||||
uv_index INT COMMENT '紫外线指数',
|
||||
humidity INT COMMENT '相对湿度 (%)',
|
||||
pressure INT COMMENT '大气压强 (hPa)',
|
||||
vis INT COMMENT '能见度 (km)',
|
||||
cloud INT COMMENT '云量 (%)',
|
||||
update_time DATETIME COMMENT '数据更新时间',
|
||||
UNIQUE KEY unique_city_date (city, fx_date)
|
||||
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='天气数据表';
|
||||
121
SmartVoyage/sql/flight_tickets_202601251131.csv
Normal file
121
SmartVoyage/sql/flight_tickets_202601251131.csv
Normal file
@@ -0,0 +1,121 @@
|
||||
"id","departure_city","arrival_city","departure_time","arrival_time","flight_number","cabin_type","total_seats","remaining_seats","price","created_at"
|
||||
1,上海,北京,"2025-09-21 22:00:00","2025-08-27 00:00:00",CA7151,公务舱,148,148,1311.36,"2025-07-27 16:04:21"
|
||||
2,北京,深圳,"2025-08-13 09:36:00","2025-08-13 11:36:00",CA1270,头等舱,119,119,2290.31,"2025-07-27 16:04:21"
|
||||
3,上海,北京,"2025-08-01 00:27:00","2025-08-01 05:27:00",CA6557,经济舱,134,134,885.65,"2025-07-27 16:04:21"
|
||||
4,广州,深圳,"2025-08-09 22:23:00","2025-08-10 02:23:00",CA3321,头等舱,87,87,2736.43,"2025-07-27 16:04:21"
|
||||
5,上海,深圳,"2025-08-15 09:32:00","2025-08-15 14:32:00",CA5040,头等舱,146,146,2455.01,"2025-07-27 16:04:21"
|
||||
6,北京,上海,"2025-08-22 21:20:00","2025-08-22 23:20:00",CA3624,公务舱,57,57,1601.75,"2025-07-27 16:04:21"
|
||||
7,北京,广州,"2025-08-03 17:20:00","2025-08-03 21:20:00",CA1906,公务舱,81,81,1731.53,"2025-07-27 16:04:21"
|
||||
8,上海,北京,"2025-09-10 21:46:00","2025-08-27 00:00:00",CA8096,经济舱,93,93,680.94,"2025-07-27 16:04:21"
|
||||
9,上海,广州,"2025-09-11 11:57:00","2025-08-27 00:00:00",CA6284,头等舱,149,149,2851.80,"2025-07-27 16:04:21"
|
||||
10,上海,北京,"2025-09-02 11:26:00","2025-08-27 00:00:00",CA6382,头等舱,96,96,2835.52,"2025-07-27 16:04:21"
|
||||
11,广州,上海,"2025-09-24 16:30:00","2025-08-27 00:00:00",CA6744,经济舱,105,105,958.30,"2025-07-27 16:04:21"
|
||||
12,上海,广州,"2025-08-24 22:39:00","2025-08-25 02:39:00",CA1212,公务舱,52,52,1337.76,"2025-07-27 16:04:21"
|
||||
13,深圳,广州,"2025-09-09 20:06:00","2025-08-27 00:00:00",CA5548,经济舱,125,125,990.82,"2025-07-27 16:04:21"
|
||||
14,北京,深圳,"2025-09-12 18:40:00","2025-08-27 00:00:00",CA1459,头等舱,130,130,2410.36,"2025-07-27 16:04:21"
|
||||
15,深圳,上海,"2025-09-23 18:50:00","2025-08-27 00:00:00",CA5385,经济舱,75,75,665.93,"2025-07-27 16:04:21"
|
||||
16,深圳,广州,"2025-09-16 22:14:00","2025-08-27 00:00:00",CA5159,头等舱,89,89,2301.25,"2025-07-27 16:04:21"
|
||||
17,上海,北京,"2025-08-10 13:15:00","2025-08-10 14:15:00",CA5696,经济舱,129,129,604.37,"2025-07-27 16:04:21"
|
||||
18,上海,北京,"2025-08-11 22:52:00","2025-08-12 02:52:00",CA8751,经济舱,96,96,678.59,"2025-07-27 16:04:21"
|
||||
19,广州,上海,"2025-08-02 00:11:00","2025-08-02 05:11:00",CA4339,经济舱,101,101,631.34,"2025-07-27 16:04:21"
|
||||
20,广州,上海,"2025-08-18 15:42:00","2025-08-18 16:42:00",CA3244,经济舱,114,114,806.98,"2025-07-27 16:04:21"
|
||||
21,深圳,广州,"2025-07-30 22:33:00","2025-07-30 23:33:00",CA4724,头等舱,87,87,2996.21,"2025-07-27 16:04:21"
|
||||
22,广州,北京,"2025-08-01 15:06:00","2025-08-01 16:06:00",CA4167,经济舱,51,51,749.33,"2025-07-27 16:04:21"
|
||||
23,广州,北京,"2025-09-08 14:05:00","2025-08-27 00:00:00",CA3184,头等舱,59,59,2386.98,"2025-07-27 16:04:21"
|
||||
24,深圳,广州,"2025-09-16 13:30:00","2025-08-27 00:00:00",CA2898,公务舱,69,69,1581.42,"2025-07-27 16:04:21"
|
||||
25,上海,深圳,"2025-09-24 00:38:00","2025-08-27 00:00:00",CA4504,公务舱,79,79,1724.66,"2025-07-27 16:04:21"
|
||||
26,上海,深圳,"2025-08-20 13:54:00","2025-08-20 18:54:00",CA8638,头等舱,94,94,2472.95,"2025-07-27 16:04:21"
|
||||
27,深圳,上海,"2025-08-03 19:03:00","2025-08-03 23:03:00",CA1764,头等舱,123,123,2560.29,"2025-07-27 16:04:21"
|
||||
28,上海,深圳,"2025-08-27 16:32:00","2025-08-27 00:00:00",CA7695,头等舱,135,135,2593.06,"2025-07-27 16:04:21"
|
||||
29,上海,深圳,"2025-09-11 15:54:00","2025-08-27 00:00:00",CA2637,公务舱,66,66,1856.64,"2025-07-27 16:04:21"
|
||||
30,上海,广州,"2025-09-24 08:48:00","2025-08-27 00:00:00",CA3274,经济舱,76,76,926.89,"2025-07-27 16:04:21"
|
||||
31,广州,北京,"2025-08-16 16:14:00","2025-08-16 18:14:00",CA3246,公务舱,62,62,1438.12,"2025-07-27 16:04:21"
|
||||
32,深圳,北京,"2025-08-28 12:14:00","2025-08-27 00:00:00",CA2174,经济舱,131,131,1121.44,"2025-07-27 16:04:21"
|
||||
33,北京,上海,"2025-09-01 15:32:00","2025-08-27 00:00:00",CA2714,经济舱,133,133,629.95,"2025-07-27 16:04:21"
|
||||
34,上海,北京,"2025-08-08 09:04:00","2025-08-08 12:04:00",CA1284,公务舱,82,82,1638.03,"2025-07-27 16:04:21"
|
||||
35,北京,广州,"2025-09-03 22:08:00","2025-08-27 00:00:00",CA6851,经济舱,56,56,503.59,"2025-07-27 16:04:21"
|
||||
36,广州,北京,"2025-08-03 22:30:00","2025-08-04 03:30:00",CA7417,头等舱,72,72,2014.35,"2025-07-27 16:04:21"
|
||||
37,深圳,上海,"2025-07-31 07:45:00","2025-07-31 10:45:00",CA8102,经济舱,70,70,853.45,"2025-07-27 16:04:21"
|
||||
38,北京,上海,"2025-07-30 12:46:00","2025-07-30 17:46:00",CA2104,头等舱,58,58,2938.34,"2025-07-27 16:04:21"
|
||||
39,北京,上海,"2025-08-11 09:03:00","2025-08-11 12:03:00",CA1085,经济舱,80,80,923.65,"2025-07-27 16:04:21"
|
||||
40,深圳,北京,"2025-08-28 12:31:00","2025-08-27 00:00:00",CA5786,经济舱,98,98,1096.58,"2025-07-27 16:04:21"
|
||||
41,深圳,北京,"2025-09-17 14:03:00","2025-08-27 00:00:00",CA7813,经济舱,119,119,1146.29,"2025-07-27 16:04:21"
|
||||
42,北京,广州,"2025-08-28 08:15:00","2025-08-27 00:00:00",CA3636,公务舱,58,58,1560.16,"2025-07-27 16:04:21"
|
||||
43,广州,北京,"2025-09-02 13:23:00","2025-08-27 00:00:00",CA8286,公务舱,136,136,1599.04,"2025-07-27 16:04:21"
|
||||
44,广州,深圳,"2025-09-19 07:13:00","2025-08-27 00:00:00",CA4803,头等舱,88,88,2556.78,"2025-07-27 16:04:21"
|
||||
45,广州,上海,"2025-09-06 19:26:00","2025-08-27 00:00:00",CA9428,头等舱,56,56,2478.31,"2025-07-27 16:04:21"
|
||||
46,广州,北京,"2025-09-08 15:44:00","2025-08-27 00:00:00",CA3851,公务舱,81,81,1774.53,"2025-07-27 16:04:21"
|
||||
47,上海,广州,"2025-08-12 14:02:00","2025-08-12 16:02:00",CA2493,头等舱,150,150,2898.23,"2025-07-27 16:04:21"
|
||||
48,深圳,上海,"2025-09-07 00:34:00","2025-08-27 00:00:00",CA6405,经济舱,95,95,555.32,"2025-07-27 16:04:21"
|
||||
49,广州,北京,"2025-09-12 20:15:00","2025-08-27 00:00:00",CA5318,公务舱,62,62,1991.59,"2025-07-27 16:04:21"
|
||||
50,北京,深圳,"2025-09-01 21:13:00","2025-08-27 00:00:00",CA8925,公务舱,110,110,1633.21,"2025-07-27 16:04:21"
|
||||
51,上海,广州,"2025-09-18 18:35:00","2025-08-27 00:00:00",CA7931,公务舱,123,123,1304.42,"2025-07-27 16:04:21"
|
||||
52,广州,深圳,"2025-09-07 07:02:00","2025-08-27 00:00:00",CA8830,经济舱,71,71,695.24,"2025-07-27 16:04:21"
|
||||
53,深圳,北京,"2025-09-14 00:28:00","2025-08-27 00:00:00",CA3742,经济舱,57,57,532.13,"2025-07-27 16:04:21"
|
||||
54,广州,上海,"2025-09-04 08:51:00","2025-08-27 00:00:00",CA3248,经济舱,85,85,885.20,"2025-07-27 16:04:21"
|
||||
55,北京,深圳,"2025-08-13 16:39:00","2025-08-13 17:39:00",CA4473,经济舱,91,91,506.43,"2025-07-27 16:04:21"
|
||||
56,北京,广州,"2025-09-16 13:44:00","2025-08-27 00:00:00",CA1201,头等舱,100,100,2139.98,"2025-07-27 16:04:21"
|
||||
57,广州,上海,"2025-09-08 16:57:00","2025-08-27 00:00:00",CA7206,经济舱,95,95,784.11,"2025-07-27 16:04:21"
|
||||
58,广州,深圳,"2025-08-31 13:14:00","2025-08-27 00:00:00",CA7429,经济舱,54,54,954.49,"2025-07-27 16:04:21"
|
||||
59,上海,深圳,"2025-08-10 13:44:00","2025-08-10 14:44:00",CA4709,经济舱,125,125,594.29,"2025-07-27 16:04:21"
|
||||
60,深圳,上海,"2025-08-03 08:05:00","2025-08-03 12:05:00",CA4574,头等舱,117,117,2614.51,"2025-07-27 16:04:21"
|
||||
61,深圳,广州,"2025-09-14 20:57:00","2025-08-27 00:00:00",CA7019,公务舱,111,111,1524.63,"2025-07-27 16:04:21"
|
||||
62,深圳,广州,"2025-09-15 12:41:00","2025-08-27 00:00:00",CA7257,头等舱,101,101,2210.88,"2025-07-27 16:04:21"
|
||||
63,深圳,广州,"2025-07-27 16:52:00","2025-07-27 18:52:00",CA8321,公务舱,137,137,1615.02,"2025-07-27 16:04:21"
|
||||
64,北京,上海,"2025-08-23 09:59:00","2025-08-23 10:59:00",CA4293,公务舱,98,98,1878.45,"2025-07-27 16:04:21"
|
||||
65,广州,深圳,"2025-08-23 10:06:00","2025-08-23 14:06:00",CA8471,头等舱,52,52,2157.26,"2025-07-27 16:04:21"
|
||||
66,广州,北京,"2025-08-04 17:13:00","2025-08-04 18:13:00",CA2987,公务舱,75,75,1770.52,"2025-07-27 16:04:21"
|
||||
67,广州,上海,"2025-09-24 00:36:00","2025-08-27 00:00:00",CA7851,头等舱,58,58,2015.88,"2025-07-27 16:04:21"
|
||||
68,上海,北京,"2025-09-11 19:49:00","2025-08-27 00:00:00",CA7328,头等舱,67,67,2530.49,"2025-07-27 16:04:21"
|
||||
69,北京,广州,"2025-08-16 11:41:00","2025-08-16 16:41:00",CA5645,公务舱,108,108,1840.09,"2025-07-27 16:04:21"
|
||||
70,广州,深圳,"2025-09-02 19:16:00","2025-08-27 00:00:00",CA4124,头等舱,106,106,2423.91,"2025-07-27 16:04:21"
|
||||
71,广州,深圳,"2025-08-26 20:11:00","2025-08-26 22:11:00",CA2124,公务舱,58,58,1873.24,"2025-07-27 16:04:21"
|
||||
72,深圳,北京,"2025-08-16 18:06:00","2025-08-16 19:06:00",CA1397,经济舱,109,109,1058.82,"2025-07-27 16:04:21"
|
||||
73,广州,深圳,"2025-09-14 23:44:00","2025-08-27 00:00:00",CA8512,头等舱,91,91,2556.04,"2025-07-27 16:04:21"
|
||||
74,深圳,上海,"2025-08-27 13:13:00","2025-08-27 00:00:00",CA8073,经济舱,50,50,612.09,"2025-07-27 16:04:21"
|
||||
75,上海,广州,"2025-08-29 12:38:00","2025-08-27 00:00:00",CA4782,公务舱,118,118,1524.59,"2025-07-27 16:04:21"
|
||||
76,广州,北京,"2025-09-22 12:09:00","2025-08-27 00:00:00",CA7280,经济舱,125,125,1167.26,"2025-07-27 16:04:21"
|
||||
77,深圳,上海,"2025-09-22 21:36:00","2025-08-27 00:00:00",CA2829,经济舱,95,95,518.21,"2025-07-27 16:04:21"
|
||||
78,北京,上海,"2025-09-05 00:54:00","2025-08-27 00:00:00",CA6247,头等舱,67,67,2339.68,"2025-07-27 16:04:21"
|
||||
79,广州,上海,"2025-08-19 15:56:00","2025-08-19 20:56:00",CA4457,头等舱,142,142,2796.88,"2025-07-27 16:04:21"
|
||||
80,北京,上海,"2025-08-06 06:57:00","2025-08-06 11:57:00",CA3933,公务舱,104,104,1499.78,"2025-07-27 16:04:21"
|
||||
81,北京,广州,"2025-07-31 19:51:00","2025-07-31 20:51:00",CA5990,经济舱,121,121,711.14,"2025-07-27 16:04:21"
|
||||
82,上海,广州,"2025-09-01 22:37:00","2025-08-27 00:00:00",CA1435,头等舱,103,103,2397.56,"2025-07-27 16:04:21"
|
||||
83,广州,深圳,"2025-08-10 20:34:00","2025-08-10 21:34:00",CA8408,头等舱,104,104,2512.60,"2025-07-27 16:04:21"
|
||||
84,广州,北京,"2025-07-30 21:02:00","2025-07-30 22:02:00",CA9211,经济舱,97,97,1092.13,"2025-07-27 16:04:21"
|
||||
85,广州,深圳,"2025-09-25 00:52:00","2025-08-27 00:00:00",CA3700,经济舱,102,102,902.71,"2025-07-27 16:04:21"
|
||||
86,广州,上海,"2025-07-31 19:46:00","2025-08-01 00:46:00",CA6241,头等舱,109,109,2894.67,"2025-07-27 16:04:21"
|
||||
87,上海,北京,"2025-09-14 23:22:00","2025-08-27 00:00:00",CA3245,公务舱,123,123,1301.33,"2025-07-27 16:04:21"
|
||||
88,北京,上海,"2025-08-31 21:02:00","2025-08-27 00:00:00",CA9695,头等舱,55,55,2463.32,"2025-07-27 16:04:21"
|
||||
89,广州,深圳,"2025-09-25 14:14:00","2025-08-27 00:00:00",CA7785,公务舱,62,62,1754.83,"2025-07-27 16:04:21"
|
||||
90,上海,广州,"2025-09-03 19:39:00","2025-08-27 00:00:00",CA6577,头等舱,95,95,2543.82,"2025-07-27 16:04:21"
|
||||
91,北京,广州,"2025-08-13 00:04:00","2025-08-13 03:04:00",CA7722,头等舱,137,137,2344.17,"2025-07-27 16:04:21"
|
||||
92,上海,北京,"2025-07-28 15:26:00","2025-07-28 18:26:00",CA4722,经济舱,106,106,878.85,"2025-07-27 16:04:21"
|
||||
93,北京,上海,"2025-09-17 23:50:00","2025-08-27 00:00:00",CA3197,公务舱,100,100,1240.91,"2025-07-27 16:04:21"
|
||||
94,北京,广州,"2025-08-23 18:41:00","2025-08-23 21:41:00",CA4501,经济舱,66,66,884.40,"2025-07-27 16:04:21"
|
||||
95,广州,北京,"2025-09-03 12:28:00","2025-08-27 00:00:00",CA5092,头等舱,102,102,2610.10,"2025-07-27 16:04:21"
|
||||
96,深圳,北京,"2025-08-19 13:20:00","2025-08-19 16:20:00",CA2989,经济舱,70,70,829.00,"2025-07-27 16:04:21"
|
||||
97,上海,北京,"2025-09-18 19:27:00","2025-08-27 00:00:00",CA7162,公务舱,145,145,1928.03,"2025-07-27 16:04:21"
|
||||
98,上海,广州,"2025-08-02 23:55:00","2025-08-03 02:55:00",CA2917,经济舱,82,82,584.62,"2025-07-27 16:04:21"
|
||||
99,上海,广州,"2025-08-11 15:41:00","2025-08-11 16:41:00",CA7090,经济舱,58,58,890.63,"2025-07-27 16:04:21"
|
||||
100,广州,深圳,"2025-08-16 17:37:00","2025-08-16 20:37:00",CA9163,头等舱,50,50,2405.28,"2025-07-27 16:04:21"
|
||||
101,上海,深圳,"2025-09-15 14:31:00","2025-08-27 00:00:00",CA7520,经济舱,92,92,1045.44,"2025-07-27 16:04:21"
|
||||
102,上海,北京,"2025-09-19 13:51:00","2025-08-27 00:00:00",CA2409,公务舱,88,88,1442.46,"2025-07-27 16:04:21"
|
||||
103,深圳,上海,"2025-08-28 11:05:00","2025-08-27 00:00:00",CA5510,头等舱,66,66,2969.17,"2025-07-27 16:04:21"
|
||||
104,深圳,上海,"2025-08-02 08:25:00","2025-08-02 11:25:00",CA2274,经济舱,84,84,546.04,"2025-07-27 16:04:21"
|
||||
105,深圳,广州,"2025-09-07 19:03:00","2025-08-27 00:00:00",CA5416,经济舱,145,145,1041.12,"2025-07-27 16:04:21"
|
||||
106,广州,上海,"2025-08-08 17:17:00","2025-08-08 22:17:00",CA9553,经济舱,108,108,1172.30,"2025-07-27 16:04:21"
|
||||
107,上海,广州,"2025-08-07 23:13:00","2025-08-08 00:13:00",CA8253,公务舱,97,97,1295.42,"2025-07-27 16:04:21"
|
||||
108,深圳,上海,"2025-09-22 22:33:00","2025-08-27 00:00:00",CA6255,头等舱,94,94,2729.88,"2025-07-27 16:04:21"
|
||||
109,北京,深圳,"2025-09-22 00:05:00","2025-08-27 00:00:00",CA7690,头等舱,102,102,2278.72,"2025-07-27 16:04:21"
|
||||
110,北京,广州,"2025-08-11 21:01:00","2025-08-12 02:01:00",CA3625,头等舱,61,61,2150.65,"2025-07-27 16:04:21"
|
||||
111,北京,深圳,"2025-09-20 10:03:00","2025-08-27 00:00:00",CA5282,经济舱,99,99,893.35,"2025-07-27 16:04:21"
|
||||
112,北京,广州,"2025-08-25 10:54:00","2025-08-25 15:54:00",CA5992,公务舱,62,62,1479.05,"2025-07-27 16:04:21"
|
||||
113,广州,北京,"2025-08-10 16:02:00","2025-08-10 18:02:00",CA3044,公务舱,73,73,1573.03,"2025-07-27 16:04:21"
|
||||
114,北京,上海,"2025-09-09 00:46:00","2025-08-27 00:00:00",CA5397,公务舱,137,137,1722.66,"2025-07-27 16:04:21"
|
||||
115,深圳,广州,"2025-09-11 22:03:00","2025-08-27 00:00:00",CA9216,头等舱,91,91,2712.58,"2025-07-27 16:04:21"
|
||||
116,广州,北京,"2025-09-04 10:57:00","2025-08-27 00:00:00",CA3316,头等舱,122,122,2651.39,"2025-07-27 16:04:21"
|
||||
117,上海,广州,"2025-09-04 15:42:00","2025-08-27 00:00:00",CA1997,公务舱,105,105,1729.53,"2025-07-27 16:04:21"
|
||||
118,广州,北京,"2025-08-02 11:53:00","2025-08-02 12:53:00",CA6923,头等舱,127,127,2537.66,"2025-07-27 16:04:21"
|
||||
119,北京,上海,"2025-09-19 23:26:00","2025-08-27 00:00:00",CA7566,经济舱,99,99,1066.76,"2025-07-27 16:04:21"
|
||||
120,上海,深圳,"2025-08-21 22:29:00","2025-08-22 01:29:00",CA4422,头等舱,118,118,2441.84,"2025-07-27 16:04:21"
|
||||
|
28
SmartVoyage/sql/insert_data.sql
Normal file
28
SmartVoyage/sql/insert_data.sql
Normal file
File diff suppressed because one or more lines are too long
121
SmartVoyage/sql/train_tickets_202601251131.csv
Normal file
121
SmartVoyage/sql/train_tickets_202601251131.csv
Normal file
@@ -0,0 +1,121 @@
|
||||
"id","departure_city","arrival_city","departure_time","arrival_time","train_number","seat_type","total_seats","remaining_seats","price","created_at"
|
||||
1,北京,上海,"2025-08-02 20:36:00","2025-08-02 22:36:00",G703,二等座,183,183,167.85,"2025-07-27 16:04:25"
|
||||
2,深圳,上海,"2025-08-08 17:00:00","2025-08-08 23:00:00",G195,商务座,286,286,1032.21,"2025-07-27 16:04:25"
|
||||
3,广州,上海,"2025-07-28 15:45:00","2025-07-28 18:45:00",G567,一等座,106,106,651.42,"2025-07-27 16:04:25"
|
||||
4,广州,北京,"2025-08-18 23:30:00","2025-08-19 05:30:00",G854,一等座,207,207,721.96,"2025-07-27 16:04:25"
|
||||
5,广州,深圳,"2025-08-13 16:50:00","2025-08-13 22:50:00",G280,二等座,283,283,160.49,"2025-07-27 16:04:25"
|
||||
6,北京,广州,"2025-08-16 22:08:00","2025-08-17 03:08:00",G751,二等座,280,280,217.92,"2025-07-27 16:04:25"
|
||||
7,深圳,上海,"2025-08-17 13:28:00","2025-08-17 18:28:00",G400,商务座,248,248,1060.86,"2025-07-27 16:04:25"
|
||||
8,广州,深圳,"2025-08-21 21:24:00","2025-08-21 23:24:00",G561,商务座,265,265,812.59,"2025-07-27 16:04:25"
|
||||
9,上海,广州,"2025-08-04 18:22:00","2025-08-05 00:22:00",G926,二等座,242,242,318.26,"2025-07-27 16:04:25"
|
||||
10,北京,深圳,"2025-08-11 13:23:00","2025-08-11 18:23:00",G556,二等座,100,100,331.84,"2025-07-27 16:04:25"
|
||||
11,上海,广州,"2025-08-21 20:20:00","2025-08-21 22:20:00",G305,商务座,154,154,956.04,"2025-07-27 16:04:25"
|
||||
12,广州,深圳,"2025-07-27 10:06:00","2025-07-27 14:06:00",G674,商务座,165,165,1013.28,"2025-07-27 16:04:25"
|
||||
13,广州,上海,"2025-08-20 18:58:00","2025-08-20 20:58:00",G778,商务座,210,210,952.15,"2025-07-27 16:04:25"
|
||||
14,北京,上海,"2025-08-26 19:58:00","2025-08-27 00:00:00",G346,二等座,284,284,397.55,"2025-07-27 16:04:25"
|
||||
15,上海,深圳,"2025-08-15 14:25:00","2025-08-15 17:25:00",G854,二等座,115,115,143.30,"2025-07-27 16:04:25"
|
||||
16,深圳,上海,"2025-08-17 16:45:00","2025-08-17 21:45:00",G466,二等座,147,147,314.59,"2025-07-27 16:04:25"
|
||||
17,北京,上海,"2025-07-28 14:25:00","2025-07-28 19:25:00",G715,一等座,282,282,539.17,"2025-07-27 16:04:25"
|
||||
18,北京,广州,"2025-08-13 11:35:00","2025-08-13 16:35:00",G188,商务座,263,263,1157.71,"2025-07-27 16:04:25"
|
||||
19,深圳,上海,"2025-08-18 23:07:00","2025-08-19 03:07:00",G472,商务座,259,259,815.69,"2025-07-27 16:04:25"
|
||||
20,广州,北京,"2025-08-08 12:31:00","2025-08-08 14:31:00",G880,一等座,104,104,500.71,"2025-07-27 16:04:25"
|
||||
21,北京,广州,"2025-08-15 10:04:00","2025-08-15 13:04:00",G361,一等座,164,164,646.70,"2025-07-27 16:04:25"
|
||||
22,北京,广州,"2025-08-23 22:33:00","2025-08-24 01:33:00",G499,商务座,228,228,816.56,"2025-07-27 16:04:25"
|
||||
23,广州,上海,"2025-07-30 06:58:00","2025-07-30 08:58:00",G229,商务座,158,158,984.22,"2025-07-27 16:04:25"
|
||||
24,北京,广州,"2025-08-18 18:17:00","2025-08-19 00:17:00",G407,商务座,229,229,1117.76,"2025-07-27 16:04:25"
|
||||
25,深圳,上海,"2025-08-07 07:20:00","2025-08-07 11:20:00",G359,商务座,183,183,985.25,"2025-07-27 16:04:25"
|
||||
26,广州,上海,"2025-08-26 22:42:00","2025-08-27 00:00:00",G135,二等座,162,162,435.84,"2025-07-27 16:04:25"
|
||||
27,北京,上海,"2025-08-02 21:15:00","2025-08-02 23:15:00",G499,商务座,254,254,964.94,"2025-07-27 16:04:25"
|
||||
28,上海,北京,"2025-08-21 07:42:00","2025-08-21 10:42:00",G264,二等座,254,254,409.88,"2025-07-27 16:04:25"
|
||||
29,上海,广州,"2025-08-05 23:49:00","2025-08-06 02:49:00",G175,商务座,279,279,881.48,"2025-07-27 16:04:25"
|
||||
30,北京,深圳,"2025-08-10 11:49:00","2025-08-10 16:49:00",G985,商务座,107,107,1108.01,"2025-07-27 16:04:25"
|
||||
31,上海,广州,"2025-08-09 21:21:00","2025-08-10 03:21:00",G373,一等座,256,256,532.61,"2025-07-27 16:04:25"
|
||||
32,广州,深圳,"2025-07-30 13:42:00","2025-07-30 18:42:00",G536,一等座,241,241,647.11,"2025-07-27 16:04:25"
|
||||
33,深圳,广州,"2025-08-27 11:39:00","2025-08-27 00:00:00",G303,一等座,214,214,661.10,"2025-07-27 16:04:25"
|
||||
34,北京,深圳,"2025-08-27 21:46:00","2025-08-27 00:00:00",G416,商务座,181,181,973.53,"2025-07-27 16:04:25"
|
||||
35,北京,广州,"2025-08-11 18:08:00","2025-08-11 20:08:00",G529,商务座,164,164,860.61,"2025-07-27 16:04:25"
|
||||
36,北京,深圳,"2025-08-27 14:30:00","2025-08-27 00:00:00",G767,二等座,100,100,377.62,"2025-07-27 16:04:25"
|
||||
37,上海,深圳,"2025-08-16 10:18:00","2025-08-16 13:18:00",G717,二等座,300,300,348.43,"2025-07-27 16:04:25"
|
||||
38,北京,广州,"2025-08-05 08:51:00","2025-08-05 14:51:00",G295,商务座,202,202,833.75,"2025-07-27 16:04:25"
|
||||
39,深圳,广州,"2025-08-27 23:45:00","2025-08-27 00:00:00",G444,商务座,136,136,1096.68,"2025-07-27 16:04:25"
|
||||
40,北京,深圳,"2025-08-04 15:28:00","2025-08-04 21:28:00",G591,商务座,110,110,850.18,"2025-07-27 16:04:25"
|
||||
41,上海,深圳,"2025-08-11 17:24:00","2025-08-11 20:24:00",G997,一等座,199,199,507.04,"2025-07-27 16:04:25"
|
||||
42,深圳,北京,"2025-07-31 21:52:00","2025-07-31 23:52:00",G129,二等座,264,264,334.37,"2025-07-27 16:04:25"
|
||||
43,上海,广州,"2025-08-05 08:46:00","2025-08-05 14:46:00",G546,一等座,152,152,576.66,"2025-07-27 16:04:25"
|
||||
44,上海,深圳,"2025-08-03 23:12:00","2025-08-04 03:12:00",G929,一等座,213,213,570.96,"2025-07-27 16:04:25"
|
||||
45,上海,北京,"2025-08-19 13:11:00","2025-08-19 16:11:00",G942,商务座,197,197,808.51,"2025-07-27 16:04:25"
|
||||
46,广州,北京,"2025-08-06 15:32:00","2025-08-06 20:32:00",G118,商务座,288,288,851.79,"2025-07-27 16:04:25"
|
||||
47,广州,北京,"2025-08-06 18:31:00","2025-08-06 23:31:00",G423,一等座,123,123,613.49,"2025-07-27 16:04:25"
|
||||
48,深圳,北京,"2025-08-08 11:52:00","2025-08-08 13:52:00",G565,二等座,223,223,330.15,"2025-07-27 16:04:25"
|
||||
49,上海,广州,"2025-07-29 16:57:00","2025-07-29 21:57:00",G999,商务座,261,261,976.29,"2025-07-27 16:04:25"
|
||||
50,上海,广州,"2025-08-03 10:08:00","2025-08-03 12:08:00",G874,商务座,201,201,810.12,"2025-07-27 16:04:25"
|
||||
51,上海,广州,"2025-08-11 21:00:00","2025-08-12 00:00:00",G646,二等座,289,289,353.64,"2025-07-27 16:04:25"
|
||||
52,北京,上海,"2025-08-20 10:24:00","2025-08-20 16:24:00",G273,商务座,245,245,949.04,"2025-07-27 16:04:25"
|
||||
53,深圳,广州,"2025-07-31 12:07:00","2025-07-31 18:07:00",G415,一等座,140,140,660.54,"2025-07-27 16:04:25"
|
||||
54,北京,广州,"2025-08-13 19:00:00","2025-08-13 23:00:00",G684,商务座,278,278,1010.40,"2025-07-27 16:04:25"
|
||||
55,北京,上海,"2025-08-01 10:31:00","2025-08-01 13:31:00",G283,一等座,201,201,799.32,"2025-07-27 16:04:25"
|
||||
56,北京,上海,"2025-08-12 13:04:00","2025-08-12 19:04:00",G135,商务座,103,103,986.00,"2025-07-27 16:04:25"
|
||||
57,深圳,北京,"2025-08-13 08:28:00","2025-08-13 11:28:00",G111,二等座,124,124,392.69,"2025-07-27 16:04:25"
|
||||
58,广州,深圳,"2025-08-15 08:46:00","2025-08-15 10:46:00",G502,二等座,178,178,110.15,"2025-07-27 16:04:25"
|
||||
59,广州,北京,"2025-08-23 08:44:00","2025-08-23 10:44:00",G948,商务座,195,195,1021.77,"2025-07-27 16:04:25"
|
||||
60,深圳,上海,"2025-08-23 12:18:00","2025-08-23 17:18:00",G447,二等座,219,219,331.16,"2025-07-27 16:04:25"
|
||||
61,深圳,广州,"2025-07-31 17:27:00","2025-07-31 21:27:00",G303,一等座,212,212,703.15,"2025-07-27 16:04:25"
|
||||
62,上海,广州,"2025-08-15 19:57:00","2025-08-16 01:57:00",G185,二等座,237,237,295.43,"2025-07-27 16:04:25"
|
||||
63,北京,上海,"2025-08-06 13:06:00","2025-08-06 17:06:00",G795,一等座,290,290,564.04,"2025-07-27 16:04:25"
|
||||
64,广州,上海,"2025-08-14 09:49:00","2025-08-14 14:49:00",G400,商务座,267,267,1045.80,"2025-07-27 16:04:25"
|
||||
65,北京,广州,"2025-08-27 20:47:00","2025-08-27 00:00:00",G242,二等座,262,262,209.73,"2025-07-27 16:04:25"
|
||||
66,广州,深圳,"2025-08-05 15:33:00","2025-08-05 18:33:00",G804,一等座,155,155,676.63,"2025-07-27 16:04:25"
|
||||
67,上海,广州,"2025-08-27 11:10:00","2025-08-27 00:00:00",G311,一等座,248,248,703.68,"2025-07-27 16:04:25"
|
||||
68,北京,广州,"2025-08-14 18:59:00","2025-08-14 23:59:00",G389,商务座,247,247,1164.69,"2025-07-27 16:04:25"
|
||||
69,上海,北京,"2025-08-24 21:01:00","2025-08-25 00:01:00",G365,商务座,234,234,893.20,"2025-07-27 16:04:25"
|
||||
70,北京,广州,"2025-07-29 12:02:00","2025-07-29 18:02:00",G716,一等座,228,228,791.22,"2025-07-27 16:04:25"
|
||||
71,上海,广州,"2025-08-07 21:58:00","2025-08-08 00:58:00",G326,二等座,233,233,109.16,"2025-07-27 16:04:25"
|
||||
72,深圳,广州,"2025-08-19 23:28:00","2025-08-20 03:28:00",G954,商务座,175,175,1033.73,"2025-07-27 16:04:25"
|
||||
73,广州,北京,"2025-08-21 19:29:00","2025-08-22 00:29:00",G658,一等座,128,128,686.68,"2025-07-27 16:04:25"
|
||||
74,广州,北京,"2025-08-09 16:26:00","2025-08-09 22:26:00",G268,商务座,214,214,850.37,"2025-07-27 16:04:25"
|
||||
75,广州,深圳,"2025-08-25 16:28:00","2025-08-25 19:28:00",G983,二等座,163,163,389.07,"2025-07-27 16:04:25"
|
||||
76,广州,北京,"2025-07-31 17:37:00","2025-07-31 21:37:00",G798,一等座,288,288,552.14,"2025-07-27 16:04:25"
|
||||
77,深圳,上海,"2025-07-30 12:55:00","2025-07-30 18:55:00",G806,一等座,300,300,531.94,"2025-07-27 16:04:25"
|
||||
78,深圳,广州,"2025-08-05 10:25:00","2025-08-05 16:25:00",G287,商务座,107,107,1002.25,"2025-07-27 16:04:25"
|
||||
79,北京,深圳,"2025-08-20 21:55:00","2025-08-21 02:55:00",G196,商务座,242,242,1111.37,"2025-07-27 16:04:25"
|
||||
80,深圳,广州,"2025-08-04 19:04:00","2025-08-05 01:04:00",G384,商务座,177,177,1045.08,"2025-07-27 16:04:25"
|
||||
81,上海,深圳,"2025-08-14 18:57:00","2025-08-14 22:57:00",G680,二等座,240,240,358.23,"2025-07-27 16:04:25"
|
||||
82,上海,广州,"2025-07-28 20:11:00","2025-07-28 23:11:00",G813,二等座,140,140,182.71,"2025-07-27 16:04:25"
|
||||
83,上海,广州,"2025-08-23 11:37:00","2025-08-23 16:37:00",G446,商务座,152,152,992.52,"2025-07-27 16:04:25"
|
||||
84,上海,广州,"2025-07-30 21:30:00","2025-07-30 23:30:00",G251,一等座,253,253,570.24,"2025-07-27 16:04:25"
|
||||
85,广州,深圳,"2025-08-26 21:53:00","2025-08-27 00:00:00",G113,商务座,275,275,1143.96,"2025-07-27 16:04:25"
|
||||
86,上海,广州,"2025-07-27 12:12:00","2025-07-27 18:12:00",G841,一等座,284,284,768.87,"2025-07-27 16:04:25"
|
||||
87,广州,上海,"2025-08-06 08:19:00","2025-08-06 13:19:00",G970,商务座,276,276,1055.65,"2025-07-27 16:04:25"
|
||||
88,深圳,北京,"2025-08-25 10:02:00","2025-08-25 16:02:00",G611,一等座,194,194,551.83,"2025-07-27 16:04:25"
|
||||
89,深圳,北京,"2025-08-13 09:39:00","2025-08-13 13:39:00",G588,商务座,258,258,817.85,"2025-07-27 16:04:25"
|
||||
90,上海,北京,"2025-07-27 22:12:00","2025-07-28 01:12:00",G434,一等座,147,147,741.97,"2025-07-27 16:04:25"
|
||||
91,广州,上海,"2025-08-24 23:13:00","2025-08-25 04:13:00",G764,商务座,280,280,890.17,"2025-07-27 16:04:25"
|
||||
92,上海,北京,"2025-08-18 20:31:00","2025-08-18 23:31:00",G355,商务座,232,232,960.37,"2025-07-27 16:04:25"
|
||||
93,深圳,上海,"2025-08-13 17:12:00","2025-08-13 22:12:00",G104,一等座,219,219,513.02,"2025-07-27 16:04:25"
|
||||
94,深圳,北京,"2025-07-27 14:59:00","2025-07-27 16:59:00",G656,二等座,144,144,403.38,"2025-07-27 16:04:25"
|
||||
95,上海,北京,"2025-08-21 10:36:00","2025-08-21 14:36:00",G188,二等座,296,296,187.76,"2025-07-27 16:04:25"
|
||||
96,上海,北京,"2025-08-02 20:09:00","2025-08-03 01:09:00",G276,一等座,252,252,628.64,"2025-07-27 16:04:25"
|
||||
97,北京,深圳,"2025-08-16 11:04:00","2025-08-16 17:04:00",G670,一等座,182,182,606.45,"2025-07-27 16:04:25"
|
||||
98,深圳,北京,"2025-07-30 08:13:00","2025-07-30 10:13:00",G327,商务座,107,107,1004.35,"2025-07-27 16:04:25"
|
||||
99,深圳,广州,"2025-08-14 15:50:00","2025-08-14 20:50:00",G348,一等座,237,237,611.31,"2025-07-27 16:04:25"
|
||||
100,广州,北京,"2025-08-12 09:51:00","2025-08-12 13:51:00",G273,商务座,108,108,816.47,"2025-07-27 16:04:25"
|
||||
101,广州,上海,"2025-08-14 11:35:00","2025-08-14 14:35:00",G294,商务座,154,154,1058.42,"2025-07-27 16:04:25"
|
||||
102,上海,北京,"2025-08-19 16:52:00","2025-08-19 18:52:00",G604,二等座,140,140,250.95,"2025-07-27 16:04:25"
|
||||
103,广州,北京,"2025-07-30 09:44:00","2025-07-30 14:44:00",G950,商务座,162,162,1019.56,"2025-07-27 16:04:25"
|
||||
104,北京,深圳,"2025-08-15 11:42:00","2025-08-15 15:42:00",G681,一等座,123,123,651.70,"2025-07-27 16:04:25"
|
||||
105,广州,北京,"2025-08-21 19:30:00","2025-08-21 22:30:00",G487,一等座,294,294,730.46,"2025-07-27 16:04:25"
|
||||
106,深圳,北京,"2025-08-19 15:04:00","2025-08-19 20:04:00",G583,二等座,140,140,205.26,"2025-07-27 16:04:25"
|
||||
107,上海,广州,"2025-08-11 14:03:00","2025-08-11 18:03:00",G995,商务座,204,204,964.67,"2025-07-27 16:04:25"
|
||||
108,上海,深圳,"2025-08-26 22:16:00","2025-08-27 00:00:00",G725,一等座,103,103,585.21,"2025-07-27 16:04:25"
|
||||
109,上海,北京,"2025-08-08 09:57:00","2025-08-08 13:57:00",G660,商务座,149,149,812.18,"2025-07-27 16:04:25"
|
||||
110,深圳,广州,"2025-08-12 12:24:00","2025-08-12 17:24:00",G708,商务座,277,277,1115.17,"2025-07-27 16:04:25"
|
||||
111,上海,深圳,"2025-08-03 13:15:00","2025-08-03 16:15:00",G136,二等座,241,241,196.91,"2025-07-27 16:04:25"
|
||||
112,广州,深圳,"2025-08-21 07:46:00","2025-08-21 12:46:00",G482,一等座,210,210,541.67,"2025-07-27 16:04:25"
|
||||
113,北京,深圳,"2025-08-20 19:53:00","2025-08-20 21:53:00",G374,二等座,147,147,239.14,"2025-07-27 16:04:25"
|
||||
114,上海,广州,"2025-08-24 13:04:00","2025-08-24 15:04:00",G516,二等座,127,127,404.41,"2025-07-27 16:04:25"
|
||||
115,广州,深圳,"2025-08-14 20:00:00","2025-08-15 01:00:00",G509,二等座,134,134,269.29,"2025-07-27 16:04:25"
|
||||
116,北京,深圳,"2025-08-23 08:24:00","2025-08-23 13:24:00",G944,二等座,179,179,449.69,"2025-07-27 16:04:25"
|
||||
117,广州,上海,"2025-08-26 16:34:00","2025-08-26 19:34:00",G292,商务座,246,246,943.47,"2025-07-27 16:04:25"
|
||||
118,广州,深圳,"2025-08-03 10:33:00","2025-08-03 14:33:00",G244,商务座,156,156,1042.67,"2025-07-27 16:04:25"
|
||||
119,上海,北京,"2025-08-05 18:54:00","2025-08-05 23:54:00",G132,商务座,220,220,1086.29,"2025-07-27 16:04:25"
|
||||
120,上海,广州,"2025-08-03 10:25:00","2025-08-03 13:25:00",G758,一等座,191,191,517.92,"2025-07-27 16:04:25"
|
||||
|
297
SmartVoyage/sql/weather_data_202601251130.csv
Normal file
297
SmartVoyage/sql/weather_data_202601251130.csv
Normal file
@@ -0,0 +1,297 @@
|
||||
"id","city","fx_date","sunrise","sunset","moonrise","moonset","moon_phase","moon_phase_icon","temp_max","temp_min","icon_day","text_day","icon_night","text_night","wind360_day","wind_dir_day","wind_scale_day","wind_speed_day","wind360_night","wind_dir_night","wind_scale_night","wind_speed_night","precip","uv_index","humidity","pressure","vis","cloud","update_time"
|
||||
241,北京,"2025-07-28","05:10:00","19:33:00","08:36:00","21:34:00",蛾眉月,"801",30,25,"302",雷阵雨,"307",大雨,225,西南风,"1-3",3,270,西风,"1-3",3,2.1,8,89,992,20,40,"2025-07-28 14:52:00"
|
||||
242,北京,"2025-07-29","05:11:00","19:33:00","09:39:00","21:54:00",蛾眉月,"801",33,24,"302",雷阵雨,"151",多云,270,西风,"1-3",3,45,东北风,"1-3",3,7.8,5,85,994,24,48,"2025-07-28 14:52:00"
|
||||
243,北京,"2025-07-30","05:11:00","19:32:00","10:40:00","22:13:00",蛾眉月,"801",32,24,"101",多云,"104",阴,90,东风,"1-3",3,45,东北风,"1-3",3,1.0,10,83,995,24,40,"2025-07-28 14:52:00"
|
||||
244,北京,"2025-07-31","05:12:00","19:31:00","11:40:00","22:34:00",蛾眉月,"801",30,24,"101",多云,"151",多云,135,东南风,"1-3",3,45,东北风,"1-3",3,1.0,5,88,996,24,40,"2025-07-28 14:52:00"
|
||||
245,北京,"2025-08-01","05:13:00","19:30:00","12:41:00","22:58:00",上弦月,"802",30,24,"104",阴,"104",阴,180,南风,"1-3",3,135,东南风,"1-3",3,0.0,9,69,995,24,25,"2025-07-28 14:52:00"
|
||||
246,北京,"2025-08-02","05:14:00","19:29:00","13:43:00","23:24:00",盈凸月,"803",32,24,"302",雷阵雨,"151",多云,135,东南风,"1-3",3,135,东南风,"1-3",3,0.0,9,72,992,22,2,"2025-07-28 14:52:00"
|
||||
247,北京,"2025-08-03","05:15:00","19:27:00","14:45:00","23:59:00",盈凸月,"803",32,24,"101",多云,"302",雷阵雨,225,西南风,"1-3",3,0,北风,"1-3",3,0.3,5,80,995,24,40,"2025-07-28 14:52:00"
|
||||
248,北京,"2025-08-04","05:16:00","19:26:00","15:46:00","00:00:00",盈凸月,"803",32,23,"305",小雨,"104",阴,135,东南风,"1-3",3,45,东北风,"1-3",3,16.7,9,90,993,20,85,"2025-07-28 14:52:00"
|
||||
249,北京,"2025-08-05","05:17:00","19:25:00","16:43:00","00:40:00",盈凸月,"803",32,24,"101",多云,"150",晴,180,南风,"1-3",3,45,东北风,"1-3",3,0.0,9,91,993,25,1,"2025-07-28 14:52:00"
|
||||
250,北京,"2025-08-06","05:18:00","19:24:00","17:34:00","01:29:00",盈凸月,"803",34,25,"104",阴,"104",阴,180,南风,"1-3",3,90,东风,"1-3",3,0.0,9,76,997,24,0,"2025-07-28 14:52:00"
|
||||
251,北京,"2025-08-07","05:19:00","19:23:00","18:18:00","02:28:00",盈凸月,"803",33,20,"305",小雨,"305",小雨,270,西风,"1-3",3,315,西北风,"1-3",3,0.0,5,82,1000,23,10,"2025-07-28 14:52:00"
|
||||
252,北京,"2025-08-08","05:20:00","19:22:00","18:55:00","03:34:00",盈凸月,"803",31,18,"101",多云,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,0.0,9,89,1000,22,15,"2025-07-28 14:52:00"
|
||||
253,北京,"2025-08-09","05:21:00","19:21:00","19:26:00","04:44:00",满月,"804",30,18,"104",阴,"150",晴,0,北风,"1-3",3,0,北风,"1-3",3,0.6,9,85,999,24,56,"2025-07-28 14:52:00"
|
||||
254,北京,"2025-08-10","05:22:00","19:19:00","19:54:00","05:55:00",亏凸月,"805",34,20,"101",多云,"104",阴,225,西南风,"1-3",3,225,西南风,"1-3",3,0.0,8,72,997,25,20,"2025-07-28 14:52:00"
|
||||
255,北京,"2025-08-11","05:23:00","19:18:00","20:19:00","07:06:00",亏凸月,"805",33,24,"101",多云,"302",雷阵雨,180,南风,"1-3",3,180,南风,"1-3",3,0.0,9,88,999,24,6,"2025-08-11 20:18:00"
|
||||
256,北京,"2025-08-12","05:24:00","19:17:00","20:44:00","08:17:00",亏凸月,"805",31,22,"302",雷阵雨,"306",中雨,90,东风,"1-3",3,0,北风,"1-3",3,5.0,5,94,1003,24,80,"2025-08-11 20:18:00"
|
||||
257,北京,"2025-08-13","05:25:00","19:16:00","21:08:00","09:29:00",亏凸月,"805",31,23,"302",雷阵雨,"151",多云,225,西南风,"1-3",3,0,北风,"1-3",3,0.0,3,94,1005,24,25,"2025-08-11 20:18:00"
|
||||
258,北京,"2025-08-14","05:26:00","19:14:00","21:36:00","10:44:00",亏凸月,"805",31,23,"104",阴,"302",雷阵雨,180,南风,"1-3",3,135,东南风,"1-3",3,0.0,9,95,1005,19,25,"2025-08-11 20:18:00"
|
||||
259,北京,"2025-08-15","05:27:00","19:13:00","22:07:00","12:02:00",亏凸月,"805",31,23,"101",多云,"302",雷阵雨,180,南风,"1-3",3,135,东南风,"1-3",3,0.0,5,91,1002,24,14,"2025-08-11 20:18:00"
|
||||
260,北京,"2025-08-16","05:28:00","19:12:00","22:46:00","13:19:00",下弦月,"806",31,24,"302",雷阵雨,"302",雷阵雨,180,南风,"1-3",3,180,南风,"1-3",3,4.9,3,92,1002,23,88,"2025-08-11 20:18:00"
|
||||
261,北京,"2025-08-17","05:29:00","19:10:00","23:34:00","14:37:00",残月,"807",31,24,"302",雷阵雨,"104",阴,180,南风,"1-3",3,180,南风,"1-3",3,1.0,2,95,998,22,55,"2025-08-11 20:18:00"
|
||||
262,北京,"2025-08-18","05:30:00","19:09:00","00:00:00","15:50:00",残月,"807",30,24,"104",阴,"305",小雨,180,南风,"1-3",3,0,北风,"1-3",3,2.5,2,90,998,25,55,"2025-08-11 20:18:00"
|
||||
263,北京,"2025-08-19","05:31:00","19:08:00","00:33:00","16:52:00",残月,"807",31,23,"104",阴,"305",小雨,90,东风,"1-3",3,0,北风,"1-3",3,4.6,2,97,996,7,55,"2025-08-11 20:18:00"
|
||||
264,北京,"2025-08-20","05:31:00","19:06:00","01:40:00","17:41:00",残月,"807",31,23,"305",小雨,"305",小雨,45,东北风,"1-3",3,45,东北风,"1-3",3,0.0,4,97,996,12,10,"2025-08-11 20:18:00"
|
||||
265,北京,"2025-08-21","05:32:00","19:05:00","02:53:00","18:19:00",残月,"807",28,23,"305",小雨,"305",小雨,180,南风,"1-3",3,0,北风,"1-3",3,22.4,1,81,1005,24,80,"2025-08-11 20:18:00"
|
||||
266,北京,"2025-08-22","05:33:00","19:03:00","04:05:00","18:51:00",残月,"807",29,19,"104",阴,"104",阴,45,东北风,"1-3",16,135,东南风,"1-3",3,0.0,8,77,1009,24,2,"2025-08-11 20:18:00"
|
||||
267,北京,"2025-08-23","05:34:00","19:02:00","05:16:00","19:16:00",新月,"800",26,19,"101",多云,"104",阴,180,南风,"1-3",3,180,南风,"1-3",3,5.9,4,90,1008,20,65,"2025-08-11 20:18:00"
|
||||
268,北京,"2025-08-24","05:35:00","19:00:00","06:23:00","19:38:00",蛾眉月,"801",28,21,"104",阴,"305",小雨,180,南风,"1-3",3,0,北风,"1-3",3,0.6,2,92,1006,16,56,"2025-08-11 20:18:00"
|
||||
269,北京,"2025-08-25","05:36:00","18:59:00","07:27:00","19:59:00",蛾眉月,"801",23,20,"305",小雨,"104",阴,0,北风,"1-3",3,0,北风,"1-3",3,1.4,2,99,1000,12,55,"2025-08-11 20:18:00"
|
||||
270,北京,"2025-08-26","05:37:00","18:57:00","08:29:00","20:17:00",蛾眉月,"801",27,21,"302",雷阵雨,"302",雷阵雨,122,东南风,"1-3",7,145,东南风,"1-3",11,11.2,2,91,1003,24,69,"2025-08-11 20:18:00"
|
||||
271,上海,"2025-07-28","05:09:00","18:54:00","08:21:00","21:10:00",蛾眉月,"801",31,25,"305",小雨,"305",小雨,90,东风,"1-3",16,90,东风,"1-3",3,3.8,5,80,999,24,78,"2025-07-28 14:52:00"
|
||||
272,上海,"2025-07-29","05:09:00","18:53:00","09:18:00","21:35:00",蛾眉月,"801",29,26,"310",暴雨,"306",中雨,135,东南风,"1-3",16,90,东风,"1-3",16,28.0,3,95,995,4,98,"2025-07-28 14:52:00"
|
||||
273,上海,"2025-07-30","05:10:00","18:52:00","10:13:00","22:01:00",蛾眉月,"801",29,26,"307",大雨,"307",大雨,135,东南风,"1-3",16,135,东南风,"1-3",16,10.4,6,95,990,12,87,"2025-07-28 14:52:00"
|
||||
274,上海,"2025-07-31","05:11:00","18:52:00","11:08:00","22:26:00",蛾眉月,"801",31,27,"305",小雨,"305",小雨,135,东南风,"1-3",16,135,东南风,"1-3",16,1.0,11,93,996,24,40,"2025-07-28 14:52:00"
|
||||
275,上海,"2025-08-01","05:11:00","18:51:00","12:03:00","22:56:00",上弦月,"802",32,28,"305",小雨,"104",阴,135,东南风,"1-3",16,135,东南风,"1-3",16,0.7,9,96,996,23,56,"2025-07-28 14:52:00"
|
||||
276,上海,"2025-08-02","05:12:00","18:50:00","12:59:00","23:27:00",盈凸月,"803",32,27,"305",小雨,"305",小雨,135,东南风,"1-3",16,90,东风,"1-3",3,2.5,5,91,998,24,41,"2025-07-28 14:52:00"
|
||||
277,上海,"2025-08-03","05:13:00","18:50:00","13:57:00","00:00:00",盈凸月,"803",33,28,"104",阴,"151",多云,135,东南风,"1-3",3,0,北风,"1-3",3,2.4,8,84,1001,25,43,"2025-07-28 14:52:00"
|
||||
278,上海,"2025-08-04","05:13:00","18:49:00","14:54:00","00:05:00",盈凸月,"803",34,28,"305",小雨,"151",多云,135,东南风,"1-3",3,180,南风,"1-3",3,0.0,8,81,1001,24,25,"2025-07-28 14:52:00"
|
||||
279,上海,"2025-08-05","05:14:00","18:48:00","15:50:00","00:50:00",盈凸月,"803",35,28,"100",晴,"104",阴,135,东南风,"1-3",3,225,西南风,"1-3",3,1.8,8,83,1000,25,63,"2025-07-28 14:52:00"
|
||||
280,上海,"2025-08-06","05:15:00","18:47:00","16:42:00","01:40:00",盈凸月,"803",35,29,"305",小雨,"104",阴,180,南风,"1-3",3,90,东风,"1-3",3,8.5,7,89,1001,24,64,"2025-07-28 14:52:00"
|
||||
281,上海,"2025-08-07","05:15:00","18:46:00","17:29:00","02:38:00",盈凸月,"803",35,28,"104",阴,"104",阴,90,东风,"1-3",3,90,东风,"1-3",3,8.5,5,91,1001,24,64,"2025-07-28 14:52:00"
|
||||
282,上海,"2025-08-08","05:16:00","18:45:00","18:11:00","03:39:00",盈凸月,"803",38,29,"104",阴,"104",阴,45,东北风,"1-3",3,90,东风,"1-3",3,7.3,5,95,999,24,61,"2025-07-28 14:52:00"
|
||||
283,上海,"2025-08-09","05:17:00","18:44:00","18:48:00","04:44:00",满月,"804",37,28,"305",小雨,"305",小雨,90,东风,"1-3",3,0,北风,"1-3",3,0.0,4,95,996,23,25,"2025-07-28 14:52:00"
|
||||
284,上海,"2025-08-10","05:17:00","18:44:00","19:22:00","05:49:00",亏凸月,"805",33,28,"305",小雨,"305",小雨,0,北风,"1-3",3,270,西风,"1-3",3,12.1,3,96,997,15,65,"2025-07-28 14:52:00"
|
||||
285,上海,"2025-08-11","05:18:00","18:43:00","19:53:00","06:54:00",亏凸月,"805",35,27,"305",小雨,"305",小雨,45,东北风,"1-3",3,90,东风,"1-3",3,4.1,7,94,1005,24,55,"2025-08-11 20:18:00"
|
||||
286,上海,"2025-08-12","05:18:00","18:42:00","20:24:00","07:59:00",亏凸月,"805",35,28,"305",小雨,"104",阴,180,南风,"1-3",3,180,南风,"1-3",3,3.3,3,82,1008,24,88,"2025-08-11 20:18:00"
|
||||
287,上海,"2025-08-13","05:19:00","18:41:00","20:55:00","09:04:00",亏凸月,"805",35,28,"104",阴,"104",阴,180,南风,"1-3",3,180,南风,"1-3",16,0.0,11,83,1011,25,5,"2025-08-11 20:18:00"
|
||||
288,上海,"2025-08-14","05:20:00","18:40:00","21:29:00","10:11:00",亏凸月,"805",35,28,"104",阴,"104",阴,135,东南风,"1-3",16,180,南风,"1-3",16,0.0,9,82,1011,25,4,"2025-08-11 20:18:00"
|
||||
289,上海,"2025-08-15","05:20:00","18:39:00","22:07:00","11:21:00",亏凸月,"805",35,27,"101",多云,"104",阴,135,东南风,"1-3",16,135,东南风,"1-3",3,0.0,11,82,1011,25,2,"2025-08-11 20:18:00"
|
||||
290,上海,"2025-08-16","05:21:00","18:38:00","22:52:00","12:33:00",下弦月,"806",35,27,"104",阴,"104",阴,135,东南风,"1-3",16,135,东南风,"1-3",3,0.0,11,85,1011,25,2,"2025-08-11 20:18:00"
|
||||
291,上海,"2025-08-17","05:22:00","18:37:00","23:44:00","13:46:00",残月,"807",35,27,"104",阴,"104",阴,135,东南风,"1-3",3,180,南风,"1-3",3,0.0,10,83,1009,25,3,"2025-08-11 20:18:00"
|
||||
292,上海,"2025-08-18","05:22:00","18:36:00","00:00:00","14:56:00",残月,"807",36,28,"104",阴,"150",晴,135,东南风,"1-3",3,180,南风,"1-3",3,0.0,10,83,1008,25,3,"2025-08-11 20:18:00"
|
||||
293,上海,"2025-08-19","05:23:00","18:35:00","00:44:00","15:59:00",残月,"807",35,27,"101",多云,"150",晴,135,东南风,"1-3",16,135,东南风,"1-3",3,0.0,10,82,1005,25,2,"2025-08-11 20:18:00"
|
||||
294,上海,"2025-08-20","05:24:00","18:34:00","01:50:00","16:52:00",残月,"807",35,27,"100",晴,"150",晴,135,东南风,"1-3",16,135,东南风,"1-3",3,0.3,10,72,1004,25,55,"2025-08-11 20:18:00"
|
||||
295,上海,"2025-08-21","05:24:00","18:32:00","02:58:00","17:35:00",残月,"807",34,27,"100",晴,"151",多云,135,东南风,"3-4",24,135,东南风,"1-3",16,0.0,10,77,1007,25,1,"2025-08-11 20:18:00"
|
||||
296,上海,"2025-08-22","05:25:00","18:31:00","04:06:00","18:12:00",残月,"807",34,28,"101",多云,"151",多云,135,东南风,"3-4",24,135,东南风,"1-3",16,0.0,10,75,1009,25,1,"2025-08-11 20:18:00"
|
||||
297,上海,"2025-08-23","05:25:00","18:30:00","05:10:00","18:44:00",新月,"800",34,27,"101",多云,"151",多云,135,东南风,"1-3",16,135,东南风,"1-3",16,0.0,6,81,1011,25,25,"2025-08-11 20:18:00"
|
||||
298,上海,"2025-08-24","05:26:00","18:29:00","06:11:00","19:12:00",蛾眉月,"801",34,27,"101",多云,"151",多云,135,东南风,"1-3",16,135,东南风,"1-3",16,3.2,10,83,1011,25,65,"2025-08-11 20:18:00"
|
||||
299,上海,"2025-08-25","05:27:00","18:28:00","07:08:00","19:38:00",蛾眉月,"801",35,26,"100",晴,"150",晴,135,东南风,"1-3",16,135,东南风,"1-3",16,2.2,4,83,1008,25,65,"2025-08-11 20:18:00"
|
||||
300,上海,"2025-08-26","05:27:00","18:27:00","08:04:00","20:03:00",蛾眉月,"801",31,25,"302",雷阵雨,"350",阵雨,131,东南风,"3-4",26,132,东南风,"3-4",24,2.9,5,81,1008,25,65,"2025-08-11 20:18:00"
|
||||
301,广州,"2025-07-28","05:56:00","19:12:00","09:00:00","21:41:00",蛾眉月,"801",35,25,"315",中到大雨,"315",中到大雨,0,北风,"1-3",3,0,北风,"1-3",3,15.1,5,81,994,24,92,"2025-07-28 14:52:00"
|
||||
302,广州,"2025-07-29","05:57:00","19:11:00","09:52:00","22:10:00",蛾眉月,"801",33,25,"315",中到大雨,"302",雷阵雨,0,北风,"1-3",3,0,北风,"1-3",3,5.9,4,78,994,21,78,"2025-07-28 14:52:00"
|
||||
303,广州,"2025-07-30","05:57:00","19:11:00","10:43:00","22:40:00",蛾眉月,"801",33,26,"302",雷阵雨,"302",雷阵雨,0,北风,"1-3",3,0,北风,"1-3",3,12.0,3,77,994,22,88,"2025-07-28 14:52:00"
|
||||
304,广州,"2025-07-31","05:58:00","19:10:00","11:34:00","23:10:00",蛾眉月,"801",34,26,"302",雷阵雨,"302",雷阵雨,0,北风,"1-3",3,0,北风,"1-3",3,8.9,12,74,996,24,76,"2025-07-28 14:52:00"
|
||||
305,广州,"2025-08-01","05:58:00","19:10:00","12:25:00","23:43:00",上弦月,"802",34,26,"302",雷阵雨,"302",雷阵雨,0,北风,"1-3",3,0,北风,"1-3",3,4.2,3,77,997,19,71,"2025-07-28 14:52:00"
|
||||
306,广州,"2025-08-02","05:58:00","19:09:00","13:17:00","00:00:00",盈凸月,"803",33,25,"302",雷阵雨,"302",雷阵雨,0,北风,"1-3",3,0,北风,"1-3",3,4.5,3,82,999,18,60,"2025-07-28 14:52:00"
|
||||
307,广州,"2025-08-03","05:59:00","19:09:00","14:11:00","00:19:00",盈凸月,"803",30,26,"307",大雨,"307",大雨,0,北风,"1-3",3,0,北风,"1-3",3,24.1,3,83,1002,21,69,"2025-07-28 14:52:00"
|
||||
308,广州,"2025-08-04","05:59:00","19:08:00","15:05:00","01:01:00",盈凸月,"803",29,25,"305",小雨,"305",小雨,180,南风,"1-3",3,225,西南风,"1-3",3,21.7,4,73,1002,24,68,"2025-07-28 14:52:00"
|
||||
309,广州,"2025-08-05","06:00:00","19:08:00","15:59:00","01:47:00",盈凸月,"803",31,26,"305",小雨,"305",小雨,90,东风,"1-3",3,180,南风,"1-3",3,9.8,3,68,1001,25,64,"2025-07-28 14:52:00"
|
||||
310,广州,"2025-08-06","06:00:00","19:07:00","16:52:00","02:39:00",盈凸月,"803",32,27,"305",小雨,"305",小雨,135,东南风,"1-3",3,180,南风,"1-3",3,1.6,11,70,1001,25,56,"2025-07-28 14:52:00"
|
||||
311,广州,"2025-08-07","06:01:00","19:06:00","17:42:00","03:34:00",盈凸月,"803",33,27,"305",小雨,"104",阴,180,南风,"1-3",3,180,南风,"1-3",3,1.8,5,71,1002,25,57,"2025-07-28 14:52:00"
|
||||
312,广州,"2025-08-08","06:01:00","19:06:00","18:27:00","04:34:00",盈凸月,"803",32,27,"104",阴,"104",阴,135,东南风,"1-3",3,180,南风,"1-3",3,2.0,6,71,1000,24,40,"2025-07-28 14:52:00"
|
||||
313,广州,"2025-08-09","06:01:00","19:05:00","19:08:00","05:34:00",满月,"804",33,27,"305",小雨,"305",小雨,225,西南风,"1-3",3,180,南风,"1-3",3,0.0,5,73,998,22,25,"2025-07-28 14:52:00"
|
||||
314,广州,"2025-08-10","06:02:00","19:04:00","19:46:00","06:35:00",亏凸月,"805",34,27,"305",小雨,"305",小雨,270,西风,"1-3",3,180,南风,"1-3",3,0.0,4,73,998,23,25,"2025-07-28 14:52:00"
|
||||
315,广州,"2025-08-11","06:02:00","19:04:00","20:23:00","07:34:00",亏凸月,"805",35,26,"101",多云,"350",阵雨,0,北风,"1-3",3,0,北风,"1-3",3,3.7,6,71,1004,24,80,"2025-08-11 20:18:00"
|
||||
316,广州,"2025-08-12","06:03:00","19:03:00","20:58:00","08:34:00",亏凸月,"805",35,26,"302",雷阵雨,"350",阵雨,0,北风,"1-3",3,0,北风,"1-3",3,8.4,6,76,1005,24,89,"2025-08-11 20:18:00"
|
||||
317,广州,"2025-08-13","06:03:00","19:02:00","21:35:00","09:34:00",亏凸月,"805",35,24,"302",雷阵雨,"302",雷阵雨,0,北风,"1-3",3,0,北风,"1-3",3,2.0,12,77,1001,22,80,"2025-08-11 20:18:00"
|
||||
318,广州,"2025-08-14","06:04:00","19:02:00","22:14:00","10:37:00",亏凸月,"805",29,24,"307",大雨,"307",大雨,180,南风,"1-3",16,0,北风,"1-3",3,15.1,4,89,1005,16,95,"2025-08-11 20:18:00"
|
||||
319,广州,"2025-08-15","06:04:00","19:01:00","22:57:00","11:42:00",亏凸月,"805",31,24,"307",大雨,"302",雷阵雨,0,北风,"1-3",3,0,北风,"1-3",3,7.6,3,82,1007,24,75,"2025-08-11 20:18:00"
|
||||
320,广州,"2025-08-16","06:04:00","19:00:00","23:46:00","12:49:00",下弦月,"806",33,26,"302",雷阵雨,"302",雷阵雨,0,北风,"1-3",3,0,北风,"1-3",3,0.7,8,68,1006,24,62,"2025-08-11 20:18:00"
|
||||
321,广州,"2025-08-17","06:05:00","18:59:00","00:00:00","13:58:00",残月,"807",34,26,"302",雷阵雨,"302",雷阵雨,0,北风,"1-3",3,0,北风,"1-3",3,0.0,11,67,1006,24,25,"2025-08-11 20:18:00"
|
||||
322,广州,"2025-08-18","06:05:00","18:58:00","00:42:00","15:06:00",残月,"807",34,24,"305",小雨,"151",多云,0,北风,"1-3",3,45,东北风,"1-3",3,2.9,7,66,1002,24,70,"2025-08-11 20:18:00"
|
||||
323,广州,"2025-08-19","06:05:00","18:58:00","01:43:00","16:08:00",残月,"807",28,24,"305",小雨,"305",小雨,90,东风,"1-3",3,90,东风,"1-3",3,8.3,4,85,1002,10,62,"2025-08-11 20:18:00"
|
||||
324,广州,"2025-08-20","06:06:00","18:57:00","02:48:00","17:04:00",残月,"807",28,24,"305",小雨,"305",小雨,180,南风,"1-3",3,90,东风,"1-3",3,2.0,6,89,1002,13,55,"2025-08-11 20:18:00"
|
||||
325,广州,"2025-08-21","06:06:00","18:56:00","03:53:00","17:52:00",残月,"807",26,24,"305",小雨,"305",小雨,180,南风,"1-3",3,135,东南风,"1-3",3,0.7,11,91,1003,13,56,"2025-08-11 20:18:00"
|
||||
326,广州,"2025-08-22","06:07:00","18:55:00","04:56:00","18:33:00",残月,"807",27,23,"305",小雨,"305",小雨,180,南风,"1-3",3,180,南风,"1-3",3,2.9,10,91,1004,17,75,"2025-08-11 20:18:00"
|
||||
327,广州,"2025-08-23","06:07:00","18:54:00","05:56:00","19:09:00",新月,"800",23,22,"305",小雨,"305",小雨,135,东南风,"1-3",3,45,东北风,"1-3",3,1.4,3,92,1005,24,62,"2025-08-11 20:18:00"
|
||||
328,广州,"2025-08-24","06:07:00","18:53:00","06:52:00","19:41:00",蛾眉月,"801",24,22,"305",小雨,"305",小雨,45,东北风,"1-3",3,45,东北风,"1-3",3,0.0,11,91,1004,24,20,"2025-08-11 20:18:00"
|
||||
329,广州,"2025-08-25","06:08:00","18:53:00","07:45:00","20:11:00",蛾眉月,"801",25,22,"305",小雨,"305",小雨,90,东风,"1-3",3,45,东北风,"1-3",3,0.0,11,77,1003,24,25,"2025-08-11 20:18:00"
|
||||
330,广州,"2025-08-26","06:08:00","18:52:00","08:37:00","20:41:00",蛾眉月,"801",33,25,"101",多云,"153",晴间多云,52,东北风,"1-3",13,78,东北风,"1-3",6,5.3,4,71,1003,24,58,"2025-08-11 20:18:00"
|
||||
331,深圳,"2025-07-28","05:54:00","19:08:00","08:57:00","21:37:00",蛾眉月,"801",32,26,"300",阵雨,"350",阵雨,0,北风,"1-3",3,0,北风,"1-3",3,14.2,5,84,987,24,90,"2025-07-28 14:52:00"
|
||||
332,深圳,"2025-07-29","05:54:00","19:07:00","09:49:00","22:07:00",蛾眉月,"801",32,26,"306",中雨,"307",大雨,0,北风,"1-3",3,0,北风,"1-3",3,10.9,3,84,987,24,94,"2025-07-28 14:52:00"
|
||||
333,深圳,"2025-07-30","05:55:00","19:07:00","10:40:00","22:37:00",蛾眉月,"801",32,26,"307",大雨,"350",阵雨,0,北风,"1-3",3,0,北风,"1-3",3,22.5,3,88,988,24,97,"2025-07-28 14:52:00"
|
||||
334,深圳,"2025-07-31","05:55:00","19:06:00","11:30:00","23:08:00",蛾眉月,"801",30,26,"300",阵雨,"350",阵雨,0,北风,"1-3",3,0,北风,"1-3",3,3.8,6,87,990,24,70,"2025-07-28 14:52:00"
|
||||
335,深圳,"2025-08-01","05:56:00","19:06:00","12:20:00","23:41:00",上弦月,"802",32,27,"300",阵雨,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,9.7,11,87,991,21,84,"2025-07-28 14:52:00"
|
||||
336,深圳,"2025-08-02","05:56:00","19:05:00","13:12:00","00:00:00",盈凸月,"803",32,27,"300",阵雨,"350",阵雨,0,北风,"1-3",3,225,西南风,"1-3",16,21.2,5,84,993,24,74,"2025-07-28 14:52:00"
|
||||
337,深圳,"2025-08-03","05:57:00","19:05:00","14:06:00","00:17:00",盈凸月,"803",30,26,"104",阴,"310",暴雨,0,北风,"1-3",3,0,北风,"1-3",3,26.1,4,83,995,23,70,"2025-07-28 14:52:00"
|
||||
338,深圳,"2025-08-04","05:57:00","19:04:00","15:00:00","00:59:00",盈凸月,"803",30,27,"305",小雨,"305",小雨,180,南风,"1-3",3,225,西南风,"1-3",3,21.5,2,86,996,24,72,"2025-07-28 14:52:00"
|
||||
339,深圳,"2025-08-05","05:57:00","19:03:00","15:55:00","01:45:00",盈凸月,"803",30,27,"305",小雨,"305",小雨,180,南风,"1-3",3,225,西南风,"1-3",3,15.2,3,87,995,25,72,"2025-07-28 14:52:00"
|
||||
340,深圳,"2025-08-06","05:58:00","19:03:00","16:48:00","02:37:00",盈凸月,"803",30,28,"305",小雨,"305",小雨,180,南风,"1-3",3,180,南风,"1-3",3,2.2,7,87,995,22,55,"2025-07-28 14:52:00"
|
||||
341,深圳,"2025-08-07","05:58:00","19:02:00","17:37:00","03:33:00",盈凸月,"803",31,28,"305",小雨,"305",小雨,180,南风,"1-3",16,180,南风,"1-3",3,0.4,5,87,996,24,43,"2025-07-28 14:52:00"
|
||||
342,深圳,"2025-08-08","05:59:00","19:02:00","18:22:00","04:32:00",盈凸月,"803",31,28,"305",小雨,"305",小雨,180,南风,"1-3",3,225,西南风,"1-3",3,0.3,6,87,994,24,41,"2025-07-28 14:52:00"
|
||||
343,深圳,"2025-08-09","05:59:00","19:01:00","19:03:00","05:32:00",满月,"804",30,27,"305",小雨,"305",小雨,225,西南风,"1-3",16,225,西南风,"1-3",3,0.0,3,88,992,22,25,"2025-07-28 14:52:00"
|
||||
344,深圳,"2025-08-10","05:59:00","19:00:00","19:43:00","06:32:00",亏凸月,"805",30,27,"305",小雨,"305",小雨,225,西南风,"1-3",16,180,南风,"1-3",3,0.0,3,83,992,18,25,"2025-07-28 14:52:00"
|
||||
345,深圳,"2025-08-11","06:00:00","19:00:00","20:19:00","07:31:00",亏凸月,"805",33,27,"300",阵雨,"350",阵雨,0,北风,"1-3",3,0,北风,"1-3",3,10.1,6,86,997,23,100,"2025-08-11 20:18:00"
|
||||
346,深圳,"2025-08-12","06:00:00","18:59:00","20:55:00","08:31:00",亏凸月,"805",33,27,"300",阵雨,"150",晴,0,北风,"1-3",3,0,北风,"1-3",3,7.6,5,86,999,24,75,"2025-08-11 20:18:00"
|
||||
347,深圳,"2025-08-13","06:01:00","18:58:00","21:32:00","09:31:00",亏凸月,"805",33,27,"300",阵雨,"350",阵雨,0,北风,"1-3",3,225,西南风,"1-3",16,6.0,7,83,995,22,69,"2025-08-11 20:18:00"
|
||||
348,深圳,"2025-08-14","06:01:00","18:58:00","22:11:00","10:33:00",亏凸月,"805",30,26,"300",阵雨,"350",阵雨,225,西南风,"1-3",16,0,北风,"1-3",3,17.3,2,83,999,24,96,"2025-08-11 20:18:00"
|
||||
349,深圳,"2025-08-15","06:01:00","18:57:00","22:55:00","11:37:00",亏凸月,"805",31,26,"300",阵雨,"350",阵雨,0,北风,"1-3",3,0,北风,"1-3",3,4.8,3,81,1000,24,74,"2025-08-11 20:18:00"
|
||||
350,深圳,"2025-08-16","06:02:00","18:56:00","23:44:00","12:45:00",下弦月,"806",33,27,"300",阵雨,"350",阵雨,0,北风,"1-3",3,0,北风,"1-3",3,1.5,9,80,1000,25,68,"2025-08-11 20:18:00"
|
||||
351,深圳,"2025-08-17","06:02:00","18:55:00","00:00:00","13:53:00",残月,"807",32,26,"300",阵雨,"350",阵雨,0,北风,"1-3",3,0,北风,"1-3",3,2.1,12,82,999,24,61,"2025-08-11 20:18:00"
|
||||
352,深圳,"2025-08-18","06:03:00","18:55:00","00:40:00","15:01:00",残月,"807",31,25,"305",小雨,"305",小雨,0,北风,"1-3",3,90,东风,"1-3",3,6.7,4,80,995,20,62,"2025-08-11 20:18:00"
|
||||
353,深圳,"2025-08-19","06:03:00","18:54:00","01:41:00","16:03:00",残月,"807",29,26,"305",小雨,"305",小雨,90,东风,"1-3",3,90,东风,"1-3",3,3.1,3,93,996,7,62,"2025-08-11 20:18:00"
|
||||
354,深圳,"2025-08-20","06:03:00","18:53:00","02:46:00","16:59:00",残月,"807",28,25,"305",小雨,"305",小雨,90,东风,"1-3",3,90,东风,"1-3",3,1.3,10,92,996,9,59,"2025-08-11 20:18:00"
|
||||
355,深圳,"2025-08-21","06:04:00","18:52:00","03:51:00","17:47:00",残月,"807",27,25,"305",小雨,"305",小雨,180,南风,"1-3",3,225,西南风,"1-3",3,0.5,12,92,997,18,55,"2025-08-11 20:18:00"
|
||||
356,深圳,"2025-08-22","06:04:00","18:51:00","04:54:00","18:28:00",残月,"807",26,24,"305",小雨,"305",小雨,180,南风,"1-3",3,135,东南风,"1-3",3,0.4,10,90,998,20,55,"2025-08-11 20:18:00"
|
||||
357,深圳,"2025-08-23","06:04:00","18:50:00","05:53:00","19:05:00",新月,"800",25,23,"305",小雨,"305",小雨,180,南风,"1-3",3,45,东北风,"1-3",3,1.0,11,94,997,13,41,"2025-08-11 20:18:00"
|
||||
358,深圳,"2025-08-24","06:05:00","18:50:00","06:49:00","19:37:00",蛾眉月,"801",25,23,"305",小雨,"305",小雨,45,东北风,"1-3",16,90,东风,"3-4",24,0.7,11,88,996,24,41,"2025-08-11 20:18:00"
|
||||
359,深圳,"2025-08-25","06:05:00","18:49:00","07:42:00","20:08:00",蛾眉月,"801",25,23,"305",小雨,"305",小雨,90,东风,"3-4",24,90,东风,"1-3",16,1.3,11,77,995,24,61,"2025-08-11 20:18:00"
|
||||
360,深圳,"2025-08-26","06:05:00","18:48:00","08:33:00","20:38:00",蛾眉月,"801",33,27,"103",晴间多云,"151",多云,55,东北风,"1-3",7,98,东风,"1-3",15,2.5,5,81,996,22,57,"2025-08-11 20:18:00"
|
||||
377,北京,"2025-08-27","05:38:00","18:56:00","09:30:00","20:38:00",蛾眉月,"801",28,21,"302",雷阵雨,"350",阵雨,235,西南风,"1-3",6,217,西南风,"1-3",7,6.3,2,67,1005,25,65,"2025-08-11 20:18:00"
|
||||
378,北京,"2025-08-28","05:39:00","18:54:00","10:31:00","21:01:00",蛾眉月,"801",30,21,"101",多云,"151",多云,45,东北风,"1-3",7,342,西北风,"1-3",9,0.0,3,90,1003,19,25,"2025-08-11 20:18:00"
|
||||
379,北京,"2025-08-29","05:40:00","18:53:00","11:33:00","21:26:00",蛾眉月,"801",26,18,"305",小雨,"305",小雨,353,北风,"1-3",15,165,东南风,"1-3",11,10.3,2,89,1001,19,64,"2025-08-11 20:18:00"
|
||||
380,北京,"2025-08-30","05:41:00","18:51:00","12:35:00","21:58:00",蛾眉月,"801",26,17,"101",多云,"153",晴间多云,340,西北风,"1-3",4,276,西风,"1-3",6,0.0,2,89,1003,18,25,"2025-08-11 20:18:00"
|
||||
381,北京,"2025-08-31","05:42:00","18:50:00","13:36:00","22:35:00",上弦月,"802",25,16,"100",晴,"150",晴,281,西风,"1-3",7,230,西南风,"1-3",7,0.0,7,89,1003,20,10,"2025-08-11 20:18:00"
|
||||
382,北京,"2025-09-01","05:43:00","18:48:00","14:35:00","23:22:00",盈凸月,"803",26,16,"100",晴,"150",晴,323,西北风,"1-3",4,286,西北风,"1-3",6,0.0,7,89,1004,21,10,"2025-08-11 20:18:00"
|
||||
383,北京,"2025-09-02","05:44:00","18:47:00","15:28:00","00:00:00",盈凸月,"803",28,17,"100",晴,"150",晴,338,西北风,"1-3",17,292,西北风,"1-3",7,0.0,7,91,1000,20,20,"2025-08-11 20:18:00"
|
||||
384,北京,"2025-09-03","05:45:00","18:45:00","16:14:00","00:17:00",盈凸月,"803",27,16,"100",晴,"150",晴,27,东北风,"1-3",7,79,东风,"1-3",7,0.0,7,89,1001,20,5,"2025-08-11 20:18:00"
|
||||
385,北京,"2025-09-04","05:46:00","18:43:00","16:53:00","01:20:00",盈凸月,"803",26,17,"101",多云,"151",多云,35,东北风,"1-3",7,93,东风,"1-3",7,0.0,7,88,1003,19,25,"2025-08-11 20:18:00"
|
||||
386,北京,"2025-09-05","05:47:00","18:42:00","17:26:00","02:28:00",盈凸月,"803",26,18,"300",阵雨,"151",多云,100,东风,"1-3",15,117,东南风,"1-3",15,1.1,1,88,1001,21,58,"2025-08-11 20:18:00"
|
||||
387,北京,"2025-09-06","05:48:00","18:40:00","17:55:00","03:38:00",盈凸月,"803",25,18,"101",多云,"350",阵雨,121,东南风,"1-3",15,159,东南风,"1-3",15,0.0,3,91,1001,21,25,"2025-08-11 20:18:00"
|
||||
388,北京,"2025-09-07","05:48:00","18:39:00","18:21:00","04:50:00",盈凸月,"803",25,17,"302",雷阵雨,"350",阵雨,162,东南风,"1-3",15,95,东风,"1-3",15,3.0,2,89,1002,19,65,"2025-08-11 20:18:00"
|
||||
389,北京,"2025-09-08","05:49:00","18:37:00","18:45:00","06:01:00",满月,"804",25,17,"102",少云,"150",晴,321,西北风,"1-3",4,127,东南风,"1-3",6,0.0,6,89,1003,22,20,"2025-08-11 20:18:00"
|
||||
390,北京,"2025-09-09","05:50:00","18:35:00","19:09:00","07:12:00",亏凸月,"805",25,16,"103",晴间多云,"350",阵雨,43,东北风,"1-3",4,42,东北风,"1-3",4,0.0,3,90,1001,20,25,"2025-08-11 20:18:00"
|
||||
467,上海,"2025-08-27","05:28:00","18:26:00","08:59:00","20:29:00",蛾眉月,"801",31,25,"103",晴间多云,"153",晴间多云,139,东南风,"3-4",26,129,东南风,"3-4",24,1.9,10,50,1008,25,55,"2025-08-11 20:18:00"
|
||||
468,上海,"2025-08-28","05:28:00","18:24:00","09:55:00","20:57:00",蛾眉月,"801",31,25,"102",少云,"150",晴,136,东南风,"3-4",20,135,东南风,"3-4",20,0.0,9,79,1009,24,25,"2025-08-11 20:18:00"
|
||||
469,上海,"2025-08-29","05:29:00","18:23:00","10:51:00","21:27:00",蛾眉月,"801",31,25,"102",少云,"151",多云,156,东南风,"1-3",17,153,东南风,"1-3",19,0.0,9,79,1006,24,20,"2025-08-11 20:18:00"
|
||||
470,上海,"2025-08-30","05:30:00","18:22:00","11:48:00","22:03:00",蛾眉月,"801",31,25,"302",雷阵雨,"302",雷阵雨,160,东南风,"1-3",9,68,东北风,"1-3",7,5.7,2,81,1009,24,65,"2025-08-11 20:18:00"
|
||||
471,上海,"2025-08-31","05:30:00","18:21:00","12:46:00","22:45:00",上弦月,"802",30,25,"302",雷阵雨,"151",多云,343,西北风,"1-3",6,348,西北风,"1-3",9,13.4,3,78,1006,25,70,"2025-08-11 20:18:00"
|
||||
472,上海,"2025-09-01","05:31:00","18:20:00","13:42:00","23:33:00",盈凸月,"803",30,25,"302",雷阵雨,"302",雷阵雨,21,东北风,"1-3",13,47,东北风,"1-3",11,1.2,3,79,1008,24,61,"2025-08-11 20:18:00"
|
||||
473,上海,"2025-09-02","05:31:00","18:18:00","14:35:00","00:00:00",盈凸月,"803",29,23,"302",雷阵雨,"302",雷阵雨,44,东北风,"3-4",26,41,东北风,"3-4",26,9.0,2,80,1009,24,65,"2025-08-11 20:18:00"
|
||||
474,上海,"2025-09-03","05:32:00","18:17:00","15:24:00","00:28:00",盈凸月,"803",27,23,"302",雷阵雨,"151",多云,50,东北风,"1-3",19,35,东北风,"1-3",17,13.4,2,81,1008,25,70,"2025-08-11 20:18:00"
|
||||
475,上海,"2025-09-04","05:33:00","18:16:00","16:07:00","01:27:00",盈凸月,"803",27,22,"300",阵雨,"150",晴,20,东北风,"4-5",32,35,东北风,"4-5",30,1.4,2,80,1006,25,59,"2025-08-11 20:18:00"
|
||||
476,上海,"2025-09-05","05:33:00","18:15:00","16:46:00","02:31:00",盈凸月,"803",27,21,"101",多云,"151",多云,33,东北风,"3-4",28,12,东北风,"3-4",26,0.0,9,80,1010,25,20,"2025-08-11 20:18:00"
|
||||
477,上海,"2025-09-06","05:34:00","18:13:00","17:20:00","03:35:00",盈凸月,"803",28,21,"101",多云,"153",晴间多云,17,东北风,"1-3",13,62,东北风,"1-3",13,0.0,2,81,1009,24,25,"2025-08-11 20:18:00"
|
||||
478,上海,"2025-09-07","05:34:00","18:12:00","17:52:00","04:40:00",盈凸月,"803",28,21,"103",晴间多云,"151",多云,170,南风,"1-3",17,148,东南风,"1-3",19,0.0,5,80,1010,25,25,"2025-08-11 20:18:00"
|
||||
479,上海,"2025-09-08","05:35:00","18:11:00","18:23:00","05:44:00",满月,"804",29,22,"103",晴间多云,"153",晴间多云,262,西风,"4-5",30,330,西北风,"4-5",30,3.1,3,80,1007,25,56,"2025-08-11 20:18:00"
|
||||
480,上海,"2025-09-09","05:35:00","18:10:00","18:54:00","06:49:00",亏凸月,"805",28,22,"100",晴,"153",晴间多云,316,西北风,"1-3",19,357,北风,"1-3",17,0.0,8,78,1009,25,20,"2025-08-11 20:18:00"
|
||||
497,广州,"2025-08-27","06:08:00","18:51:00","09:27:00","21:11:00",蛾眉月,"801",33,25,"302",雷阵雨,"302",雷阵雨,49,东北风,"1-3",6,95,东风,"1-3",6,8.4,2,55,1003,25,60,"2025-08-11 20:18:00"
|
||||
498,广州,"2025-08-28","06:09:00","18:50:00","10:18:00","21:43:00",蛾眉月,"801",32,25,"103",晴间多云,"350",阵雨,42,东北风,"1-3",7,47,东北风,"1-3",7,0.0,11,77,1003,19,25,"2025-08-11 20:18:00"
|
||||
499,广州,"2025-08-29","06:09:00","18:49:00","11:10:00","22:18:00",蛾眉月,"801",32,25,"103",晴间多云,"350",阵雨,54,东北风,"3-4",20,76,东北风,"1-3",19,0.0,10,78,1005,22,25,"2025-08-11 20:18:00"
|
||||
500,广州,"2025-08-30","06:09:00","18:48:00","12:03:00","22:57:00",蛾眉月,"801",32,25,"302",雷阵雨,"350",阵雨,67,东北风,"3-4",20,84,东风,"3-4",20,1.2,7,79,1003,20,61,"2025-08-11 20:18:00"
|
||||
501,广州,"2025-08-31","06:10:00","18:47:00","12:57:00","23:41:00",上弦月,"802",32,25,"302",雷阵雨,"350",阵雨,82,东风,"3-4",20,79,东风,"1-3",19,2.5,3,79,1005,21,65,"2025-08-11 20:18:00"
|
||||
502,广州,"2025-09-01","06:10:00","18:46:00","13:52:00","00:00:00",盈凸月,"803",31,26,"101",多云,"302",雷阵雨,68,东北风,"1-3",15,84,东风,"1-3",11,1.3,3,79,1005,19,41,"2025-08-11 20:18:00"
|
||||
503,广州,"2025-09-02","06:10:00","18:45:00","14:45:00","00:31:00",盈凸月,"803",31,25,"103",晴间多云,"151",多云,37,东北风,"1-3",6,104,东南风,"1-3",4,2.1,11,79,1005,18,55,"2025-08-11 20:18:00"
|
||||
504,广州,"2025-09-03","06:11:00","18:44:00","15:36:00","01:25:00",盈凸月,"803",32,25,"103",晴间多云,"350",阵雨,30,东北风,"1-3",4,88,东风,"1-3",7,0.6,7,78,1004,19,40,"2025-08-11 20:18:00"
|
||||
505,广州,"2025-09-04","06:11:00","18:43:00","16:22:00","02:23:00",盈凸月,"803",32,24,"302",雷阵雨,"302",雷阵雨,40,东北风,"1-3",7,55,东北风,"1-3",7,1.7,4,77,1002,21,64,"2025-08-11 20:18:00"
|
||||
506,广州,"2025-09-05","06:11:00","18:42:00","17:03:00","03:22:00",盈凸月,"803",32,25,"302",雷阵雨,"151",多云,41,东北风,"1-3",7,90,东风,"1-3",11,1.5,5,77,1003,20,62,"2025-08-11 20:18:00"
|
||||
507,广州,"2025-09-06","06:12:00","18:41:00","17:43:00","04:23:00",盈凸月,"803",31,25,"300",阵雨,"302",雷阵雨,75,东北风,"1-3",17,101,东风,"1-3",15,0.7,7,77,1002,22,56,"2025-08-11 20:18:00"
|
||||
508,广州,"2025-09-07","06:12:00","18:40:00","18:20:00","05:22:00",盈凸月,"803",31,24,"103",晴间多云,"153",晴间多云,72,东北风,"1-3",7,92,东风,"1-3",7,0.9,5,76,1005,19,58,"2025-08-11 20:18:00"
|
||||
509,广州,"2025-09-08","06:12:00","18:39:00","18:55:00","06:22:00",满月,"804",32,25,"100",晴,"153",晴间多云,14,东北风,"1-3",6,36,东北风,"1-3",11,0.9,10,76,1004,19,40,"2025-08-11 20:18:00"
|
||||
510,广州,"2025-09-09","06:12:00","18:38:00","19:31:00","07:21:00",亏凸月,"805",32,25,"102",少云,"350",阵雨,29,东北风,"3-4",20,66,东北风,"1-3",19,0.6,10,80,1004,22,39,"2025-08-11 20:18:00"
|
||||
527,深圳,"2025-08-27","06:06:00","18:47:00","09:23:00","21:08:00",蛾眉月,"801",33,27,"302",雷阵雨,"151",多云,60,东北风,"3-4",20,94,东风,"3-4",20,2.1,4,76,996,23,64,"2025-08-11 20:18:00"
|
||||
528,深圳,"2025-08-28","06:06:00","18:46:00","10:14:00","21:40:00",蛾眉月,"801",32,27,"103",晴间多云,"302",雷阵雨,82,东风,"3-4",24,80,东风,"3-4",20,2.6,11,84,997,19,58,"2025-08-11 20:18:00"
|
||||
529,深圳,"2025-08-29","06:06:00","18:45:00","11:05:00","22:15:00",蛾眉月,"801",32,27,"302",雷阵雨,"151",多云,79,东风,"4-5",32,86,东风,"4-5",30,5.5,4,84,995,18,65,"2025-08-11 20:18:00"
|
||||
530,深圳,"2025-08-30","06:07:00","18:44:00","11:58:00","22:55:00",蛾眉月,"801",31,26,"302",雷阵雨,"302",雷阵雨,84,东风,"4-5",32,93,东风,"4-5",30,8.2,3,86,997,18,62,"2025-08-11 20:18:00"
|
||||
531,深圳,"2025-08-31","06:07:00","18:43:00","12:53:00","23:39:00",上弦月,"802",31,27,"302",雷阵雨,"302",雷阵雨,102,东南风,"3-4",28,98,东风,"3-4",28,8.2,2,85,995,21,60,"2025-08-11 20:18:00"
|
||||
532,深圳,"2025-09-01","06:07:00","18:42:00","13:47:00","00:00:00",盈凸月,"803",31,27,"302",雷阵雨,"302",雷阵雨,94,东风,"3-4",20,89,东风,"1-3",19,4.9,4,86,998,21,65,"2025-08-11 20:18:00"
|
||||
533,深圳,"2025-09-02","06:07:00","18:41:00","14:41:00","00:29:00",盈凸月,"803",32,27,"300",阵雨,"151",多云,84,东风,"3-4",20,99,东风,"1-3",13,7.5,11,85,997,22,58,"2025-08-11 20:18:00"
|
||||
534,深圳,"2025-09-03","06:08:00","18:41:00","15:31:00","01:23:00",盈凸月,"803",32,27,"302",雷阵雨,"350",阵雨,54,东北风,"1-3",7,44,东北风,"1-3",4,1.5,4,85,995,19,63,"2025-08-11 20:18:00"
|
||||
535,深圳,"2025-09-04","06:08:00","18:40:00","16:17:00","02:21:00",盈凸月,"803",32,26,"302",雷阵雨,"302",雷阵雨,63,东北风,"1-3",15,70,东北风,"1-3",11,3.1,3,86,995,19,65,"2025-08-11 20:18:00"
|
||||
536,深圳,"2025-09-05","06:08:00","18:39:00","16:59:00","03:20:00",盈凸月,"803",32,26,"302",雷阵雨,"302",雷阵雨,61,东北风,"3-4",20,77,东北风,"3-4",20,2.9,4,85,997,18,65,"2025-08-11 20:18:00"
|
||||
537,深圳,"2025-09-06","06:09:00","18:38:00","17:39:00","04:20:00",盈凸月,"803",31,26,"101",多云,"302",雷阵雨,82,东风,"3-4",28,98,东风,"3-4",26,1.9,3,85,994,20,41,"2025-08-11 20:18:00"
|
||||
538,深圳,"2025-09-07","06:09:00","18:37:00","18:16:00","05:19:00",盈凸月,"803",31,26,"302",雷阵雨,"153",晴间多云,90,东风,"3-4",22,99,东风,"3-4",20,2.3,3,83,998,21,65,"2025-08-11 20:18:00"
|
||||
539,深圳,"2025-09-08","06:09:00","18:36:00","18:52:00","06:18:00",满月,"804",32,26,"102",少云,"302",雷阵雨,77,东北风,"1-3",17,72,东北风,"1-3",13,1.4,11,86,996,21,55,"2025-08-11 20:18:00"
|
||||
540,深圳,"2025-09-09","06:09:00","18:35:00","19:28:00","07:18:00",亏凸月,"805",32,27,"302",雷阵雨,"302",雷阵雨,68,东北风,"3-4",24,81,东风,"3-4",22,2.0,3,85,998,21,64,"2025-08-11 20:18:00"
|
||||
541,北京,"2026-01-23","07:31:00","17:22:00","09:42:00","22:10:00",蛾眉月,"801",3,-11,"100",晴,"150",晴,45,东北风,"1-3",3,0,北风,"1-3",3,0.0,3,31,1021,25,0,"2026-01-23 17:50:00"
|
||||
542,北京,"2026-01-24","07:30:00","17:24:00","10:05:00","23:21:00",蛾眉月,"801",3,-8,"100",晴,"151",多云,45,东北风,"1-3",3,0,北风,"1-3",3,0.0,3,44,1027,25,0,"2026-01-23 17:50:00"
|
||||
543,北京,"2026-01-25","07:30:00","17:25:00","10:32:00","00:00:00",蛾眉月,"801",-2,-6,"400",小雪,"400",小雪,135,东南风,"1-3",3,180,南风,"1-3",3,0.0,1,71,1023,24,0,"2026-01-23 17:50:00"
|
||||
544,北京,"2026-01-26","07:29:00","17:26:00","11:00:00","00:36:00",上弦月,"802",2,-7,"101",多云,"151",多云,315,西北风,"1-3",3,0,北风,"1-3",3,0.0,3,26,1025,25,0,"2026-01-23 17:50:00"
|
||||
545,北京,"2026-01-27","07:28:00","17:27:00","11:37:00","01:54:00",盈凸月,"803",1,-9,"101",多云,"151",多云,45,东北风,"1-3",3,45,东北风,"1-3",3,0.0,2,26,1024,25,1,"2026-01-23 17:50:00"
|
||||
546,北京,"2026-01-28","07:27:00","17:28:00","12:21:00","03:12:00",盈凸月,"803",1,-9,"101",多云,"151",多云,90,东风,"1-3",3,0,北风,"1-3",3,0.0,3,29,1027,25,0,"2026-01-23 17:50:00"
|
||||
547,北京,"2026-01-29","07:27:00","17:30:00","13:15:00","04:27:00",盈凸月,"803",1,-8,"101",多云,"151",多云,225,西南风,"1-3",3,180,南风,"1-3",3,0.0,3,84,1028,5,0,"2026-01-23 17:50:00"
|
||||
548,北京,"2026-01-30","07:26:00","17:31:00","14:21:00","05:34:00",盈凸月,"803",0,-6,"404",雨夹雪,"400",小雪,180,南风,"1-3",3,180,南风,"1-3",3,0.2,1,60,1026,24,0,"2026-01-23 17:50:00"
|
||||
549,北京,"2026-01-31","07:25:00","17:32:00","15:34:00","06:29:00",盈凸月,"803",3,-6,"104",阴,"151",多云,315,西北风,"1-3",3,45,东北风,"1-3",3,0.0,3,48,1020,25,1,"2026-01-23 17:50:00"
|
||||
550,北京,"2026-02-01","07:24:00","17:33:00","16:49:00","07:14:00",盈凸月,"803",4,-6,"101",多云,"150",晴,0,北风,"1-3",3,0,北风,"1-3",3,0.0,3,44,1021,25,0,"2026-01-23 17:50:00"
|
||||
551,北京,"2026-02-02","07:23:00","17:34:00","18:03:00","07:49:00",满月,"804",5,-6,"104",阴,"104",阴,45,东北风,"1-3",3,90,东风,"1-3",3,0.0,3,41,1026,25,0,"2026-01-23 17:50:00"
|
||||
552,北京,"2026-02-03","07:22:00","17:36:00","19:14:00","08:17:00",亏凸月,"805",3,-10,"101",多云,"151",多云,0,北风,"1-3",3,45,东北风,"1-3",3,0.0,3,50,1028,25,0,"2026-01-23 17:50:00"
|
||||
553,北京,"2026-02-04","07:21:00","17:37:00","20:21:00","08:41:00",亏凸月,"805",-1,-10,"101",多云,"151",多云,315,西北风,"1-3",16,315,西北风,"1-3",16,0.0,3,48,1020,25,0,"2026-01-23 17:50:00"
|
||||
554,北京,"2026-02-05","07:20:00","17:38:00","21:26:00","09:03:00",亏凸月,"805",0,-9,"100",晴,"150",晴,315,西北风,"1-3",3,135,东南风,"1-3",3,0.0,3,52,1019,25,4,"2026-01-23 17:50:00"
|
||||
555,北京,"2026-02-06","07:19:00","17:39:00","22:29:00","09:23:00",亏凸月,"805",1,-9,"100",晴,"150",晴,45,东北风,"1-3",3,0,北风,"1-3",3,0.0,3,57,1021,25,4,"2026-01-23 17:50:00"
|
||||
556,北京,"2026-02-07","07:18:00","17:40:00","23:32:00","09:45:00",亏凸月,"805",7,-5,"102",少云,"153",晴间多云,109,东南风,"1-3",13,336,西北风,"4-5",32,0.0,3,61,1017,25,19,"2026-01-23 17:50:00"
|
||||
557,北京,"2026-02-08","07:17:00","17:42:00","00:00:00","10:07:00",亏凸月,"805",1,-8,"100",晴,"150",晴,339,西北风,"4-5",37,339,西北风,"4-5",33,0.0,3,67,1019,25,0,"2026-01-23 17:50:00"
|
||||
558,北京,"2026-02-09","07:16:00","17:43:00","00:35:00","10:33:00",下弦月,"806",1,-8,"100",晴,"150",晴,323,西北风,"3-4",24,250,西南风,"3-4",22,0.0,3,48,1024,25,0,"2026-01-23 17:50:00"
|
||||
559,北京,"2026-02-10","07:15:00","17:44:00","01:37:00","11:04:00",残月,"807",1,-7,"100",晴,"150",晴,288,西北风,"1-3",7,261,西风,"1-3",6,0.0,3,49,1023,22,1,"2026-01-23 17:50:00"
|
||||
560,北京,"2026-02-11","07:14:00","17:45:00","02:38:00","11:41:00",残月,"807",7,-5,"101",多云,"153",晴间多云,311,西北风,"1-3",7,343,西北风,"1-3",6,0.0,3,48,1022,23,25,"2026-01-23 17:50:00"
|
||||
561,北京,"2026-02-12","07:13:00","17:46:00","03:36:00","12:25:00",残月,"807",8,-4,"100",晴,"153",晴间多云,300,西北风,"1-3",17,103,东南风,"1-3",15,0.0,3,51,1021,23,20,"2026-01-23 17:50:00"
|
||||
562,北京,"2026-02-13","07:11:00","17:48:00","04:29:00","13:18:00",残月,"807",8,-2,"103",晴间多云,"151",多云,43,东北风,"1-3",6,275,西风,"1-3",7,0.0,2,50,1022,23,25,"2026-01-23 17:50:00"
|
||||
563,北京,"2026-02-14","07:10:00","17:49:00","05:14:00","14:18:00",残月,"807",8,-2,"101",多云,"153",晴间多云,20,东北风,"1-3",17,177,南风,"1-3",4,0.0,1,47,1024,23,25,"2026-01-23 17:50:00"
|
||||
564,北京,"2026-02-15","07:09:00","17:50:00","05:53:00","15:22:00",残月,"807",8,-2,"100",晴,"151",多云,51,东北风,"3-4",22,131,东南风,"3-4",22,0.0,3,50,1021,22,20,"2026-01-23 17:50:00"
|
||||
565,北京,"2026-02-16","07:08:00","17:51:00","06:26:00","16:29:00",残月,"807",6,-3,"103",晴间多云,"150",晴,63,东北风,"1-3",6,359,北风,"1-3",4,0.0,2,48,1024,25,20,"2026-01-23 17:50:00"
|
||||
566,北京,"2026-02-17","07:06:00","17:52:00","06:54:00","17:37:00",新月,"800",7,-2,"100",晴,"150",晴,305,西北风,"1-3",17,290,西北风,"1-3",17,0.0,3,47,1022,25,20,"2026-01-23 17:50:00"
|
||||
567,北京,"2026-02-18","07:05:00","17:54:00","07:20:00","18:45:00",蛾眉月,"801",9,-2,"100",晴,"150",晴,347,西北风,"1-3",15,163,东南风,"1-3",7,0.0,4,50,1022,21,20,"2026-01-23 17:50:00"
|
||||
568,北京,"2026-02-19","07:04:00","17:55:00","07:44:00","19:54:00",蛾眉月,"801",8,-3,"100",晴,"151",多云,91,东风,"1-3",19,127,东南风,"1-3",19,0.0,4,50,1024,25,20,"2026-01-23 17:50:00"
|
||||
569,北京,"2026-02-20","07:02:00","17:56:00","08:07:00","21:05:00",蛾眉月,"801",6,-1,"101",多云,"153",晴间多云,91,东风,"1-3",6,85,东风,"1-3",7,0.0,1,48,1021,25,25,"2026-01-23 17:50:00"
|
||||
570,北京,"2026-02-21","07:01:00","17:57:00","08:32:00","22:17:00",蛾眉月,"801",6,-2,"100",晴,"150",晴,302,西北风,"1-3",6,287,西北风,"1-3",6,0.0,4,51,1021,24,5,"2026-01-23 17:50:00"
|
||||
571,上海,"2026-01-23","06:52:00","17:21:00","09:20:00","21:47:00",蛾眉月,"801",8,1,"100",晴,"151",多云,225,西南风,"1-3",3,0,北风,"1-3",3,0.0,4,53,1028,25,0,"2026-01-23 17:50:00"
|
||||
572,上海,"2026-01-24","06:52:00","17:22:00","09:50:00","22:52:00",蛾眉月,"801",11,1,"100",晴,"150",晴,45,东北风,"1-3",3,90,东风,"1-3",3,0.0,4,75,1026,25,0,"2026-01-23 17:50:00"
|
||||
573,上海,"2026-01-25","06:51:00","17:23:00","10:22:00","00:00:00",蛾眉月,"801",12,6,"104",阴,"305",小雨,90,东风,"1-3",3,90,东风,"1-3",3,0.0,3,88,1022,25,25,"2026-01-23 17:50:00"
|
||||
574,上海,"2026-01-26","06:51:00","17:24:00","10:58:00","00:00:00",上弦月,"802",13,5,"305",小雨,"104",阴,270,西风,"1-3",3,0,北风,"1-3",3,3.8,1,77,1027,24,81,"2026-01-23 17:50:00"
|
||||
575,上海,"2026-01-27","06:50:00","17:25:00","11:40:00","01:10:00",盈凸月,"803",8,3,"104",阴,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,0.0,1,66,1029,25,1,"2026-01-23 17:50:00"
|
||||
576,上海,"2026-01-28","06:50:00","17:25:00","12:29:00","02:22:00",盈凸月,"803",8,3,"100",晴,"150",晴,45,东北风,"1-3",3,45,东北风,"1-3",3,0.0,4,64,1029,25,0,"2026-01-23 17:50:00"
|
||||
577,上海,"2026-01-29","06:49:00","17:26:00","13:26:00","03:34:00",盈凸月,"803",9,4,"101",多云,"104",阴,90,东风,"1-3",3,45,东北风,"1-3",3,0.0,4,79,1027,13,4,"2026-01-23 17:50:00"
|
||||
578,上海,"2026-01-30","06:49:00","17:27:00","14:32:00","04:41:00",盈凸月,"803",8,4,"305",小雨,"305",小雨,45,东北风,"1-3",16,45,东北风,"1-3",3,0.0,1,88,1025,23,25,"2026-01-23 17:50:00"
|
||||
579,上海,"2026-01-31","06:48:00","17:28:00","15:42:00","05:39:00",盈凸月,"803",7,4,"104",阴,"104",阴,45,东北风,"1-3",3,270,西风,"1-3",3,1.3,1,74,1029,24,39,"2026-01-23 17:50:00"
|
||||
580,上海,"2026-02-01","06:48:00","17:29:00","16:51:00","06:28:00",盈凸月,"803",9,4,"104",阴,"305",小雨,90,东风,"1-3",3,90,东风,"1-3",3,0.0,4,60,1027,25,0,"2026-01-23 17:50:00"
|
||||
581,上海,"2026-02-02","06:47:00","17:30:00","17:58:00","07:09:00",满月,"804",9,8,"305",小雨,"305",小雨,90,东风,"1-3",3,315,西北风,"1-3",3,0.0,4,72,1030,25,1,"2026-01-23 17:50:00"
|
||||
582,上海,"2026-02-03","06:46:00","17:31:00","19:03:00","07:43:00",亏凸月,"805",10,6,"305",小雨,"305",小雨,45,东北风,"1-3",3,45,东北风,"1-3",3,7.9,1,59,1034,25,75,"2026-01-23 17:50:00"
|
||||
583,上海,"2026-02-04","06:46:00","17:32:00","20:04:00","08:13:00",亏凸月,"805",9,3,"104",阴,"104",阴,45,东北风,"1-3",16,45,东北风,"1-3",3,8.9,1,67,1028,25,75,"2026-01-23 17:50:00"
|
||||
584,上海,"2026-02-05","06:45:00","17:33:00","21:02:00","08:41:00",亏凸月,"805",7,3,"104",阴,"104",阴,45,东北风,"1-3",16,45,东北风,"1-3",3,0.0,3,80,1025,25,25,"2026-01-23 17:50:00"
|
||||
585,上海,"2026-02-06","06:44:00","17:34:00","21:59:00","09:07:00",亏凸月,"805",8,5,"104",阴,"104",阴,45,东北风,"1-3",3,90,东风,"1-3",3,0.0,4,80,1022,25,10,"2026-01-23 17:50:00"
|
||||
586,上海,"2026-02-07","06:44:00","17:35:00","22:56:00","09:34:00",亏凸月,"805",12,3,"100",晴,"150",晴,267,西风,"1-3",17,190,南风,"1-3",7,0.0,4,94,1020,22,20,"2026-01-23 17:50:00"
|
||||
587,上海,"2026-02-08","06:43:00","17:35:00","23:54:00","10:03:00",亏凸月,"805",12,0,"101",多云,"151",多云,289,西北风,"4-5",35,345,西北风,"4-5",35,0.0,3,93,1022,25,25,"2026-01-23 17:50:00"
|
||||
588,上海,"2026-02-09","06:42:00","17:36:00","00:00:00","10:34:00",下弦月,"806",10,0,"100",晴,"150",晴,318,西北风,"5-6",48,322,西北风,"5-6",46,0.0,4,76,1027,21,10,"2026-01-23 17:50:00"
|
||||
589,上海,"2026-02-10","06:41:00","17:37:00","00:51:00","11:09:00",残月,"807",6,-1,"100",晴,"150",晴,311,西北风,"3-4",22,287,西北风,"1-3",19,0.0,4,74,1026,24,10,"2026-01-23 17:50:00"
|
||||
590,上海,"2026-02-11","06:40:00","17:38:00","01:48:00","11:50:00",残月,"807",6,0,"100",晴,"150",晴,218,西南风,"1-3",17,168,东南风,"1-3",15,0.0,4,76,1026,23,5,"2026-01-23 17:50:00"
|
||||
591,上海,"2026-02-12","06:40:00","17:39:00","02:44:00","12:36:00",残月,"807",10,0,"103",晴间多云,"150",晴,215,西南风,"1-3",13,151,东南风,"1-3",6,0.0,2,75,1027,24,25,"2026-01-23 17:50:00"
|
||||
592,上海,"2026-02-13","06:39:00","17:40:00","03:36:00","13:28:00",残月,"807",12,3,"101",多云,"153",晴间多云,149,东南风,"1-3",19,179,南风,"1-3",15,0.0,1,73,1025,25,25,"2026-01-23 17:50:00"
|
||||
593,上海,"2026-02-14","06:38:00","17:41:00","04:24:00","14:25:00",残月,"807",12,4,"102",少云,"151",多云,173,南风,"1-3",17,124,东南风,"1-3",11,0.0,4,72,1026,23,20,"2026-01-23 17:50:00"
|
||||
594,上海,"2026-02-15","06:37:00","17:41:00","05:06:00","15:25:00",残月,"807",13,5,"101",多云,"151",多云,55,东北风,"5-6",43,42,东北风,"4-5",37,0.0,1,74,1025,22,25,"2026-01-23 17:50:00"
|
||||
595,上海,"2026-02-16","06:36:00","17:42:00","05:45:00","16:27:00",残月,"807",12,4,"103",晴间多云,"150",晴,39,东北风,"3-4",22,48,东北风,"3-4",20,0.0,4,73,1027,25,25,"2026-01-23 17:50:00"
|
||||
596,上海,"2026-02-17","06:35:00","17:43:00","06:18:00","17:28:00",新月,"800",11,3,"100",晴,"151",多云,51,东北风,"1-3",19,81,东风,"1-3",17,0.0,5,74,1024,23,10,"2026-01-23 17:50:00"
|
||||
597,上海,"2026-02-18","06:34:00","17:44:00","06:50:00","18:31:00",蛾眉月,"801",12,4,"103",晴间多云,"153",晴间多云,64,东北风,"1-3",15,22,东北风,"1-3",19,0.0,5,75,1024,22,25,"2026-01-23 17:50:00"
|
||||
598,上海,"2026-02-19","06:33:00","17:45:00","07:19:00","19:33:00",蛾眉月,"801",12,2,"100",晴,"150",晴,24,东北风,"3-4",28,39,东北风,"3-4",22,0.0,5,73,1024,21,10,"2026-01-23 17:50:00"
|
||||
599,上海,"2026-02-20","06:32:00","17:46:00","07:49:00","20:37:00",蛾眉月,"801",10,3,"101",多云,"305",小雨,66,东北风,"3-4",20,73,东北风,"3-4",20,0.0,1,74,1027,25,25,"2026-01-23 17:50:00"
|
||||
600,上海,"2026-02-21","06:31:00","17:46:00","08:21:00","21:43:00",蛾眉月,"801",8,6,"300",阵雨,"350",阵雨,56,东北风,"3-4",28,34,东北风,"3-4",24,1.1,1,75,1027,23,57,"2026-01-23 17:50:00"
|
||||
601,广州,"2026-01-23","07:10:00","18:08:00","09:52:00","22:19:00",蛾眉月,"801",14,7,"101",多云,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,0.0,5,46,1021,25,3,"2026-01-23 17:50:00"
|
||||
602,广州,"2026-01-24","07:10:00","18:09:00","10:28:00","23:19:00",蛾眉月,"801",20,8,"101",多云,"104",阴,0,北风,"1-3",3,0,北风,"1-3",3,0.0,2,78,1019,25,3,"2026-01-23 17:50:00"
|
||||
603,广州,"2026-01-25","07:10:00","18:10:00","11:04:00","00:00:00",蛾眉月,"801",22,10,"104",阴,"305",小雨,0,北风,"1-3",3,0,北风,"1-3",3,0.0,5,79,1018,17,1,"2026-01-23 17:50:00"
|
||||
604,广州,"2026-01-26","07:10:00","18:10:00","11:46:00","00:22:00",上弦月,"802",21,14,"305",小雨,"305",小雨,0,北风,"1-3",3,0,北风,"1-3",3,3.8,1,74,1018,24,70,"2026-01-23 17:50:00"
|
||||
605,广州,"2026-01-27","07:09:00","18:11:00","12:32:00","01:27:00",盈凸月,"803",19,13,"305",小雨,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,2.4,2,79,1018,23,71,"2026-01-23 17:50:00"
|
||||
606,广州,"2026-01-28","07:09:00","18:12:00","13:25:00","02:36:00",盈凸月,"803",21,13,"101",多云,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,0.0,5,71,1018,24,1,"2026-01-23 17:50:00"
|
||||
607,广州,"2026-01-29","07:09:00","18:12:00","14:25:00","03:45:00",盈凸月,"803",20,15,"100",晴,"305",小雨,0,北风,"1-3",3,0,北风,"1-3",3,0.0,5,67,1018,25,3,"2026-01-23 17:50:00"
|
||||
608,广州,"2026-01-30","07:08:00","18:13:00","15:30:00","04:51:00",盈凸月,"803",21,13,"104",阴,"104",阴,135,东南风,"1-3",3,90,东风,"1-3",3,0.9,2,66,1018,25,56,"2026-01-23 17:50:00"
|
||||
609,广州,"2026-01-31","07:08:00","18:14:00","16:37:00","05:51:00",盈凸月,"803",21,11,"104",阴,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,2.5,1,58,1020,25,64,"2026-01-23 17:50:00"
|
||||
610,广州,"2026-02-01","07:08:00","18:15:00","17:44:00","06:43:00",盈凸月,"803",21,12,"104",阴,"104",阴,180,南风,"1-3",3,135,东南风,"1-3",3,0.0,1,54,1020,25,6,"2026-01-23 17:50:00"
|
||||
611,广州,"2026-02-02","07:07:00","18:15:00","18:47:00","07:27:00",满月,"804",21,15,"104",阴,"104",阴,180,南风,"1-3",3,135,东南风,"1-3",3,1.5,1,57,1020,25,60,"2026-01-23 17:50:00"
|
||||
612,广州,"2026-02-03","07:07:00","18:16:00","19:46:00","08:07:00",亏凸月,"805",26,16,"101",多云,"305",小雨,180,南风,"1-3",3,135,东南风,"1-3",3,0.5,2,64,1022,25,55,"2026-01-23 17:50:00"
|
||||
613,广州,"2026-02-04","07:07:00","18:17:00","20:42:00","08:42:00",亏凸月,"805",22,13,"305",小雨,"305",小雨,0,北风,"1-3",3,0,北风,"1-3",3,0.0,5,64,1021,25,1,"2026-01-23 17:50:00"
|
||||
614,广州,"2026-02-05","07:06:00","18:17:00","21:35:00","09:13:00",亏凸月,"805",18,11,"305",小雨,"305",小雨,45,东北风,"1-3",3,90,东风,"1-3",3,0.0,5,66,1019,25,20,"2026-01-23 17:50:00"
|
||||
615,广州,"2026-02-06","07:06:00","18:18:00","22:28:00","09:45:00",亏凸月,"805",16,9,"305",小雨,"305",小雨,0,北风,"1-3",3,0,北风,"1-3",3,0.0,2,67,1017,25,25,"2026-01-23 17:50:00"
|
||||
616,广州,"2026-02-07","07:05:00","18:18:00","23:20:00","10:16:00",亏凸月,"805",22,14,"100",晴,"150",晴,6,北风,"3-4",20,28,东北风,"1-3",15,0.0,5,74,1012,24,20,"2026-01-23 17:50:00"
|
||||
617,广州,"2026-02-08","07:05:00","18:19:00","00:00:00","10:49:00",亏凸月,"805",22,13,"100",晴,"150",晴,45,东北风,"1-3",6,12,东北风,"1-3",7,0.0,5,82,1012,9,20,"2026-01-23 17:50:00"
|
||||
618,广州,"2026-02-09","07:04:00","18:20:00","00:13:00","11:23:00",下弦月,"806",21,9,"100",晴,"151",多云,25,东北风,"5-6",41,17,东北风,"5-6",39,0.0,5,69,1016,23,10,"2026-01-23 17:50:00"
|
||||
619,广州,"2026-02-10","07:04:00","18:20:00","01:06:00","12:03:00",残月,"807",20,9,"103",晴间多云,"150",晴,13,东北风,"4-5",32,16,东北风,"3-4",26,0.0,6,68,1018,21,25,"2026-01-23 17:50:00"
|
||||
620,广州,"2026-02-11","07:03:00","18:21:00","02:00:00","12:46:00",残月,"807",17,9,"100",晴,"150",晴,40,东北风,"1-3",15,130,东南风,"1-3",4,0.0,6,66,1019,21,20,"2026-01-23 17:50:00"
|
||||
621,广州,"2026-02-12","07:02:00","18:22:00","02:54:00","13:33:00",残月,"807",19,11,"101",多云,"151",多云,44,东北风,"1-3",4,2,北风,"1-3",6,0.0,2,66,1017,21,25,"2026-01-23 17:50:00"
|
||||
622,广州,"2026-02-13","07:02:00","18:22:00","03:47:00","14:25:00",残月,"807",21,14,"103",晴间多云,"150",晴,338,西北风,"1-3",4,50,东北风,"1-3",6,0.0,2,66,1019,23,25,"2026-01-23 17:50:00"
|
||||
623,广州,"2026-02-14","07:01:00","18:23:00","04:36:00","15:21:00",残月,"807",22,13,"101",多云,"153",晴间多云,129,东南风,"1-3",17,153,东南风,"1-3",17,0.0,6,67,1016,24,25,"2026-01-23 17:50:00"
|
||||
624,广州,"2026-02-15","07:01:00","18:23:00","05:20:00","16:18:00",残月,"807",22,15,"103",晴间多云,"350",阵雨,124,东南风,"1-3",7,265,西风,"1-3",7,0.0,3,65,1017,24,25,"2026-01-23 17:50:00"
|
||||
625,广州,"2026-02-16","07:00:00","18:24:00","06:01:00","17:15:00",残月,"807",22,15,"101",多云,"151",多云,2,北风,"3-4",20,25,东北风,"1-3",17,0.0,2,66,1017,24,25,"2026-01-23 17:50:00"
|
||||
626,广州,"2026-02-17","06:59:00","18:25:00","06:40:00","18:13:00",新月,"800",22,14,"102",少云,"150",晴,53,东北风,"1-3",7,125,东南风,"1-3",6,0.0,6,66,1017,22,20,"2026-01-23 17:50:00"
|
||||
627,广州,"2026-02-18","06:59:00","18:25:00","07:15:00","19:10:00",蛾眉月,"801",22,14,"100",晴,"151",多云,73,东北风,"1-3",6,132,东南风,"1-3",6,0.0,6,68,1018,21,5,"2026-01-23 17:50:00"
|
||||
628,广州,"2026-02-19","06:58:00","18:26:00","07:50:00","20:08:00",蛾眉月,"801",23,15,"101",多云,"153",晴间多云,105,东南风,"1-3",6,145,东南风,"1-3",15,0.0,2,67,1017,24,25,"2026-01-23 17:50:00"
|
||||
629,广州,"2026-02-20","06:57:00","18:26:00","08:25:00","21:07:00",蛾眉月,"801",23,15,"103",晴间多云,"150",晴,122,东南风,"1-3",7,154,东南风,"1-3",19,0.0,2,66,1017,24,25,"2026-01-23 17:50:00"
|
||||
630,广州,"2026-02-21","06:56:00","18:27:00","09:00:00","22:08:00",蛾眉月,"801",22,15,"100",晴,"150",晴,110,东南风,"1-3",6,157,东南风,"1-3",17,0.0,6,65,1017,24,20,"2026-01-23 17:50:00"
|
||||
631,深圳,"2026-01-23","07:06:00","18:06:00","09:49:00","22:16:00",蛾眉月,"801",16,10,"101",多云,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,0.0,4,61,1013,25,3,"2026-01-23 17:50:00"
|
||||
632,深圳,"2026-01-24","07:06:00","18:07:00","10:25:00","23:15:00",蛾眉月,"801",21,12,"101",多云,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,0.0,5,81,1011,25,2,"2026-01-23 17:50:00"
|
||||
633,深圳,"2026-01-25","07:06:00","18:07:00","11:02:00","00:00:00",蛾眉月,"801",23,13,"101",多云,"104",阴,0,北风,"1-3",3,0,北风,"1-3",3,0.0,5,84,1010,24,25,"2026-01-23 17:50:00"
|
||||
634,深圳,"2026-01-26","07:05:00","18:08:00","11:44:00","00:17:00",上弦月,"802",22,17,"101",多云,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,0.5,1,77,1010,24,55,"2026-01-23 17:50:00"
|
||||
635,深圳,"2026-01-27","07:05:00","18:09:00","12:30:00","01:23:00",盈凸月,"803",23,15,"101",多云,"151",多云,0,北风,"1-3",3,0,北风,"1-3",3,3.5,5,83,1011,24,85,"2026-01-23 17:50:00"
|
||||
636,深圳,"2026-01-28","07:05:00","18:09:00","13:23:00","02:31:00",盈凸月,"803",23,14,"101",多云,"151",多云,0,北风,"1-3",3,90,东风,"1-3",16,0.0,5,76,1011,25,2,"2026-01-23 17:50:00"
|
||||
637,深圳,"2026-01-29","07:05:00","18:10:00","14:23:00","03:40:00",盈凸月,"803",20,16,"100",晴,"305",小雨,0,北风,"1-3",3,90,东风,"1-3",16,0.0,5,78,1011,25,4,"2026-01-23 17:50:00"
|
||||
638,深圳,"2026-01-30","07:04:00","18:11:00","15:28:00","04:46:00",盈凸月,"803",21,16,"104",阴,"305",小雨,90,东风,"1-3",3,45,东北风,"1-3",3,0.0,5,82,1011,25,25,"2026-01-23 17:50:00"
|
||||
639,深圳,"2026-01-31","07:04:00","18:11:00","16:35:00","05:46:00",盈凸月,"803",21,15,"104",阴,"151",多云,90,东风,"1-3",3,90,东风,"1-3",3,7.7,1,56,1011,25,61,"2026-01-23 17:50:00"
|
||||
640,深圳,"2026-02-01","07:04:00","18:12:00","17:41:00","06:38:00",盈凸月,"803",20,15,"101",多云,"305",小雨,135,东南风,"1-3",3,90,东风,"1-3",3,1.7,1,73,1013,25,55,"2026-01-23 17:50:00"
|
||||
641,深圳,"2026-02-02","07:03:00","18:13:00","18:44:00","07:23:00",满月,"804",22,18,"104",阴,"104",阴,90,东风,"1-3",3,90,东风,"1-3",3,0.3,2,81,1013,25,55,"2026-01-23 17:50:00"
|
||||
642,深圳,"2026-02-03","07:03:00","18:13:00","19:43:00","08:03:00",亏凸月,"805",25,14,"101",多云,"305",小雨,180,南风,"1-3",3,90,东风,"1-3",3,0.0,3,74,1015,25,1,"2026-01-23 17:50:00"
|
||||
643,深圳,"2026-02-04","07:03:00","18:14:00","20:39:00","08:38:00",亏凸月,"805",23,16,"104",阴,"305",小雨,135,东南风,"1-3",3,90,东风,"1-3",3,0.0,4,73,1014,25,1,"2026-01-23 17:50:00"
|
||||
644,深圳,"2026-02-05","07:02:00","18:15:00","21:32:00","09:10:00",亏凸月,"805",19,15,"104",阴,"104",阴,90,东风,"1-3",3,90,东风,"1-3",16,0.0,5,74,1012,25,20,"2026-01-23 17:50:00"
|
||||
645,深圳,"2026-02-06","07:02:00","18:15:00","22:24:00","09:42:00",亏凸月,"805",18,13,"305",小雨,"305",小雨,90,东风,"1-3",3,45,东北风,"1-3",3,0.0,5,79,1010,25,25,"2026-01-23 17:50:00"
|
||||
646,深圳,"2026-02-07","07:01:00","18:16:00","23:16:00","10:13:00",亏凸月,"805",22,16,"103",晴间多云,"150",晴,15,东北风,"3-4",22,104,东南风,"1-3",11,0.0,5,85,1005,21,25,"2026-01-23 17:50:00"
|
||||
647,深圳,"2026-02-08","07:01:00","18:17:00","00:00:00","10:46:00",亏凸月,"805",21,15,"100",晴,"150",晴,78,东北风,"3-4",24,99,东风,"1-3",15,0.0,6,85,1005,21,10,"2026-01-23 17:50:00"
|
||||
648,深圳,"2026-02-09","07:00:00","18:17:00","00:08:00","11:21:00",下弦月,"806",22,11,"101",多云,"151",多云,40,东北风,"4-5",33,19,东北风,"4-5",33,0.0,2,77,1012,25,25,"2026-01-23 17:50:00"
|
||||
649,深圳,"2026-02-10","07:00:00","18:18:00","01:01:00","12:01:00",残月,"807",20,11,"103",晴间多云,"150",晴,16,东北风,"4-5",33,29,东北风,"3-4",26,0.0,3,77,1010,24,25,"2026-01-23 17:50:00"
|
||||
650,深圳,"2026-02-11","06:59:00","18:18:00","01:56:00","12:44:00",残月,"807",18,12,"100",晴,"150",晴,59,东北风,"3-4",24,99,东风,"1-3",19,0.0,6,76,1010,23,20,"2026-01-23 17:50:00"
|
||||
651,深圳,"2026-02-12","06:59:00","18:19:00","02:50:00","13:31:00",残月,"807",19,13,"102",少云,"151",多云,70,东北风,"1-3",17,77,东北风,"1-3",6,0.0,6,76,1009,24,20,"2026-01-23 17:50:00"
|
||||
652,深圳,"2026-02-13","06:58:00","18:20:00","03:42:00","14:24:00",残月,"807",21,16,"101",多云,"150",晴,96,东风,"1-3",4,125,东南风,"1-3",11,0.0,2,76,1012,25,25,"2026-01-23 17:50:00"
|
||||
653,深圳,"2026-02-14","06:57:00","18:20:00","04:31:00","15:19:00",残月,"807",22,16,"103",晴间多云,"150",晴,100,东风,"3-4",24,114,东南风,"3-4",24,0.0,2,77,1010,25,25,"2026-01-23 17:50:00"
|
||||
654,深圳,"2026-02-15","06:57:00","18:21:00","05:16:00","16:16:00",残月,"807",22,16,"102",少云,"153",晴间多云,98,东风,"1-3",19,133,东南风,"1-3",19,0.0,4,78,1010,24,20,"2026-01-23 17:50:00"
|
||||
655,深圳,"2026-02-16","06:56:00","18:21:00","05:57:00","17:13:00",残月,"807",22,17,"300",阵雨,"350",阵雨,20,东北风,"1-3",7,81,东风,"1-3",15,0.6,2,77,1012,25,55,"2026-01-23 17:50:00"
|
||||
656,深圳,"2026-02-17","06:55:00","18:22:00","06:36:00","18:10:00",新月,"800",22,16,"101",多云,"150",晴,74,东北风,"1-3",19,102,东南风,"3-4",22,0.0,6,76,1010,23,25,"2026-01-23 17:50:00"
|
||||
657,深圳,"2026-02-18","06:55:00","18:22:00","07:12:00","19:07:00",蛾眉月,"801",22,16,"100",晴,"151",多云,86,东风,"4-5",30,98,东风,"3-4",24,0.0,6,76,1010,25,5,"2026-01-23 17:50:00"
|
||||
658,深圳,"2026-02-19","06:54:00","18:23:00","07:47:00","20:04:00",蛾眉月,"801",22,17,"101",多云,"151",多云,87,东风,"4-5",32,96,东风,"4-5",37,0.0,2,78,1012,22,25,"2026-01-23 17:50:00"
|
||||
659,深圳,"2026-02-20","06:53:00","18:23:00","08:22:00","21:03:00",蛾眉月,"801",23,17,"103",晴间多云,"150",晴,90,东风,"4-5",33,103,东南风,"4-5",32,0.0,4,76,1012,22,25,"2026-01-23 17:50:00"
|
||||
660,深圳,"2026-02-21","06:53:00","18:24:00","08:58:00","22:04:00",蛾眉月,"801",22,16,"100",晴,"150",晴,92,东风,"3-4",24,112,东南风,"3-4",20,0.0,7,76,1012,24,5,"2026-01-23 17:50:00"
|
||||
|
20
SmartVoyage/test/hf_test.py
Normal file
20
SmartVoyage/test/hf_test.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import requests
|
||||
import gzip
|
||||
import json
|
||||
|
||||
# 配置(使用自己的密钥)
|
||||
API_KEY = "e50365e0418a456dac7910bd2d51dd39"
|
||||
url = "https://nc33jqauxb.re.qweatherapi.com/v7/weather/7d?location=101010100" # 北京30天预报
|
||||
headers = {
|
||||
"X-QW-Api-Key": API_KEY,
|
||||
"Accept-Encoding": "gzip" # 请求gzip,但不强制
|
||||
}
|
||||
try:
|
||||
print("正在请求API...")
|
||||
response = requests.get(url, headers=headers, timeout=10)
|
||||
data = response.text
|
||||
parsed_data = json.loads(data)
|
||||
print("直接解析成功!")
|
||||
print(parsed_data)
|
||||
except requests.RequestException as e:
|
||||
print(f"直接解析失败哦: {e}")
|
||||
66
SmartVoyage/test/test_order_mcp_server.py
Normal file
66
SmartVoyage/test/test_order_mcp_server.py
Normal file
@@ -0,0 +1,66 @@
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
from langchain.agents import create_tool_calling_agent, AgentExecutor
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
from langchain_mcp_adapters.tools import load_mcp_tools
|
||||
from langchain_openai import ChatOpenAI
|
||||
from mcp import ClientSession
|
||||
from mcp.client.streamable_http import streamablehttp_client
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
from SmartVoyage.create_logger import logger
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 初始化LLM
|
||||
llm = ChatOpenAI(
|
||||
model=conf.model_name,
|
||||
base_url=conf.base_url,
|
||||
api_key=conf.api_key,
|
||||
temperature=0.1
|
||||
)
|
||||
async def order_tickets(query):
|
||||
try:
|
||||
# 启动 MCP server,通过streamable建立连接
|
||||
async with streamablehttp_client("http://127.0.0.1:8003/mcp") as (read, write, _):
|
||||
# 使用读写通道创建 MCP 会话
|
||||
async with ClientSession(read, write) as session:
|
||||
try:
|
||||
await session.initialize()
|
||||
|
||||
# 从 session 自动获取 MCP server 提供的工具列表。
|
||||
tools = await load_mcp_tools(session)
|
||||
# print(f"tools-->{tools}")
|
||||
|
||||
# 创建 agent 的提示模板
|
||||
prompt = ChatPromptTemplate.from_messages([
|
||||
("system",
|
||||
"你是一个票务预定助手,能够调用工具来完成火车票、飞机票或演出票的预定。你需要仔细分析工具需要的参数,然后从用户提供的信息中提取信息。如果用户提供的信息不足以提取到调用工具所有必要参数,则向用户追问,以获取该信息。不能自己编撰参数。"),
|
||||
("human", "{input}"),
|
||||
("placeholder", "{agent_scratchpad}"),
|
||||
])
|
||||
|
||||
# 构建工具调用代理
|
||||
agent = create_tool_calling_agent(llm, tools, prompt)
|
||||
|
||||
# 创建代理执行器
|
||||
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
||||
|
||||
# 代理调用
|
||||
response = await agent_executor.ainvoke({"input": query})
|
||||
return response['output']
|
||||
except Exception as e:
|
||||
logger.info(f"票务 MCP 测试出错:{str(e)}")
|
||||
return f"票务 MCP 查询出错:{str(e)}"
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"连接或会话初始化时发生错误: {e}")
|
||||
return "连接或会话初始化时发生错误"
|
||||
|
||||
if __name__ == "__main__":
|
||||
while True:
|
||||
query = input("请输入查询:")
|
||||
if query == "exit":
|
||||
break
|
||||
print(asyncio.run(order_tickets(query)))
|
||||
91
SmartVoyage/test/test_ticket_agent_server.py
Normal file
91
SmartVoyage/test/test_ticket_agent_server.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import asyncio
|
||||
import uuid
|
||||
|
||||
from python_a2a import A2AClient, Message, TextContent, MessageRole, Task
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
from SmartVoyage.create_logger import logger
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 初始化 LLM
|
||||
llm = ChatOpenAI(
|
||||
model=conf.model_name,
|
||||
api_key=conf.api_key,
|
||||
base_url=conf.base_url,
|
||||
temperature=0.1
|
||||
)
|
||||
ticket_prompt = ChatPromptTemplate.from_template(
|
||||
"""
|
||||
您是一位票务解说员,以生动、引人入胜的风格为用户介绍票务查询结果。基于以下查询结果,生成一段总结:
|
||||
- 突出出发/到达城市、时间、类型、价格和剩余票数,提及关键亮点。
|
||||
- 使用解说员的语气,例如“欢迎来到票务宝库!今天我们为您精选了...”。
|
||||
- 如果结果为空,建议用户尝试其他查询条件。
|
||||
- 保持中文叙述,字数控制在 100-150 字。
|
||||
|
||||
查询结果:
|
||||
{tickets}
|
||||
|
||||
总结:
|
||||
"""
|
||||
)
|
||||
def main():
|
||||
# 初始化票务客户端
|
||||
ticket_client = A2AClient("http://localhost:5006")
|
||||
|
||||
# 获取票务代理信息
|
||||
try:
|
||||
logger.info("获取票务助手信息")
|
||||
logger.info(f"名称: {ticket_client.agent_card.name}")
|
||||
logger.info(f"描述: {ticket_client.agent_card.description}")
|
||||
logger.info(f"版本: {ticket_client.agent_card.version}")
|
||||
if ticket_client.agent_card.skills:
|
||||
logger.info("支持技能:")
|
||||
for skill in ticket_client.agent_card.skills:
|
||||
logger.info(f"- {skill.name}: {skill.description}")
|
||||
if skill.examples:
|
||||
logger.info(f" 示例: {', '.join(skill.examples)}")
|
||||
except Exception as e:
|
||||
logger.error(f"无法获取票务助手信息: {str(e)}")
|
||||
|
||||
# 交互循环
|
||||
while True:
|
||||
user_input = input("输入您的票务查询(输入 'exit' 退出):")
|
||||
if user_input.lower() == 'exit':
|
||||
break
|
||||
|
||||
try:
|
||||
query = user_input.strip()
|
||||
logger.info(f"用户查询 (票务): {query}")
|
||||
|
||||
# 发送查询
|
||||
logger.info("正在查询数据...")
|
||||
message_ticket = Message(content=TextContent(text=query), role=MessageRole.USER)
|
||||
task_ticket = Task(id="task-" + str(uuid.uuid4()), message=message_ticket.to_dict())
|
||||
|
||||
# 发送任务并获取最终结果
|
||||
ticket_result_task = asyncio.run(ticket_client.send_task_async(task_ticket))
|
||||
logger.info(f"原始响应: {ticket_result_task}")
|
||||
|
||||
# 生成 LLM 总结
|
||||
if ticket_result_task.status.state == 'completed':
|
||||
try:
|
||||
summary_chain = ticket_prompt | llm
|
||||
ticket_result = ticket_result_task.artifacts[0]["parts"][0]["text"]
|
||||
summary = summary_chain.invoke({"tickets": ticket_result}).content.strip()
|
||||
logger.info(f"**票务解说员总结**:\n{summary}")
|
||||
except Exception as e:
|
||||
error_message = f"生成总结失败: {str(e)}"
|
||||
logger.error(error_message)
|
||||
else:
|
||||
logger.info(ticket_result_task.status.message['content']['text'])
|
||||
except Exception as e:
|
||||
error_message = f"查询失败: {str(e)}"
|
||||
logger.error(error_message)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("票务agent server查询客户端测试脚本")
|
||||
main()
|
||||
53
SmartVoyage/test/test_ticket_mcp_server.py
Normal file
53
SmartVoyage/test/test_ticket_mcp_server.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
from langchain_mcp_adapters.tools import load_mcp_tools
|
||||
from mcp import ClientSession
|
||||
from mcp.client.streamable_http import streamablehttp_client
|
||||
|
||||
|
||||
|
||||
# 定义服务器地址
|
||||
server_url = "http://127.0.0.1:8001/mcp"
|
||||
|
||||
async def test_ticket_mcp():
|
||||
try:
|
||||
# 启动 MCP server,通过streamable建立连接
|
||||
async with streamablehttp_client(server_url) as (read, write, _):
|
||||
# 使用读写通道创建 MCP 会话
|
||||
async with ClientSession(read, write) as session:
|
||||
try:
|
||||
await session.initialize()
|
||||
print("会话初始化成功,可以开始调用工具。")
|
||||
|
||||
# 从 session 自动获取 MCP server 提供的工具列表。
|
||||
tools = await load_mcp_tools(session)
|
||||
print(f"tools-->{tools}")
|
||||
|
||||
# 调用远程工具
|
||||
# 测试1: 查询机票
|
||||
sql_flights = "SELECT * FROM flight_tickets WHERE departure_city = '上海' AND arrival_city = '北京' AND DATE(departure_time) = '2026-05-15' AND cabin_type = '公务舱'"
|
||||
result_flights = await session.call_tool("query_tickets", {"sql": sql_flights})
|
||||
result_flights_data = json.loads(result_flights) if isinstance(result_flights, str) else result_flights
|
||||
print(f"机票查询结果:{result_flights_data}")
|
||||
|
||||
# 测试2: 查询火车票
|
||||
sql_trains = "SELECT * FROM train_tickets WHERE departure_city = '北京' AND arrival_city = '上海' AND DATE(departure_time) = '2025-08-26' AND seat_type = '二等座'"
|
||||
result_trains = await session.call_tool("query_tickets", {"sql": sql_trains})
|
||||
result_trains_data = json.loads(result_trains) if isinstance(result_trains, str) else result_trains
|
||||
print(f"火车票查询结果:{result_trains_data}")
|
||||
# 测试3: 查询演唱会票
|
||||
sql_concerts = "SELECT * FROM concert_tickets WHERE city = '北京' AND artist = '刀郎' AND DATE(start_time) = '2025-08-24' AND ticket_type = '看台'"
|
||||
result_concerts = await session.call_tool("query_tickets", {"sql": sql_concerts})
|
||||
result_concerts_data = json.loads(result_concerts) if isinstance(result_concerts,
|
||||
str) else result_concerts
|
||||
print(f"演唱会票查询结果:{result_concerts_data}")
|
||||
except Exception as e:
|
||||
print(f"票务 MCP 测试出错:{str(e)}")
|
||||
except Exception as e:
|
||||
print(f"连接或会话初始化时发生错误: {e}")
|
||||
print("请确认服务端脚本已启动并运行在 http://127.0.0.1:8001/mcp")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_ticket_mcp())
|
||||
93
SmartVoyage/test/test_weather_agent_server.py
Normal file
93
SmartVoyage/test/test_weather_agent_server.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import asyncio
|
||||
import uuid
|
||||
|
||||
from python_a2a import A2AClient, Message, TextContent, MessageRole, Task
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
|
||||
from SmartVoyage.config import Config
|
||||
from SmartVoyage.create_logger import logger
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 初始化 LLM
|
||||
llm = ChatOpenAI(
|
||||
model=conf.model_name,
|
||||
api_key=conf.api_key,
|
||||
base_url=conf.base_url,
|
||||
temperature=0.1
|
||||
)
|
||||
|
||||
# 天气总结提示模板
|
||||
weather_prompt = ChatPromptTemplate.from_template(
|
||||
"""
|
||||
您是一位天气解说员,以生动、引人入胜的风格为用户介绍天气查询结果。基于以下查询结果,生成一段总结:
|
||||
- 突出城市、日期、温度、天气描述和湿度,提及关键亮点如适宜活动。
|
||||
- 使用解说员的语气,例如“欢迎来到天气宝库!今天我们为您带来...”。
|
||||
- 如果结果为空,建议用户尝试其他查询条件。
|
||||
- 保持中文叙述,字数控制在 100-150 字。
|
||||
|
||||
查询结果:
|
||||
{weather}
|
||||
|
||||
总结:
|
||||
"""
|
||||
)
|
||||
|
||||
def main():
|
||||
# 初始化天气客户端
|
||||
weather_client = A2AClient("http://localhost:5005")
|
||||
|
||||
# 获取天气代理信息
|
||||
try:
|
||||
logger.info("获取天气助手信息")
|
||||
logger.info(f"名称: {weather_client.agent_card.name}")
|
||||
logger.info(f"描述: {weather_client.agent_card.description}")
|
||||
logger.info(f"版本: {weather_client.agent_card.version}")
|
||||
if weather_client.agent_card.skills:
|
||||
logger.info("支持技能:")
|
||||
for skill in weather_client.agent_card.skills:
|
||||
logger.info(f"- {skill.name}: {skill.description}")
|
||||
if skill.examples:
|
||||
logger.info(f" 示例: {', '.join(skill.examples)}")
|
||||
except Exception as e:
|
||||
logger.error(f"无法获取天气助手信息: {str(e)}")
|
||||
|
||||
# 交互循环
|
||||
while True:
|
||||
user_input = input("输入您的天气查询(输入 'exit' 退出):")
|
||||
if user_input.lower() == 'exit':
|
||||
break
|
||||
|
||||
try:
|
||||
query = user_input.strip()
|
||||
logger.info(f"用户查询 (天气): {query}")
|
||||
|
||||
# 发送查询
|
||||
logger.info("正在查询数据...")
|
||||
message_weather = Message(content=TextContent(text=query), role=MessageRole.USER)
|
||||
task_weather = Task(id="task-" + str(uuid.uuid4()), message=message_weather.to_dict())
|
||||
|
||||
weather_result_task = asyncio.run(weather_client.send_task_async(task_weather))
|
||||
logger.info(f"原始响应: {weather_result_task}")
|
||||
|
||||
# 生成 LLM 总结
|
||||
if weather_result_task.status.state == 'completed':
|
||||
try:
|
||||
summary_chain = weather_prompt | llm
|
||||
weather_result = weather_result_task.artifacts[0]["parts"][0]["text"]
|
||||
summary = summary_chain.invoke({"weather": weather_result}).content.strip()
|
||||
logger.info(f"**天气解说员总结**:\n{summary}")
|
||||
except Exception as e:
|
||||
error_message = f"生成总结失败: {str(e)}"
|
||||
logger.error(error_message)
|
||||
else:
|
||||
logger.info(weather_result_task.status.message['content']['text'])
|
||||
except Exception as e:
|
||||
error_message = f"查询失败: {str(e)}"
|
||||
logger.error(error_message)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("天气agent server查询客户端测试脚本")
|
||||
main()
|
||||
45
SmartVoyage/test/test_weather_mcp_server.py
Normal file
45
SmartVoyage/test/test_weather_mcp_server.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import asyncio
|
||||
import json
|
||||
|
||||
from langchain_mcp_adapters.tools import load_mcp_tools
|
||||
from mcp import ClientSession
|
||||
from mcp.client.streamable_http import streamablehttp_client
|
||||
|
||||
|
||||
# 定义服务器地址
|
||||
server_url = "http://127.0.0.1:8002/mcp"
|
||||
|
||||
async def test_weather_mcp():
|
||||
try:
|
||||
# 启动 MCP server,通过streamable建立连接
|
||||
async with streamablehttp_client(server_url) as (read, write, _):
|
||||
# 使用读写通道创建 MCP 会话
|
||||
async with ClientSession(read, write) as session:
|
||||
try:
|
||||
await session.initialize()
|
||||
print("会话初始化成功,可以开始调用工具。")
|
||||
|
||||
# 从 session 自动获取 MCP server 提供的工具列表。
|
||||
tools = await load_mcp_tools(session)
|
||||
print(f"tools-->{tools}")
|
||||
|
||||
# 测试1: 查询指定日期天气
|
||||
sql = "SELECT * FROM weather_data WHERE city = '北京' AND fx_date = '2026-03-22'"
|
||||
result = await session.call_tool("query_weather", {"sql": sql})
|
||||
result_data = json.loads(result) if isinstance(result, str) else result
|
||||
print(f"指定日期天气结果:{result_data}")
|
||||
|
||||
# 测试2: 查询未来3天天气
|
||||
sql_range = "SELECT * FROM weather_data WHERE city = '北京' AND fx_date BETWEEN '2026-01-28' AND '2026-01-30'"
|
||||
result_range = await session.call_tool("query_weather", {"sql": sql_range})
|
||||
result_range_data = json.loads(result_range) if isinstance(result_range, str) else result_range
|
||||
print(f"天气范围查询结果:{result_range_data}")
|
||||
except Exception as e:
|
||||
print(f"天气 MCP 测试出错:{str(e)}")
|
||||
except Exception as e:
|
||||
print(f"连接或会话初始化时发生错误: {e}")
|
||||
print("请确认服务端脚本已启动并运行在 http://127.0.0.1:8002/mcp")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(test_weather_mcp())
|
||||
38
SmartVoyage/utils/format.py
Normal file
38
SmartVoyage/utils/format.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import json
|
||||
from datetime import date, datetime, timedelta
|
||||
from decimal import Decimal
|
||||
|
||||
|
||||
def default_encoder(obj): # 定义编码器方法,用于格式化单个对象
|
||||
if isinstance(obj, datetime): # 检查是否为datetime,返回带时间的格式化字符串
|
||||
return obj.strftime('%Y-%m-%d %H:%M:%S')
|
||||
if isinstance(obj, date): # 检查是否为date,返回日期格式化字符串
|
||||
return obj.strftime('%Y-%m-%d')
|
||||
if isinstance(obj, timedelta): # 检查是否为timedelta,转换为字符串
|
||||
return str(obj)
|
||||
if isinstance(obj, Decimal): # 检查是否为Decimal,转换为浮点数
|
||||
return float(obj)
|
||||
return obj # 否则返回原对象
|
||||
|
||||
# 定义自定义JSON编码器类,继承自json.JSONEncoder,用于处理非标准类型序列化
|
||||
class DateEncoder(json.JSONEncoder):
|
||||
def default(self, obj): # 重写default方法,处理序列化时的默认对象转换
|
||||
if isinstance(obj, (date, datetime)): # 检查对象是否为date或datetime类型,对于datetime返回带时间的字符串,对于date返回日期字符串
|
||||
return obj.strftime('%Y-%m-%d %H:%M:%S') if isinstance(obj, datetime) else obj.strftime('%Y-%m-%d')
|
||||
if isinstance(obj, timedelta): # 检查对象是否为timedelta类型,将时间差转换为字符串
|
||||
return str(obj)
|
||||
if isinstance(obj, Decimal): # 检查对象是否为Decimal类型,将Decimal转换为浮点数以兼容JSON
|
||||
return float(obj)
|
||||
return super().default(obj) # 对于其他类型,调用父类默认方法
|
||||
if __name__ == '__main__':
|
||||
print(default_encoder(datetime(2025, 8, 11, 8, 0)))
|
||||
print(default_encoder(date(2025, 8, 11)))
|
||||
print(default_encoder(timedelta(days=1)))
|
||||
print(default_encoder(Decimal('123.45')))
|
||||
print('*'*80)
|
||||
|
||||
encoder = DateEncoder()
|
||||
print(encoder.default(datetime(2025, 8, 11, 8, 0)))
|
||||
print(encoder.default(date(2025, 8, 11)))
|
||||
print(encoder.default(timedelta(days=1)))
|
||||
print(encoder.default(Decimal('123.45')))
|
||||
240
SmartVoyage/utils/spider_weather.py
Normal file
240
SmartVoyage/utils/spider_weather.py
Normal file
@@ -0,0 +1,240 @@
|
||||
import requests
|
||||
import pymysql
|
||||
from datetime import datetime, timedelta
|
||||
import schedule
|
||||
import time
|
||||
import json
|
||||
import gzip
|
||||
import pytz
|
||||
from SmartVoyage.config import Config
|
||||
|
||||
conf = Config()
|
||||
|
||||
# 配置
|
||||
API_KEY = "d18b2e8db59d466585507624e248d719"
|
||||
city_codes = {
|
||||
"北京": "101010100",
|
||||
"上海": "101020100",
|
||||
"广州": "101280101",
|
||||
"深圳": "101280601"
|
||||
}
|
||||
BASE_URL = "https://np6hey8bmx.re.qweatherapi.com/v7/weather/7d"
|
||||
TZ = pytz.timezone('Asia/Shanghai') # 使用上海时区
|
||||
|
||||
# MySQL 配置
|
||||
db_config = {
|
||||
"host": conf.host,
|
||||
"user": conf.user,
|
||||
"password": conf.password,
|
||||
"database": conf.database,
|
||||
"charset": "utf8mb4"
|
||||
}
|
||||
def connect_db():
|
||||
return pymysql.connect(**db_config)
|
||||
def fetch_weather_data(city, location):
|
||||
headers = {
|
||||
"X-QW-Api-Key": API_KEY,
|
||||
"Accept-Encoding": "gzip"
|
||||
}
|
||||
url = f"{BASE_URL}?location={location}"
|
||||
try:
|
||||
response = requests.get(url, headers=headers, timeout=10)
|
||||
response.raise_for_status()
|
||||
if response.headers.get('Content-Encoding') == 'gzip':
|
||||
data = gzip.decompress(response.content).decode('utf-8')
|
||||
else:
|
||||
data = response.text
|
||||
return json.loads(data)
|
||||
except requests.RequestException as e:
|
||||
print(f"请求 {city} 天气数据失败: {e}")
|
||||
return None
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"{city} JSON 解析错误: {e}, 响应内容: {response.text[:500]}...")
|
||||
return None
|
||||
except gzip.BadGzipFile:
|
||||
print(f"{city} 数据未正确解压,尝试直接解析: {response.text[:500]}...")
|
||||
return json.loads(response.text) if response.text else None
|
||||
|
||||
def get_latest_update_time(cursor, city):
|
||||
cursor.execute("SELECT MAX(update_time) FROM weather_data WHERE city = %s", (city,))
|
||||
result = cursor.fetchone()
|
||||
return result[0] if result[0] else None
|
||||
def should_update_data(latest_time, force_update=False):
|
||||
if force_update:
|
||||
return True
|
||||
if latest_time is None:
|
||||
return True
|
||||
|
||||
# 时区问题:确保 latest_time 有时区信息
|
||||
if latest_time and latest_time.tzinfo is None:
|
||||
latest_time = latest_time.replace(tzinfo=TZ)
|
||||
|
||||
current_time = datetime.now(TZ)
|
||||
return (current_time - latest_time) > timedelta(days=1)
|
||||
def store_weather_data(conn, cursor, city, data):
|
||||
if not data or data.get("code") != "200":
|
||||
print(f"{city} 数据无效,跳过存储。")
|
||||
return
|
||||
|
||||
daily_data = data.get("daily", [])
|
||||
update_time = datetime.fromisoformat(data.get("updateTime").replace("+08:00", "+08:00")).replace(tzinfo=TZ)
|
||||
|
||||
for day in daily_data:
|
||||
fx_date = datetime.strptime(day["fxDate"], "%Y-%m-%d").date()
|
||||
values = (
|
||||
city, fx_date,
|
||||
day.get("sunrise"), day.get("sunset"),
|
||||
day.get("moonrise"), day.get("moonset"),
|
||||
day.get("moonPhase"), day.get("moonPhaseIcon"),
|
||||
day.get("tempMax"), day.get("tempMin"),
|
||||
day.get("iconDay"), day.get("textDay"),
|
||||
day.get("iconNight"), day.get("textNight"),
|
||||
day.get("wind360Day"), day.get("windDirDay"), day.get("windScaleDay"), day.get("windSpeedDay"),
|
||||
day.get("wind360Night"), day.get("windDirNight"), day.get("windScaleNight"), day.get("windSpeedNight"),
|
||||
day.get("precip"), day.get("uvIndex"),
|
||||
day.get("humidity"), day.get("pressure"),
|
||||
day.get("vis"), day.get("cloud"),
|
||||
update_time
|
||||
)
|
||||
insert_query = """
|
||||
INSERT INTO weather_data (
|
||||
city, fx_date, sunrise, sunset, moonrise, moonset, moon_phase, moon_phase_icon,
|
||||
temp_max, temp_min, icon_day, text_day, icon_night, text_night,
|
||||
wind360_day, wind_dir_day, wind_scale_day, wind_speed_day,
|
||||
wind360_night, wind_dir_night, wind_scale_night, wind_speed_night,
|
||||
precip, uv_index, humidity, pressure, vis, cloud, update_time
|
||||
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
sunrise = VALUES(sunrise), sunset = VALUES(sunset), moonrise = VALUES(moonrise),
|
||||
moonset = VALUES(moonset), moon_phase = VALUES(moon_phase), moon_phase_icon = VALUES(moon_phase_icon),
|
||||
temp_max = VALUES(temp_max), temp_min = VALUES(temp_min), icon_day = VALUES(icon_day),
|
||||
text_day = VALUES(text_day), icon_night = VALUES(icon_night), text_night = VALUES(text_night),
|
||||
wind360_day = VALUES(wind360_day), wind_dir_day = VALUES(wind_dir_day), wind_scale_day = VALUES(wind_scale_day),
|
||||
wind_speed_day = VALUES(wind_speed_day), wind360_night = VALUES(wind360_night),
|
||||
wind_dir_night = VALUES(wind_dir_night), wind_scale_night = VALUES(wind_scale_night),
|
||||
wind_speed_night = VALUES(wind_speed_night), precip = VALUES(precip), uv_index = VALUES(uv_index),
|
||||
humidity = VALUES(humidity), pressure = VALUES(pressure), vis = VALUES(vis),
|
||||
cloud = VALUES(cloud), update_time = VALUES(update_time)
|
||||
"""
|
||||
try:
|
||||
cursor.execute(insert_query, values)
|
||||
print(f"{city} {fx_date} 数据写入/更新成功: {day.get('textDay')}, 影响行数: {cursor.rowcount}")
|
||||
conn.commit()
|
||||
print(f"{city} 事务提交完成。")
|
||||
except pymysql.Error as e:
|
||||
print(f"{city} {fx_date} 数据库错误: {e}")
|
||||
conn.rollback()
|
||||
print(f"{city} 事务回滚。")
|
||||
def update_weather(force_update=False):
|
||||
conn = connect_db()
|
||||
cursor = conn.cursor()
|
||||
|
||||
for city, location in city_codes.items():
|
||||
latest_time = get_latest_update_time(cursor, city)
|
||||
if should_update_data(latest_time, force_update):
|
||||
print(f"开始更新 {city} 天气数据...")
|
||||
data = fetch_weather_data(city, location)
|
||||
if data:
|
||||
store_weather_data(conn, cursor, city, data)
|
||||
else:
|
||||
print(f"{city} 数据已为最新,无需更新。最新更新时间: {latest_time}")
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
def setup_scheduler():
|
||||
# 北京时间 1:00 对应 PDT 前一天的 16:00(夏令时)
|
||||
schedule.every().day.at("16:00").do(update_weather)
|
||||
while True:
|
||||
schedule.run_pending()
|
||||
time.sleep(60)
|
||||
|
||||
if __name__ == '__main__':
|
||||
with pymysql.connect(**db_config) as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS weather_data
|
||||
(
|
||||
id
|
||||
INT
|
||||
AUTO_INCREMENT
|
||||
PRIMARY
|
||||
KEY,
|
||||
city
|
||||
VARCHAR
|
||||
(
|
||||
50
|
||||
) NOT NULL COMMENT '城市名称',
|
||||
fx_date DATE NOT NULL COMMENT '预报日期',
|
||||
sunrise TIME COMMENT '日出时间',
|
||||
sunset TIME COMMENT '日落时间',
|
||||
moonrise TIME COMMENT '月升时间',
|
||||
moonset TIME COMMENT '月落时间',
|
||||
moon_phase VARCHAR
|
||||
(
|
||||
20
|
||||
) COMMENT '月相名称',
|
||||
moon_phase_icon VARCHAR
|
||||
(
|
||||
10
|
||||
) COMMENT '月相图标代码',
|
||||
temp_max INT COMMENT '最高温度',
|
||||
temp_min INT COMMENT '最低温度',
|
||||
icon_day VARCHAR
|
||||
(
|
||||
10
|
||||
) COMMENT '白天天气图标代码',
|
||||
text_day VARCHAR
|
||||
(
|
||||
20
|
||||
) COMMENT '白天天气描述',
|
||||
icon_night VARCHAR
|
||||
(
|
||||
10
|
||||
) COMMENT '夜间天气图标代码',
|
||||
text_night VARCHAR
|
||||
(
|
||||
20
|
||||
) COMMENT '夜间天气描述',
|
||||
wind360_day INT COMMENT '白天风向360角度',
|
||||
wind_dir_day VARCHAR
|
||||
(
|
||||
20
|
||||
) COMMENT '白天风向',
|
||||
wind_scale_day VARCHAR
|
||||
(
|
||||
10
|
||||
) COMMENT '白天风力等级',
|
||||
wind_speed_day INT COMMENT '白天风速 (km/h)',
|
||||
wind360_night INT COMMENT '夜间风向360角度',
|
||||
wind_dir_night VARCHAR
|
||||
(
|
||||
20
|
||||
) COMMENT '夜间风向',
|
||||
wind_scale_night VARCHAR
|
||||
(
|
||||
10
|
||||
) COMMENT '夜间风力等级',
|
||||
wind_speed_night INT COMMENT '夜间风速 (km/h)',
|
||||
precip DECIMAL
|
||||
(
|
||||
5,
|
||||
1
|
||||
) COMMENT '降水量 (mm)',
|
||||
uv_index INT COMMENT '紫外线指数',
|
||||
humidity INT COMMENT '相对湿度 (%)',
|
||||
pressure INT COMMENT '大气压强 (hPa)',
|
||||
vis INT COMMENT '能见度 (km)',
|
||||
cloud INT COMMENT '云量 (%)',
|
||||
update_time DATETIME COMMENT '数据更新时间',
|
||||
UNIQUE KEY unique_city_date
|
||||
(
|
||||
city,
|
||||
fx_date
|
||||
)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE =utf8mb4_unicode_ci COMMENT='天气数据表'
|
||||
""")
|
||||
conn.commit()
|
||||
update_weather()
|
||||
|
||||
# 启动定时任务
|
||||
setup_scheduler()
|
||||
72
mymath.py
Normal file
72
mymath.py
Normal file
@@ -0,0 +1,72 @@
|
||||
def multiply(a, b):
|
||||
"""
|
||||
计算两个数字的乘积
|
||||
|
||||
Args:
|
||||
a: 第一个数字
|
||||
b: 第二个数字
|
||||
|
||||
Returns:
|
||||
两个数字的乘积
|
||||
"""
|
||||
return a * b
|
||||
|
||||
def divide(a, b):
|
||||
"""
|
||||
计算两个数字的商
|
||||
|
||||
Args:
|
||||
a: 被除数
|
||||
b: 除数
|
||||
|
||||
Returns:
|
||||
两个数字的商
|
||||
|
||||
Raises:
|
||||
ValueError: 如果除数为零
|
||||
"""
|
||||
if b == 0:
|
||||
raise ValueError("除数不能为零")
|
||||
return a / b
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 测试乘法函数
|
||||
print("测试乘法函数:")
|
||||
test_cases_multiply = [
|
||||
(2, 3, 6),
|
||||
(-2, 3, -6),
|
||||
(0, 5, 0),
|
||||
(2.5, 4, 10.0),
|
||||
(-2.5, -2, 5.0)
|
||||
]
|
||||
|
||||
for a, b, expected in test_cases_multiply:
|
||||
result = multiply(a, b)
|
||||
status = "PASS" if result == expected else "FAIL"
|
||||
print(f" {status} multiply({a}, {b}) = {result} (期望: {expected})")
|
||||
|
||||
# 测试除法函数
|
||||
print("\n测试除法函数:")
|
||||
test_cases_divide = [
|
||||
(6, 3, 2),
|
||||
(10, 2, 5),
|
||||
(-6, 2, -3),
|
||||
(5, 2, 2.5),
|
||||
(0, 5, 0)
|
||||
]
|
||||
|
||||
for a, b, expected in test_cases_divide:
|
||||
try:
|
||||
result = divide(a, b)
|
||||
status = "PASS" if result == expected else "FAIL"
|
||||
print(f" {status} divide({a}, {b}) = {result} (期望: {expected})")
|
||||
except ValueError as e:
|
||||
print(f" FAIL divide({a}, {b}) 出错: {e}")
|
||||
|
||||
# 测试除数为零的情况
|
||||
print("\n测试除数为零:")
|
||||
try:
|
||||
divide(5, 0)
|
||||
print(" FAIL divide(5, 0) 应该抛出异常但没有")
|
||||
except ValueError as e:
|
||||
print(f" PASS divide(5, 0) 正确抛出异常: {e}")
|
||||
Reference in New Issue
Block a user