day17-Trae开发微信小程序02

今日内容

0 项目回顾

# 1 一键换脸微信小程序
	-微信小程序中:用户注册,登陆成功后,上传两张人脸---》实现换脸
    
# 2 架构

image-20260308200805147

1 安装Mysql8

1.1 docker安装

# 1 mysql 官方镜像:https://hub.docker.com/_/mysql
# 2 拉取 mysql 8  ---->  速度慢
docker pull mysql:8.4.5
# docker pull mysql:8
    
# 3 创建文件夹,授权   
mkdir -p /home/lqz/mysql/data
mkdir -p /home/lqz/mysql/logs
chown -R 999:999 /home/lqz/mysql/data
chown -R 999:999 /home/lqz/mysql/logs
    
# 4 创建mysql配置文件
cd /home/lqz/mysql
vi my.cnf  # mysql软件的配置文件



[mysqld]
# MySQL 数据存储路径
datadir=/var/lib/mysql

# MySQL 错误日志路径
log-error=/var/log/mysql/error.log

# 启用远程连接
bind-address=0.0.0.0

# 设置字符集为 utf8mb4
character-set-server=utf8mb4

# 默认排序规则为 utf8mb4_0900_ai_ci,若需兼容 MySQL 5.7 可使用 utf8mb4_unicode_ci
collation-server=utf8mb4_0900_ai_ci




# 5 启动mysql 
docker run -d \
  --name mysql8 \
  -e MYSQL_ROOT_PASSWORD=lqz12345 \
  -p 3307:3306 \
  -v /home/lqz/mysql/my.cnf:/etc/mysql/my.cnf \
  -v /home/lqz/mysql/data:/var/lib/mysql \
  -v /home/lqz/mysql/logs:/var/log/mysql \
  mysql:8.4.5

# 6 查看mysql8是否正常启动
docker ps |grep mysql8

# 7 本地win-远程链接

image-20260308201443801

1.2 本地安装

# 1 本地安装mysql
https://zhuanlan.zhihu.com/p/571585588
    

############### 以下做参考 步骤  ##############
# 1 下载mysql:mysql-8.4.4-winx64.zip
# 2 解压:
# 3 在软件根路径:D:\mysql-8.4.4-winx64\mysql-8.4.4-winx64 
	1 创建一个文件夹  data
    2 创建一个文件:my.ini,编写配置如下

[mysqld]
# 设置3307端口
port=3307
# 设置mysql的安装目录 ---这里输入你安装的文件路径----
basedir=D:\\mysql-8.4.4-winx64\mysql-8.4.4-winx64\
# 设置mysql数据库的数据的存放目录
datadir=D:\\mysql-8.4.4-winx64\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=3307
default-character-set=utf8mb4

# 4 来到mysql解压后的bin路径下(以管理员身份运行)
以管理员身份打开cmd
敲 D:  回车
cd D:\mysql-8.4.4-winx64\mysql-8.4.4-winx64\bin # 来到了目录下
    
# 5 安装mysql  安装完成后Mysql会有一个随机密码(记住这个密码,如下图)
mysqld --initialize --console

# 6 把mysql创建成系统服务 
mysqld --install mysql8

# 7 启动mysql服务,也可以按老师刚刚点击右键启动
net start mysql8





# 8 改密码,打开cmd,来到mysql解压后的bin路径下
# 登录(服务启动才能登录)
mysql -uroot -p -P 3307
# 输入刚刚上面生成的随机密码

# 9 修改密码(8.0以后)
ALTER USER 'root'@'localhost' IDENTIFIED BY 'lqz123?';
FLUSH PRIVILEGES;

# 10 记住密码

image-20260308201842631

image-20250911221009916

image-20260308203019978

1.3 Navicate连接

# 1 mysql 装好了--》连接上:创建数据库,创建表,插入数据,查询数据。。
# 2 正常可以再命令行中操作:比较难,要记很多命令,必须是本地安装的,用docker装的没有mysql命令
	mysql -uroot -p  # 登陆进去
    输入密码           # 需要记很多
    show databases;  # 查看有哪些数据库
    .......
    

# 3 使用图形化界面操作--》这个如果同学破解不了 ,使用 1.5操作即可
	-很多软件,大部分都是收费的,也有免费的
    -收费的,可以破解,是市面上用的最多:Navicat:图形化连接和操作mysql的(前提是装好mysql)
    	-按照老师步骤破解:按照说明做
        0. 安装Navicat,一路下一步:navicat160_premium_cs_x64.exe
        	-试用七天,如果七天够用,就不用破解
        1. 以管理员身份运行 NavicatCracker.exe
        2. 断网
        3. 选择安装目录
        4. 点击 Patch!
        5. 点击 Generate!
        6. 使用生成的序列号激活
        7. 弹出激活失败窗口 选择 手动激活
        8. 将 Navicat 给的请求码复制到注册机 Request Code 中
        9. 点击 Generate Activation Code!
        10. 使用激活码激活
# 4 使用navicat连接mysql
  - 连本地
    1 连接--》mysql
    2 输入名字,地址,端口,用户,密码,连接
    3 双击打开,看到所有数据库
    
  - 连docker中的
	1 连接--》mysql
    2 输入名字,地址:虚拟机地址,端口,用户,密码,连接
    3 双击打开,看到所有数据库

image-20260308204328366

image-20260308204415790

image-20260308204504689

image-20260308204614331

1.4 Trae插件连接【免费】

# 1 trae 的插件
# 2 如下图安装插件
# 3 连接

image-20260308204753808

image-20260308204915548

image-20260308205041754

1.5 创建数据库

# 1 写的项目要存到数据库中,要创建数据库

# 2 再Trae插件中创建数据库【本地还是docker中?】
	如下图
    再navicat中也可以看到chang_face数据库

# 3 再 navicat 中创建
	如下图

image-20260308205443207

image-20260308205559926

image-20260308205700882

扩展说明

# 1 mysql 软件装好后,要创建库,查看库,查看表,如果都用命令,比较麻烦

# 2 会有各种各样的图形化界面操作
	-navicat
    -trae的插件
    -pycharm
# 3 其他
最好用的12款 MySQL可视化管理工具(Windows):

MySQL Workbench
MySQL Workbench作为MySQL公司自己出产的可视化管理工具,本身就是质量的保证。优点:应该是功能最强大、最稳定流程的免费MySQL可视化管理工具了。缺点:以前的版本对资源要求较大,电脑配置不足时会略显缓慢,而最近的版本已有充足改良,运行非常流畅。官网主页:https://www.mysql.com/products/workbench/

德易点MySQL套件
德易点MySQL套件内置了主流关系型数据库mysql 服务和图形化客户端工具MySQL Workbench ,实现一键式安装或卸载,运行与停止,客户端管理以及开机启动类型设置等功能。官方主页:德易点MySQL套件 - 德易点软件

DBeaver
优点:DBeaver功能比较强大,使用也较便利。缺点:对于系统资源要求较高,运行速度相对较慢,特别是导入大文件时比较明显。官方主页:https://dbeaver.io/

Navicat
优点:Navicat使用普及率较高,功能非常完整,包括比较强大的SQL补全、导入导出、结果集编辑、E-R模型、数据对比、结构对比、数据迁移等,但有部分功能仅企业版才具备。缺点:需要注册为Navicat用户才能够使用,而且定期会失效,需要重新下载和登录申请为免费使用。官方主页:https://navicat.com/

phpMyAdmin
优点:phpMyAdmin功能非常强大,操作流程简单易懂,大部分PHP网站的运营环境或本地开发环境都会配置phpMyAdmin工具。 缺点:需要额外安装PHP服务器,这带来了很大的不便利。官方主页:https://www.phpmyadmin.net/

阿里云DMS
阿里云DMS的优点:因为阿里云在国内市占率非常高,所以,阿里云DMS也是一个使用比较广,但是也因为其为阿里云的产品,所以其作为MySQL管理工具并不是非常有名。DMS比较完整的支持MySQL日常SQL开发相关的工作,其功能矩阵也比较完整,可以完成日常的开发工作。缺点:1)对于其他云数据库(诸如腾讯、华为、AWS)的支持比较有限。2)需要连接互联网才能使用,无法搭建本地离线开发环境。 官方主页:https://www.aliyun.com/product/dms

NineData
优点:功能较强大,包括智能的SQL补全、SQL执行历史、结果集编辑、数据对比、结构对比、数据迁移与复制等。采用SaaS架构模式,免费使用,无需下载安装。缺点:需要连接互联网才能使用,无法搭建本地离线开发环境。官方主页:https://www.ninedata.cloud/

DbVisualizer
优点:DbVisualizer发展时间也比较长了,功能较强大。缺点:仅支持英语,没有对应的中文支持。

BeepKeeper Studio
Beekeeper目前是由一个由个人开发的MySQL GUI软件。界面简洁现代,支持比较基础的SQL开发功能,包括了SQL窗口、创建表等能力,同时有非常好的平台兼容性。官方主页:https://www.beekeeperstudio.io/

dbForge
dbForge 是一个商业化收费软件,产品可以下载试用一段时间。官方主页:https://www.devart.com/dbforge/mysql/

SQLyog
SQLyog更多的是专注于数据库的管理,包括性能、监控、优化等方面,也提供基础SQL编辑功能,所以在早期,其在DBA群体中比较受欢迎,但是在整体的开发者中,使用比率并不高。缺点:在云时代对于监控与实例管理方面的诉求在降低,在SQL开发与云适配上需求更强,但这方面发展缓慢,而且产品以商业收费版为主。官方主页:https://webyog.com/product/sqlyog/

HeidiSQL
HeidiSQL也是一个发展了很长时间的MySQL客户端,使用Delphi构建,所以整体上,有非常好的Windows使用体验,功能也比较完整。官方主页:https://www.heidisql.com/

2 Trae编写后端

2.1 Python调用普通换脸

# 1 我们的核心换脸功能,不是自己写的,是使用coze的换脸工作流
# 2 demo:使用python调用 coze的换脸工作流
	2.1 把工作流发布
    2.2 记住工作流的id号:7536960050292998154
    2.3 获取鉴权token:https://www.coze.cn/open/oauth/pats
           -添加令牌
           -pat_W7Ez5WFGBvXtxZvgIZDtGFv2qYFCQ16A6uT1j0lsWCagpjQjCukfNIR7qvSYR7NE
   2.4 代码测试:
# 3 后续再django项目中也可以调用成功

image-20260308210234999

image-20260308210446526

image-20260308210701927

image-20260308210352348

# 命令行中运行:pip install requests
import requests
import json
import time
import os
from typing import Optional, Dict, Any
'''
个人访问令牌:https://www.coze.cn/open/oauth/pats
'''

class CozeAPI:
    """Coze API客户端,用于调用Coze的换脸工作流"""

    def __init__(self, api_key: str = None, workflow_id: str = None):
        self.api_key = api_key or 'pat_9kMZVTvr3AQ9aexJjRxoqe7zY28cUzTahbZDGYgNhzNEsRytAs14VVqhOzzJaEOx'
        self.workflow_id = workflow_id or '7536960050292998154'
        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('face_swap', 'coze_results')
        os.makedirs(result_dir, exist_ok=True)
        filename = f"result_{task_id}_{int(time.time())}.jpg"
        return os.path.join(result_dir, filename)

    def download_image(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": {
                    "face": json.dumps({"file_id": source_id}),
                    "backed": 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', '{}'))
            image_url = result_data.get('output')

            if not image_url:
                return {'status': 'success', 'message': '任务成功但未返回图片', 'task_id': task_id}

            local_path = self.download_image(image_url, task_id)
            return {
                'status': 'success',
                'result_image_url': image_url,
                'local_image_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()
        source_path, target_path = './test_source.jpg', './test_target.jpg'
        print("开始测试Coze换脸工作流...")

        # 运行工作流并获取任务ID
        run_result = coze_api.run_workflow(source_path, target_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(20)  # 等待任务处理

            # 查询结果
            result = coze_api.get_workflow_result(task_id)
            print(f"任务结果: {result}")

            # 精简结果判断逻辑
            status_map = {
                'success': f"✅ 测试成功!\nURL: {result.get('result_image_url')}\n本地路径: {result.get('local_image_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)

image-20260308211315602

2.2 提示词-AI编辑器帮我们把代码实现

# 1 非常简单,只需要输入提示词即可--》但是由于不同的代码大模型写代码质量不一样,就会出现,写完的代码可能会有bug
	-cursor,Claude---》花钱--》写出来的代码质量高,bug少--》通常一次成功
    -Trae --》免费的--》国产模型--》可能bug---》运行不成功
    	-我们需要反复的跟ai交互,直到他把代码改的能顺利运行
        	-这个过程中,好的小白就崩溃了:这些是我们必经之路
            -一定稳住心态,慢慢调试
            
# 3 提示词:
根据项目需求: 和项目后端架构文档: ,生成智能换脸微信小程序后台Django的项目和代码
要求:
1.项目写入到目录change_face_api中。
2.生成相关表模型,写入到每个app的models中。
3.生成所有接口,并能正常调用。
4.链接数据库地址为:
    -host:127.0.0.1
    -port:3306
    -database:change_face
    -user:root
    -password:lqz123?
5.Django 后台admin使用django-simpleui美化,项目做好本地化和时区设置。
6.换脸功能对接Coze一键换脸工作流,对接方案参照代码:
	-API_KEY:pat_W7Ez5WFGBvXtxZvgIZDtGFv2qYFCQ16A6uT1j0lsWCagpjQjCukfNIR7qvSYR7NE
    -工作流ID:7536960050292998154

3 小程序概述

# 1 想学:
视频:
	https://www.bilibili.com/video/BV1WgQdYNERe/
笔记:
 	https://pan.baidu.com/s/1VTd6S3rJKQ42MRFPsFwaZQ 提取码: bpxa
            
            

3.1 小程序账号注册

# 1 要做微信小程序开发,要注册微信小程序账号
	-https://mp.weixin.qq.com/
        
# 2 申请账号需要准备一个邮箱,该邮箱要求:
    -未被微信公众平台注册
    -未被微信开放平台注册
    -未被个人微信号绑定过
    -如果被绑定了需要解绑 或 使用其他邮箱

image-20240401162948430

image-20240401163023686

image-20240401163050951

image-20240401163142613

image-20240401163812295

image-20240401163835864

image-20240401163920407

3.2 小程序信息配置

# 1 注册成功后,登陆上--》需要打开微信公众平台对小程序账号进行一些设置
	-小程序后续需要 提交审核和上线--》提交审核时,小程序账号信息是必填项
	-名称、图标、类目等
    -小程序备案和微信认证

image-20240401164834700

image-20240401165216886

3.3 小程序开发流程

image-20260308214509438

# 1 下载微信开发者工具:下载【微信开发工具】--需要联网才能使用  
	最新稳定版:https://developers.weixin.qq.com/miniprogram/dev/devtools/stable.html
    老版本:https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html
        
# 2 重要:获取小程序id:
	小程序后台--》开发--》开发管理--》开发设置--》开发者ID--》wx539e097341fc7588
# 3 一路下一步安装

# 4 创建项目

# 5 配合后端API

image-20260308214833226

image-20240401171756755

image-20240401171823876

3.4 创建项目

# 1 打开微信开发者工具--》使用微信扫描二维码
# 2 创建项目:在原来Trad的项目目录下新建文件夹:change_face_front
	-填写名字
    -路径
    -APPID
    -不使用云开发【使用腾讯云的云函数,服务器等等,需要花钱】
    -不使用模版
# 3 创建完成后,界面如下

# 4 设置
	-设置--》编辑器设置--》改变字体大小
    -视图--》外观--》移动模拟器位置
    -可以勾选掉不显示:模拟器,调试器等

image-20240401172015541

image-20240401172035213

image-20260308215439792

image-20260308215726169

3.5 本地开发支持http

# 1 微信小程序代码再本地 , 后端也再本地
	-通信:本地再相互通信
    -也是通过http:后续微信小程序代码发送到腾讯服务上,咱们后端django代码自己部署--》通信也是通过http---》ip地址很重要
    -开发阶段使用:127.0.0.1
    -上线阶段使用:后端云服务地址
    
# 2 本地开发,需要修改一点配置

image-20260308220250033

2.6 目录结构介绍

image-20260308220342322

# 重点目录:
	# 项目主配置文件
	项目主配置文件必须放到项目的根目录下,控制整个项目
    	- app.js:  小程序入口文件
    	- app.json:小程序的全局配置文件
    	- app.wxss:小程序的全局样式
    # 页面文件
	小程序有一个个页面,每个页面所需的文件,都存放在 pages 目录下,一个页面一个文件夹
        -xx.js:  页面逻辑  js代码存放位置
        -xx.wxml:页面结构  类html文件存放位置
        -xx.wxss:页面样式  css存放位置
        -xx.json:小页面配置 

2.7 纯净项目

# 1 只有一个页面,没有其它文件的空项目--》让Trae再这个基础上,完成一键换脸的微信小程序

# 2 目录结构如下
## index.js
// index.js
Page({})

## index.json
{
  "usingComponents": {

  }
}

## index.wxml

  <view class="container">
    刘清政
  </view>

## index.wxss   空的

## app.js
// app.js
App({})

## app.wxss  空的

## app.json
{
  "pages": [
    "pages/index/index"
  ],
  "window": {
    "navigationBarTextStyle": "black",
    "navigationStyle": "custom"
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json",
  "lazyCodeLoading": "requiredComponents"
}

# 其他的不动

image-20260308220818159

image-20260308221906648

posted @ 2026-03-09 19:57  凫弥  阅读(0)  评论(0)    收藏  举报