美化packages.php界面:1)添加了套餐卡片网格布局;2)优化了表单样式和按钮设计;3)增强了套餐卡片的视觉层次;4)改进了空状态显示;5)添加了响应式设计支持

This commit is contained in:
2025-12-06 02:08:38 +08:00
parent b5cacb9e0b
commit 9d8fa49206
2 changed files with 409 additions and 115 deletions
+123 -115
View File
@@ -82,19 +82,19 @@ $packages = $stmt->fetchAll();
</div>
<?php endif; ?>
<div class="package-form-container">
<div class="package-form-container card">
<h2>添加新套餐</h2>
<form method="POST" class="form">
<input type="hidden" name="action" value="add">
<div class="form-group">
<label for="package_name">套餐名称:</label>
<input type="text" id="package_name" name="package_name" required>
<input type="text" id="package_name" name="package_name" required placeholder="请输入套餐名称">
</div>
<div class="form-group">
<label for="description">套餐描述:</label>
<textarea id="description" name="description" rows="3"></textarea>
<textarea id="description" name="description" rows="3" placeholder="请输入套餐描述"></textarea>
</div>
<div class="form-row">
@@ -105,7 +105,7 @@ $packages = $stmt->fetchAll();
<div class="form-group">
<label for="price">价格(元):</label>
<input type="number" id="price" name="price" min="0" step="0.01" required>
<input type="number" id="price" name="price" min="0" step="0.01" required placeholder="请输入套餐价格">
</div>
</div>
@@ -114,18 +114,18 @@ $packages = $stmt->fetchAll();
<div class="services-container">
<div class="service-item">
<input type="text" name="services[]" placeholder="服务项目1" value="外观清洗">
<button type="button" class="btn-remove" onclick="removeService(this)">删除</button>
<button type="button" class="btn btn-danger btn-sm" onclick="removeService(this)">删除</button>
</div>
<div class="service-item">
<input type="text" name="services[]" placeholder="服务项目2" value="内饰清洁">
<button type="button" class="btn-remove" onclick="removeService(this)">删除</button>
<button type="button" class="btn btn-danger btn-sm" onclick="removeService(this)">删除</button>
</div>
</div>
<button type="button" class="btn-add" onclick="addService()">+ 添加服务项目</button>
<button type="button" class="btn btn-outline btn-sm" onclick="addService()">+ 添加服务项目</button>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">添加套餐</button>
<button type="submit" class="btn btn-primary btn-lg">添加套餐</button>
</div>
</form>
</div>
@@ -133,120 +133,128 @@ $packages = $stmt->fetchAll();
<div class="packages-list">
<h2>套餐列表</h2>
<?php if (empty($packages)): ?>
<p class="empty-message">暂无套餐数据</p>
<div class="empty-state">
<div class="empty-icon">📦</div>
<p class="empty-message">暂无套餐数据</p>
<p class="empty-submessage">点击上方"添加套餐"按钮创建第一个套餐吧!</p>
</div>
<?php else: ?>
<?php foreach ($packages as $package): ?>
<div class="package-card <?= $package['is_active'] ? '' : 'inactive' ?>">
<div class="package-header">
<h3><?= htmlspecialchars($package['package_name']) ?></h3>
<div class="package-status">
<span class="status-badge <?= $package['is_active'] ? 'active' : 'inactive' ?>">
<?= $package['is_active'] ? '启用' : '禁用' ?>
</span>
</div>
</div>
<?php if ($package['description']): ?>
<p class="package-description"><?= htmlspecialchars($package['description']) ?></p>
<?php endif; ?>
<div class="package-details">
<div class="detail-item">
<span class="detail-label">基础时长:</span>
<span class="detail-value"><?= $package['base_duration'] ?>分钟</span>
</div>
<div class="detail-item">
<span class="detail-label">价格:</span>
<span class="detail-value">¥<?= number_format($package['price'], 2) ?></span>
</div>
</div>
<?php
$services = explode(',', $package['services']);
if ($services && !empty(trim($services[0]))):
?>
<div class="package-services">
<span class="detail-label">包含服务:</span>
<div class="services-tags">
<?php foreach ($services as $service): ?>
<?php if (trim($service)): ?>
<span class="service-tag"><?= htmlspecialchars(trim($service)) ?></span>
<?php endif; ?>
<?php endforeach; ?>
<div class="packages-grid">
<?php foreach ($packages as $package): ?>
<div class="package-card card <?= $package['is_active'] ? '' : 'inactive' ?>">
<div class="package-header">
<h3 class="package-title"><?= htmlspecialchars($package['package_name']) ?></h3>
<div class="package-status">
<span class="status-badge <?= $package['is_active'] ? 'active' : 'inactive' ?>">
<?= $package['is_active'] ? '启用' : '禁用' ?>
</span>
</div>
</div>
<?php endif; ?>
<?php if ($package['description']): ?>
<p class="package-description"><?= htmlspecialchars($package['description']) ?></p>
<?php endif; ?>
<div class="package-actions">
<button class="btn btn-sm" onclick="editPackage(<?= $package['id'] ?>)">编辑</button>
<form method="POST" style="display: inline;" onsubmit="return confirmDelete()">
<input type="hidden" name="action" value="delete">
<div class="package-details">
<div class="detail-item">
<span class="detail-label">基础时长:</span>
<span class="detail-value"><strong><?= $package['base_duration'] ?></strong>分钟</span>
</div>
<div class="detail-item">
<span class="detail-label">价格:</span>
<span class="detail-value price"><strong>¥<?= number_format($package['price'], 2) ?></strong></span>
</div>
</div>
<?php
$services = explode(',', $package['services']);
if ($services && !empty(trim($services[0]))):
?>
<div class="package-services">
<span class="detail-label">包含服务:</span>
<div class="services-tags">
<?php foreach ($services as $service): ?>
<?php if (trim($service)): ?>
<span class="service-tag"><?= htmlspecialchars(trim($service)) ?></span>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<div class="package-actions">
<button class="btn btn-primary btn-sm" onclick="editPackage(<?= $package['id'] ?>">编辑</button>
<form method="POST" style="display: inline;" onsubmit="return confirmDelete()">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= $package['id'] ?>">
<button type="submit" class="btn btn-danger btn-sm">删除</button>
</form>
</div>
<!-- 编辑表单 -->
<form method="POST" class="edit-form card" id="edit-form-<?= $package['id'] ?>" style="display: none;">
<input type="hidden" name="action" value="update">
<input type="hidden" name="id" value="<?= $package['id'] ?>">
<button type="submit" class="btn btn-danger btn-sm">删除</button>
<h4>编辑套餐</h4>
<div class="form-group">
<label>套餐名称:</label>
<input type="text" name="package_name" value="<?= htmlspecialchars($package['package_name']) ?>" required placeholder="请输入套餐名称">
</div>
<div class="form-group">
<label>套餐描述:</label>
<textarea name="description" rows="2" placeholder="请输入套餐描述"><?= htmlspecialchars($package['description']) ?></textarea>
</div>
<div class="form-row">
<div class="form-group">
<label>基础时长(分钟):</label>
<input type="number" name="base_duration" min="15" step="15" value="<?= $package['base_duration'] ?>" required>
</div>
<div class="form-group">
<label>价格(元):</label>
<input type="number" name="price" min="0" step="0.01" value="<?= $package['price'] ?>" required placeholder="请输入套餐价格">
</div>
</div>
<div class="form-group">
<label>服务项目:</label>
<div class="services-container">
<?php
$services = explode(',', $package['services']);
foreach ($services as $service):
if (trim($service)):
?>
<div class="service-item">
<input type="text" name="services[]" value="<?= htmlspecialchars(trim($service)) ?>">
<button type="button" class="btn btn-danger btn-sm" onclick="removeService(this)">删除</button>
</div>
<?php
endif;
endforeach;
?>
</div>
<button type="button" class="btn btn-outline btn-sm" onclick="addService()">+ 添加服务项目</button>
</div>
<div class="form-group">
<label class="checkbox-label">
<input type="checkbox" name="is_active" <?= $package['is_active'] ? 'checked' : '' ?>>
<span class="checkbox-text">启用此套餐</span>
</label>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">保存更改</button>
<button type="button" class="btn btn-outline" onclick="cancelEdit(<?= $package['id'] ?>)">取消</button>
</div>
</form>
</div>
<!-- 编辑表单 -->
<form method="POST" class="edit-form" id="edit-form-<?= $package['id'] ?>" style="display: none;">
<input type="hidden" name="action" value="update">
<input type="hidden" name="id" value="<?= $package['id'] ?>">
<div class="form-group">
<label>套餐名称:</label>
<input type="text" name="package_name" value="<?= htmlspecialchars($package['package_name']) ?>" required>
</div>
<div class="form-group">
<label>套餐描述:</label>
<textarea name="description" rows="2"><?= htmlspecialchars($package['description']) ?></textarea>
</div>
<div class="form-row">
<div class="form-group">
<label>基础时长(分钟):</label>
<input type="number" name="base_duration" min="15" step="15" value="<?= $package['base_duration'] ?>" required>
</div>
<div class="form-group">
<label>价格(元):</label>
<input type="number" name="price" min="0" step="0.01" value="<?= $package['price'] ?>" required>
</div>
</div>
<div class="form-group">
<label>服务项目:</label>
<div class="services-container">
<?php
$services = explode(',', $package['services']);
foreach ($services as $service):
if (trim($service)):
?>
<div class="service-item">
<input type="text" name="services[]" value="<?= htmlspecialchars(trim($service)) ?>">
<button type="button" class="btn-remove" onclick="removeService(this)">删除</button>
</div>
<?php
endif;
endforeach;
?>
</div>
<button type="button" class="btn-add" onclick="addService()">+ 添加服务项目</button>
</div>
<div class="form-group">
<label>
<input type="checkbox" name="is_active" <?= $package['is_active'] ? 'checked' : '' ?>>
启用此套餐
</label>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">保存更改</button>
<button type="button" class="btn" onclick="cancelEdit(<?= $package['id'] ?>)">取消</button>
</div>
</form>
</div>
<?php endforeach; ?>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</div>
+286
View File
@@ -1124,4 +1124,290 @@ label {
::-webkit-scrollbar-thumb:hover {
background: var(--el-text-secondary);
}
/* 套餐管理页面样式 */
.package-form-container {
margin-bottom: var(--el-spacing-extra-large);
}
.package-form-container h2,
.packages-list h2 {
margin: 0 0 var(--el-spacing-large) 0;
font-size: var(--el-font-size-large);
font-weight: 600;
color: var(--el-text-primary);
padding-bottom: var(--el-spacing-base);
border-bottom: 1px solid var(--el-border-lighter);
}
/* 套餐卡片网格布局 */
.packages-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: var(--el-spacing-large);
margin-top: var(--el-spacing-large);
}
/* 套餐卡片样式 */
.package-card {
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.package-card:hover {
transform: translateY(-4px);
box-shadow: var(--el-shadow-dark);
}
.package-card.inactive {
opacity: 0.7;
border: 1px dashed var(--el-border-color);
}
.package-card.inactive::before {
content: '已禁用';
position: absolute;
top: 16px;
right: -30px;
background: var(--el-danger-color);
color: white;
padding: 4px 32px;
font-size: 12px;
font-weight: 500;
transform: rotate(45deg);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
.package-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: var(--el-spacing-base);
}
.package-title {
margin: 0;
font-size: var(--el-font-size-large);
font-weight: 600;
color: var(--el-text-primary);
flex: 1;
margin-right: var(--el-spacing-base);
}
.package-status {
display: flex;
align-items: center;
}
.status-badge {
padding: 4px 8px;
border-radius: var(--el-border-radius-round);
font-size: var(--el-font-size-extra-small);
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.status-badge.active {
background: rgba(103, 194, 58, 0.1);
color: var(--el-success-color);
}
.status-badge.inactive {
background: rgba(245, 108, 108, 0.1);
color: var(--el-danger-color);
}
.package-description {
margin: 0 0 var(--el-spacing-base) 0;
color: var(--el-text-secondary);
font-size: var(--el-font-size-small);
line-height: 1.5;
}
.package-details {
margin: var(--el-spacing-base) 0;
padding: var(--el-spacing-base);
background: var(--el-bg-color-page);
border-radius: var(--el-border-radius-base);
}
.detail-item {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--el-spacing-small);
font-size: var(--el-font-size-small);
}
.detail-item:last-child {
margin-bottom: 0;
}
.detail-label {
color: var(--el-text-secondary);
font-weight: 500;
}
.detail-value {
color: var(--el-text-primary);
font-weight: 600;
}
.detail-value.price {
color: var(--el-danger-color);
font-size: var(--el-font-size-base);
}
/* 服务项目标签 */
.package-services {
margin: var(--el-spacing-base) 0;
}
.package-services .detail-label {
display: block;
margin-bottom: var(--el-spacing-small);
font-size: var(--el-font-size-small);
}
.services-tags {
display: flex;
flex-wrap: wrap;
gap: var(--el-spacing-small);
}
.service-tag {
background: var(--el-border-extra-light);
color: var(--el-text-regular);
padding: 4px 12px;
border-radius: var(--el-border-radius-round);
font-size: var(--el-font-size-extra-small);
font-weight: 500;
border: 1px solid var(--el-border-lighter);
transition: all 0.3s ease;
}
.service-tag:hover {
background: var(--el-primary-light);
color: var(--el-primary-color);
border-color: var(--el-primary-light);
}
/* 套餐操作按钮 */
.package-actions {
margin-top: var(--el-spacing-base);
display: flex;
gap: var(--el-spacing-small);
justify-content: flex-end;
}
/* 空状态样式 */
.empty-state {
text-align: center;
padding: var(--el-spacing-extra-large) 0;
background: var(--el-bg-color);
border-radius: var(--el-border-radius-base);
box-shadow: var(--el-shadow-light);
margin-top: var(--el-spacing-large);
}
.empty-icon {
font-size: 48px;
margin-bottom: var(--el-spacing-base);
opacity: 0.5;
}
.empty-message {
font-size: var(--el-font-size-large);
font-weight: 600;
color: var(--el-text-secondary);
margin: 0 0 var(--el-spacing-small) 0;
}
.empty-submessage {
font-size: var(--el-font-size-base);
color: var(--el-text-placeholder);
margin: 0;
}
/* 编辑表单样式 */
.edit-form {
margin-top: var(--el-spacing-base);
border-top: 2px solid var(--el-border-lighter);
padding-top: var(--el-spacing-large);
animation: fadeIn 0.3s ease;
}
.edit-form h4 {
margin: 0 0 var(--el-spacing-base) 0;
font-size: var(--el-font-size-base);
font-weight: 600;
color: var(--el-text-primary);
}
/* 服务项目样式 */
.services-container {
margin-bottom: var(--el-spacing-small);
}
.service-item {
display: flex;
align-items: center;
gap: var(--el-spacing-small);
margin-bottom: var(--el-spacing-small);
}
.service-item input {
flex: 1;
}
/* 复选框标签样式 */
.checkbox-label {
display: flex;
align-items: center;
cursor: pointer;
user-select: none;
}
.checkbox-text {
margin-left: var(--el-spacing-small);
color: var(--el-text-primary);
}
/* 动画效果 */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 响应式设计 */
@media (max-width: 768px) {
.packages-grid {
grid-template-columns: 1fr;
}
.package-header {
flex-direction: column;
align-items: flex-start;
}
.package-status {
margin-top: var(--el-spacing-small);
}
.form-row {
flex-direction: column;
}
.form-row .form-group {
width: 100%;
}
}