197 lines
5.1 KiB
Python
197 lines
5.1 KiB
Python
|
|
import os
|
|||
|
|
from flask import Flask, render_template, request, jsonify
|
|||
|
|
from dotenv import load_dotenv
|
|||
|
|
import dashscope
|
|||
|
|
from dashscope import Generation
|
|||
|
|
from datetime import datetime
|
|||
|
|
import json
|
|||
|
|
|
|||
|
|
load_dotenv()
|
|||
|
|
dashscope.api_key = os.getenv("DASHSCOPE_API_KEY")
|
|||
|
|
|
|||
|
|
app = Flask(__name__)
|
|||
|
|
|
|||
|
|
# --------------------------
|
|||
|
|
# 配置
|
|||
|
|
# --------------------------
|
|||
|
|
SCENE_PROMPTS = {
|
|||
|
|
"general": "这是通用写作场景,语言自然清晰。",
|
|||
|
|
"media": "这是自媒体写作,语言有吸引力,适合传播。",
|
|||
|
|
"script": "这是剧本写作,语言有画面感和情绪张力。",
|
|||
|
|
"essay": "这是学生作文写作,结构清晰、表达规范。",
|
|||
|
|
"academic_scene": "这是学术写作,语言严谨、逻辑清楚。"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
POLISH_STYLES = {
|
|||
|
|
"formal": "正式、书面",
|
|||
|
|
"literary": "文学性强、有文采",
|
|||
|
|
"spoken": "口语化、自然",
|
|||
|
|
"business": "商务、专业",
|
|||
|
|
"internet": "网络风格、轻松"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
history_records = []
|
|||
|
|
MAX_HISTORY = 10
|
|||
|
|
|
|||
|
|
# --------------------------
|
|||
|
|
# AI 调用
|
|||
|
|
# --------------------------
|
|||
|
|
def call_ai(prompt):
|
|||
|
|
resp = Generation.call(model="qwen-turbo", prompt=prompt)
|
|||
|
|
if resp.status_code == 200:
|
|||
|
|
return resp.output.text
|
|||
|
|
return "❌ AI 调用失败"
|
|||
|
|
|
|||
|
|
# --------------------------
|
|||
|
|
# 多版本润色
|
|||
|
|
# --------------------------
|
|||
|
|
def multi_version_rewrite(text, style):
|
|||
|
|
prompt = f"""
|
|||
|
|
请对以下文本进行润色,生成 3 个不同版本:
|
|||
|
|
要求:
|
|||
|
|
1. 保持原意
|
|||
|
|
2. 风格:{style}
|
|||
|
|
3. 输出 3 个版本,分别标记 版本1/版本2/版本3
|
|||
|
|
原文:
|
|||
|
|
{text}
|
|||
|
|
"""
|
|||
|
|
return call_ai(prompt)
|
|||
|
|
|
|||
|
|
# --------------------------
|
|||
|
|
# 扩写
|
|||
|
|
# --------------------------
|
|||
|
|
def expand_text(text, target_length):
|
|||
|
|
"""
|
|||
|
|
扩写文本到指定长度(字数/字符)
|
|||
|
|
"""
|
|||
|
|
prompt = f"""
|
|||
|
|
请将以下文本扩写,保持原意,但丰富细节和表达,使字数达到 {target_length} 字左右。
|
|||
|
|
可以生成 3 个不同版本,分别标记 版本1/版本2/版本3。
|
|||
|
|
原文:
|
|||
|
|
{text}
|
|||
|
|
"""
|
|||
|
|
return call_ai(prompt)
|
|||
|
|
|
|||
|
|
# --------------------------
|
|||
|
|
# 修改原因生成
|
|||
|
|
# --------------------------
|
|||
|
|
def generate_revision_reason(original, revised):
|
|||
|
|
prompt = f"""
|
|||
|
|
请对下面两段文本进行对比,说明修改的原因。
|
|||
|
|
仅输出文字说明,不要高亮或格式化。
|
|||
|
|
|
|||
|
|
原文:
|
|||
|
|
{original}
|
|||
|
|
|
|||
|
|
改写后:
|
|||
|
|
{revised}
|
|||
|
|
|
|||
|
|
请详细说明改动原因。
|
|||
|
|
"""
|
|||
|
|
return call_ai(prompt)
|
|||
|
|
|
|||
|
|
# --------------------------
|
|||
|
|
# 文学参考
|
|||
|
|
# --------------------------
|
|||
|
|
def generate_literary_reference(text):
|
|||
|
|
prompt = f"""
|
|||
|
|
请理解下面这句话的含义,然后给出 3 条
|
|||
|
|
“文学作品风格中的相似表达示例”。
|
|||
|
|
|
|||
|
|
要求:
|
|||
|
|
1. 不是原文引用
|
|||
|
|
2. 给出【风格参考作者】和【作品名】
|
|||
|
|
3. 仅作为文学风格参考
|
|||
|
|
|
|||
|
|
输出格式:
|
|||
|
|
1. 句子内容
|
|||
|
|
—— 风格参考:作者《作品名》
|
|||
|
|
|
|||
|
|
原句:
|
|||
|
|
{text}
|
|||
|
|
"""
|
|||
|
|
return call_ai(prompt)
|
|||
|
|
|
|||
|
|
# --------------------------
|
|||
|
|
# 历史记录
|
|||
|
|
# --------------------------
|
|||
|
|
def save_history(data, result):
|
|||
|
|
history_records.insert(0, {
|
|||
|
|
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|||
|
|
"mode": data.get("mode"),
|
|||
|
|
"scene": data.get("scene"),
|
|||
|
|
"input": data.get("text", "")[:100],
|
|||
|
|
"output": result[:200]
|
|||
|
|
})
|
|||
|
|
if len(history_records) > MAX_HISTORY:
|
|||
|
|
history_records.pop()
|
|||
|
|
|
|||
|
|
# --------------------------
|
|||
|
|
# 情感分析
|
|||
|
|
# --------------------------
|
|||
|
|
def sentiment_analysis(text):
|
|||
|
|
prompt = f"""
|
|||
|
|
请分析下面文本的情感倾向,仅返回严格 JSON 格式:
|
|||
|
|
{{"positive": %, "neutral": %, "negative": %}}
|
|||
|
|
文本:
|
|||
|
|
{text}
|
|||
|
|
"""
|
|||
|
|
result = call_ai(prompt)
|
|||
|
|
try:
|
|||
|
|
parsed = json.loads(result.replace(":", ":").replace("%",""))
|
|||
|
|
return parsed
|
|||
|
|
except:
|
|||
|
|
return {"positive":0, "neutral":0, "negative":0}
|
|||
|
|
|
|||
|
|
# --------------------------
|
|||
|
|
# 路由
|
|||
|
|
# --------------------------
|
|||
|
|
@app.route("/")
|
|||
|
|
def index():
|
|||
|
|
return render_template("index.html")
|
|||
|
|
|
|||
|
|
@app.route("/rewrite", methods=["POST"])
|
|||
|
|
def rewrite():
|
|||
|
|
data = request.json
|
|||
|
|
text = data.get("text","")
|
|||
|
|
mode = data.get("mode")
|
|||
|
|
scene = data.get("scene","general")
|
|||
|
|
|
|||
|
|
# 根据模式生成文本
|
|||
|
|
if mode=="polish":
|
|||
|
|
style = data.get("style","formal")
|
|||
|
|
result = multi_version_rewrite(text, style)
|
|||
|
|
elif mode=="expand":
|
|||
|
|
target_length = data.get("target_length", 300)
|
|||
|
|
result = expand_text(text, target_length)
|
|||
|
|
else:
|
|||
|
|
result = f"普通生成模式:{text}" # 保留原功能
|
|||
|
|
|
|||
|
|
save_history(data, result)
|
|||
|
|
return jsonify({"result": result})
|
|||
|
|
|
|||
|
|
@app.route("/literary", methods=["POST"])
|
|||
|
|
def literary():
|
|||
|
|
text = request.json.get("text","")
|
|||
|
|
return jsonify({"reference": generate_literary_reference(text)})
|
|||
|
|
|
|||
|
|
@app.route("/history")
|
|||
|
|
def history():
|
|||
|
|
return jsonify(history_records)
|
|||
|
|
|
|||
|
|
@app.route("/revision_reason", methods=["POST"])
|
|||
|
|
def revision_reason():
|
|||
|
|
data = request.json
|
|||
|
|
original = data.get("original","")
|
|||
|
|
revised = data.get("revised","")
|
|||
|
|
reason = generate_revision_reason(original, revised)
|
|||
|
|
return jsonify({"reason": reason})
|
|||
|
|
|
|||
|
|
@app.route("/sentiment", methods=["POST"])
|
|||
|
|
def sentiment():
|
|||
|
|
text = request.json.get("text","")
|
|||
|
|
return jsonify({"result": sentiment_analysis(text)})
|
|||
|
|
|
|||
|
|
if __name__=="__main__":
|
|||
|
|
app.run(debug=True)
|