Browse Source

[new]完善总结模板编辑、删除、详情以及谈话相关流程

zk 1 year ago
parent
commit
3dbe98c13d

+ 2 - 0
assets/string/base/string.xml

@@ -166,4 +166,6 @@
     <string name="template_add_success">新建成功,即将返回上一页</string>
     <string name="template_add_success">新建成功,即将返回上一页</string>
     <string name="template_update_success">保存成功,即将返回上一页</string>
     <string name="template_update_success">保存成功,即将返回上一页</string>
     <string name="template_title_not_fail">添加模板标题</string>
     <string name="template_title_not_fail">添加模板标题</string>
+    <string name="template_detail_update">编辑模板</string>
+    <string name="template_dialog_delete_title">是否删除“%s”模板?</string>
 </resources>
 </resources>

+ 4 - 0
lib/data/api/atmob_api.dart

@@ -19,6 +19,7 @@ import 'package:electronic_assistant/data/api/request/talk_query_request.dart';
 import 'package:electronic_assistant/data/api/request/talk_rename_request.dart';
 import 'package:electronic_assistant/data/api/request/talk_rename_request.dart';
 import 'package:electronic_assistant/data/api/request/talk_request.dart';
 import 'package:electronic_assistant/data/api/request/talk_request.dart';
 import 'package:electronic_assistant/data/api/request/talk_translate_request.dart';
 import 'package:electronic_assistant/data/api/request/talk_translate_request.dart';
+import 'package:electronic_assistant/data/api/request/template_delete_request.dart';
 import 'package:electronic_assistant/data/api/request/template_update_request.dart';
 import 'package:electronic_assistant/data/api/request/template_update_request.dart';
 import 'package:electronic_assistant/data/api/request/user_info_update_request.dart';
 import 'package:electronic_assistant/data/api/request/user_info_update_request.dart';
 import 'package:electronic_assistant/data/api/request/verification_code_request.dart';
 import 'package:electronic_assistant/data/api/request/verification_code_request.dart';
@@ -175,6 +176,9 @@ abstract class AtmobApi {
 
 
   @POST("/project/secretary/v1/template/update")
   @POST("/project/secretary/v1/template/update")
   Future<BaseResponse> templateUpdate(@Body() TemplateUpdateRequest request);
   Future<BaseResponse> templateUpdate(@Body() TemplateUpdateRequest request);
+
+  @POST("/project/secretary/v1/template/delete")
+  Future<BaseResponse> templateDelete(@Body() TemplateDeleteRequest request);
 }
 }
 
 
 final atmobApi = AtmobApi(defaultDio, baseUrl: Constants.baseUrl);
 final atmobApi = AtmobApi(defaultDio, baseUrl: Constants.baseUrl);

+ 15 - 0
lib/data/api/request/template_delete_request.dart

@@ -0,0 +1,15 @@
+import 'package:electronic_assistant/base/app_base_request.dart';
+import 'package:json_annotation/json_annotation.dart';
+
+part 'template_delete_request.g.dart';
+
+@JsonSerializable()
+class TemplateDeleteRequest extends AppBaseRequest {
+  @JsonKey(name: 'id')
+  int id;
+
+  TemplateDeleteRequest(this.id);
+
+  @override
+  Map<String, dynamic> toJson() => _$TemplateDeleteRequestToJson(this);
+}

+ 1 - 1
lib/data/consts/constants.dart

@@ -6,7 +6,7 @@ import '../../utils/common_utils.dart';
 class Constants {
 class Constants {
   Constants._();
   Constants._();
 
 
-  static const String env = envProd;
+  static const String env = envTest;
 
 
   static const String envDev = 'dev';
   static const String envDev = 'dev';
 
 

+ 7 - 0
lib/data/repositories/template_repository.dart

@@ -2,6 +2,7 @@ import 'package:electronic_assistant/base/app_base_request.dart';
 
 
 import '../../utils/http_handler.dart';
 import '../../utils/http_handler.dart';
 import '../api/atmob_api.dart';
 import '../api/atmob_api.dart';
+import '../api/request/template_delete_request.dart';
 import '../api/request/template_update_request.dart';
 import '../api/request/template_update_request.dart';
 import '../api/response/template_list_response.dart';
 import '../api/response/template_list_response.dart';
 
 
@@ -26,6 +27,12 @@ class TemplateRepository {
         .templateUpdate(TemplateUpdateRequest(id, name, titles))
         .templateUpdate(TemplateUpdateRequest(id, name, titles))
         .then(HttpHandler.handle(true));
         .then(HttpHandler.handle(true));
   }
   }
+
+  Future<void> templateDelete(int id) {
+    return atmobApi
+        .templateDelete(TemplateDeleteRequest(id))
+        .then(HttpHandler.handle(true));
+  }
 }
 }
 
 
 final templateRepository = TemplateRepository._();
 final templateRepository = TemplateRepository._();

+ 2 - 3
lib/module/main/view.dart

@@ -30,9 +30,8 @@ class MainTabPage extends BasePage<MainController> {
           controller.closeDrawer();
           controller.closeDrawer();
           return;
           return;
         }
         }
-        if (!didPop &&
-            (controller.lastPressedAt == null ||
-                DateTime.now().difference(controller.lastPressedAt!) >
+        if ((controller.lastPressedAt == null ||
+            DateTime.now().difference(controller.lastPressedAt!) >
                     const Duration(seconds: 2))) {
                     const Duration(seconds: 2))) {
           controller.setLastPressedAt(DateTime.now());
           controller.setLastPressedAt(DateTime.now());
           ToastUtil.showToast(StringName.exitAppTip.tr);
           ToastUtil.showToast(StringName.exitAppTip.tr);

+ 8 - 5
lib/module/talk/summary/controller.dart

@@ -86,12 +86,12 @@ class SummaryController extends BaseController {
     if (talkBean == null || maxTemplateCount == null) {
     if (talkBean == null || maxTemplateCount == null) {
       return;
       return;
     }
     }
-    if ((talkController.templateList.value?.length ?? 0) >= maxTemplateCount) {
+    if ((talkController.templateList.value?.length ?? 0) <= maxTemplateCount) {
       _showMaxTemplateDialog();
       _showMaxTemplateDialog();
       return;
       return;
     }
     }
-    bool refresh = await TemplateEditPage.addStart();
-    if (refresh) {
+    dynamic isSuccess = await TemplateEditPage.addStart();
+    if (isSuccess == true) {
       talkController.refreshTalkDetail();
       talkController.refreshTalkDetail();
     }
     }
   }
   }
@@ -113,9 +113,12 @@ class SummaryController extends BaseController {
         cancelOnTap: () {
         cancelOnTap: () {
           EAAlertDialog.dismiss();
           EAAlertDialog.dismiss();
         },
         },
-        confirmOnTap: () {
+        confirmOnTap: () async {
           EAAlertDialog.dismiss();
           EAAlertDialog.dismiss();
-          TemplateListPage.start();
+          dynamic isSuccess = await TemplateListPage.start();
+          if (isSuccess == true) {
+            talkController.refreshTalkDetail();
+          }
         });
         });
   }
   }
 
 

+ 58 - 0
lib/module/template/template_detail/controller.dart

@@ -0,0 +1,58 @@
+import 'package:electronic_assistant/base/base_controller.dart';
+import 'package:electronic_assistant/data/bean/template_bean.dart';
+import 'package:electronic_assistant/module/template/template_edit/view.dart';
+import 'package:get/get.dart';
+import 'package:get/get_core/src/get_main.dart';
+
+class TemplateDetailController extends BaseController {
+  final Rxn<TemplateBean> _templateBean = Rxn<TemplateBean>();
+
+  final RxList<String> templateTitle = RxList();
+
+  TemplateBean? get templateBean => _templateBean.value;
+
+  dynamic result;
+
+  @override
+  void onInit() {
+    super.onInit();
+    _getArguments();
+  }
+
+  void _getArguments() {
+    var arguments = Get.arguments;
+    if (arguments is TemplateBean) {
+      _templateBean.value = arguments;
+      _combinationTemplateList(arguments);
+    }
+  }
+
+  void onBack() {
+    Get.back(result: result);
+  }
+
+  void onUpdateTemplate() async {
+    final templateBean = _templateBean.value;
+    if (templateBean == null || templateBean.isDefaultTemp) {
+      return;
+    }
+    dynamic isSuccess = await TemplateEditPage.editDetail(templateBean);
+    if (isSuccess == true) {
+      _templateBean.refresh();
+      if (_templateBean.value != null) {
+        _combinationTemplateList(_templateBean.value!);
+      }
+    }
+    result = isSuccess;
+  }
+
+  void _combinationTemplateList(TemplateBean bean) {
+    templateTitle.clear();
+    if (bean.titles != null) {
+      templateTitle.addAll(bean.titles!);
+    }
+    if (bean.defaultTitle?.isNotEmpty == true) {
+      templateTitle.add(bean.defaultTitle!);
+    }
+  }
+}

+ 132 - 0
lib/module/template/template_detail/view.dart

@@ -0,0 +1,132 @@
+import 'package:electronic_assistant/base/base_page.dart';
+import 'package:electronic_assistant/data/bean/template_bean.dart';
+import 'package:electronic_assistant/utils/expand.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+import 'package:get/get_core/src/get_main.dart';
+
+import '../../../resource/assets.gen.dart';
+import '../../../resource/colors.gen.dart';
+import '../../../resource/string.gen.dart';
+import '../../../router/app_pages.dart';
+import '../../../utils/common_style.dart';
+import 'controller.dart';
+
+class TemplateDetailPage extends BasePage<TemplateDetailController> {
+  const TemplateDetailPage({super.key});
+
+  static Future<dynamic> start(TemplateBean bean) async {
+    return Get.toNamed(RoutePath.templateDetail, arguments: bean);
+  }
+
+  @override
+  bool immersive() {
+    return true;
+  }
+
+  @override
+  Widget buildBody(BuildContext context) {
+    return WillPopScope(
+      onWillPop: () async {
+        controller.onBack();
+        return false;
+      },
+      child: Scaffold(
+        backgroundColor: '#F6F6F6'.color,
+        appBar: _buildAppBar(),
+        body: Column(
+          children: [
+            Expanded(child: _buildTemplateList()),
+            _buildTemplateBtn()
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget _buildTemplateBtn() {
+    return Obx(() {
+      return Visibility(
+        visible: controller.templateBean != null,
+        child: GestureDetector(
+          onTap: () {
+            controller.onUpdateTemplate();
+          },
+          child: Center(
+            child: Obx(() {
+              return Opacity(
+                opacity:
+                    controller.templateBean?.isDefaultTemp == true ? 0.4 : 1,
+                child: Container(
+                  margin: EdgeInsets.only(bottom: 16.w),
+                  decoration: getCommonDecoration(8.w),
+                  width: 328.w,
+                  height: 48.w,
+                  child: Center(
+                    child: Text(
+                      StringName.templateDetailUpdate.tr,
+                      style: TextStyle(fontSize: 16.sp, color: ColorName.white),
+                    ),
+                  ),
+                ),
+              );
+            }),
+          ),
+        ),
+      );
+    });
+  }
+
+  Widget _buildTemplateList() {
+    return Obx(() {
+      return ListView.builder(
+        padding: EdgeInsets.only(top: 12.w),
+        itemCount: controller.templateTitle.length,
+        itemBuilder: (context, index) {
+          return _buildTemplateItem(controller.templateTitle[index]);
+        },
+      );
+    });
+  }
+
+  Widget _buildTemplateItem(String title) {
+    return Container(
+      decoration: BoxDecoration(
+          color: ColorName.white, borderRadius: BorderRadius.circular(8.w)),
+      padding: EdgeInsets.only(left: 16.w, right: 12.w),
+      margin: EdgeInsets.only(bottom: 8.h, left: 12.w, right: 12.w),
+      child: Padding(
+        padding: EdgeInsets.symmetric(vertical: 20.w),
+        child: Text(title,
+            style: TextStyle(
+                fontSize: 15.sp, color: ColorName.primaryTextColor, height: 1)),
+      ),
+    );
+  }
+
+  AppBar _buildAppBar() {
+    return AppBar(
+      scrolledUnderElevation: 0,
+      systemOverlayStyle: SystemUiOverlayStyle.dark,
+      backgroundColor: Colors.transparent,
+      title: Obx(() {
+        return Text(
+          controller.templateBean?.name ?? '',
+          style: TextStyle(fontSize: 17.sp, color: ColorName.primaryTextColor),
+        );
+      }),
+      centerTitle: true,
+      leading: IconButton(
+          onPressed: () {
+            controller.onBack();
+          },
+          icon: SizedBox(
+              width: 24.w,
+              height: 24.w,
+              child: Assets.images.iconBack.image())),
+    );
+  }
+}

+ 6 - 0
lib/module/template/template_edit/controller.dart

@@ -16,6 +16,8 @@ class TemplateEditController extends BaseController {
   final titleController = TextEditingController();
   final titleController = TextEditingController();
   final focusNode = FocusNode();
   final focusNode = FocusNode();
 
 
+  TemplateBean? targetTemplateBean;
+
   final Rxn<String> _defaultTemplate = Rxn();
   final Rxn<String> _defaultTemplate = Rxn();
 
 
   String? get defaultTemplate => _defaultTemplate.value;
   String? get defaultTemplate => _defaultTemplate.value;
@@ -27,9 +29,11 @@ class TemplateEditController extends BaseController {
     super.onInit();
     super.onInit();
     var arguments = Get.arguments;
     var arguments = Get.arguments;
     if (arguments is TemplateBean) {
     if (arguments is TemplateBean) {
+      targetTemplateBean = arguments;
       templateId = arguments.id;
       templateId = arguments.id;
       titleController.text = arguments.name ?? '';
       titleController.text = arguments.name ?? '';
       templateCustomTitle.assignAll(arguments.titles ?? []);
       templateCustomTitle.assignAll(arguments.titles ?? []);
+      _defaultTemplate.value = arguments.defaultTitle;
     }
     }
     if (templateId == null) {
     if (templateId == null) {
       _getDefaultTitle();
       _getDefaultTitle();
@@ -72,6 +76,8 @@ class TemplateEditController extends BaseController {
       if (templateId == null) {
       if (templateId == null) {
         ToastUtil.showToast(StringName.templateAddSuccess.tr);
         ToastUtil.showToast(StringName.templateAddSuccess.tr);
       } else {
       } else {
+        targetTemplateBean?.name = titleController.text;
+        targetTemplateBean?.titles = templateCustomTitle;
         ToastUtil.showToast(StringName.templateUpdateSuccess.tr);
         ToastUtil.showToast(StringName.templateUpdateSuccess.tr);
       }
       }
       await Future.delayed(const Duration(milliseconds: 400));
       await Future.delayed(const Duration(milliseconds: 400));

+ 4 - 5
lib/module/template/template_edit/view.dart

@@ -16,12 +16,12 @@ import 'controller.dart';
 class TemplateEditPage extends BasePage<TemplateEditController> {
 class TemplateEditPage extends BasePage<TemplateEditController> {
   const TemplateEditPage({super.key});
   const TemplateEditPage({super.key});
 
 
-  static Future<T?>? addStart<T>() {
-    return Get.toNamed<T>(RoutePath.templateEdit);
+  static Future<dynamic> addStart() async {
+    return Get.toNamed(RoutePath.templateEdit);
   }
   }
 
 
-  static void updateDetail(TemplateBean bean) {
-    Get.toNamed(RoutePath.templateEdit, arguments: bean);
+  static Future<dynamic> editDetail(TemplateBean bean) async {
+    return Get.toNamed(RoutePath.templateEdit, arguments: bean);
   }
   }
 
 
   @override
   @override
@@ -121,7 +121,6 @@ class TemplateEditPage extends BasePage<TemplateEditController> {
             });
             });
           },
           },
           itemCount: controller.templateCustomTitle.length,
           itemCount: controller.templateCustomTitle.length,
-          reverse: true,
           shrinkWrap: true);
           shrinkWrap: true);
     });
     });
   }
   }

+ 62 - 4
lib/module/template/template_list/controller.dart

@@ -1,8 +1,14 @@
 import 'package:electronic_assistant/base/base_controller.dart';
 import 'package:electronic_assistant/base/base_controller.dart';
 import 'package:electronic_assistant/data/bean/template_bean.dart';
 import 'package:electronic_assistant/data/bean/template_bean.dart';
+import 'package:electronic_assistant/module/template/template_detail/view.dart';
 import 'package:electronic_assistant/module/template/template_edit/view.dart';
 import 'package:electronic_assistant/module/template/template_edit/view.dart';
+import 'package:electronic_assistant/resource/colors.gen.dart';
+import 'package:electronic_assistant/resource/string.gen.dart';
 import 'package:electronic_assistant/utils/error_handler.dart';
 import 'package:electronic_assistant/utils/error_handler.dart';
+import 'package:electronic_assistant/utils/expand.dart';
+import 'package:electronic_assistant/widget/alert_dialog.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/cupertino.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:get/get.dart';
 import 'package:get/get.dart';
 import 'package:get/get_core/src/get_main.dart';
 import 'package:get/get_core/src/get_main.dart';
 
 
@@ -13,6 +19,8 @@ class TemplateListController extends BaseController {
 
 
   int? maxTemplateCount;
   int? maxTemplateCount;
 
 
+  bool? result;
+
   @override
   @override
   void onInit() {
   void onInit() {
     super.onInit();
     super.onInit();
@@ -39,12 +47,62 @@ class TemplateListController extends BaseController {
   }
   }
 
 
   void onBack() {
   void onBack() {
-    Get.back();
+    Get.back(result: result);
+  }
+
+  void onAddTemplate() async {
+    dynamic isSuccess = await TemplateEditPage.addStart();
+    if (isSuccess is bool && isSuccess) {
+      result = true;
+      refreshTemplateList();
+    }
   }
   }
 
 
-  void onAddTemplate() {
-    TemplateEditPage.addStart();
+  void onDetailClick(TemplateBean bean) async {
+    dynamic isSuccess = await TemplateDetailPage.start(bean);
+    if (isSuccess == true) {
+      result = true;
+      refreshTemplateList();
+    }
   }
   }
 
 
-  void onDetailClick(TemplateBean bean) {}
+  void templateEdit(TemplateBean item) async {
+    dynamic isSuccess = await TemplateEditPage.editDetail(item);
+    if (isSuccess == true) {
+      result = true;
+      templateList.refresh();
+    }
+  }
+
+  void onDeleteTemplate(TemplateBean item) {
+    EAAlertDialog.show(
+        contentWidget: Padding(
+          padding: EdgeInsets.only(top: 8.w),
+          child: Text(
+            StringName.templateDialogDeleteTitle.tr
+                .replacePlaceholders([item.name]),
+            style: TextStyle(
+                fontSize: 15.sp,
+                color: ColorName.primaryTextColor,
+                fontWeight: FontWeight.bold),
+          ),
+        ),
+        cancelText: StringName.cancel.tr,
+        confirmText: StringName.sure.tr,
+        confirmOnTap: () {
+          _deleteTemplate(item);
+        });
+  }
+
+  void _deleteTemplate(TemplateBean item) {
+    if (item.id == null) {
+      return;
+    }
+    templateRepository.templateDelete(item.id!).then((value) {
+      result = true;
+      refreshTemplateList();
+    }).catchError((error) {
+      ErrorHandler.toastError(error);
+    });
+  }
 }
 }

+ 45 - 9
lib/module/template/template_list/view.dart

@@ -6,9 +6,12 @@ import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter/src/widgets/framework.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
 import 'package:get/get.dart';
 import 'package:get/get.dart';
 import 'package:get/get_core/src/get_main.dart';
 import 'package:get/get_core/src/get_main.dart';
 import '../../../data/bean/template_bean.dart';
 import '../../../data/bean/template_bean.dart';
+import '../../../popup/common_popup.dart';
+import '../../../popup/template_utils.dart';
 import '../../../resource/assets.gen.dart';
 import '../../../resource/assets.gen.dart';
 import '../../../resource/colors.gen.dart';
 import '../../../resource/colors.gen.dart';
 import '../../../resource/string.gen.dart';
 import '../../../resource/string.gen.dart';
@@ -18,8 +21,8 @@ import 'controller.dart';
 class TemplateListPage extends BasePage<TemplateListController> {
 class TemplateListPage extends BasePage<TemplateListController> {
   const TemplateListPage({super.key});
   const TemplateListPage({super.key});
 
 
-  static void start() {
-    Get.toNamed(RoutePath.templateList);
+  static Future<dynamic> start() async {
+    return Get.toNamed(RoutePath.templateList);
   }
   }
 
 
   @override
   @override
@@ -29,11 +32,20 @@ class TemplateListPage extends BasePage<TemplateListController> {
 
 
   @override
   @override
   Widget buildBody(BuildContext context) {
   Widget buildBody(BuildContext context) {
-    return Scaffold(
-      backgroundColor: '#F6F6F6'.color,
-      appBar: _buildAppBar(),
-      body: Column(
-        children: [Expanded(child: _buildTemplateList()), _buildTemplateBtn()],
+    return WillPopScope(
+      onWillPop: () async {
+        controller.onBack();
+        return false;
+      },
+      child: Scaffold(
+        backgroundColor: '#F6F6F6'.color,
+        appBar: _buildAppBar(),
+        body: Column(
+          children: [
+            Expanded(child: _buildTemplateList()),
+            _buildTemplateBtn()
+          ],
+        ),
       ),
       ),
     );
     );
   }
   }
@@ -116,11 +128,35 @@ class TemplateListPage extends BasePage<TemplateListController> {
             const Spacer(),
             const Spacer(),
             Visibility(
             Visibility(
                 visible: !templateBean.isDefaultTemp,
                 visible: !templateBean.isDefaultTemp,
-                child: Assets.images.iconTemplateMoreOperation
-                    .image(width: 24.w, height: 24.w)),
+                child: GestureDetector(
+                  onTapUp: (details) {
+                    showPressTouchPopup(
+                        details.globalPosition + Offset(-40.w, 20.w),
+                        Alignment.bottomLeft,
+                        _buildPopupView(templateBean, 'templateMorePopup'),
+                        tag: 'templateMorePopup');
+                  },
+                  child: Assets.images.iconTemplateMoreOperation
+                      .image(width: 24.w, height: 24.w),
+                )),
           ],
           ],
         ),
         ),
       ),
       ),
     );
     );
   }
   }
+
+  List<Widget> _buildPopupView(TemplateBean item, String tag) {
+    return [
+      createNormalPopupItem(StringName.agendaDetailPopupUpdate.tr,
+          onItemClick: () {
+        SmartDialog.dismiss(tag: tag);
+        controller.templateEdit(item);
+      }),
+      createPopupDivider(),
+      createDeletePopupItem(() {
+        SmartDialog.dismiss(tag: tag);
+        controller.onDeleteTemplate(item);
+      }),
+    ];
+  }
 }
 }

+ 7 - 0
lib/router/app_pages.dart

@@ -15,6 +15,8 @@ import 'package:electronic_assistant/module/splash/controller.dart';
 import 'package:electronic_assistant/module/store/controller.dart';
 import 'package:electronic_assistant/module/store/controller.dart';
 import 'package:electronic_assistant/module/store/view.dart';
 import 'package:electronic_assistant/module/store/view.dart';
 import 'package:electronic_assistant/module/talk/view.dart';
 import 'package:electronic_assistant/module/talk/view.dart';
+import 'package:electronic_assistant/module/template/template_detail/controller.dart';
+import 'package:electronic_assistant/module/template/template_detail/view.dart';
 import 'package:electronic_assistant/module/template/template_edit/controller.dart';
 import 'package:electronic_assistant/module/template/template_edit/controller.dart';
 import 'package:get/get.dart';
 import 'package:get/get.dart';
 import '../module/agenda/controller.dart';
 import '../module/agenda/controller.dart';
@@ -80,6 +82,8 @@ abstract class RoutePath {
   static const templateEdit = '/templateEdit';
   static const templateEdit = '/templateEdit';
 
 
   static const templateList = '/templateList';
   static const templateList = '/templateList';
+
+  static const templateDetail = '/templateDetail';
 }
 }
 
 
 class AppBinding extends Bindings {
 class AppBinding extends Bindings {
@@ -105,6 +109,7 @@ class AppBinding extends Bindings {
     lazyPut(() => ModelExplainController());
     lazyPut(() => ModelExplainController());
     lazyPut(() => TemplateEditController());
     lazyPut(() => TemplateEditController());
     lazyPut(() => TemplateListController());
     lazyPut(() => TemplateListController());
+    lazyPut(() => TemplateDetailController());
   }
   }
 
 
   void lazyPut<S>(InstanceBuilderCallback<S> builder) {
   void lazyPut<S>(InstanceBuilderCallback<S> builder) {
@@ -136,4 +141,6 @@ final generalPages = [
   GetPage(name: RoutePath.modelExplain, page: () => const ModelExplainPage()),
   GetPage(name: RoutePath.modelExplain, page: () => const ModelExplainPage()),
   GetPage(name: RoutePath.templateEdit, page: () => const TemplateEditPage()),
   GetPage(name: RoutePath.templateEdit, page: () => const TemplateEditPage()),
   GetPage(name: RoutePath.templateList, page: () => const TemplateListPage()),
   GetPage(name: RoutePath.templateList, page: () => const TemplateListPage()),
+  GetPage(
+      name: RoutePath.templateDetail, page: () => const TemplateDetailPage()),
 ];
 ];