ops-console v1.0.2 (versionCode 8) 源码入库
This commit is contained in:
125
lib/widgets/store_theme_preview.dart
Normal file
125
lib/widgets/store_theme_preview.dart
Normal file
@@ -0,0 +1,125 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../models/theme_template.dart';
|
||||
|
||||
/// 模拟门店主页头部预览浮层。
|
||||
///
|
||||
/// 依据选中的 [ThemeTemplate] 渲染一个模拟的门店主页头部
|
||||
///(主色背景 + 门店名 + Logo 占位),用于主题选择时实时预览效果。
|
||||
class StoreThemePreview extends StatelessWidget {
|
||||
const StoreThemePreview({
|
||||
super.key,
|
||||
this.template,
|
||||
this.storeName = '示例门店',
|
||||
});
|
||||
|
||||
/// 选中的主题模板;空时回退默认主题。
|
||||
final ThemeTemplate? template;
|
||||
|
||||
/// 预览中的门店名称。
|
||||
final String storeName;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final primary = _accentColor(template?.name ?? '');
|
||||
final label = template?.name ?? '默认主题';
|
||||
final onColor = Colors.white;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [primary, primary.withOpacity(0.75)],
|
||||
begin: Alignment.topLeft,
|
||||
end: Alignment.bottomRight,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
_placeholderLogo(primary, onColor),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
storeName,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 2,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.25),
|
||||
borderRadius: BorderRadius.circular(999),
|
||||
),
|
||||
child: Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
// 模拟内容卡占位。
|
||||
Container(
|
||||
height: 56,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.18),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _placeholderLogo(Color primary, Color onColor) {
|
||||
return Container(
|
||||
width: 48,
|
||||
height: 48,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(color: primary, width: 2),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Icon(Icons.storefront, color: primary, size: 26),
|
||||
);
|
||||
}
|
||||
|
||||
static const _palette = [
|
||||
Color(0xFF3B82F6),
|
||||
Color(0xFF8B5CF6),
|
||||
Color(0xFFEC4899),
|
||||
Color(0xFFF59E0B),
|
||||
Color(0xFF10B981),
|
||||
Color(0xFF6366F1),
|
||||
];
|
||||
|
||||
static Color _accentColor(String name) {
|
||||
var hash = 0;
|
||||
for (var i = 0; i < name.length; i++) {
|
||||
hash = (hash + name.codeUnitAt(i) * (i + 1)) % _palette.length;
|
||||
}
|
||||
return _palette[hash];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user