123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 |
- import 'package:fis_jsonrpc/rpc.dart';
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- import 'package:vnoteapp/architecture/types/index.dart';
- import 'package:vnoteapp/architecture/utils/datetime.dart';
- import 'package:vnoteapp/components/button.dart';
- import 'package:vnoteapp/components/cell.dart';
- import 'package:vnoteapp/components/checkbox_button.dart';
- import 'package:vnoteapp/components/dialog_date.dart';
- import 'package:vnoteapp/components/dialog_input.dart';
- import 'package:vnoteapp/components/dialog_select.dart';
- import 'package:vnoteapp/components/dynamic_drawer.dart';
- import 'package:vnoteapp/consts/nations.dart';
- import 'package:vnoteapp/consts/rpc_enum_labels.dart';
- import 'package:vnoteapp/pages/controllers/crowd_labels.dart';
- import 'package:vnoteapp/pages/patient/create/controller.dart';
- class CreatePatientPage extends GetView<CreatePatientController> {
- const CreatePatientPage({super.key});
- @override
- Widget build(BuildContext context) {
- return Stack(
- children: [
- Scrollbar(
- thumbVisibility: true,
- child: SingleChildScrollView(
- child: Container(
- alignment: Alignment.topCenter,
- color: const Color.fromRGBO(238, 238, 238, 1),
- padding: const EdgeInsets.only(bottom: 64),
- child: SizedBox(
- width: 800,
- child: Column(
- children: [
- _AreaPanel(),
- const SizedBox(height: 12),
- _PatientInfoPanel(),
- const SizedBox(height: 12),
- _AddressPanel(),
- const SizedBox(height: 12),
- _CrowdLabelPanel(),
- const SizedBox(height: 24),
- ],
- ),
- ),
- ),
- ),
- ),
- Positioned(
- bottom: 8,
- left: 200,
- right: 200,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: [
- VButton(
- label: "下一步",
- onTap: () {
- controller.gotoSignContract();
- },
- ),
- VButton(
- label: "存为档案",
- onTap: () {
- controller.gotoPatientDetail();
- },
- ),
- ],
- ),
- ),
- // Positioned(
- // top: 20,
- // right: 20,
- // child: SizedBox(
- // width: 90,
- // height: 90,
- // child: ElevatedButton(
- // style: ButtonStyle(
- // shape: MaterialStatePropertyAll(
- // RoundedRectangleBorder(
- // borderRadius: BorderRadius.circular(45),
- // side: BorderSide(color: Theme.of(context).primaryColor),
- // ),
- // ),
- // ),
- // onPressed: () {
- // controller.onReadCardClicked();
- // },
- // child: const Text(
- // "读卡",
- // style: TextStyle(fontWeight: FontWeight.bold),
- // ),
- // ),
- // ),
- // ),
- ],
- );
- }
- }
- class _PatientInfoPanel extends GetView<CreatePatientController> {
- @override
- Widget build(BuildContext context) {
- final state = controller.state;
- return VListFormCellGroup(
- children: [
- Obx(
- () => VListFormCell(
- label: "证件类型",
- content: RpcEnumLabels.cardType[state.cardType],
- onTap: () async {
- final result = await VDialogSelect<CardTypeEnum, CardTypeEnum>(
- title: "选择证件类型",
- source: CardTypeEnum.values,
- valueGetter: (data) => data,
- labelGetter: (data) => RpcEnumLabels.cardType[data] ?? "",
- initialValue: state.cardType,
- ).show();
- if (result != null) {
- controller.state.cardType = result;
- }
- },
- ),
- ),
- Obx(
- () => VListFormCell(
- label: "证件号",
- content: controller.state.cardNo,
- onTap: () async {
- final result = await VDialogInput(
- title: "证件号",
- initialValue: controller.state.cardNo,
- placeholder: "请填写证件号",
- ).show();
- if (result != null) {
- controller.state.cardNo = result;
- }
- },
- ),
- ),
- Obx(
- () => VListFormCell(
- label: "姓名",
- content: controller.state.name,
- onTap: () async {
- final result = await VDialogInput(
- title: "姓名",
- initialValue: controller.state.name,
- placeholder: "请填写姓名",
- ).show();
- if (result != null) {
- controller.state.name = result;
- }
- },
- ),
- ),
- Obx(
- () => VListFormCell(
- label: "性别",
- content: RpcEnumLabels.gender[state.gender],
- onTap: () async {
- final result = await VDialogSelect<GenderEnum, GenderEnum>(
- title: "选择性别",
- source: const [
- GenderEnum.Male,
- GenderEnum.Female,
- GenderEnum.Unknown,
- GenderEnum.Unspecified
- ],
- valueGetter: (data) => data,
- labelGetter: (data) => RpcEnumLabels.gender[data] ?? "",
- initialValue: state.gender,
- ).show();
- if (result != null) {
- controller.state.gender = result;
- }
- },
- ),
- ),
- Obx(
- () => VListFormCell(
- label: "民族",
- content: state.nation,
- onTap: () async {
- final result = await VDialogSelect<String, String>(
- title: "选择民族",
- source: Nations.china,
- valueGetter: (data) => data,
- labelGetter: (data) => data,
- initialValue: state.nation,
- ).show();
- if (result != null) {
- controller.state.nation = result;
- }
- },
- ),
- ),
- Obx(
- () => VListFormCell(
- label: "出生日期",
- content: DataTimeUtils.formatDateString(controller.state.birthday),
- onTap: () async {
- final result = await VDialogDate(
- title: "设置出生日期",
- initialValue: controller.state.birthday,
- ).show();
- if (result != null) {
- controller.state.birthday = result;
- }
- },
- ),
- ),
- Obx(
- () => VListFormCell(
- label: "年龄",
- content: controller.state.age.toString(),
- ),
- ),
- Obx(
- () => VListFormCell(
- label: "手机号码",
- content: controller.state.phoneNo,
- onTap: () async {
- final result = await VDialogInput(
- title: "手机号码",
- initialValue: controller.state.phoneNo,
- placeholder: "请填写手机号码",
- ).show();
- if (result != null) {
- controller.state.phoneNo = result;
- }
- },
- ),
- ),
- ],
- );
- }
- }
- class _AddressPanel extends GetView<CreatePatientController> {
- @override
- Widget build(BuildContext context) {
- return VListFormCellGroup(
- children: [
- VListFormCell(
- label: "同步户籍地址到现住地址",
- labelWidth: 250,
- contentWidget: Container(
- child: Obx(
- () => Switch(
- onChanged: (value) {
- controller.onSyncAddressCheckChanged(value);
- },
- value: controller.state.isSyncAddresses,
- ),
- ),
- ),
- ),
- Obx(
- () => VListFormCell(
- label: "户籍地址",
- content: controller.state.censusRegister,
- onTap: () async {
- final result = await VDialogInput(
- title: "户籍地址",
- initialValue: controller.state.censusRegister,
- placeholder: "请填写户籍地址",
- ).show();
- if (result != null) {
- controller.onCensusRegisterChanged(result);
- }
- },
- ),
- ),
- Obx(
- () => VListFormCell(
- label: "现住地址",
- content: controller.state.address,
- onTap: () async {
- final result = await VDialogInput(
- title: "现住地址",
- initialValue: controller.state.address,
- placeholder: "请填写现住地址",
- ).show();
- if (result != null) {
- controller.state.address = result;
- }
- },
- ),
- ),
- ],
- );
- }
- }
- class _AreaPanel extends GetView<CreatePatientController> {
- @override
- Widget build(BuildContext context) {
- return VListFormCellGroup(
- children: [
- VListFormCell(
- label: "签约机构",
- content: controller.state.organizationName,
- ),
- Obx(
- () {
- return VListFormCell(
- label: "签约区域",
- content: controller.state.villageName,
- onTap: () async {
- final result = await VDialogSelect<StringKVModel, String>(
- title: "选择签约区域",
- source: controller.state.villageOptions,
- valueGetter: (data) => data.key,
- labelGetter: (data) => data.value,
- initialValue: controller.state.villageCode,
- ).show();
- if (result != null) {
- controller.state.villageCode = result;
- }
- },
- );
- },
- ),
- ],
- );
- }
- }
- class _CrowdLabelPanel extends GetView<CrowdLabelsController> {
- final createController = Get.find<CreatePatientController>();
- @override
- Widget build(BuildContext context) {
- return VListFormCellGroup(
- children: [
- Obx(
- () => VListFormCell(
- label: "个人编号",
- content: createController.state.personalNo,
- onTap: () async {
- final result = await VDialogInput(
- title: "个人编号",
- initialValue: createController.state.personalNo,
- placeholder: "请填写个人编号",
- ).show();
- if (result != null) {
- createController.state.personalNo = result;
- }
- },
- ),
- ),
- VListFormCell(
- label: "人群分类",
- contentWidget: _buildContent(context),
- onTap: () {
- VDynamicDrawerWrapper.show(
- scaffoldKey: createController.homeScaffoldKey,
- builder: (_) => _buildDrawer(),
- );
- },
- ),
- ],
- );
- }
- Widget _buildDrawer() {
- final state = controller.state;
- List<String> selectedNormalCodes = state.selectedNormalCodes;
- List<String> selectedDiseaseCodes = state.selectedDiseaseCodes;
- List<String> selectedSpecialCareCodes = state.selectedSpecialCareCodes;
- final scrollController = ScrollController();
- return VDrawer(
- width: 600,
- title: "设置人群分类",
- scaffoldKey: createController.homeScaffoldKey,
- onConfirm: () {
- VDynamicDrawerWrapper.hide(
- scaffoldKey: createController.homeScaffoldKey,
- );
- state.selectedNormalCodes = selectedNormalCodes;
- state.selectedDiseaseCodes = selectedDiseaseCodes;
- state.selectedSpecialCareCodes = selectedSpecialCareCodes;
- },
- child: Scrollbar(
- controller: scrollController,
- thumbVisibility: true,
- child: SingleChildScrollView(
- controller: scrollController,
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 50),
- child: Column(
- children: [
- const SizedBox(height: 24),
- VCheckBoxButtonGroup<LabelDTO, String>(
- source: state.normalOptions,
- values: state.selectedNormalCodes,
- labelGetter: (LabelDTO data) => data.labelName!,
- valueGetter: (LabelDTO data) => data.code!,
- onChanged: (value) {
- selectedNormalCodes = value;
- },
- ),
- const SizedBox(height: 8),
- Divider(
- indent: 32,
- endIndent: 32,
- thickness: 1,
- color: Colors.grey.shade300,
- ),
- const SizedBox(height: 8),
- VCheckBoxButtonGroup<LabelDTO, String>(
- source: state.diseaseOptions,
- values: state.selectedDiseaseCodes,
- labelGetter: (LabelDTO data) => data.labelName!,
- valueGetter: (LabelDTO data) => data.code!,
- onChanged: (value) {
- selectedDiseaseCodes = value;
- },
- ),
- const SizedBox(height: 8),
- Divider(
- indent: 32,
- endIndent: 32,
- thickness: 1,
- color: Colors.grey.shade300,
- ),
- const SizedBox(height: 8),
- VCheckBoxButtonGroup<LabelDTO, String>(
- source: state.specialCareOptions,
- values: state.selectedSpecialCareCodes,
- labelGetter: (LabelDTO data) => data.labelName!,
- valueGetter: (LabelDTO data) => data.code!,
- onChanged: (value) {
- selectedSpecialCareCodes = value;
- },
- ),
- ],
- ),
- ),
- ),
- ),
- );
- }
- Widget _buildContent(BuildContext context) {
- return Obx(
- () {
- final themeData = Theme.of(context);
- final color = themeData.secondaryHeaderColor;
- final names = controller.state.selectedNames;
- const itemHeight = 32.0;
- const itemRadius = itemHeight / 2;
- final itemTextStyle = TextStyle(
- color: themeData.primaryColor,
- fontSize: 14,
- );
- return Wrap(
- spacing: 16,
- runSpacing: 16,
- children: names.map(
- (e) {
- return Container(
- height: itemHeight,
- alignment: Alignment.center,
- padding: const EdgeInsets.symmetric(horizontal: 12),
- decoration: BoxDecoration(
- color: color,
- border: Border.all(style: BorderStyle.none),
- borderRadius: BorderRadius.circular(itemRadius),
- ),
- child: Text(e, style: itemTextStyle),
- );
- },
- ).toList(),
- );
- },
- );
- }
- }
|