临时保存2
This commit is contained in:
260
wechat-miniprogram/pages/meal-planning/meal-planning.js
Normal file
260
wechat-miniprogram/pages/meal-planning/meal-planning.js
Normal file
@@ -0,0 +1,260 @@
|
||||
// 智能饭菜规划页面逻辑
|
||||
Page({
|
||||
data: {
|
||||
// 表单数据
|
||||
regionIndex: 0,
|
||||
regionOptions: ['全国', '北方', '南方', '川菜', '粤菜', '鲁菜', '苏菜', '浙菜', '闽菜', '湘菜', '徽菜'],
|
||||
dinerCountIndex: 1,
|
||||
dinerCountOptions: ['1人', '2人', '3人', '4人', '5人', '6人', '8人', '10人'],
|
||||
mealTypeIndex: 1,
|
||||
mealTypeOptions: ['早餐', '午餐', '晚餐', '全天'],
|
||||
hometown: '',
|
||||
preferences: '',
|
||||
dietaryRestrictions: '',
|
||||
budgetIndex: 1,
|
||||
budgetOptions: ['50元以下', '50-100元', '100-150元', '150-200元', '200-300元', '300-500元', '500元以上'],
|
||||
|
||||
// 状态数据
|
||||
isGenerating: false,
|
||||
mealPlanResult: '',
|
||||
|
||||
// API配置
|
||||
apiBaseUrl: 'https://your-domain.com/api'
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
console.log('饭菜规划页面加载');
|
||||
},
|
||||
|
||||
// 地区类型选择
|
||||
onRegionChange(e) {
|
||||
this.setData({
|
||||
regionIndex: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 就餐人数选择
|
||||
onDinerCountChange(e) {
|
||||
this.setData({
|
||||
dinerCountIndex: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 用餐类型选择
|
||||
onMealTypeChange(e) {
|
||||
this.setData({
|
||||
mealTypeIndex: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 家乡输入
|
||||
onHometownInput(e) {
|
||||
this.setData({
|
||||
hometown: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 个人喜好输入
|
||||
onPreferencesInput(e) {
|
||||
this.setData({
|
||||
preferences: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 饮食禁忌输入
|
||||
onDietaryRestrictionsInput(e) {
|
||||
this.setData({
|
||||
dietaryRestrictions: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 预算选择
|
||||
onBudgetChange(e) {
|
||||
this.setData({
|
||||
budgetIndex: e.detail.value
|
||||
});
|
||||
},
|
||||
|
||||
// 生成饭菜规划
|
||||
async generateMealPlan() {
|
||||
// 验证必填字段
|
||||
if (!this.data.hometown.trim()) {
|
||||
wx.showToast({
|
||||
title: '请输入用餐者家乡',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置生成状态
|
||||
this.setData({
|
||||
isGenerating: true
|
||||
});
|
||||
|
||||
try {
|
||||
// 构建请求数据
|
||||
const requestData = {
|
||||
region_type: this.data.regionOptions[this.data.regionIndex],
|
||||
diner_count: this.data.dinerCountOptions[this.data.dinerCountIndex],
|
||||
meal_type: this.data.mealTypeOptions[this.data.mealTypeIndex],
|
||||
hometown: this.data.hometown,
|
||||
preferences: this.data.preferences,
|
||||
dietary_restrictions: this.data.dietaryRestrictions,
|
||||
budget: this.data.budgetOptions[this.data.budgetIndex]
|
||||
};
|
||||
|
||||
// 发送请求
|
||||
const response = await wx.request({
|
||||
url: `${this.data.apiBaseUrl}/meal-planning/generate`,
|
||||
method: 'POST',
|
||||
data: requestData,
|
||||
header: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
// 处理Markdown格式的结果
|
||||
const formattedResult = this.formatMarkdownToHtml(response.data.data.meal_plan);
|
||||
this.setData({
|
||||
mealPlanResult: formattedResult
|
||||
});
|
||||
|
||||
wx.showToast({
|
||||
title: '生成成功!',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
// 滚动到结果区域
|
||||
wx.pageScrollTo({
|
||||
selector: '.result-container',
|
||||
duration: 500
|
||||
});
|
||||
} else {
|
||||
throw new Error(response.data.message || '生成失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('生成饭菜规划失败:', error);
|
||||
wx.showToast({
|
||||
title: error.message || '生成失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
this.setData({
|
||||
isGenerating: false
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 格式化Markdown为HTML
|
||||
formatMarkdownToHtml(text) {
|
||||
return text
|
||||
.replace(/^### (.*$)/gim, '<h3>$1</h3>')
|
||||
.replace(/^## (.*$)/gim, '<h2>$1</h2>')
|
||||
.replace(/^# (.*$)/gim, '<h1>$1</h1>')
|
||||
.replace(/\*\*(.*)\*\*/gim, '<strong>$1</strong>')
|
||||
.replace(/\*(.*)\*/gim, '<em>$1</em>')
|
||||
.replace(/^\* (.*$)/gim, '<li>$1</li>')
|
||||
.replace(/^\d+\. (.*$)/gim, '<li>$1</li>')
|
||||
.replace(/\n\n/gim, '</p><p>')
|
||||
.replace(/\n/gim, '<br>')
|
||||
.replace(/^(.*)$/gim, '<p>$1</p>');
|
||||
},
|
||||
|
||||
// 复制结果
|
||||
copyResult() {
|
||||
if (!this.data.mealPlanResult) {
|
||||
wx.showToast({
|
||||
title: '没有可复制的内容',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 提取纯文本内容
|
||||
const textContent = this.data.mealPlanResult.replace(/<[^>]*>/g, '');
|
||||
|
||||
wx.setClipboardData({
|
||||
data: textContent,
|
||||
success: () => {
|
||||
wx.showToast({
|
||||
title: '已复制到剪贴板',
|
||||
icon: 'success'
|
||||
});
|
||||
},
|
||||
fail: () => {
|
||||
wx.showToast({
|
||||
title: '复制失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 保存结果
|
||||
async saveResult() {
|
||||
if (!this.data.mealPlanResult) {
|
||||
wx.showToast({
|
||||
title: '没有可保存的内容',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 构建保存数据
|
||||
const saveData = {
|
||||
meal_plan_content: this.data.mealPlanResult.replace(/<[^>]*>/g, ''),
|
||||
region_type: this.data.regionOptions[this.data.regionIndex],
|
||||
diner_count: this.data.dinerCountOptions[this.data.dinerCountIndex],
|
||||
meal_type: this.data.mealTypeOptions[this.data.mealTypeIndex],
|
||||
hometown: this.data.hometown,
|
||||
preferences: this.data.preferences,
|
||||
dietary_restrictions: this.data.dietaryRestrictions,
|
||||
budget: this.data.budgetOptions[this.data.budgetIndex]
|
||||
};
|
||||
|
||||
// 发送保存请求
|
||||
const response = await wx.request({
|
||||
url: `${this.data.apiBaseUrl}/meal-planning/save`,
|
||||
method: 'POST',
|
||||
data: saveData,
|
||||
header: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (response.data.success) {
|
||||
wx.showToast({
|
||||
title: '保存成功!',
|
||||
icon: 'success'
|
||||
});
|
||||
} else {
|
||||
throw new Error(response.data.message || '保存失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存饭菜规划失败:', error);
|
||||
wx.showToast({
|
||||
title: error.message || '保存失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 页面分享
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: '智能饭菜规划 - AI驱动的个性化饭菜清单规划师',
|
||||
path: '/pages/meal-planning/meal-planning',
|
||||
imageUrl: '/images/meal-planning-share.jpg'
|
||||
};
|
||||
},
|
||||
|
||||
// 分享到朋友圈
|
||||
onShareTimeline() {
|
||||
return {
|
||||
title: '智能饭菜规划 - AI驱动的个性化饭菜清单规划师',
|
||||
imageUrl: '/images/meal-planning-share.jpg'
|
||||
};
|
||||
}
|
||||
});
|
||||
104
wechat-miniprogram/pages/meal-planning/meal-planning.wxml
Normal file
104
wechat-miniprogram/pages/meal-planning/meal-planning.wxml
Normal file
@@ -0,0 +1,104 @@
|
||||
<!-- 智能饭菜规划页面 -->
|
||||
<view class="container">
|
||||
<!-- 页面标题 -->
|
||||
<view class="page-header">
|
||||
<view class="page-title">
|
||||
<text class="title-icon">🍽️</text>
|
||||
<text class="title-text">智能饭菜规划</text>
|
||||
</view>
|
||||
<view class="page-subtitle">AI驱动的个性化饭菜清单规划师</view>
|
||||
</view>
|
||||
|
||||
<!-- 表单区域 -->
|
||||
<view class="form-container">
|
||||
<view class="form-section">
|
||||
<view class="section-title">规划参数</view>
|
||||
|
||||
<!-- 地区类型 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label">地区类型</view>
|
||||
<picker bindchange="onRegionChange" value="{{regionIndex}}" range="{{regionOptions}}">
|
||||
<view class="picker-display">{{regionOptions[regionIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<!-- 就餐人数 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label">就餐人数</view>
|
||||
<picker bindchange="onDinerCountChange" value="{{dinerCountIndex}}" range="{{dinerCountOptions}}">
|
||||
<view class="picker-display">{{dinerCountOptions[dinerCountIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<!-- 用餐类型 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label">用餐类型</view>
|
||||
<picker bindchange="onMealTypeChange" value="{{mealTypeIndex}}" range="{{mealTypeOptions}}">
|
||||
<view class="picker-display">{{mealTypeOptions[mealTypeIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<!-- 用餐者家乡 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label">用餐者家乡 <text class="required">*</text></view>
|
||||
<input class="form-input" placeholder="如:四川成都" value="{{hometown}}" bindinput="onHometownInput" />
|
||||
</view>
|
||||
|
||||
<!-- 个人喜好 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label">个人喜好</view>
|
||||
<textarea class="form-textarea" placeholder="如:喜欢辣味、偏爱素食、喜欢海鲜等" value="{{preferences}}" bindinput="onPreferencesInput"></textarea>
|
||||
</view>
|
||||
|
||||
<!-- 饮食禁忌 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label">饮食禁忌</view>
|
||||
<textarea class="form-textarea" placeholder="如:不吃猪肉、对花生过敏、素食主义等" value="{{dietaryRestrictions}}" bindinput="onDietaryRestrictionsInput"></textarea>
|
||||
</view>
|
||||
|
||||
<!-- 预算范围 -->
|
||||
<view class="form-item">
|
||||
<view class="form-label">预算范围(元)</view>
|
||||
<picker bindchange="onBudgetChange" value="{{budgetIndex}}" range="{{budgetOptions}}">
|
||||
<view class="picker-display">{{budgetOptions[budgetIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<!-- 生成按钮 -->
|
||||
<button class="generate-btn" bindtap="generateMealPlan" disabled="{{isGenerating}}">
|
||||
<text wx:if="{{!isGenerating}}">🎯 生成饭菜规划</text>
|
||||
<text wx:else>⏳ 生成中...</text>
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 结果展示区域 -->
|
||||
<view class="result-container" wx:if="{{mealPlanResult}}">
|
||||
<view class="result-header">
|
||||
<view class="result-title">🍽️ 饭菜规划结果</view>
|
||||
<view class="result-actions">
|
||||
<button class="action-btn copy-btn" bindtap="copyResult">📋 复制</button>
|
||||
<button class="action-btn save-btn" bindtap="saveResult">💾 保存</button>
|
||||
</view>
|
||||
</view>
|
||||
<view class="result-content">
|
||||
<rich-text nodes="{{mealPlanResult}}"></rich-text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 历史记录入口 -->
|
||||
<view class="history-entry">
|
||||
<navigator url="/pages/meal-history/meal-history" class="history-link">
|
||||
<text class="history-icon">📚</text>
|
||||
<text class="history-text">查看历史规划</text>
|
||||
</navigator>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载提示 -->
|
||||
<view class="loading-overlay" wx:if="{{isGenerating}}">
|
||||
<view class="loading-content">
|
||||
<view class="loading-spinner"></view>
|
||||
<view class="loading-text">AI正在为您制定个性化的饭菜清单,请稍候...</view>
|
||||
</view>
|
||||
</view>
|
||||
341
wechat-miniprogram/pages/meal-planning/meal-planning.wxss
Normal file
341
wechat-miniprogram/pages/meal-planning/meal-planning.wxss
Normal file
@@ -0,0 +1,341 @@
|
||||
/* 智能饭菜规划页面样式 */
|
||||
.container {
|
||||
padding: 20rpx;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 页面标题 */
|
||||
.page-header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 40rpx 30rpx;
|
||||
margin: -20rpx -20rpx 30rpx -20rpx;
|
||||
border-radius: 0 0 40rpx 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.title-icon {
|
||||
font-size: 60rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 28rpx;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 表单容器 */
|
||||
.form-container {
|
||||
background: white;
|
||||
border-radius: 30rpx;
|
||||
padding: 40rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.form-section {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 40rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 表单项 */
|
||||
.form-item {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #ff4757;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
/* 选择器样式 */
|
||||
.picker-display {
|
||||
background: #f8f9fa;
|
||||
border: 2rpx solid #e9ecef;
|
||||
border-radius: 20rpx;
|
||||
padding: 24rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.picker-display::after {
|
||||
content: '▼';
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #667eea;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
/* 输入框样式 */
|
||||
.form-input {
|
||||
background: #f8f9fa;
|
||||
border: 2rpx solid #e9ecef;
|
||||
border-radius: 20rpx;
|
||||
padding: 24rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-input:focus {
|
||||
border-color: #667eea;
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* 文本域样式 */
|
||||
.form-textarea {
|
||||
background: #f8f9fa;
|
||||
border: 2rpx solid #e9ecef;
|
||||
border-radius: 20rpx;
|
||||
padding: 24rpx 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
width: 100%;
|
||||
min-height: 120rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-textarea:focus {
|
||||
border-color: #667eea;
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* 生成按钮 */
|
||||
.generate-btn {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 25rpx;
|
||||
padding: 30rpx 60rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
width: 100%;
|
||||
margin-top: 40rpx;
|
||||
box-shadow: 0 8rpx 30rpx rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.generate-btn:active {
|
||||
transform: translateY(2rpx);
|
||||
box-shadow: 0 4rpx 15rpx rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.generate-btn[disabled] {
|
||||
opacity: 0.6;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
/* 结果容器 */
|
||||
.result-container {
|
||||
background: white;
|
||||
border-radius: 30rpx;
|
||||
padding: 40rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.result-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.result-actions {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
background: #f8f9fa;
|
||||
border: 2rpx solid #e9ecef;
|
||||
border-radius: 20rpx;
|
||||
padding: 16rpx 24rpx;
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.copy-btn:active {
|
||||
background: #e3f2fd;
|
||||
border-color: #2196f3;
|
||||
color: #2196f3;
|
||||
}
|
||||
|
||||
.save-btn:active {
|
||||
background: #e8f5e8;
|
||||
border-color: #4caf50;
|
||||
color: #4caf50;
|
||||
}
|
||||
|
||||
/* 结果内容 */
|
||||
.result-content {
|
||||
background: #f8f9fa;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
border-left: 8rpx solid #667eea;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.result-content h1,
|
||||
.result-content h2,
|
||||
.result-content h3 {
|
||||
color: #333;
|
||||
margin: 30rpx 0 20rpx 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.result-content h1:first-child,
|
||||
.result-content h2:first-child,
|
||||
.result-content h3:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.result-content strong {
|
||||
color: #667eea;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.result-content ul,
|
||||
.result-content ol {
|
||||
padding-left: 40rpx;
|
||||
}
|
||||
|
||||
.result-content li {
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
/* 历史记录入口 */
|
||||
.history-entry {
|
||||
background: white;
|
||||
border-radius: 30rpx;
|
||||
padding: 30rpx;
|
||||
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.history-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-decoration: none;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.history-icon {
|
||||
font-size: 40rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.history-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 加载遮罩 */
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
background: white;
|
||||
border-radius: 30rpx;
|
||||
padding: 60rpx 40rpx;
|
||||
text-align: center;
|
||||
max-width: 500rpx;
|
||||
margin: 0 40rpx;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border: 6rpx solid #f3f3f3;
|
||||
border-top: 6rpx solid #667eea;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 0 auto 30rpx;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 响应式适配 */
|
||||
@media (max-width: 750rpx) {
|
||||
.container {
|
||||
padding: 15rpx;
|
||||
}
|
||||
|
||||
.form-container,
|
||||
.result-container,
|
||||
.history-entry {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
padding: 30rpx 20rpx;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user