day15-Codex开发数字人后端-微信小程序创建-仅笔记
今日内容
1 立项:决定开发xx项目
2 需求调研:需求分析书
3 设计图:html版本----》转到了figma中微调
4 分任务开发
-架构文档
-前端:微信小程序
-后端:Django后端
5 联调-测试
6 上线
1 后端环境搭建
本地开发完【我们目前用的机器】---》测试通过---》上线到服务器【购买阿里云】
1.1 Python环境【必须】
# 0 前置条件:先刷苑老师讲的python课,两三天才能继续往后做
-最好全看完,至少看到pycharm环境装好
-我们的后端使用Python编写,本地开发,本地要有Python环境
-Go,java,php,c。。。其实都可以编写后端---》但是都需要搭建对应语言的环境
# 1 老师用的Python3.13.11
-如果大家会装python解释器---》最好跟我一样【3.13 小版本不需要区分】
-如果大家不会--》之前装了其他版本,用其他版本也可以--》3.14 ,3.12
# 2 验证一下自己python版本
# 验证-打开cmd,输入
python --version
Python 3.13.11

1.2 Django环境【可以不装】
# 1 Python 环境搭建好,可以写python代码,并运行了
# 2 我们后端项目还基于Django,其实需要安装Django环境
# 3 Django 环境,可以不用搭建,Codex可以帮我们装好
# 4 想搭建:按照如下步骤
1 打开cmd
2 pip install django==4.2
# 4 在我们本地的python解释器上,装了django框架
python3.13+django4.2 ---》就可以开发Django项目了


1.3 Pycharm环境【必须】
# 1 有了Python环境,我们可以开发python代码并运行
# 2 代码编辑器:python代码-pycharm软件
-vscode
-记事本
。。。
# 3 按照苑老师视频下载并破解成功
1.4 Python调用Coze口播工作流代码【可以不测-给Codex用而已】
# 1 使用Python 调用我们coze工作流:口播数字人
-能调通,就能集成到我们项目中
# 2 同学们不需要懂--》是我 + AI写的
-纯AI写有bug---》python调用coze工作流--》API是Coze提供的--》有的ai读不到Coze提供的文档--》有时候Coze文档改了--》ai还是用老办法写,就会有bug
-把coze文档的说明网页给AI不行吗?--》》可以解决百分之90的问题
-Coze的官方文档--》可能更新不及时
# 3 使用代码之前:
1 获取口播工作流的id号【必须发布】:7669850629418647590
2 获取令牌:https://www.coze.cn/open/oauth/pats:只会出现一次
-pat_MU1wMhrbv1NbXEK43vUTvZSKJHiu5sy8aaF8rH3HbpIED69FxPIaG5ogE7fOraVE
3 修改下面代码:你们改 14-api_key密钥行 和 15行-id号




import requests
import json
import time
import os
from typing import Optional, Dict, Any
'''
个人访问令牌:https://www.coze.cn/open/oauth/pats
'''
class CozeAPI:
def __init__(self, api_key: str = None, workflow_id: str = None):
self.api_key = api_key or '你们要改'
self.workflow_id = workflow_id or '你们要改'
self.base_url = 'https://api.coze.cn'
self.upload_url = f"{self.base_url}/v1/files/upload"
self.run_url = f"{self.base_url}/v1/workflow/run"
self.headers = {'Authorization': f'Bearer {self.api_key}', 'Content-Type': 'application/json'}
def _get_save_path(self, task_id: str) -> str:
"""内部方法:生成视频保存路径(精简路径处理逻辑)"""
result_dir = os.path.join('coze_results')
os.makedirs(result_dir, exist_ok=True)
filename = f"result_{task_id}_{int(time.time())}.mp4"
return os.path.join(result_dir, filename)
def download_video(self, image_url: str, task_id: str) -> Optional[str]:
"""下载视频到本地,返回跨平台路径"""
try:
save_path = self._get_save_path(task_id)
resp = requests.get(image_url, stream=True)
resp.raise_for_status()
with open(save_path, 'wb') as f:
for chunk in resp.iter_content(chunk_size=8192):
f.write(chunk)
print(f"视频下载成功: {save_path}")
return save_path.replace('\\', '/')
except Exception as e:
print(f"视频下载失败: {str(e)}")
return None
def upload_file(self, file_path: str) -> str:
"""上传文件到Coze并获取文件ID"""
if not os.path.exists(file_path):
raise FileNotFoundError(f"文件不存在: {file_path}")
try:
print(f"开始上传文件: {file_path}")
with open(file_path, 'rb') as f:
files = {'file': (os.path.basename(file_path), f)}
resp = requests.post(self.upload_url, headers={'Authorization': f'Bearer {self.api_key}'}, files=files)
print(f"上传响应: {resp.status_code} | {resp.text}")
result = resp.json()
if resp.status_code == 200 and result.get('code') == 0 and 'data' in result:
file_id = result['data'].get('id')
if not file_id:
raise Exception(f"未提取到文件ID: {result}")
print(f"文件上传成功,ID: {file_id}")
return file_id
raise Exception(f"文件上传失败: {result}")
except Exception as e:
print(f"文件上传异常: {str(e)}")
raise
def run_workflow(self, source_image: str, target_image: str) -> Dict[str, Any]:
"""运行Coze换脸工作流,返回任务信息"""
try:
# 批量上传文件
source_id, target_id = self.upload_file(source_image), self.upload_file(target_image)
payload = {
"workflow_id": self.workflow_id,
"parameters": {
"voice": json.dumps({"file_id": source_id}),
"video": json.dumps({"file_id": target_id}),
"text": "执行数字人操作"
},
"app_id": "",
#"is_async": True
}
print(f"调用工作流 {self.workflow_id}...")
resp = requests.post(self.run_url, headers=self.headers, json=payload)
if resp.status_code != 200:
raise Exception(f"工作流调用失败: {resp.status_code} | {resp.text}")
result = resp.json()
if (result.get('code') == 0 or result.get('msg') == '') and (task_id := result.get('execute_id')):
print(f"工作流调用成功,任务ID: {task_id}")
return {'code': 0, 'msg': 'success',
'data': {'task_id': task_id, 'workflow_id': self.workflow_id, 'status': 'pending'}}
raise Exception(f"工作流调用失败: {result.get('msg')} | {result}")
except Exception as e:
print(f"工作流调用异常: {str(e)}")
raise
def get_workflow_result(self, task_id: str) -> Dict[str, Any]:
"""查询工作流执行结果"""
try:
print(f"查询任务 {task_id} 结果...")
# 简化URL拼接(移除模板字符串,直接格式化)
query_url = f"{self.base_url}/v1/workflows/{self.workflow_id}/run_histories/{task_id}"
resp = requests.get(query_url, headers=self.headers)
if resp.status_code != 200:
raise Exception(f"查询失败: {resp.status_code} | {resp.text}")
result = resp.json()
if result.get('code') != 0:
raise Exception(f"查询结果失败: {result.get('msg')} | {result}")
# 提取核心数据
data = result.get('data', [{}])[0]
exec_status = data.get('execute_status', '')
if exec_status == 'Success':
return self._parse_success_result(data, task_id)
elif exec_status == 'Fail':
return {'status': 'failed', 'error_message': '任务执行失败', 'task_id': task_id}
return {'status': 'processing', 'task_id': task_id}
except Exception as e:
print(f"查询结果异常: {str(e)}")
raise
def _parse_success_result(self, data: Dict[str, Any], task_id: str) -> Dict[str, Any]:
"""内部方法:解析成功的任务结果(拆分复杂的解析逻辑)"""
try:
output = json.loads(data.get('output', '{}'))
result_data = json.loads(output.get('Output', '{}'))
video_url = result_data.get('output')
if not video_url:
return {'status': 'success', 'message': '任务成功但未返回视频', 'task_id': task_id}
local_path = self.download_video(video_url, task_id)
return {
'status': 'success',
'result_video_url': video_url,
'local_video_path': local_path,
'processing_time': data.get('processing_time', 0),
'task_id': task_id
}
except (json.JSONDecodeError, KeyError) as e:
print(f"解析输出失败: {str(e)}")
return {'status': 'success', 'message': '任务成功但解析输出失败', 'task_id': task_id}
if __name__ == '__main__':
try:
coze_api = CozeAPI()
voice_path, video_path = './lqz.mp3', './lqz.mp4'
print("开始测试Coze数字人工作流...")
# 运行工作流并获取任务ID
run_result = coze_api.run_workflow(voice_path, video_path)
print(f"工作流提交结果: {run_result}")
if run_result.get('code') == 0:
task_id = run_result['data']['task_id']
print(f"任务ID: {task_id}")
time.sleep(60) # 等待任务处理
# 查询结果
result = coze_api.get_workflow_result(task_id)
print(f"任务结果: {result}")
# 精简结果判断逻辑
status_map = {
'success': f"测试成功!\nURL: {result.get('result_video_url')}\n本地路径: {result.get('local_video_path')}",
'processing': "任务仍在处理中",
'failed': f"任务失败: {result.get('error_message')}"
}
print(status_map.get(result.get('status'), " 未知状态"))
except Exception as e:
print(f" 测试失败: {str(e)}", exc_info=True)
2 前后端架构文档
# 1 架构说明书是由公司架构师编写,规定,规范的--》后期开发人员按照这个说明书的要求开发项目
-内部涵盖开发技术,数据库等等
# 2 使用Codex生成---》大家不用改了,如果大家不懂后端和小程序开发,好多技术点大家可能看不懂
# 3 提示词
根据01-需求分析/项目需求.md 和02-UI设计下所有html设计图,生成项目架构设计文档,包含后端架构文档和微信小程序架构文档
要求:
1.后端使用Python+Django 4 + Mysql8 + DjangoRestFramework等技术实现。
2.微信小程序端使用小程序原生框架。
3.后台管理使用django 自带admin和Simpleui美化。
4.前后端目录结构都一并生成,后端接口格式和参数和返回值格式也生成。
5.后端数据库设计:设计出项目所需表和字段(简要ER图),用户表使用Django自带的User表。
6.以Markdown格式生成并输出。
7.后端文档写入到文件中: 03-架构设计 /1-项目后端架构文档.md。
8.微信小程序文档写入文件: 03-架构设计 /2-微信小程序架构文档.md。
2.1 详见老师的--》在资料中存放
3 Mysql数据库环境
3.1 本地安装mysql
# 1 本地安装mysql【本地开发和测试】---》后续项目上线,要在服务器上安装mysql【简单一些】
# 2 mysql 开源数据库,有很多版本
-企业主流使用:mysql8版本
-少量企业:mysql7版本
-极少量企业:mysql9版本
# 3 mysql 数据库管理软件
-1 软件--》装在操作系统上-->就像qq,微信,是个软件,需要转在操作系统上
-2 库 :你家,张三家,李四家--》有好几个库,相互隔离
-3 表 :你家有一个个房间:你的房间,你爸的房间,你妹妹的房间
-4 数据:房间中存放的物品
# 4 具体例子【excel表格】:用户表、口播历史表。。。
# User 表
id name password age
1 zhangsan 1234 18
2 lqz 666 19
# 5 使用python程序来操作数据库:安全,可靠,效率高

# 1 我很早之前写一了一篇文章:安装mysql :https://zhuanlan.zhihu.com/p/571585588
############### 具体步骤 ######################
# 1 下载mysql8.4.4
-https://downloads.mysql.com/archives/community/
# 2 解压到某个路径下--》不要带中文
-D:\soft\mysql-8.4.4-winx64
# 3 在 bin所在目录创建 my.ini # 后缀名注意,不要带 .txt
# 4 创建 data文件夹:D:\soft\mysql-8.4.4-winx64\data\
########## 在 my.ini 中写入
[mysqld]
port=3306
basedir=D:\\soft\\mysql-8.4.4-winx64\
datadir=D:\\soft\\mysql-8.4.4-winx64\\data\
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。
max_connect_errors=10
# 服务端使用的字符集默认为utf8
character-set-server=utf8mb4
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8mb4
[client]
# 设置mysql客户端连接服务端时默认使用的端口
port=3306
default-character-set=utf8mb4
# 5 来到mysql解压后的bin路径下(以管理员身份运行)
以管理员打开cmd
D: # 回车
cd D:\soft\mysql-8.4.4-winx64\bin
# 6 安装mysql 安装完成后Mysql会有一个随机密码(记住这个密码)--》这里可能会出错 dll文件缺失
mysqld --initialize --console
# 密码: FXfM&kQoi2lL
# 7 把mysql创建成系统服务 :以后开机后自启动
mysqld --install mysql844
# 8 启动mysql服务
net start mysql844
# 9 停止服务
net stop mysql844
#### 或者在我的电脑--》管理--》服务中--》点击开启或停止
# 9 做成服务后,没有开启自启动--》win关机了,再开启,mysql没启动
命令行中执行:net start mysql844
在服务上点右键启动
如果做成了 自动 --》以后重启后,都是自动开启
# 10 做成开机自启动
如下图



3.2 修改mysql密码
# 1 打开cmd
以管理员打开cmd
D: # 回车
cd D:\soft\mysql-8.4.4-winx64\bin
# 2 来到这个路径下输入:D:\soft\mysql-8.4.4-winx64\bin 输入
mysql -uroot -p -P 3306 # 回车后,输入密码,进入后
# 3 改密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'lqz123?';
FLUSH PRIVILEGES;
quit # 退出
# 4 mysql 装好后,可以在黑色的命令窗口下操作mysql--》需要用命令
- 不学命令,学习使用图形化界面操作
3.3 Navicat操作mysql
# 1 在黑色命令下操作数据库,需要会很多命令--》很难记---》使用图形化界面连接操作--》点点的即可
# 2 mysql官方没有提供可视化,只能用命令,有很多第三方,用谁都行:收费的,免费的,最好用的: Navicat
### DBeaver
优点:DBeaver功能比较强大,使用也较便利。缺点:对于系统资源要求较高,运行速度相对较慢,特别是导入大文件时比较明显。官方主页:https://dbeaver.io/
#### Navicat--收费的--》破解--》好用
# 个人没事
# 不要在公司内部使用破解--》这个公司能根据你的ip--》定位到你公司--》发律师函--》告你
优点:Navicat使用普及率较高,功能非常完整,包括比较强大的SQL补全、导入导出、结果集编辑、E-R模型、数据对比、结构对比、数据迁移等,但有部分功能仅企业版才具备。缺点:需要注册为Navicat用户才能够使用,而且定期会失效,需要重新下载和登录申请为免费使用。官方主页:https://navicat.com/
####SQLyog
SQLyog更多的是专注于数据库的管理,包括性能、监控、优化等方面,也提供基础SQL编辑功能,所以在早期,其在DBA群体中比较受欢迎,但是在整体的开发者中,使用比率并不高。缺点:在云时代对于监控与实例管理方面的诉求在降低,在SQL开发与云适配上需求更强,但这方面发展缓慢,而且产品以商业收费版为主。官方主页:https://webyog.com/product/sqlyog/
3.3.1 破解Navicat
# 1 双击安装:navicat160_premium_cs_x64.exe
-安装完后,要付费,可以试用30天--》嫌破解麻烦可以试用30天
# 2 如下步骤破解
1. 以管理员身份运行 NavicatCracker.exe
2. 断网
3. 选择安装目录
4. 点击 Patch!
5. 点击 Generate!
6. 使用生成的序列号激活
7. 弹出激活失败窗口 选择 手动激活
8. 将 Navicat 给的请求码复制到注册机 Request Code 中
9. 点击 Generate Activation Code!
10. 使用激活码激活
# 3 连接mysql :如下图
# 4 创建一个数据库:shuziren




3.3.2 操作mysql
# 1 Navicat连接到mysql【图形化界面】
# 2 创建一个数据库:shuziren
-字符集:utf8mb4





4 Codex编写后端项目
4.1 提示词
# 1 本地后端环境搭建好了--》使用提示词,让Codex编写后端了
# 2 提示词:思考模式改成 高
根据项目需求:01-需求分析/项目需求.md 和项目后端架构文档:03-架构设计/1-项目后端架构文档.md 和前端设计图:02-UI设计 ,生成口播数字人微信小程序后台Django的项目和代码
要求:
1.项目写入到目录shuziren_api中。
2.生成相关表模型,写入到每个app的models中。
3.生成所有接口,并能正常调用。
4.链接数据库地址为:
-host:127.0.0.1
-port:3306
-database:shuziren
-user:root
-password:lqz123?
5.Django 后台admin使用django-simpleui美化,项目做好本地化和时区设置。
6.口播数字人功能对接Coze数字人工作流,对接方案参照代码:coze_shuziren.py
-API_KEY:pat_v3bcwP3HOJxuUr7a6VWau4HEbFBMwFNzlHvy6vhQ3URBIaxMBFZOpDBuFUrEYBfE
-工作流ID:7669850629418647590
5 小程序概述
5.1 创建小程序账号
# 1 访问【微信公众平台】,注册一个微信小程序账号
-https://mp.weixin.qq.com/
# 2 申请账号需要准备一个邮箱,该邮箱要求:
-未被微信公众平台注册
-未被微信开放平台注册
-未被个人微信号绑定过
-如果被绑定了需要解绑 或 使用其他邮箱
# 3 注册过程中需要微信扫码-->绑定你个人微信--》后续用微信扫码登录









5.2 小程序开发流程
# 1 注册号微信小程序账号,就可以开发微信小程序了
# 2 使用微信提供的专门的开发工具:类似于Pycharm

5.3 微信开发者工具
# 0 后端代码Codex帮我们写的,前端小程序代码:Codex帮我们写的---》运行项目查看样子?
-后端:Pycharm
-微信小程序:微信开发者工具
# 1 查看codex帮我们写的样子,调试bug--》需要用微信开发者工具
# 2 微信开发者工具:
-https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
# 3 一路下一步安装
# 4 双击点开
# 5 创建项目,进入

5.4 创建微信小程序项目
# 0 Codex 无论项目有或没有,都能帮我们做
0--1 一个项目:Django后端
1--100:这个项目有了,我们让Codex加功能,改bug,以微信小程序为例
# 1 Django项目,我们创建了吗?没有,Codex从0到1写的
# 2 微信小程序,我们不从0创建了【绝对能从0创建】,我们先创建好,有个页面【很简单】--》继续编写完成我们的要求
# 3 我们创建的小程序项目,有一个页面,显示 LQZ
-我们的数字人,有很多页面
-从1--100:项目有页面,只是不符合我们需求,我们继续使用Codex帮我们开发完成









浙公网安备 33010602011771号