789 lines
30 KiB
Python
789 lines
30 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
提示词管理接口
|
||
"""
|
||
|
||
from flask import Blueprint, request, jsonify
|
||
import logging
|
||
from datetime import datetime
|
||
from auth_utils import require_auth, AuthUtils
|
||
from database_config import get_db_manager, format_datetime_fields
|
||
from log_utils import log_create, log_update, log_delete, log_error, log_operation
|
||
|
||
logger = logging.getLogger('article_server')
|
||
|
||
# 创建蓝图
|
||
prompt_bp = Blueprint('prompt', __name__, url_prefix='/api/prompts')
|
||
|
||
@prompt_bp.route('/list_info', methods=['GET'])
|
||
@require_auth
|
||
def get_prompts_list_info():
|
||
"""获取提示词列表(简化版,仅返回4个字段)"""
|
||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||
logger.info(f"[获取提示词列表简化版] 开始处理请求, IP: {client_ip}")
|
||
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
|
||
logger.info(f"[获取提示词列表简化版] 用户信息 - 用户ID: {current_user.get('user_id')}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
if not enterprise_id:
|
||
logger.warning(f"[获取提示词列表简化版] 无法获取企业ID, IP: {client_ip}")
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# 查询提示词列表(仅返回4个字段,优化性能)
|
||
sql = """
|
||
SELECT id, prompt_workflow_name, created_at, updated_at
|
||
FROM ai_prompt_workflow
|
||
WHERE enterprise_id = %s
|
||
ORDER BY created_at DESC
|
||
"""
|
||
prompts = db_manager.execute_query(sql, (enterprise_id,))
|
||
|
||
# 格式化日期时间字段
|
||
prompts = format_datetime_fields(prompts)
|
||
|
||
logger.info(f"[获取提示词列表简化版] 查询成功, 返回数量: {len(prompts)}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': 'success',
|
||
'data': {
|
||
'list': prompts
|
||
},
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[获取提示词列表简化版] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
@prompt_bp.route('/list', methods=['GET'])
|
||
@require_auth
|
||
def get_prompts_list():
|
||
"""获取提示词列表"""
|
||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||
logger.info(f"[获取提示词列表] 开始处理请求, IP: {client_ip}")
|
||
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
user_id = current_user.get('user_id')
|
||
|
||
logger.info(f"[获取提示词列表] 用户信息 - 用户ID: {user_id}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 获取查询参数
|
||
page = int(request.args.get('page', 1))
|
||
page_size = int(request.args.get('pageSize', 20))
|
||
|
||
# 计算偏移量
|
||
offset = (page - 1) * page_size
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# 查询总数
|
||
count_sql = "SELECT COUNT(*) as total FROM ai_prompt_workflow WHERE enterprise_id = %s"
|
||
count_result = db_manager.execute_query(count_sql, (enterprise_id,))
|
||
total = count_result[0]['total']
|
||
|
||
# 查询提示词列表
|
||
sql = """
|
||
SELECT id, prompt_workflow_name, workflow_id, content, usage_count, created_at, updated_at
|
||
FROM ai_prompt_workflow
|
||
WHERE enterprise_id = %s
|
||
ORDER BY created_at DESC
|
||
LIMIT %s OFFSET %s
|
||
"""
|
||
prompts = db_manager.execute_query(sql, (enterprise_id, page_size, offset))
|
||
|
||
# 查询每个提示词的标签
|
||
for prompt in prompts:
|
||
tag_sql = """
|
||
SELECT t.id, t.tag_name
|
||
FROM ai_prompt_tags t
|
||
INNER JOIN ai_prompt_tags_relation r ON t.id = r.tag_id
|
||
WHERE r.prompt_workflow_id = %s
|
||
"""
|
||
tags = db_manager.execute_query(tag_sql, (prompt['id'],))
|
||
prompt['tags'] = [tag['tag_name'] for tag in tags]
|
||
|
||
# 格式化日期时间字段
|
||
prompts = format_datetime_fields(prompts)
|
||
|
||
logger.info(f"[获取提示词列表] 查询成功, 总数: {total}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': 'success',
|
||
'data': {
|
||
'total': total,
|
||
'list': prompts
|
||
},
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[获取提示词列表] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
@prompt_bp.route('/create', methods=['POST'])
|
||
@require_auth
|
||
def create_prompt():
|
||
"""创建提示词"""
|
||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||
logger.info(f"[创建提示词] 开始处理请求, IP: {client_ip}")
|
||
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
user_id = current_user.get('user_id')
|
||
|
||
logger.info(f"[创建提示词] 用户信息 - 用户ID: {user_id}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '请求参数错误',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 验证必需字段
|
||
required_fields = ['prompt_workflow_name', 'content']
|
||
for field in required_fields:
|
||
if not data.get(field):
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': f'缺少必需字段: {field}',
|
||
'data': None
|
||
}), 400
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# 生成workflow_id
|
||
import uuid
|
||
workflow_id = f"WF-{str(uuid.uuid4())[:8].upper()}"
|
||
|
||
# 创建提示词
|
||
sql = """
|
||
INSERT INTO ai_prompt_workflow
|
||
(enterprise_id, prompt_workflow_name, workflow_id, content, usage_count)
|
||
VALUES (%s, %s, %s, %s, %s)
|
||
"""
|
||
prompt_id = db_manager.execute_insert(sql, (
|
||
enterprise_id,
|
||
data['prompt_workflow_name'],
|
||
workflow_id,
|
||
data['content'],
|
||
0
|
||
))
|
||
|
||
# 记录SQL操作日志
|
||
log_create(
|
||
target_type='prompt_workflow',
|
||
target_id=prompt_id,
|
||
description=f"创建提示词: {data['prompt_workflow_name']}"
|
||
)
|
||
|
||
# 添加标签关联
|
||
if data.get('tags'):
|
||
# ✅ 去重处理,避免重复标签导致唯一索引冲突
|
||
unique_tags = list(set(data['tags'])) # 去除重复标签
|
||
processed_tag_ids = set() # 记录已处理的 tag_id
|
||
|
||
for tag_name in unique_tags:
|
||
if not tag_name or not tag_name.strip(): # 跳过空标签
|
||
continue
|
||
|
||
tag_name = tag_name.strip()
|
||
|
||
# ✅ 查找或创建标签(基于 enterprise_id 隔离)
|
||
tag_sql = "SELECT id FROM ai_prompt_tags WHERE enterprise_id = %s AND tag_name = %s"
|
||
tag_result = db_manager.execute_query(tag_sql, (enterprise_id, tag_name))
|
||
|
||
if tag_result:
|
||
tag_id = tag_result[0]['id']
|
||
else:
|
||
tag_insert_sql = "INSERT INTO ai_prompt_tags (enterprise_id, tag_name, created_user_id) VALUES (%s, %s, %s)"
|
||
tag_id = db_manager.execute_insert(tag_insert_sql, (enterprise_id, tag_name, current_user.get('user_id', 0)))
|
||
|
||
# ✅ 检查是否已经处理过该 tag_id,避免重复插入
|
||
if tag_id in processed_tag_ids:
|
||
continue
|
||
|
||
processed_tag_ids.add(tag_id)
|
||
|
||
# ✅ 创建关联(添加 enterprise_id)
|
||
try:
|
||
rel_sql = "INSERT INTO ai_prompt_tags_relation (enterprise_id, prompt_workflow_id, prompt_workflow_name, tag_id, tag_name, created_user_id) VALUES (%s, %s, %s, %s, %s, %s)"
|
||
db_manager.execute_insert(rel_sql, (enterprise_id, prompt_id, data['prompt_workflow_name'], tag_id, tag_name, current_user.get('user_id', 0)))
|
||
except Exception as rel_error:
|
||
# 如果关联已存在,跳过
|
||
logger.warning(f"标签关联已存在: prompt_id={prompt_id}, tag_id={tag_id}, error={str(rel_error)}")
|
||
continue
|
||
|
||
logger.info(f"[创建提示词] 创建成功, ID: {prompt_id}, 名称: {data['prompt_workflow_name']}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': '创建成功',
|
||
'data': {
|
||
'id': prompt_id,
|
||
'prompt_workflow_name': data['prompt_workflow_name']
|
||
},
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[创建提示词] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
@prompt_bp.route('/<int:prompt_id>', methods=['PUT'])
|
||
@require_auth
|
||
def update_prompt(prompt_id):
|
||
"""更新提示词"""
|
||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||
logger.info(f"[更新提示词] 开始处理请求, ID: {prompt_id}, IP: {client_ip}")
|
||
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
user_id = current_user.get('user_id')
|
||
|
||
logger.info(f"[更新提示词] 用户信息 - 用户ID: {user_id}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '请求参数错误',
|
||
'data': None
|
||
}), 400
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# 检查提示词是否存在且属于当前企业
|
||
check_sql = "SELECT id FROM ai_prompt_workflow WHERE id = %s AND enterprise_id = %s"
|
||
existing = db_manager.execute_query(check_sql, (prompt_id, enterprise_id))
|
||
|
||
if not existing:
|
||
return jsonify({
|
||
'code': 404,
|
||
'message': '提示词不存在',
|
||
'data': None
|
||
}), 404
|
||
|
||
# 构建更新字段
|
||
update_fields = []
|
||
params = []
|
||
|
||
if 'prompt_workflow_name' in data:
|
||
update_fields.append("prompt_workflow_name = %s")
|
||
params.append(data['prompt_workflow_name'])
|
||
|
||
if 'content' in data:
|
||
update_fields.append("content = %s")
|
||
params.append(data['content'])
|
||
|
||
if update_fields:
|
||
params.append(prompt_id)
|
||
sql = f"UPDATE ai_prompt_workflow SET {', '.join(update_fields)}, updated_at = NOW() WHERE id = %s"
|
||
db_manager.execute_update(sql, params)
|
||
|
||
# 记录SQL操作日志
|
||
log_update(
|
||
target_type='prompt_workflow',
|
||
target_id=prompt_id,
|
||
description=f"更新提示词字段: {', '.join(update_fields)}"
|
||
)
|
||
|
||
# 更新标签关联
|
||
if 'tags' in data:
|
||
# 删除旧标签关联
|
||
del_sql = "DELETE FROM ai_prompt_tags_relation WHERE prompt_workflow_id = %s"
|
||
db_manager.execute_update(del_sql, (prompt_id,))
|
||
|
||
# ✅ 去重处理,避免重复标签导致唯一索引冲突
|
||
unique_tags = list(set(data['tags'])) # 去除重复标签
|
||
processed_tag_ids = set() # 记录已处理的 tag_id
|
||
|
||
# 查询prompt_workflow_name
|
||
prompt_info = db_manager.execute_query("SELECT prompt_workflow_name FROM ai_prompt_workflow WHERE id = %s", (prompt_id,))
|
||
prompt_workflow_name = prompt_info[0]['prompt_workflow_name'] if prompt_info else ''
|
||
|
||
# 添加新标签
|
||
for tag_name in unique_tags:
|
||
if not tag_name or not tag_name.strip(): # 跳过空标签
|
||
continue
|
||
|
||
tag_name = tag_name.strip()
|
||
|
||
# ✅ 查找或创建标签(基于 enterprise_id 隔离)
|
||
tag_sql = "SELECT id FROM ai_prompt_tags WHERE enterprise_id = %s AND tag_name = %s"
|
||
tag_result = db_manager.execute_query(tag_sql, (enterprise_id, tag_name))
|
||
|
||
if tag_result:
|
||
tag_id = tag_result[0]['id']
|
||
else:
|
||
tag_insert_sql = "INSERT INTO ai_prompt_tags (enterprise_id, tag_name, created_user_id) VALUES (%s, %s, %s)"
|
||
tag_id = db_manager.execute_insert(tag_insert_sql, (enterprise_id, tag_name, current_user.get('user_id', 0)))
|
||
|
||
# ✅ 检查是否已经处理过该 tag_id,避免重复插入
|
||
if tag_id in processed_tag_ids:
|
||
continue
|
||
|
||
processed_tag_ids.add(tag_id)
|
||
|
||
# ✅ 创建关联(添加 enterprise_id)
|
||
try:
|
||
rel_sql = "INSERT INTO ai_prompt_tags_relation (enterprise_id, prompt_workflow_id, prompt_workflow_name, tag_id, tag_name, created_user_id) VALUES (%s, %s, %s, %s, %s, %s)"
|
||
db_manager.execute_insert(rel_sql, (enterprise_id, prompt_id, prompt_workflow_name, tag_id, tag_name, current_user.get('user_id', 0)))
|
||
except Exception as rel_error:
|
||
# 如果关联已存在,跳过
|
||
logger.warning(f"标签关联已存在: prompt_id={prompt_id}, tag_id={tag_id}, error={str(rel_error)}")
|
||
continue
|
||
|
||
logger.info(f"[更新提示词] 更新成功, ID: {prompt_id}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': '更新成功',
|
||
'data': None,
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[更新提示词] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
@prompt_bp.route('/<int:prompt_id>', methods=['DELETE'])
|
||
@require_auth
|
||
def delete_prompt(prompt_id):
|
||
"""删除提示词"""
|
||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||
logger.info(f"[删除提示词] 开始处理请求, ID: {prompt_id}, IP: {client_ip}")
|
||
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
user_id = current_user.get('user_id')
|
||
|
||
logger.info(f"[删除提示词] 用户信息 - 用户ID: {user_id}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# 检查提示词是否存在且属于当前企业
|
||
check_sql = "SELECT id, prompt_workflow_name FROM ai_prompt_workflow WHERE id = %s AND enterprise_id = %s"
|
||
existing = db_manager.execute_query(check_sql, (prompt_id, enterprise_id))
|
||
|
||
if not existing:
|
||
return jsonify({
|
||
'code': 404,
|
||
'message': '提示词不存在',
|
||
'data': None
|
||
}), 404
|
||
|
||
# 删除标签关联
|
||
del_rel_sql = "DELETE FROM ai_prompt_tags_relation WHERE prompt_workflow_id = %s"
|
||
db_manager.execute_update(del_rel_sql, (prompt_id,))
|
||
|
||
# 删除提示词
|
||
sql = "DELETE FROM ai_prompt_workflow WHERE id = %s"
|
||
db_manager.execute_update(sql, (prompt_id,))
|
||
|
||
# 记录SQL操作日志
|
||
log_delete(
|
||
target_type='prompt_workflow',
|
||
target_id=prompt_id,
|
||
description=f"删除提示词: {existing[0]['prompt_workflow_name']}"
|
||
)
|
||
|
||
logger.info(f"[删除提示词] 删除成功, ID: {prompt_id}, 名称: {existing[0]['prompt_workflow_name']}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': '删除成功',
|
||
'data': None,
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[删除提示词] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
|
||
# ==================== 提示词标签管理 (ai_prompt_tags) ====================
|
||
|
||
@prompt_bp.route('/tags/list', methods=['GET'])
|
||
@require_auth
|
||
def get_tags_list():
|
||
"""获取标签列表"""
|
||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||
logger.info(f"[获取标签列表] 开始处理请求, IP: {client_ip}")
|
||
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
user_id = current_user.get('user_id')
|
||
|
||
logger.info(f"[获取标签列表] 用户信息 - 用户ID: {user_id}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 获取查询参数
|
||
page = int(request.args.get('page', 1))
|
||
page_size = int(request.args.get('pageSize', 20))
|
||
keyword = request.args.get('keyword', '').strip()
|
||
|
||
# 计算偏移量
|
||
offset = (page - 1) * page_size
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# ✅ 构建查询条件(基于 enterprise_id 隔离)
|
||
where_conditions = ["enterprise_id = %s"]
|
||
params = [enterprise_id]
|
||
|
||
if keyword:
|
||
where_conditions.append("tag_name LIKE %s")
|
||
params.append(f"%{keyword}%")
|
||
|
||
where_clause = " WHERE " + " AND ".join(where_conditions)
|
||
|
||
# 查询总数
|
||
count_sql = f"SELECT COUNT(*) as total FROM ai_prompt_tags{where_clause}"
|
||
count_result = db_manager.execute_query(count_sql, params)
|
||
total = count_result[0]['total']
|
||
|
||
# 查询标签列表
|
||
sql = f"""
|
||
SELECT id, tag_name, created_user_id, created_at, updated_at
|
||
FROM ai_prompt_tags
|
||
{where_clause}
|
||
ORDER BY created_at DESC
|
||
LIMIT %s OFFSET %s
|
||
"""
|
||
params.extend([page_size, offset])
|
||
tags = db_manager.execute_query(sql, params)
|
||
|
||
# 格式化日期时间字段
|
||
tags = format_datetime_fields(tags)
|
||
|
||
logger.info(f"[获取标签列表] 查询成功, 总数: {total}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': 'success',
|
||
'data': {
|
||
'total': total,
|
||
'list': tags
|
||
},
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[获取标签列表] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
|
||
@prompt_bp.route('/tags/create', methods=['POST'])
|
||
@require_auth
|
||
def create_tag():
|
||
"""创建标签"""
|
||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||
logger.info(f"[创建标签] 开始处理请求, IP: {client_ip}")
|
||
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
user_id = current_user.get('user_id', 0)
|
||
|
||
logger.info(f"[创建标签] 用户信息 - 用户ID: {user_id}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
data = request.get_json()
|
||
if not data or not data.get('tag_name'):
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '标签名称不能为空',
|
||
'data': None
|
||
}), 400
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# ✅ 检查标签是否已存在(基于 enterprise_id 隔离)
|
||
check_sql = "SELECT id FROM ai_prompt_tags WHERE enterprise_id = %s AND tag_name = %s"
|
||
existing = db_manager.execute_query(check_sql, (enterprise_id, data['tag_name']))
|
||
|
||
if existing:
|
||
return jsonify({
|
||
'code': 409,
|
||
'message': '标签名称已存在',
|
||
'data': None
|
||
}), 409
|
||
|
||
# ✅ 创建标签(添加 enterprise_id)
|
||
sql = """
|
||
INSERT INTO ai_prompt_tags (enterprise_id, tag_name, created_user_id)
|
||
VALUES (%s, %s, %s)
|
||
"""
|
||
tag_id = db_manager.execute_insert(sql, (enterprise_id, data['tag_name'], user_id))
|
||
|
||
# 记录SQL操作日志
|
||
log_create(
|
||
target_type='prompt_tag',
|
||
target_id=tag_id,
|
||
description=f"创建标签: {data['tag_name']}"
|
||
)
|
||
|
||
logger.info(f"[创建标签] 创建成功, ID: {tag_id}, 名称: {data['tag_name']}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': '创建成功',
|
||
'data': {
|
||
'id': tag_id,
|
||
'tag_name': data['tag_name']
|
||
},
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[创建标签] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
|
||
@prompt_bp.route('/tags/<int:tag_id>', methods=['PUT'])
|
||
@require_auth
|
||
def update_tag(tag_id):
|
||
"""更新标签"""
|
||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||
logger.info(f"[更新标签] 开始处理请求, ID: {tag_id}, IP: {client_ip}")
|
||
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
user_id = current_user.get('user_id')
|
||
|
||
logger.info(f"[更新标签] 用户信息 - 用户ID: {user_id}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
data = request.get_json()
|
||
if not data or not data.get('tag_name'):
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '标签名称不能为空',
|
||
'data': None
|
||
}), 400
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# ✅ 检查标签是否存在(基于 enterprise_id 隔离)
|
||
check_sql = "SELECT id FROM ai_prompt_tags WHERE id = %s AND enterprise_id = %s"
|
||
existing = db_manager.execute_query(check_sql, (tag_id, enterprise_id))
|
||
|
||
if not existing:
|
||
return jsonify({
|
||
'code': 404,
|
||
'message': '标签不存在',
|
||
'data': None
|
||
}), 404
|
||
|
||
# ✅ 检查新名称是否与其他标签重复(基于 enterprise_id 隔离)
|
||
dup_sql = "SELECT id FROM ai_prompt_tags WHERE enterprise_id = %s AND tag_name = %s AND id != %s"
|
||
duplicate = db_manager.execute_query(dup_sql, (enterprise_id, data['tag_name'], tag_id))
|
||
|
||
if duplicate:
|
||
return jsonify({
|
||
'code': 409,
|
||
'message': '标签名称已存在',
|
||
'data': None
|
||
}), 409
|
||
|
||
# 更新标签
|
||
sql = "UPDATE ai_prompt_tags SET tag_name = %s, updated_at = NOW() WHERE id = %s"
|
||
db_manager.execute_update(sql, (data['tag_name'], tag_id))
|
||
|
||
# 同步更新关系表中的标签名称
|
||
rel_sql = "UPDATE ai_prompt_tags_relation SET tag_name = %s WHERE tag_id = %s"
|
||
db_manager.execute_update(rel_sql, (data['tag_name'], tag_id))
|
||
|
||
# 记录SQL操作日志
|
||
log_update(
|
||
target_type='prompt_tag',
|
||
target_id=tag_id,
|
||
description=f"更新标签: {data['tag_name']}"
|
||
)
|
||
|
||
logger.info(f"[更新标签] 更新成功, ID: {tag_id}, 名称: {data['tag_name']}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': '更新成功',
|
||
'data': None,
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[更新标签] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
|
||
@prompt_bp.route('/tags/<int:tag_id>', methods=['DELETE'])
|
||
@require_auth
|
||
def delete_tag(tag_id):
|
||
"""删除标签"""
|
||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||
logger.info(f"[删除标签] 开始处理请求, ID: {tag_id}, IP: {client_ip}")
|
||
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
user_id = current_user.get('user_id')
|
||
|
||
logger.info(f"[删除标签] 用户信息 - 用户ID: {user_id}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# ✅ 检查标签是否存在(基于 enterprise_id 隔离)
|
||
check_sql = "SELECT id, tag_name FROM ai_prompt_tags WHERE id = %s AND enterprise_id = %s"
|
||
existing = db_manager.execute_query(check_sql, (tag_id, enterprise_id))
|
||
|
||
if not existing:
|
||
return jsonify({
|
||
'code': 404,
|
||
'message': '标签不存在',
|
||
'data': None
|
||
}), 404
|
||
|
||
# 检查是否有提示词正在使用该标签
|
||
rel_sql = "SELECT COUNT(*) as count FROM ai_prompt_tags_relation WHERE tag_id = %s"
|
||
rel_result = db_manager.execute_query(rel_sql, (tag_id,))
|
||
|
||
if rel_result[0]['count'] > 0:
|
||
return jsonify({
|
||
'code': 409,
|
||
'message': '该标签正在被使用,无法删除',
|
||
'data': None
|
||
}), 409
|
||
|
||
# 删除标签
|
||
sql = "DELETE FROM ai_prompt_tags WHERE id = %s"
|
||
db_manager.execute_update(sql, (tag_id,))
|
||
|
||
# 记录SQL操作日志
|
||
log_delete(
|
||
target_type='prompt_tag',
|
||
target_id=tag_id,
|
||
description=f"删除标签: {existing[0]['tag_name']}"
|
||
)
|
||
|
||
logger.info(f"[删除标签] 删除成功, ID: {tag_id}, 名称: {existing[0]['tag_name']}, 企业ID: {enterprise_id}, IP: {client_ip}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': '删除成功',
|
||
'data': None,
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[删除标签] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|