- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
199 lines
9.9 KiB
Python
199 lines
9.9 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
创建陪练场景表并插入初始数据 - 简单版本
|
||
"""
|
||
import pymysql
|
||
import sys
|
||
|
||
# 数据库连接配置
|
||
DB_CONFIG = {
|
||
'host': 'localhost',
|
||
'port': 3306,
|
||
'user': 'root',
|
||
'password': 'nj861021', # 开发环境密码
|
||
'database': 'kaopeilian',
|
||
'charset': 'utf8mb4'
|
||
}
|
||
|
||
# SQL语句
|
||
CREATE_TABLE_SQL = """
|
||
CREATE TABLE IF NOT EXISTS `practice_scenes` (
|
||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||
`name` VARCHAR(200) NOT NULL COMMENT '场景名称',
|
||
`description` TEXT COMMENT '场景描述',
|
||
`type` VARCHAR(50) NOT NULL COMMENT '场景类型',
|
||
`difficulty` VARCHAR(50) NOT NULL COMMENT '难度等级',
|
||
`status` VARCHAR(20) DEFAULT 'active' COMMENT '状态',
|
||
`background` TEXT COMMENT '场景背景设定',
|
||
`ai_role` TEXT COMMENT 'AI角色描述',
|
||
`objectives` JSON COMMENT '练习目标数组',
|
||
`keywords` JSON COMMENT '关键词数组',
|
||
`duration` INT DEFAULT 10 COMMENT '预计时长(分钟)',
|
||
`usage_count` INT DEFAULT 0 COMMENT '使用次数',
|
||
`rating` DECIMAL(3,1) DEFAULT 0.0 COMMENT '评分',
|
||
`created_by` INT COMMENT '创建人ID',
|
||
`updated_by` INT COMMENT '更新人ID',
|
||
`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
`is_deleted` BOOLEAN DEFAULT FALSE,
|
||
`deleted_at` DATETIME,
|
||
INDEX idx_type (type),
|
||
INDEX idx_difficulty (difficulty),
|
||
INDEX idx_status (status),
|
||
INDEX idx_is_deleted (is_deleted),
|
||
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL,
|
||
FOREIGN KEY (updated_by) REFERENCES users(id) ON DELETE SET NULL
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='陪练场景表'
|
||
"""
|
||
|
||
# 初始场景数据
|
||
SCENES = [
|
||
{
|
||
'name': '初次电话拜访客户',
|
||
'description': '模拟首次通过电话联系潜在客户的场景,练习专业的电话销售技巧',
|
||
'type': 'phone',
|
||
'difficulty': 'beginner',
|
||
'status': 'active',
|
||
'background': '你是一名轻医美品牌的销售专员,需要通过电话联系一位从未接触过的潜在客户。客户是某美容院的老板,你需要在短时间内引起她的兴趣,介绍你们的产品和服务。',
|
||
'ai_role': 'AI扮演一位忙碌的美容院老板,对推销电话比较抵触,但如果销售人员能够快速切入她的需求点(如提升业绩、吸引客户、新项目),她会愿意继续交谈。她关注产品效果、价格和培训支持。',
|
||
'objectives': '["学会专业的电话开场白", "快速建立信任关系", "有效探询客户需求", "预约下次沟通时间"]',
|
||
'keywords': '["开场白", "需求挖掘", "时间管理", "预约技巧"]',
|
||
'duration': 10
|
||
},
|
||
{
|
||
'name': '处理价格异议',
|
||
'description': '练习如何应对客户对产品价格的质疑和异议,强调价值而非价格',
|
||
'type': 'face',
|
||
'difficulty': 'intermediate',
|
||
'status': 'active',
|
||
'background': '客户对你们的轻医美产品很感兴趣,已经了解了产品功能和效果,但认为价格太高,超出了她的预算。你需要通过价值塑造和对比分析来化解价格异议。',
|
||
'ai_role': 'AI扮演一位对价格非常敏感的美容院老板,她会不断提出价格异议,例如"太贵了"、"竞品便宜一半"、"能不能再便宜点"。但如果销售人员能够有效展示产品价值、投资回报率和长期收益,她会逐渐被说服。',
|
||
'objectives': '["掌握价值塑造技巧", "学会处理价格异议", "提升谈判能力", "展示投资回报率"]',
|
||
'keywords': '["异议处理", "价值塑造", "谈判技巧", "ROI分析"]',
|
||
'duration': 15
|
||
},
|
||
{
|
||
'name': '客户投诉处理',
|
||
'description': '模拟客户对产品或服务不满的投诉场景,练习专业的投诉处理技巧',
|
||
'type': 'complaint',
|
||
'difficulty': 'intermediate',
|
||
'status': 'active',
|
||
'background': '一位客户购买了你们的轻医美产品后,使用效果不理想,打电话来投诉。她情绪比较激动,认为产品宣传与实际不符,要求退款。你需要安抚客户情绪,了解问题根源,并提供合理的解决方案。',
|
||
'ai_role': 'AI扮演一位情绪激动的客户,她对产品效果不满意,觉得被欺骗了。她会表达强烈的不满和质疑,但如果客服人员能够真诚道歉、耐心倾听、专业分析问题原因并提供切实可行的解决方案,她的态度会逐渐缓和。',
|
||
'objectives': '["掌握情绪安抚技巧", "学会倾听和共情", "分析问题并提供解决方案", "挽回客户信任"]',
|
||
'keywords': '["投诉处理", "情绪管理", "问题分析", "客户挽回"]',
|
||
'duration': 12
|
||
},
|
||
{
|
||
'name': '产品功能介绍',
|
||
'description': '练习向客户详细介绍轻医美产品的功能特点和优势',
|
||
'type': 'product-intro',
|
||
'difficulty': 'junior',
|
||
'status': 'active',
|
||
'background': '客户对你们的轻医美产品有一定了解,现在希望你详细介绍产品的核心功能、技术原理、使用方法和效果保证。客户比较专业,会提出一些技术性问题。',
|
||
'ai_role': 'AI扮演一位专业的美容院经营者,她对轻医美产品有一定了解,会提出具体的技术问题和需求。例如询问产品成分、作用机理、适用人群、操作流程、注意事项等。她希望得到专业、详细、真实的回答。',
|
||
'objectives': '["清晰介绍产品功能和原理", "突出产品优势和差异化", "专业回答技术问题", "建立专业形象"]',
|
||
'keywords': '["产品介绍", "功能展示", "优势分析", "技术解答"]',
|
||
'duration': 12
|
||
},
|
||
{
|
||
'name': '售后服务咨询',
|
||
'description': '模拟客户咨询售后服务的场景,练习专业的售后服务沟通技巧',
|
||
'type': 'after-sales',
|
||
'difficulty': 'beginner',
|
||
'status': 'active',
|
||
'background': '客户已经购买了你们的轻医美产品,现在打电话咨询售后服务相关问题,包括产品使用方法、遇到的小问题、培训支持、配件购买等。你需要提供专业、耐心、周到的售后服务。',
|
||
'ai_role': 'AI扮演一位已购买产品的美容院老板,她在使用产品过程中遇到一些问题或疑问,希望得到专业的指导和帮助。她的态度比较友好,但希望得到快速、有效的解决方案。她会根据服务质量评价品牌。',
|
||
'objectives': '["掌握产品使用指导技巧", "快速解决客户问题", "提供专业培训支持", "增强客户满意度和忠诚度"]',
|
||
'keywords': '["售后服务", "使用指导", "问题解决", "客户维护"]',
|
||
'duration': 10
|
||
}
|
||
]
|
||
|
||
def main():
|
||
"""主函数"""
|
||
try:
|
||
print("=" * 60)
|
||
print("陪练场景表创建和初始数据插入")
|
||
print("=" * 60)
|
||
|
||
# 连接数据库
|
||
print("\n📝 连接数据库...")
|
||
connection = pymysql.connect(**DB_CONFIG)
|
||
cursor = connection.cursor()
|
||
|
||
# 创建表
|
||
print("📝 创建practice_scenes表...")
|
||
cursor.execute(CREATE_TABLE_SQL)
|
||
print("✅ 表创建成功")
|
||
|
||
# 检查是否已有数据
|
||
cursor.execute("SELECT COUNT(*) FROM practice_scenes WHERE is_deleted = FALSE")
|
||
count = cursor.fetchone()[0]
|
||
|
||
if count > 0:
|
||
print(f"\n⚠️ 表中已有 {count} 条数据,是否要插入新数据?")
|
||
print(" 提示:如果数据已存在,将跳过插入")
|
||
|
||
# 插入数据
|
||
insert_sql = """
|
||
INSERT INTO practice_scenes
|
||
(name, description, type, difficulty, status, background, ai_role, objectives, keywords, duration, created_by, updated_by)
|
||
VALUES (%(name)s, %(description)s, %(type)s, %(difficulty)s, %(status)s, %(background)s, %(ai_role)s, %(objectives)s, %(keywords)s, %(duration)s, 1, 1)
|
||
"""
|
||
|
||
print(f"\n📝 插入 {len(SCENES)} 个初始场景...")
|
||
inserted = 0
|
||
for scene in SCENES:
|
||
try:
|
||
cursor.execute(insert_sql, scene)
|
||
inserted += 1
|
||
print(f" ✅ 插入场景: {scene['name']}")
|
||
except pymysql.err.IntegrityError as e:
|
||
if "Duplicate entry" in str(e):
|
||
print(f" ⚠️ 场景已存在: {scene['name']}")
|
||
else:
|
||
raise
|
||
|
||
# 提交事务
|
||
connection.commit()
|
||
print(f"\n✅ 成功插入 {inserted} 个场景")
|
||
|
||
# 查询验证
|
||
print("\n📝 查询验证...")
|
||
cursor.execute("SELECT id, name, type, difficulty, status FROM practice_scenes WHERE is_deleted = FALSE")
|
||
rows = cursor.fetchall()
|
||
|
||
print(f"\n当前场景列表(共 {len(rows)} 个):")
|
||
print("-" * 80)
|
||
print(f"{'ID':<5} {'名称':<30} {'类型':<15} {'难度':<15} {'状态':<10}")
|
||
print("-" * 80)
|
||
for row in rows:
|
||
print(f"{row[0]:<5} {row[1]:<30} {row[2]:<15} {row[3]:<15} {row[4]:<10}")
|
||
|
||
# 关闭连接
|
||
cursor.close()
|
||
connection.close()
|
||
|
||
print("\n" + "=" * 60)
|
||
print("✅ 陪练场景表创建和数据插入完成!")
|
||
print("=" * 60)
|
||
|
||
except pymysql.err.OperationalError as e:
|
||
print(f"\n❌ 数据库连接失败: {e}")
|
||
print(" 请检查:")
|
||
print(" 1. MySQL服务是否启动")
|
||
print(" 2. 数据库配置是否正确")
|
||
print(" 3. 数据库kaopeilian是否存在")
|
||
sys.exit(1)
|
||
except Exception as e:
|
||
print(f"\n❌ 发生错误: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
sys.exit(1)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|
||
|