customer_target_group_picker.dart 9.7 KB
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:one_key/models/customer_target_group_model.dart';
import 'package:one_key/provider/coupon_provider.dart';
import 'package:one_key/provider/user_model.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/utils/utils.dart';
import 'package:provider/provider.dart';

/// 选择目标客户群体弹窗 —— 标签选择 + 自定义添加
class CustomerTargetGroupPicker extends StatelessWidget {
  final List<CustomerTargetGroupModel> groups;

  const CustomerTargetGroupPicker({super.key, required this.groups});

  static Future<List<CustomerTargetGroupModel>?> show(
    BuildContext context, {
    required List<CustomerTargetGroupModel> groups,
  }) {
    return showModalBottomSheet<List<CustomerTargetGroupModel>>(
      context: context,
      backgroundColor: Colors.transparent,
      isScrollControlled: true,
      builder: (_) => CustomerTargetGroupPicker(groups: groups),
    );
  }

  @override
  Widget build(BuildContext context) {
    return _Sheet(groups: groups);
  }
}

/// 弹窗主体
class _Sheet extends StatefulWidget {
  final List<CustomerTargetGroupModel> groups;
  const _Sheet({required this.groups});

  @override
  State<_Sheet> createState() => _SheetState();
}

class _SheetState extends State<_Sheet> {
  late final List<CustomerTargetGroupModel> _items;
  final _inputController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _items = widget.groups.map((e) {
      return CustomerTargetGroupModel(
        id: e.id,
        name: e.name,
        isSelected: e.isSelected,
      );
    }).toList();
  }

  @override
  void dispose() {
    _inputController.dispose();
    super.dispose();
  }

  void _onTagTap(int index) {
    setState(() {
      for (int i = 0; i < _items.length; i++) {
        _items[i].isSelected = i == index;
      }
    });
    Navigator.of(context).pop(_items);
  }

  void _onAddCustom() async {
    final text = _inputController.text.trim();
    if (text.isEmpty) {
      Utils.showToast('请输入客户群体名称');
      return;
    }

    final userModel = Provider.of<UserModel>(context, listen: false);
    final couponProvider = Provider.of<CouponProvider>(context, listen: false);

    final params = <String, String?>{
      'sellerid': userModel.user!.sellerid,
      'name': text,
    };

    final newId =
        await couponProvider.createCustomerTargetGroup(context, params);
    if (newId != null) {
      print('TEST2 自定义群体创建成功: $text, id=$newId');
      setState(() {
        _items.add(CustomerTargetGroupModel(id: newId, name: text, isSelected: true));
        _inputController.clear();
      });
      for (int i = 0; i < _items.length; i++) {
        _items[i].isSelected = i == _items.length - 1;
      }
      Navigator.of(context).pop(_items);
    }
  }

  @override
  Widget build(BuildContext context) {
    final bottomInset = MediaQuery.of(context).viewInsets.bottom;

    return GestureDetector(
      onTap: () => FocusScope.of(context).unfocus(),
      child: ClipRRect(
        borderRadius: BorderRadius.circular(ScreenUtil().setWidth(16)),
        child: Container(
          color: MyColours.color_ffffff,
          child: SafeArea(
            child: Padding(
              padding: EdgeInsets.only(
                  top: ScreenUtil().setWidth(24),
                  bottom: ScreenUtil().setWidth(64) + bottomInset),
              child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                _Title(),

                SizedBox(height: ScreenUtil().setWidth(49)),
                _Divider(),

                SizedBox(height: ScreenUtil().setWidth(32)),

                _TagGrid(items: _items, onTap: _onTagTap),

                SizedBox(height: ScreenUtil().setWidth(32)),
                _Divider(),

                SizedBox(height: ScreenUtil().setWidth(32)),

                Padding(
                  padding: EdgeInsets.only(
                      left: ScreenUtil().setWidth(30),
                      right: ScreenUtil().setWidth(64)),
                  child: _AddCustomRow(
                    controller: _inputController,
                    onConfirm: _onAddCustom,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
      ),
    );
  }
}

/// 标题:16px Semibold #000 90% 居中
class _Title extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      height: ScreenUtil().setWidth(48),
      child: Center(
        child: Text(
          '选择目标客户群体',
          style: TextStyle(
            fontSize: ScreenUtil().setSp(32),
            fontWeight: FontWeight.w600,
            color: const Color(0xE6000000),
          ),
        ),
      ),
    );
  }
}

/// 分割线
class _Divider extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: ScreenUtil().setWidth(1),
      color: MyColours.color_E7E7E7,
    );
  }
}

/// 标签流式布局
class _TagGrid extends StatelessWidget {
  final List<CustomerTargetGroupModel> items;
  final void Function(int) onTap;

  const _TagGrid({required this.items, required this.onTap});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(horizontal: ScreenUtil().setWidth(30)),
      child: Wrap(
        spacing: ScreenUtil().setWidth(24),
        runSpacing: ScreenUtil().setWidth(24),
        children: List.generate(items.length, (i) {
          return _Tag(
            text: items[i].name ?? '',
            selected: items[i].isSelected,
            onTap: () => onTap(i),
          );
        }),
      ),
    );
  }
}

/// 标签按钮:padding 5px 10px / 圆角5px / 选中#588C8C白字 / 未选中白底#515151边框
class _Tag extends StatelessWidget {
  final String text;
  final bool selected;
  final VoidCallback onTap;

  const _Tag({required this.text, required this.selected, required this.onTap});

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        padding: EdgeInsets.symmetric(
            horizontal: ScreenUtil().setWidth(20),
            vertical: ScreenUtil().setWidth(10)),
        decoration: BoxDecoration(
          color: selected ? const Color(0xFF588C8C) : MyColours.color_ffffff,
          borderRadius: BorderRadius.circular(ScreenUtil().setWidth(10)),
          border: selected
              ? null
              : Border.all(
                  color: MyColours.color_515151,
                  width: ScreenUtil().setWidth(2)),
        ),
        child: Text(
          text,
          style: TextStyle(
            fontSize: ScreenUtil().setSp(28),
            color: selected ? MyColours.color_ffffff : MyColours.color_515151,
          ),
        ),
      ),
    );
  }
}

/// 添加其他群体行
class _AddCustomRow extends StatelessWidget {
  final TextEditingController controller;
  final VoidCallback onConfirm;

  const _AddCustomRow({required this.controller, required this.onConfirm});

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Text(
          '添加其他群体:',
          style: TextStyle(
            fontSize: ScreenUtil().setSp(28),
            fontWeight: FontWeight.w400,
            color: MyColours.color_515151,
          ),
        ),
        SizedBox(width: ScreenUtil().setWidth(30)),
        Expanded(
          child: SizedBox(
            height: ScreenUtil().setWidth(68),
            child: TextField(
              controller: controller,
              style: TextStyle(fontSize: ScreenUtil().setSp(28)),
              decoration: InputDecoration(
                hintText: '输入客户群体名称',
                hintStyle: TextStyle(
                  fontSize: ScreenUtil().setSp(28),
                  color: const Color(0xFFBBBBBB),
                ),
                contentPadding: EdgeInsets.symmetric(
                    horizontal: ScreenUtil().setWidth(20),
                    vertical: ScreenUtil().setWidth(10)),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.zero,
                  borderSide: const BorderSide(
                      color: Color(0xFF515151), width: 1),
                ),
                enabledBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.zero,
                  borderSide: const BorderSide(
                      color: Color(0xFF515151), width: 1),
                ),
                focusedBorder: OutlineInputBorder(
                  borderRadius: BorderRadius.zero,
                  borderSide: const BorderSide(
                      color: Color(0xFF515151), width: 1),
                ),
              ),
            ),
          ),
          ),
        SizedBox(width: ScreenUtil().setWidth(30)),
        GestureDetector(
          onTap: onConfirm,
          child: Container(
            width: ScreenUtil().setWidth(96),
            height: ScreenUtil().setWidth(68),
            alignment: Alignment.center,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(ScreenUtil().setWidth(10)),
              border: Border.all(
                  color: MyColours.color_515151,
                  width: ScreenUtil().setWidth(2)),
            ),
            child: Text(
              '确认',
              style: TextStyle(
                fontSize: ScreenUtil().setSp(28),
                fontWeight: FontWeight.w400,
                color: MyColours.color_515151,
              ),
            ),
          ),
        ),
      ],
    );
  }
}