Files
dsProject/dsLightRag/static/JiMeng/prompt_input.html
2025-08-21 11:54:59 +08:00

748 lines
27 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>一、首帧制作</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
}
body {
background-color: #f5f7fa;
color: #333;
line-height: 1.6;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
padding: 30px;
}
h1 {
text-align: center;
margin-bottom: 20px;
color: #2c3e50;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
color: #555;
}
input[type="text"], textarea {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 16px;
transition: border 0.3s;
}
input[type="text"]:focus, textarea:focus {
border-color: #3498db;
outline: none;
}
.required::after {
content: ' *';
color: red;
}
.tag-container {
display: flex;
flex-wrap: wrap;
margin-top: 10px;
padding: 10px;
border: 1px dashed #ccc;
border-radius: 6px;
min-height: 50px;
}
.tag {
background-color: #3498db;
color: white;
padding: 5px 10px;
border-radius: 20px;
margin-right: 10px;
margin-bottom: 10px;
display: flex;
align-items: center;
}
.tag span {
margin-right: 5px;
}
.tag button {
background: none;
border: none;
color: white;
cursor: pointer;
font-size: 14px;
}
.add-tag {
display: flex;
margin-top: 10px;
}
.add-tag input {
flex: 1;
margin-right: 10px;
}
.btn {
padding: 12px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
transition: background 0.3s;
}
.btn-primary {
background-color: #3498db;
color: white;
}
.btn-primary:hover {
background-color: #2980b9;
}
.btn-secondary {
background-color: #95a5a6;
color: white;
margin-left: 10px;
}
.btn-secondary:hover {
background-color: #7f8c8d;
}
.btn-group {
display: flex;
justify-content: center;
margin-top: 30px;
}
.placeholder {
color: #999;
font-style: italic;
}
.example-tip {
background-color: #f8f9fa;
padding: 15px;
border-radius: 6px;
margin-top: 5px;
font-size: 14px;
color: #666;
}
.sample-container {
margin-top: 10px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 6px;
border-left: 4px solid #3498db;
}
.sample-title {
font-weight: bold;
margin-bottom: 10px;
}
</style>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
}
body {
background-color: #f5f7fa;
color: #333;
line-height: 1.6;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
background: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
padding: 30px;
}
h1 {
text-align: center;
margin-bottom: 20px;
color: #2c3e50;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
color: #555;
}
input[type="text"], textarea {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 16px;
transition: border 0.3s;
}
input[type="text"]:focus, textarea:focus {
border-color: #3498db;
outline: none;
}
.required::after {
content: ' *';
color: red;
}
.tag-container {
display: flex;
flex-wrap: wrap;
margin-top: 10px;
padding: 10px;
border: 1px dashed #ccc;
border-radius: 6px;
min-height: 50px;
}
.tag {
background-color: #3498db;
color: white;
padding: 5px 10px;
border-radius: 20px;
margin-right: 10px;
margin-bottom: 10px;
display: flex;
align-items: center;
}
.tag span {
margin-right: 5px;
}
.tag button {
background: none;
border: none;
color: white;
cursor: pointer;
font-size: 14px;
}
.add-tag {
display: flex;
margin-top: 10px;
}
.add-tag input {
flex: 1;
margin-right: 10px;
}
.btn {
padding: 12px 20px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
transition: background 0.3s;
}
.btn-primary {
background-color: #3498db;
color: white;
}
.btn-primary:hover {
background-color: #2980b9;
}
.btn-secondary {
background-color: #95a5a6;
color: white;
margin-left: 10px;
}
.btn-secondary:hover {
background-color: #7f8c8d;
}
.btn-group {
display: flex;
justify-content: center;
margin-top: 30px;
}
.placeholder {
color: #999;
font-style: italic;
}
.example-tip {
background-color: #f8f9fa;
padding: 15px;
border-radius: 6px;
margin-top: 5px;
font-size: 14px;
color: #666;
}
.sample-container {
margin-top: 10px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 6px;
border-left: 4px solid #3498db;
}
.sample-title {
font-weight: bold;
margin-bottom: 10px;
}
/* 添加遮罩动画样式 */
.mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s;
}
.mask.active {
opacity: 1;
visibility: visible;
}
.loader {
width: 50px;
height: 50px;
border: 5px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: #3498db;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.mask-text {
color: white;
margin-top: 20px;
text-align: center;
font-size: 18px;
}
.mask-content {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
</head>
<body>
<div class="container">
<h1>一、首帧制作</h1>
<form id="promptForm">
<div class="form-group">
<label>首帧创建方式</label>
<div style="display: flex; gap: 20px; margin-bottom: 15px;">
<label style="display: flex; align-items: center; cursor: pointer;">
<input type="radio" name="creationMethod" value="prompt" checked style="margin-right: 8px;">
生成提示词
</label>
<label style="display: flex; align-items: center; cursor: pointer;">
<input type="radio" name="creationMethod" value="upload" style="margin-right: 8px;">
上传图片
</label>
</div>
</div>
<div id="promptSection">
<div class="form-group">
<label for="timeWeatherLight" class="required">时间-天气-光</label>
<input type="text" id="timeWeatherLight" placeholder="例如:傍晚小雨,路灯刚亮" required>
<div class="example-tip">请描述时间、天气状况和光线条件,这将影响画面的整体感觉</div>
</div>
<div class="form-group">
<label for="sceneLocation" class="required">场景-地点</label>
<input type="text" id="sceneLocation" placeholder="例如:老城区石板路" required>
<div class="example-tip">请描述具体的场景和地点,帮助构建画面背景</div>
</div>
<div class="form-group">
<label for="subjects">主体列表 (可选)</label>
<div class="tag-container" id="tagContainer">
<div class="placeholder" id="placeholder">点击下方添加主体(人/动物/物体),或留空</div>
</div>
<div class="add-tag">
<input type="text" id="subjectInput" placeholder="例如:工人父亲(背)">
<button type="button" class="btn btn-primary" id="addTagBtn">添加</button>
</div>
<div class="example-tip">多个主体用逗号分隔,括号内可描述动作或姿态</div>
</div>
<div class="form-group">
<label for="atmosphere" class="required">氛围-情绪</label>
<input type="text" id="atmosphere" placeholder="例如:温暖" required>
<div class="example-tip">请描述画面想要传达的整体氛围或情绪</div>
</div>
<div class="form-group">
<button type="button" class="btn btn-secondary" id="randomSampleBtn">随机示例</button>
<div class="sample-container" id="sampleContainer" style="display: none;">
<div class="sample-title">示例提示词:</div>
<div id="sampleContent"></div>
</div>
</div>
</div>
<div id="uploadSection" style="display: none;">
<div class="form-group">
<label for="imageUpload">上传图片</label>
<input type="file" id="imageUpload" accept="image/*">
<div class="example-tip">支持JPG、PNG等格式建议图片尺寸不小于1080x720像素</div>
</div>
<div id="previewContainer" style="margin-top: 20px; display: none;">
<h4>图片预览:</h4>
<img id="imagePreview" style="max-width: 100%; max-height: 400px; border-radius: 6px;">
</div>
</div>
<div class="btn-group">
<button type="submit" class="btn btn-primary" id="submitBtn">确认并继续</button>
<button type="reset" class="btn btn-secondary">重置</button>
</div>
</form>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 新增代码:定义缺失的函数
function checkTagContainer() {
const tags = tagContainer.querySelectorAll('.tag');
if (tags.length === 0) {
placeholder.style.display = 'block';
} else {
placeholder.style.display = 'none';
}
}
function addTag(text) {
if (!text.trim()) return;
// 隐藏占位符
placeholder.style.display = 'none';
const tag = document.createElement('div');
tag.className = 'tag';
const tagText = document.createElement('span');
tagText.textContent = text;
const deleteBtn = document.createElement('button');
deleteBtn.textContent = '×';
deleteBtn.addEventListener('click', function() {
tagContainer.removeChild(tag);
checkTagContainer();
});
tag.appendChild(tagText);
tag.appendChild(deleteBtn);
tagContainer.appendChild(tag);
// 清空输入框
subjectInput.value = '';
}
// 新增代码:处理创建方式切换
const creationMethodRadios = document.querySelectorAll('input[name="creationMethod"]');
const promptSection = document.getElementById('promptSection');
const uploadSection = document.getElementById('uploadSection');
const submitBtn = document.getElementById('submitBtn');
const imageUpload = document.getElementById('imageUpload');
const previewContainer = document.getElementById('previewContainer');
const imagePreview = document.getElementById('imagePreview');
const tagContainer = document.getElementById('tagContainer');
const subjectInput = document.getElementById('subjectInput');
const addTagBtn = document.getElementById('addTagBtn');
const placeholder = document.getElementById('placeholder');
const randomSampleBtn = document.getElementById('randomSampleBtn');
const sampleContainer = document.getElementById('sampleContainer');
const sampleContent = document.getElementById('sampleContent');
const promptForm = document.getElementById('promptForm');
creationMethodRadios.forEach(radio => {
radio.addEventListener('change', function() {
if (this.value === 'prompt') {
promptSection.style.display = 'block';
uploadSection.style.display = 'none';
submitBtn.textContent = '生成首帧图片';
} else {
promptSection.style.display = 'none';
uploadSection.style.display = 'block';
submitBtn.textContent = '确认上传图片';
}
});
});
// 新增代码:处理图片预览
imageUpload.addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(event) {
imagePreview.src = event.target.result;
previewContainer.style.display = 'block';
};
reader.readAsDataURL(file);
} else {
previewContainer.style.display = 'none';
}
});
// 随机示例数据
const samples = [
{
timeWeatherLight: '傍晚小雨,路灯刚亮',
sceneLocation: '老城区石板路',
subjects: ['戴斗笠的老奶奶(牵)', '穿红雨鞋的小女孩'],
atmosphere: '温暖'
},
{
timeWeatherLight: '清晨薄雾,侧逆光',
sceneLocation: '空旷高速公路',
subjects: [],
atmosphere: '寂静'
},
{
timeWeatherLight: '深夜暴雨,城市广场灯光',
sceneLocation: '城市广场',
subjects: ['一只黑伞(被风吹翻)', '一辆倒地的外卖车', '散落的黄色外卖箱'],
atmosphere: '慌乱'
},
{
timeWeatherLight: '晴天午后,阳光明媚',
sceneLocation: '公园草坪',
subjects: ['穿白色连衣裙的女孩(奔跑)', '棕色小狗(追逐)'],
atmosphere: '欢快'
},
{
timeWeatherLight: '春日清晨,阳光柔和',
sceneLocation: '乡村小道',
subjects: ['盛开的桃花树', '骑自行车的少年(笑)'],
atmosphere: '清新'
},
{
timeWeatherLight: '秋日黄昏,金色阳光',
sceneLocation: '枫树林',
subjects: ['捡枫叶的小女孩', '飘落的红枫叶'],
atmosphere: '浪漫'
},
{
timeWeatherLight: '冬夜飘雪,路灯暖光',
sceneLocation: '城市街道',
subjects: ['撑伞的情侣(依偎)', '雪地上的脚印'],
atmosphere: '温馨'
},
{
timeWeatherLight: '夏日正午,强烈阳光',
sceneLocation: '海边沙滩',
subjects: ['彩色遮阳伞', '冲浪的年轻人', '沙滩上的贝壳'],
atmosphere: '热烈'
}
];
// 随机示例按钮点击事件
randomSampleBtn.addEventListener('click', function() {
const randomIndex = Math.floor(Math.random() * samples.length);
const sample = samples[randomIndex];
// 填充表单
document.getElementById('timeWeatherLight').value = sample.timeWeatherLight;
document.getElementById('sceneLocation').value = sample.sceneLocation;
document.getElementById('atmosphere').value = sample.atmosphere;
// 清空现有标签
while (tagContainer.firstChild) {
tagContainer.removeChild(tagContainer.firstChild);
}
tagContainer.appendChild(placeholder);
// 添加示例标签
sample.subjects.forEach(subject => {
addTag(subject);
});
// 显示示例容器
sampleContent.textContent = `${sample.timeWeatherLight}${sample.sceneLocation}${sample.subjects.length ? '' + sample.subjects.join('与') : ''},氛围${sample.atmosphere}`;
sampleContainer.style.display = 'block';
});
// 表单提交事件
promptForm.addEventListener('submit', function(e) {
e.preventDefault();
const creationMethod = document.querySelector('input[name="creationMethod"]:checked').value;
if (creationMethod === 'prompt') {
// 收集表单数据
const formData = {
timeWeatherLight: document.getElementById('timeWeatherLight').value,
sceneLocation: document.getElementById('sceneLocation').value,
subjects: [],
atmosphere: document.getElementById('atmosphere').value
};
// 收集标签数据
const tags = tagContainer.querySelectorAll('.tag');
tags.forEach(tag => {
formData.subjects.push(tag.querySelector('span').textContent);
});
// 构建提示词
let prompt = `${formData.timeWeatherLight}${formData.sceneLocation}`;
if (formData.subjects.length > 0) {
prompt += '' + formData.subjects.join('与');
}
prompt += `,氛围${formData.atmosphere}`;
// 调用 API 生成图片
generateImage(prompt);
} else {
// 图片上传逻辑
if (imageUpload.files.length === 0) {
alert('请先选择要上传的图片');
return;
}
const file = imageUpload.files[0];
console.log('上传的图片:', file.name);
// 这里应该实现图片上传逻辑
alert('图片上传功能尚未实现');
}
});
// 新增函数:调用 API 生成图片
function generateImage(prompt) {
// 显示遮罩动画
mask.classList.add('active');
maskText.textContent = '正在生成图片,请稍候...';
console.log('生成的提示词:', prompt);
// 发送请求到后端 API
fetch('/api/jimeng/prompt_input', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ prompt: prompt })
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应异常');
}
return response.json();
})
.then(data => {
// 隐藏遮罩动画
mask.classList.remove('active');
if (data.code === 200) {
// 保存图片 URL 和提示词并跳转到预览页面
sessionStorage.setItem('generatedImageUrl', data.data.image_url);
sessionStorage.setItem('lastPrompt', prompt);
window.location.href = 'image_preview.html';
} else {
alert('图片生成失败: ' + data.message);
}
})
.catch(error => {
// 隐藏遮罩动画
mask.classList.remove('active');
console.error('生成图片时出错:', error);
alert('生成图片时出错: ' + error.message);
});
}
// 表单重置事件
promptForm.addEventListener('reset', function() {
// 清空标签
while (tagContainer.firstChild) {
tagContainer.removeChild(tagContainer.firstChild);
}
tagContainer.appendChild(placeholder);
checkTagContainer();
sampleContainer.style.display = 'none';
});
// 初始化检查
checkTagContainer();
});
</script>
</body>
</html>
<!-- 添加遮罩层 -->
<div class="mask" id="mask">
<div class="mask-content">
<div class="loader"></div>
<div class="mask-text" id="maskText">正在生成图片,请稍候...</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const mask = document.getElementById('mask');
const maskText = document.getElementById('maskText');
function generateImage(prompt) {
// 显示遮罩动画
mask.classList.add('active');
maskText.textContent = '正在生成图片,请稍候...';
console.log('生成的提示词:', prompt);
// 发送请求到后端 API
fetch('/api/jimeng/prompt_input', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ prompt: prompt })
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应异常');
}
return response.json();
})
.then(data => {
// 隐藏遮罩动画
mask.classList.remove('active');
if (data.code === 200) {
// 保存图片 URL 并跳转到预览页面
sessionStorage.setItem('generatedImageUrl', data.data.image_url);
window.location.href = 'image_preview.html';
} else {
alert('图片生成失败: ' + data.message);
}
})
.catch(error => {
// 恢复按钮状态
submitBtn.disabled = false;
submitBtn.textContent = '确认并继续';
console.error('生成图片时出错:', error);
alert('生成图片时出错: ' + error.message);
});
}
// 表单重置事件
promptForm.addEventListener('reset', function() {
// 清空标签
while (tagContainer.firstChild) {
tagContainer.removeChild(tagContainer.firstChild);
}
tagContainer.appendChild(placeholder);
checkTagContainer();
sampleContainer.style.display = 'none';
});
// 初始化检查
checkTagContainer();
});
</script>
</body>
</html>