更新记录
1.0.1(2025-03-17) 下载此版本
- 初次发布。上线绘画基本控制页面、激励广告组件(自行配置)、分享组件(自行配置平台) *
平台兼容性
Vue2 | Vue3 |
---|---|
× | √ |
App | 快应用 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 |
---|---|---|---|---|---|---|
HBuilderX 4.11 app-vue | × | × | × | × | × | × |
钉钉小程序 | 快手小程序 | 飞书小程序 | 京东小程序 | 鸿蒙元服务 |
---|---|---|---|---|
× | × | × | × | × |
H5-Safari | Android Browser | 微信浏览器(Android) | QQ浏览器(Android) | Chrome | IE | Edge | Firefox | PC-Safari |
---|---|---|---|---|---|---|---|---|
× | × | × | × | × | × | × | × | × |
demo演示
项目引入
下载本项目,导入所有依赖模块即可运行。
项目配置
绘画后端模块
在项目的@/page/index/index
中的函数generateImage()
中,语句baseUrl = 'https://example.com/paint';
部分需要开发者自行配置。这部分对接阿里云通义万相的绘画API,此处使用后端php
代码实现。以下为php
代码:
<?php
function err(){
exit("服务器繁忙,请稍后再试。");
}
set_error_handler("err");//如果配置到服务器发生报错,请注释此句。
// 限制请求方法为GET
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
echo 'err0';
exit;
}
// 获取并验证参数
$prompt = $_GET['prompt'] ?? '';
$height = isset($_GET['height']) ? (int)$_GET['height'] : 0;
$width = isset($_GET['width']) ? (int)$_GET['width'] : 0;
$seed = isset($_GET['seed']) ? $_GET['seed'] : rand(114,514191);
$enhance = isset($_GET['enhance']) ? (bool)$_GET['enhance'] : false;
$model = ($_GET['model']) ?? '';
if(!is_numeric($seed)){
$seed=rand(114,514191);
}
if($enhance){
$enhance=true;
}else{
$enhance=false;
}
if (empty($prompt) ||empty($model) || $height < 256 || $height > 1024 || $width < 256 || $width > 1024) {
http_response_code(500);
echo 'err1';
exit;
}
$models=['wanx2.1-t2i-turbo','wanx2.1-t2i-plus','wanx2.0-t2i-turbo'];
if(!in_array($model,$models)){
http_response_code(500);
echo 'err1';
exit;
}
// 频率控制
$ip = $_SERVER['REMOTE_ADDR'];
$rateLimitDir = './ratelimit/';
$rateLimitFile = $rateLimitDir . md5($ip).".dat";
if (!is_dir($rateLimitDir) && !mkdir($rateLimitDir)) {
http_response_code(500);
echo 'err';
exit;
}
$lastTime = file_exists($rateLimitFile) ? file_get_contents($rateLimitFile) : 0;
$currentTime = time();
if ($currentTime - (int)$lastTime < 10) {
http_response_code(500);
echo '频率超过限制,请稍后再试';
exit;
}
$currentTime = time();
file_put_contents($rateLimitFile,$currentTime);
// 获取API密钥
$apiKey = 'API_KEY';//请自行去通义万相平台配置API_KEY
if (!$apiKey) {
http_response_code(500);
echo 'err3';
exit;
}
// 发送创建任务请求
$postUrl = 'https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis';
$postData = [
'model' => $model,
'input' => ['prompt' => $prompt],
'parameters' => [
'size' => $width.'*'.$height,
'n' => 1,
'seed' => intval($seed),
'prompt_extend' => $enhance
]
];
$ch = curl_init($postUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-DashScope-Async: enable',
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode($postData,true)
]);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
http_response_code(500);
echo 'err4';//.$httpCode.$response;
exit;
}
$responseData = json_decode($response, true);
if (!isset($responseData['output']['task_id'])) {
http_response_code(500);
echo 'err5';
exit;
}
$taskId = $responseData['output']['task_id'];
// 轮询任务结果
$taskUrl = "https://dashscope.aliyuncs.com/api/v1/tasks/{$taskId}";
$maxRetries = 30;
$retryCount = 0;
$imageUrl = '';
while ($retryCount < $maxRetries) {
$ch = curl_init($taskUrl);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
CURLOPT_RETURNTRANSFER => true
]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$taskResponse = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
//echo $taskResponse."<br>";
if ($httpCode === 200) {
$taskData = json_decode($taskResponse, true);
$status = $taskData['output']['task_status'] ?? '';
if ($status === 'SUCCEEDED') {
$imageUrl = $taskData['output']['results'][0]['url'] ?? '';
if ($imageUrl) break;
} elseif ($status === 'FAILED') {
http_response_code(500);
echo 'err';
exit;
}
}
sleep(2);
$retryCount++;
}
if (!$imageUrl) {
http_response_code(500);
echo 'err6';
exit;
}
// 获取并输出图片
$ch = curl_init($imageUrl);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true
]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$imageData = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
http_response_code(500);
echo 'err7';
exit;
}
header('Content-Type: image/png');
echo $imageData;
$currentTime = time()+5;
file_put_contents($rateLimitFile,$currentTime);
?>
这个php
源码还配置了频率限制,基于文件锁实现,使用时注意文件夹写入权限。
例如开发者服务器是http://www.example.com
,则在服务器根目录创建文件夹paint
,设置读写执行权限;然后使用上述代码创建index.php
,配置好后,访问http://www.example.com/paint/?prompt=%E6%97%A5%E8%90%BD&seed=1145141&model=wanx2.1-t2i-plus&height=720&width=1024
,若能生成图片,则配置成功,否则根据错误编号在源码查询错误。
激励广告配置
本项目使用激励广告作为金币主要获取来源。项目源码有const adpids = [];
,内部配置激励广告位的id
。其具体配置,参见官方文档https://zh.uniapp.dcloud.io/uni-ad/ad-rewarded-video.html 。 打包要记得配置好激励广告,勾选需要的广告来源。
分享配置
本项目也可以根据分享来获得少量金币,可为项目增加曝光度。本项目分享主要为微信、QQ,其分享的appId
需要去各自开放平台配置。配置好后在manifest.json
配置后即可以使用。
其他接入
如果想查看应用流量,可以配置uni统计;如果要为应用加入更新,则可以配置更新相关模块。