vocabulary_entry_report.dart 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. import 'dart:convert';
  2. import 'dart:math';
  3. import 'package:fis_i18n/i18n.dart';
  4. import 'package:fis_jsonrpc/rpc.dart';
  5. import 'package:fis_lib_report/report_info/report_info.dart';
  6. import 'package:fis_theme/theme.dart';
  7. import 'package:fis_ui/base_define/page.dart';
  8. import 'package:fis_ui/index.dart';
  9. import 'package:fis_ui/interface/interactive_container.dart';
  10. import 'package:fis_ui/widgets/tree/flutter_treeview/lib/flutter_treeview.dart';
  11. import 'package:flutter/material.dart';
  12. import 'package:flutter/services.dart';
  13. // import 'package:flyinsono/pages/remedical/vocabulary_entry/view.dart';
  14. import 'package:get/get.dart' hide Node;
  15. import 'package:path/path.dart';
  16. import 'package:vitalapp/architecture/services/entity/report_editor_setting.dart';
  17. import 'package:vitalapp/architecture/services/report_editor_configuration.dart';
  18. import 'package:vitalapp/pages/consultation_record_view/widgets/search_input.dart';
  19. import 'package:vitalapp/pages/image_report_inner_view/widgets/expandable_icon_text.dart';
  20. import 'package:vitalapp/pages/report_edit/controller.dart';
  21. ///报告中词条选择
  22. class VocabularyEntryReport extends StatefulWidget implements FPage {
  23. @override
  24. State<VocabularyEntryReport> createState() => _VocabularyEntryReportState();
  25. ///关闭事件
  26. final void Function() onClose;
  27. VocabularyEntryReport({
  28. required this.onClose,
  29. });
  30. @override
  31. final String pageName = 'VocabularyEntryReport';
  32. }
  33. class _VocabularyEntryReportState extends State<VocabularyEntryReport> {
  34. /// 词条树顶层结构
  35. late List<Node<dynamic>> treeViewTopData = [];
  36. late TextEditingController _textEditingController =
  37. TextEditingController(text: keyWords);
  38. final entrysScrollController = ScrollController();
  39. double _maxHeight = 0;
  40. double _maxWidth = 0;
  41. final double _scale = 0.45;
  42. /// 当前选中项
  43. String selectedKey = '';
  44. /// 关键字搜索
  45. String keyWords = '';
  46. /// 当前词条分类的词条卡片内容
  47. List<ThesaurusItemDTO> vocabularyCard = [];
  48. /// 序列化存储的词条列表
  49. List<dynamic> defaultThesaurusList = [];
  50. /// 树形选择器控制器
  51. TreeViewController _treeViewController = TreeViewController();
  52. /// 本地报告编辑器服务
  53. LocalReportEditorService localReportEditorService =
  54. Get.find<LocalReportEditorService>();
  55. ReportEditorSetting reportEditorSetting = ReportEditorSetting.ins;
  56. String? _focusItem;
  57. void _listenKeyboardEvent(RawKeyEvent event) {
  58. if (event.isKeyPressed(LogicalKeyboardKey.enter) ||
  59. event.isKeyPressed(LogicalKeyboardKey.numpadEnter)) {
  60. getEntryByKeyWords();
  61. }
  62. }
  63. /// 报告控制器
  64. final reportEditController = Get.put(ReportEditController());
  65. /// 检查是否需要重新打开上次打开的节点
  66. void checkReopenNode() {
  67. /// 上次打开的词条分类和词条项
  68. final lastEntryCategoryCode = reportEditorSetting.lastEntryCategoryCode;
  69. final lastEntryCode = reportEditorSetting.lastEntryCode;
  70. var entryCategoryCodeToReopen = '';
  71. var entryCodeToReopen = '';
  72. treeViewTopData.forEach((element) {
  73. if (element.key == lastEntryCategoryCode) {
  74. entryCategoryCodeToReopen = element.key;
  75. }
  76. element.children.forEach((child) {
  77. if (child.key == lastEntryCode) {
  78. entryCodeToReopen = child.key;
  79. }
  80. });
  81. });
  82. if (entryCategoryCodeToReopen == '') return;
  83. List<Node> newdata =
  84. _treeViewController.expandToNode(entryCategoryCodeToReopen);
  85. if (entryCodeToReopen == '') {
  86. _treeViewController = _treeViewController.copyWith(children: newdata);
  87. } else {
  88. _treeViewController = _treeViewController.copyWith(
  89. children: newdata, selectedKey: entryCodeToReopen);
  90. vocabularyCard = reportEditController.state.allThesaurusList
  91. .where((element) => element.parentItemCode == entryCodeToReopen)
  92. .toList();
  93. }
  94. }
  95. /// 下拉项点击
  96. void onExpansionChanged(String code, bool isDrop) async {
  97. reportEditorSetting.setLastEntryCategoryCode(code);
  98. localReportEditorService.save();
  99. if (isDrop) {
  100. List<Node> newdata = _treeViewController.expandToNode(code);
  101. _treeViewController = _treeViewController.copyWith(children: newdata);
  102. } else {
  103. List<Node> newdata = _treeViewController.collapseToNode(code);
  104. _treeViewController = _treeViewController.copyWith(children: newdata);
  105. }
  106. setState(() {});
  107. }
  108. /// 词条分类的选中
  109. void onNodeTap(String code) {
  110. reportEditorSetting.setLastEntryCode(code);
  111. localReportEditorService.save();
  112. _treeViewController = _treeViewController.copyWith(selectedKey: code);
  113. if (reportEditController.state.allThesaurusList.isNotEmpty) {
  114. vocabularyCard = reportEditController.state.allThesaurusList
  115. .where((element) => element.parentItemCode == code)
  116. .toList();
  117. }
  118. setState(() {
  119. selectedKey = code;
  120. });
  121. }
  122. /// 搜索的方法
  123. void getEntryByKeyWords() {
  124. List<ThesaurusItemDTO> thesaurusItem = [];
  125. var allThesaurusList = reportEditController.state.allThesaurusList;
  126. allThesaurusList.forEach(
  127. (e) {
  128. if (e.thesaurusItemName?.contains(keyWords) == true ||
  129. e.thesaurusItemConclusion?.contains(keyWords) == true ||
  130. e.thesaurusItemDescription?.contains(keyWords) == true) {
  131. if (e.parentItemCode != '') {
  132. allThesaurusList.forEach(
  133. (element) {
  134. if (element.thesaurusItemCode == e.parentItemCode) {
  135. thesaurusItem.add(element);
  136. if (element.parentItemCode != '') {
  137. allThesaurusList.forEach(
  138. (key) {
  139. if (key.thesaurusItemCode == element.parentItemCode) {
  140. thesaurusItem.add(key);
  141. }
  142. },
  143. );
  144. }
  145. }
  146. },
  147. );
  148. }
  149. thesaurusItem.add(e);
  150. }
  151. },
  152. );
  153. thesaurusItem = thesaurusItem.toSet().toList();
  154. treeViewTopData = getThesaurusItemsAsyncList(thesaurusItem);
  155. setState(() {
  156. _treeViewController = TreeViewController(
  157. children: treeViewTopData,
  158. selectedKey: selectedKey,
  159. );
  160. });
  161. }
  162. void _initThesaurusList() {
  163. treeViewTopData = getThesaurusItemsAsyncList(
  164. reportEditController.state.allThesaurusList,
  165. );
  166. if (treeViewTopData.isNotEmpty) {
  167. var firstThesaurus = treeViewTopData.first;
  168. treeViewTopData[0] = firstThesaurus.copyWith(
  169. expanded: true,
  170. );
  171. if (firstThesaurus.children.isNotEmpty) {
  172. selectedKey = firstThesaurus.children.first.key;
  173. } else {
  174. selectedKey = firstThesaurus.key;
  175. }
  176. }
  177. _treeViewController = TreeViewController(
  178. children: treeViewTopData,
  179. selectedKey: selectedKey,
  180. );
  181. vocabularyCard = reportEditController.state.allThesaurusList
  182. .where((element) => element.parentItemCode == selectedKey)
  183. .toList();
  184. }
  185. /// 数据处理
  186. List<Node> getThesaurusItemsAsyncList(
  187. List<ThesaurusItemDTO> allThesaurusItemsAsyncList,
  188. ) {
  189. List<Node> treeView = [];
  190. allThesaurusItemsAsyncList.forEach(
  191. (element) {
  192. List<Node> treeviewChild = [];
  193. final lista = allThesaurusItemsAsyncList.where(
  194. (e) => e.parentItemCode == element.thesaurusItemCode,
  195. );
  196. lista.forEach((element) {
  197. if (element.thesaurusItemType != ThesaurusItemTypeEnum.Contents) {
  198. treeviewChild.add(
  199. Node(
  200. key: element.thesaurusItemCode ?? '',
  201. label: element.thesaurusItemName ?? '',
  202. ),
  203. );
  204. }
  205. });
  206. if (element.parentItemCode == '' || element.parentItemCode == null) {
  207. treeView.add(
  208. Node(
  209. key: element.thesaurusItemCode!,
  210. label: element.thesaurusItemName!,
  211. children: treeviewChild,
  212. ),
  213. );
  214. }
  215. },
  216. );
  217. return treeView;
  218. }
  219. @override
  220. void initState() {
  221. super.initState();
  222. RawKeyboard.instance.addListener(_listenKeyboardEvent);
  223. entrysScrollController.addListener(_scrollListener);
  224. _checkIsShowRightScrol();
  225. /// 初始化形成所需的树结构
  226. _initThesaurusList();
  227. }
  228. @override
  229. void didUpdateWidget(VocabularyEntryReport oldWidget) {
  230. super.didUpdateWidget(oldWidget);
  231. }
  232. @override
  233. void dispose() {
  234. RawKeyboard.instance.removeListener(_listenKeyboardEvent);
  235. entrysScrollController.dispose();
  236. super.dispose();
  237. }
  238. /// 左边能否滑动
  239. bool _isLeftCanScroll = false;
  240. /// 右边能否滑动
  241. bool _isRightCanScroll = false;
  242. @override
  243. Widget build(BuildContext context) {
  244. final mediaQuery = MediaQuery.of(context);
  245. _maxWidth = mediaQuery.size.width * _scale;
  246. return LayoutBuilder(
  247. builder: (BuildContext context, BoxConstraints constraints) {
  248. _maxHeight = constraints.maxHeight;
  249. return Container(
  250. width: _maxWidth,
  251. decoration: BoxDecoration(
  252. boxShadow: [
  253. BoxShadow(
  254. color: Colors.grey,
  255. blurRadius: 4,
  256. offset: Offset(2, 2),
  257. ),
  258. ],
  259. color: Colors.white,
  260. border: Border.all(
  261. color: Colors.grey,
  262. ),
  263. borderRadius: BorderRadius.circular(8),
  264. ),
  265. child: Column(
  266. children: [
  267. _buildHeader(),
  268. _buildEntrysSelected(),
  269. const FSizedBox(height: 5),
  270. Row(
  271. children: [
  272. Expanded(
  273. child: SearchInput(
  274. margin:
  275. const EdgeInsets.symmetric(vertical: 5, horizontal: 20),
  276. businessParent: widget,
  277. onChanged: (value) {
  278. keyWords = value;
  279. },
  280. serchOnPressed: () {
  281. getEntryByKeyWords();
  282. },
  283. controller: _textEditingController,
  284. hintText: i18nBook.remedical.searchKeyword.t,
  285. ),
  286. ),
  287. ],
  288. ),
  289. _buildVocabularyTreeview(context),
  290. ],
  291. ),
  292. );
  293. });
  294. }
  295. Widget _buildVocabularyTreeview(BuildContext context) {
  296. return Container(
  297. width: _maxWidth,
  298. decoration: BoxDecoration(
  299. border: Border(
  300. top: BorderSide(
  301. color: Color.fromRGBO(211, 211, 211, 1),
  302. ),
  303. ),
  304. ),
  305. margin: EdgeInsets.symmetric(
  306. vertical: 4,
  307. ),
  308. child: Row(
  309. children: [
  310. Expanded(
  311. flex: 4,
  312. child: _buildEntryTree(),
  313. ),
  314. FExpanded(
  315. flex: 11,
  316. child: FContainer(
  317. height: _maxHeight - 180,
  318. child: _EntriesItem(
  319. vocabularyCard: vocabularyCard,
  320. ),
  321. ),
  322. ),
  323. ],
  324. ),
  325. );
  326. }
  327. Widget _buildEntryTree() {
  328. return Obx(() {
  329. if (reportEditController.state.allThesaurusList.isEmpty) {
  330. return FSizedBox();
  331. }
  332. return FContainer(
  333. height: _maxHeight - 180,
  334. child: FTreeView(
  335. theme: FTreeViewTheme(
  336. levelPadding: 15,
  337. horizontalSpacing: 15,
  338. colorScheme: ColorScheme.dark(
  339. primary: const Color(0xff2c77e5),
  340. ),
  341. ),
  342. onNodeTap: (code) {
  343. onNodeTap(code);
  344. },
  345. onExpansionChanged: (code, isDrop) {
  346. onExpansionChanged(
  347. code,
  348. isDrop,
  349. );
  350. },
  351. // shrinkWrap: true,
  352. controller: _treeViewController,
  353. nodeBuilder: (buildContext, node) {
  354. return _EntryTreeView(
  355. node: node,
  356. selectedKey: selectedKey,
  357. );
  358. },
  359. ),
  360. );
  361. });
  362. }
  363. FWidget _buildHeader() {
  364. return FContainer(
  365. decoration: BoxDecoration(
  366. color: const Color(0xff2c77e5),
  367. borderRadius: BorderRadius.only(
  368. topLeft: Radius.circular(8),
  369. topRight: Radius.circular(8),
  370. ),
  371. ),
  372. child: FRow(
  373. children: [
  374. const FSizedBox(
  375. width: 10,
  376. height: 40,
  377. ),
  378. FText(
  379. i18nBook.remedical.wordSelectBox.t,
  380. style: TextStyle(
  381. color: Colors.white,
  382. fontSize: 18,
  383. ),
  384. ),
  385. FExpanded(child: FSizedBox()),
  386. FInkWell(
  387. onTap: () => widget.onClose.call(),
  388. child: FIcon(
  389. Icons.close,
  390. color: Colors.white,
  391. ),
  392. ),
  393. const FSizedBox(
  394. width: 10,
  395. ),
  396. ],
  397. ),
  398. );
  399. }
  400. void _scrollListener() {
  401. if (entrysScrollController.offset <=
  402. entrysScrollController.position.minScrollExtent) {
  403. setState(() {
  404. _isLeftCanScroll = false;
  405. _isRightCanScroll = true;
  406. });
  407. } else if (entrysScrollController.offset >=
  408. entrysScrollController.position.maxScrollExtent) {
  409. setState(() {
  410. _isLeftCanScroll = true;
  411. _isRightCanScroll = false;
  412. });
  413. } else {
  414. setState(() {
  415. _isLeftCanScroll = true;
  416. _isRightCanScroll = true;
  417. });
  418. }
  419. }
  420. Widget _buildEntrysSelected() {
  421. return Obx(() {
  422. var entryInfos = reportEditController.state.entryInfos;
  423. if (entryInfos.isEmpty) {
  424. return SizedBox();
  425. }
  426. return Container(
  427. height: 40,
  428. alignment: Alignment.center,
  429. width: _maxWidth - 20,
  430. margin: EdgeInsets.symmetric(horizontal: 5),
  431. child: Row(
  432. children: [
  433. InkWell(
  434. child: FIcon(
  435. Icons.chevron_left_rounded,
  436. color: _isLeftCanScroll ? Colors.black : Colors.grey,
  437. size: 50,
  438. ),
  439. onTap: () {
  440. var target = entrysScrollController.offset - 60;
  441. entrysScrollController.jumpTo(target > 0 ? target : 0);
  442. },
  443. ),
  444. const FSizedBox(
  445. width: 10,
  446. ),
  447. Expanded(
  448. child: ListView(
  449. shrinkWrap: true,
  450. scrollDirection: Axis.horizontal,
  451. controller: entrysScrollController,
  452. children: entryInfos
  453. .map(
  454. (e) => ExpandableIconText(
  455. icon: Icons.book,
  456. isDistinguishChinese: false,
  457. isExpandChild: false,
  458. horizontalMargin: 10,
  459. isSelected:
  460. reportEditController.state.selectedEntryCode ==
  461. e.thesaurusCode,
  462. onPressed: () async {
  463. reportEditController.state.selectedEntryCode =
  464. e.thesaurusCode ?? '';
  465. await reportEditController.thesaurusController
  466. .getDefaultThesaurus(e.thesaurusCode ?? '');
  467. _initThesaurusList();
  468. setState(() {});
  469. },
  470. onHoverChange: (v) {
  471. if (v) {
  472. setState(() {
  473. _focusItem = e.thesaurusCode;
  474. });
  475. } else {
  476. setState(() {
  477. _focusItem = reportEditController
  478. .state.selectedEntryCode;
  479. });
  480. }
  481. },
  482. text: e.thesaurusName ?? '',
  483. isExpand: _focusItem == e.thesaurusCode,
  484. ),
  485. )
  486. .toList(),
  487. ),
  488. ),
  489. const FSizedBox(width: 10),
  490. FInkWell(
  491. child: FIcon(
  492. Icons.chevron_right_rounded,
  493. size: 50,
  494. color: _isRightCanScroll ? Colors.black : Colors.grey,
  495. ),
  496. onTap: () {
  497. var target = entrysScrollController.offset + 60;
  498. var allLength =
  499. entrysScrollController.position.maxScrollExtent;
  500. entrysScrollController.jumpTo(
  501. target > allLength ? allLength.toDouble() : target);
  502. },
  503. ),
  504. ],
  505. ));
  506. });
  507. }
  508. void _checkIsShowRightScrol() {
  509. Future.delayed(Duration(milliseconds: 500), () {
  510. var target = entrysScrollController.offset + 1;
  511. var allLength = entrysScrollController.position.maxScrollExtent;
  512. entrysScrollController
  513. .jumpTo(target > allLength ? allLength.toDouble() : target);
  514. entrysScrollController.jumpTo(0);
  515. });
  516. }
  517. }
  518. class _EntryTreeView extends FStatefulWidget implements FInteractiveContainer {
  519. _EntryTreeView({Key? key, required this.node, this.selectedKey = ''})
  520. : super(key: key);
  521. /// 当前下拉节点
  522. final Node<dynamic> node;
  523. @override
  524. final String pageName = 'EntryTreeView';
  525. /// 当前选中项
  526. final String? selectedKey;
  527. @override
  528. FState<_EntryTreeView> createState() => _EntryTreeViewState();
  529. }
  530. class _EntryTreeViewState extends FState<_EntryTreeView> {
  531. final EdgeInsets _padding = const EdgeInsets.symmetric(vertical: 4);
  532. bool hovering = false;
  533. @override
  534. FWidget build(BuildContext context) {
  535. var isNormalOption = widget.selectedKey != widget.node.key;
  536. return FContainer(
  537. margin: EdgeInsets.only(right: 15),
  538. child: FMouseRegion(
  539. cursor: SystemMouseCursors.click,
  540. onEnter: (e) {
  541. setState(() {
  542. hovering = true;
  543. });
  544. },
  545. onExit: (e) {
  546. setState(() {
  547. hovering = false;
  548. });
  549. },
  550. child: FGestureDetector(
  551. name: "${widget.node.label}",
  552. businessParent: this.widget,
  553. child: FColumn(
  554. children: [
  555. hovering
  556. ? FRow(
  557. children: [
  558. FExpanded(
  559. child: FContainer(
  560. child: _SelectText(
  561. label: widget.node.label,
  562. isSelected: isNormalOption,
  563. padding: this._padding,
  564. ),
  565. ),
  566. ),
  567. ],
  568. )
  569. : FRow(
  570. children: [
  571. FExpanded(
  572. child: FContainer(
  573. padding: _padding,
  574. child: FText(
  575. widget.node.label,
  576. style: widget.selectedKey == widget.node.key
  577. ? TextStyle(
  578. color: Colors.white,
  579. )
  580. : TextStyle(
  581. color: Colors.black,
  582. ),
  583. ),
  584. ),
  585. ),
  586. ],
  587. ),
  588. ],
  589. ),
  590. ),
  591. ),
  592. );
  593. }
  594. }
  595. /// 词条分类选中样式
  596. class _SelectText extends FStatelessWidget {
  597. _SelectText({
  598. required this.isSelected,
  599. required this.label,
  600. required this.padding,
  601. });
  602. final bool isSelected;
  603. final String label;
  604. final EdgeInsetsGeometry padding;
  605. @override
  606. FWidget build(BuildContext context) {
  607. return FContainer(
  608. padding: padding,
  609. child: FText(
  610. label,
  611. style: TextStyle(
  612. color: isSelected ? Colors.black : Colors.white,
  613. ),
  614. ),
  615. );
  616. }
  617. }
  618. class _EntriesItem extends FStatelessWidget {
  619. _EntriesItem({
  620. this.vocabularyCard,
  621. });
  622. /// 词条卡片内容
  623. final List<ThesaurusItemDTO>? vocabularyCard;
  624. @override
  625. FWidget build(BuildContext context) {
  626. return FContainer(
  627. child: FReorderableListView(
  628. shrinkWrap: true,
  629. buildDefaultDragHandles: false,
  630. children: vocabularyCard!
  631. .map(
  632. (item) => FContainer(
  633. key: Key(
  634. item.thesaurusItemCode.toString(),
  635. ),
  636. child: SwipeCard(
  637. isForbiddenAnimation: true,
  638. forbiddenAnimationMargin: EdgeInsets.all(0),
  639. forbiddenAnimationPadding:
  640. EdgeInsets.only(left: 5, top: 5, right: 5),
  641. child: FColumn(
  642. crossAxisAlignment: CrossAxisAlignment.start,
  643. children: [
  644. FContainer(
  645. child: FText(
  646. i18nBook.remedical.description.t,
  647. style: TextStyle(
  648. fontWeight: FontWeight.bold,
  649. ),
  650. ),
  651. ),
  652. FRow(
  653. mainAxisSize: MainAxisSize.max,
  654. children: [
  655. FExpanded(
  656. child: FContainer(
  657. child: FText(
  658. item.thesaurusItemDescription!,
  659. textAlign: TextAlign.left,
  660. ),
  661. ),
  662. )
  663. ],
  664. ),
  665. FSizedBox(
  666. height: 5,
  667. ),
  668. FContainer(
  669. child: FText(
  670. i18nBook.remedical.conclusion.t,
  671. style: TextStyle(
  672. fontWeight: FontWeight.bold,
  673. ),
  674. ),
  675. ),
  676. FRow(
  677. mainAxisSize: MainAxisSize.max,
  678. children: [
  679. FExpanded(
  680. child: FContainer(
  681. child: FText(
  682. item.thesaurusItemConclusion!,
  683. textAlign: TextAlign.left,
  684. ),
  685. ),
  686. )
  687. ],
  688. ),
  689. FSizedBox(
  690. height: 10,
  691. ),
  692. ],
  693. ),
  694. onTap: () {
  695. FReportInfo.instance.insertDiagnostic(
  696. item.thesaurusItemDescription ?? '',
  697. item.thesaurusItemConclusion ?? '',
  698. );
  699. },
  700. isActive: false,
  701. ),
  702. ),
  703. )
  704. .toList(),
  705. onReorder: (int oldIndex, int newIndex) {
  706. /// 拖拽的方法
  707. },
  708. ),
  709. );
  710. }
  711. }