160 lines
7.8 KiB
Vue
160 lines
7.8 KiB
Vue
<template>
|
|
<view>
|
|
<view v-html="sanitizeContent(formHtml)"></view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue'
|
|
|
|
const formHtml = ref('')
|
|
const sanitizeContent = (str) => {
|
|
return str.replace(/<\/?script>/gi, (match) => {
|
|
// 将匹配到的标签转换为十六进制 Unicode
|
|
let result = '';
|
|
for (let i = 0; i < match.length; i++) {
|
|
result += '\\u' + match.charCodeAt(i).toString(16).padStart(4, '0');
|
|
}
|
|
return result;
|
|
});
|
|
}
|
|
|
|
onMounted(() => {
|
|
// 直接设置 HTML
|
|
formHtml.value = `
|
|
明白了!您希望在我的回复中直接嵌入可编辑的表单卡片。让我试试:
|
|
|
|
---
|
|
|
|
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 20px; padding: 28px; color: white; font-family: 'Microsoft YaHei', sans-serif; box-shadow: 0 10px 40px rgba(0,0,0,0.25); margin: 20px 0;">
|
|
<h2 style="margin: 0 0 20px 0; font-size: 20px; display: flex; align-items: center; gap: 12px;">
|
|
<span style="font-size: 26px;">✏️</span> 直接在下方编辑任务
|
|
</h2>
|
|
|
|
<form id="inlineTaskForm" style="background: rgba(255,255,255,0.1); border-radius: 16px; padding: 24px;">
|
|
<div style="margin-bottom: 18px;">
|
|
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">任务名称</label>
|
|
<input type="text" id="inlineTitle" placeholder="输入任务名称..." style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 15px;">
|
|
</div>
|
|
|
|
<div style="margin-bottom: 18px;">
|
|
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">任务描述</label>
|
|
<textarea id="inlineDesc" placeholder="输入详细描述..." style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 14px; resize: vertical; min-height: 60px;"></textarea>
|
|
</div>
|
|
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 18px;">
|
|
<div>
|
|
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">开始日期</label>
|
|
<input type="date" id="inlineStart" style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 15px;">
|
|
</div>
|
|
<div>
|
|
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">截止日期</label>
|
|
<input type="date" id="inlineEnd" style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 15px;">
|
|
</div>
|
|
</div>
|
|
|
|
<div style="margin-bottom: 18px;">
|
|
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 1px;">时间</label>
|
|
<input type="time" id="inlineTime" value="09:00" style="width: 100%; padding: 14px 16px; background: #1e1e2e; border: 2px solid rgba(255,255,255,0.2); border-radius: 10px; color: #fff; font-size: 15px;">
|
|
</div>
|
|
|
|
<div style="margin-bottom: 18px;">
|
|
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 10px; text-transform: uppercase; letter-spacing: 1px;">优先级</label>
|
|
<div style="display: flex; gap: 10px;">
|
|
<label style="flex: 1; text-align: center; padding: 12px; background: rgba(254, 215, 215, 0.2); border: 2px solid transparent; border-radius: 10px; cursor: pointer; transition: all 0.3s;" onclick="selectPriority(this, 'high')">
|
|
🔴 高
|
|
<input type="radio" name="priority" value="high" checked style="display: none;">
|
|
</label>
|
|
<label style="flex: 1; text-align: center; padding: 12px; background: rgba(254, 235, 200, 0.2); border: 2px solid transparent; border-radius: 10px; cursor: pointer; transition: all 0.3s;" onclick="selectPriority(this, 'medium')">
|
|
🟡 中
|
|
<input type="radio" name="priority" value="medium" style="display: none;">
|
|
</label>
|
|
<label style="flex: 1; text-align: center; padding: 12px; background: rgba(198, 246, 213, 0.2); border: 2px solid transparent; border-radius: 10px; cursor: pointer; transition: all 0.3s;" onclick="selectPriority(this, 'low')">
|
|
🟢 低
|
|
<input type="radio" name="priority" value="low" style="display: none;">
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="margin-bottom: 20px;">
|
|
<label style="display: block; font-size: 12px; opacity: 0.8; margin-bottom: 10px; text-transform: uppercase; letter-spacing: 1px;">分类</label>
|
|
<div style="display: flex; gap: 10px; flex-wrap: wrap;">
|
|
<label style="padding: 10px 16px; background: rgba(233, 216, 253, 0.2); border: 2px solid #667eea; border-radius: 20px; cursor: pointer; font-size: 13px;" onclick="selectCategory(this, 'work')">
|
|
💼 工作
|
|
<input type="radio" name="category" value="work" checked style="display: none;">
|
|
</label>
|
|
<label style="padding: 10px 16px; background: rgba(190, 227, 248, 0.2); border: 2px solid transparent; border-radius: 20px; cursor: pointer; font-size: 13px;" onclick="selectCategory(this, 'life')">
|
|
🏠 生活
|
|
<input type="radio" name="category" value="life" style="display: none;">
|
|
</label>
|
|
<label style="padding: 10px 16px; background: rgba(254, 215, 226, 0.2); border: 2px solid transparent; border-radius: 20px; cursor: pointer; font-size: 13px;" onclick="selectCategory(this, 'study')">
|
|
📚 学习
|
|
<input type="radio" name="category" value="study" style="display: none;">
|
|
</label>
|
|
<label style="padding: 10px 16px; background: rgba(198, 246, 213, 0.2); border: 2px solid transparent; border-radius: 20px; cursor: pointer; font-size: 13px;" onclick="selectCategory(this, 'health')">
|
|
💪 健康
|
|
<input type="radio" name="category" value="health" style="display: none;">
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display: flex; gap: 12px;">
|
|
<button type="button" onclick="clearInlineForm()" style="flex: 1; padding: 14px; background: rgba(255,255,255,0.2); border: none; border-radius: 12px; color: white; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.3s;">
|
|
清空
|
|
</button>
|
|
<button type="button" onclick="submitInlineForm()" style="flex: 2; padding: 14px; background: white; border: none; border-radius: 12px; color: #667eea; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.3s;">
|
|
✅ 添加任务
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
|
|
|
|
---
|
|
|
|
**✅ 您现在可以直接在上方的卡片中填写任务信息,点击"添加任务"即可!**
|
|
|
|
填写完成后告诉我"已填好"或"添加",我会帮您确认是否成功!
|
|
`
|
|
|
|
// 初始化事件
|
|
// initForm()
|
|
})
|
|
|
|
const initForm = () => {
|
|
setTimeout(() => {
|
|
const today = new Date().toISOString().split('T')[0]
|
|
const startInput = document.getElementById('inlineStart')
|
|
const endInput = document.getElementById('inlineEnd')
|
|
if (startInput) startInput.value = today
|
|
if (endInput) endInput.value = today
|
|
|
|
const clearBtn = document.getElementById('clearBtn')
|
|
const submitBtn = document.getElementById('submitBtn')
|
|
|
|
if (clearBtn) {
|
|
clearBtn.onclick = () => {
|
|
const titleInput = document.getElementById('inlineTitle')
|
|
const descInput = document.getElementById('inlineDesc')
|
|
if (titleInput) titleInput.value = ''
|
|
if (descInput) descInput.value = ''
|
|
}
|
|
}
|
|
|
|
if (submitBtn) {
|
|
submitBtn.onclick = () => {
|
|
const titleInput = document.getElementById('inlineTitle')
|
|
const title = titleInput?.value.trim()
|
|
if (!title) {
|
|
alert('请输入任务名称')
|
|
return
|
|
}
|
|
alert(`任务已添加:${title}`)
|
|
if (titleInput) titleInput.value = ''
|
|
if (document.getElementById('inlineDesc')) document.getElementById('inlineDesc').value = ''
|
|
}
|
|
}
|
|
}, 100)
|
|
}
|
|
</script> |