feat: 初始化考培练系统项目

- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
111
2026-01-24 19:33:28 +08:00
commit 998211c483
1197 changed files with 228429 additions and 0 deletions

View File

@@ -0,0 +1,198 @@
#!/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()