lineage.wxml 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <wxs src="../../utils/helpers.wxs" module="helpers"/>
  2. <view class="page">
  3. <!-- ── 搜索栏 ── -->
  4. <view class="search-bar">
  5. <view class="search-input-wrap">
  6. <text class="search-icon">🔍</text>
  7. <input
  8. class="search-input"
  9. placeholder="搜索成员姓名"
  10. value="{{searchKeyword}}"
  11. bindinput="onSearchInput"
  12. bindconfirm="searchMember"
  13. />
  14. <view class="clear-btn" wx:if="{{searchKeyword}}" bindtap="clearSearch">✕</view>
  15. </view>
  16. <button class="search-btn" bindtap="searchMember">查询</button>
  17. </view>
  18. <!-- ── 搜索结果下拉 ── -->
  19. <view class="search-dropdown" wx:if="{{searchResults.length > 0}}">
  20. <view
  21. class="search-item"
  22. wx:for="{{searchResults}}"
  23. wx:key="id"
  24. bindtap="selectMember"
  25. data-member="{{item}}"
  26. >
  27. <text class="si-name">{{item.name}}{{item.simplified_name ? ' (' + item.simplified_name + ')' : ''}}</text>
  28. <text class="si-gen">{{item.name_word_generation || ''}}</text>
  29. </view>
  30. </view>
  31. <!-- ── 空状态 ── -->
  32. <view class="empty-state" wx:if="{{!center && !loading && searchResults.length === 0}}">
  33. <view class="empty-icon">🌳</view>
  34. <text class="empty-title">世系查询</text>
  35. <text class="empty-desc">输入成员姓名,查看完整家族世系脉络</text>
  36. </view>
  37. <!-- ── 加载中 ── -->
  38. <view class="loading-state" wx:if="{{loading}}">
  39. <view class="loading-dot"></view>
  40. <text>加载中...</text>
  41. </view>
  42. <!-- ── 调试信息(有数据但不显示时排查用) ── -->
  43. <view class="debug-bar" wx:if="{{center && !loading}}">
  44. <text class="debug-text">✓ 已加载:{{center.name}} | 祖先{{reversedGenerations.length}}代 | 子女{{children.length}}人</text>
  45. </view>
  46. <!-- ══════════════════════════════════
  47. 世系树主体
  48. ══════════════════════════════════ -->
  49. <scroll-view scroll-y class="tree-scroll" wx:if="{{center && !loading}}">
  50. <view class="tree-body">
  51. <!-- ── 祖先链(由远及近,从上到下) ── -->
  52. <block wx:for="{{reversedGenerations}}" wx:key="index" wx:for-item="gen">
  53. <view class="gen-row">
  54. <!-- 代际标签 -->
  55. <view class="gen-label">
  56. <text class="gen-label-text">{{helpers.getAncestorLabel(gen.depth)}}</text>
  57. </view>
  58. <!-- 本代:祖先 + 兄弟按 child_order 排序,scroll-left 精确居中 -->
  59. <scroll-view
  60. scroll-x
  61. class="gen-peer-scroll"
  62. scroll-left="{{gen.scrollLeft}}"
  63. >
  64. <view class="gen-peer-list">
  65. <view
  66. wx:for="{{gen.allPeers}}"
  67. wx:key="id"
  68. id="{{item.isAncestor ? 'anc-' + item.id : 'sib-' + item.id}}"
  69. class="card {{item.isAncestor ? 'ancestor-card' : 'sibling-card'}}"
  70. bindtap="viewDetail"
  71. data-member="{{item}}"
  72. >
  73. <view class="order-badge" wx:if="{{item.child_order}}">
  74. <text class="order-badge-text">{{helpers.getChildOrderText(item.child_order)}}</text>
  75. </view>
  76. <view class="card-name-wrap">
  77. <text class="card-name {{item.isAncestor ? '' : 'card-name-sm'}}">{{item.name}}</text>
  78. <text class="card-simplified" wx:if="{{item.simplified_name && item.simplified_name !== item.name}}">({{item.simplified_name}})</text>
  79. </view>
  80. <text class="card-gen">{{item.name_word_generation || ''}}</text>
  81. </view>
  82. </view>
  83. </scroll-view>
  84. </view>
  85. <!-- 竖向连接线 -->
  86. <view class="connector">
  87. <view class="connector-line"></view>
  88. </view>
  89. </block>
  90. <!-- ── 查询人物(含同辈,按第几子排序,center 居中) ── -->
  91. <view class="gen-row center-row">
  92. <view class="gen-label gen-label-center">
  93. <text class="gen-label-text">查询人物</text>
  94. </view>
  95. <scroll-view
  96. scroll-x
  97. class="peer-scroll"
  98. scroll-left="{{peerScrollLeft}}"
  99. >
  100. <view class="peer-list">
  101. <view
  102. wx:for="{{peers}}"
  103. wx:key="id"
  104. id="{{item.isCenter ? 'peer-center' : 'peer-' + item.id}}"
  105. class="card {{item.isCenter ? 'center-card' : 'sibling-card'}}"
  106. bindtap="viewDetail"
  107. data-member="{{item}}"
  108. >
  109. <!-- 排行标签 -->
  110. <view class="peer-order-badge {{item.isCenter ? 'order-badge-center' : ''}}">
  111. <text class="peer-order-text">{{helpers.getChildOrderText(item.child_order)}}</text>
  112. </view>
  113. <view class="card-name-wrap">
  114. <text class="card-name {{item.isCenter ? 'center-name' : 'card-name-sm'}}">{{item.name}}</text>
  115. <text class="card-simplified {{item.isCenter ? 'center-simplified' : ''}}"
  116. wx:if="{{item.simplified_name && item.simplified_name !== item.name}}">
  117. ({{item.simplified_name}})
  118. </text>
  119. </view>
  120. <text class="card-gen {{item.isCenter ? 'center-gen' : ''}}">{{item.name_word_generation || ''}}</text>
  121. <view class="center-badge" wx:if="{{item.isCenter}}">查询人</view>
  122. </view>
  123. </view>
  124. </scroll-view>
  125. </view>
  126. <!-- ── 子女 ── -->
  127. <block wx:if="{{children.length > 0}}">
  128. <view class="connector">
  129. <view class="connector-line"></view>
  130. </view>
  131. <view class="children-section">
  132. <view class="children-label">
  133. <text class="children-label-text">子女</text>
  134. </view>
  135. <scroll-view scroll-x class="children-scroll" scroll-left="{{childrenScrollLeft}}">
  136. <view class="children-list">
  137. <view
  138. class="card child-card"
  139. wx:for="{{children}}"
  140. wx:key="id"
  141. bindtap="viewDetail"
  142. data-member="{{item}}"
  143. >
  144. <view class="order-badge">
  145. <text class="order-badge-text">{{helpers.getChildOrderText(item.child_order)}}</text>
  146. </view>
  147. <view class="card-name-wrap">
  148. <text class="card-name card-name-sm">{{item.name}}</text>
  149. <text class="card-simplified" wx:if="{{item.simplified_name && item.simplified_name !== item.name}}">({{item.simplified_name}})</text>
  150. </view>
  151. <text class="card-gen">{{item.name_word_generation || ''}}</text>
  152. <view class="has-children-dot" wx:if="{{item.has_children}}">▼</view>
  153. </view>
  154. </view>
  155. </scroll-view>
  156. </view>
  157. </block>
  158. </view>
  159. </scroll-view>
  160. <!-- ══════════════════════════════════
  161. 成员详情弹窗
  162. ══════════════════════════════════ -->
  163. <view class="modal-mask" wx:if="{{showDetail}}" bindtap="closeDetail">
  164. <view class="modal-box" catchtap="stopProp">
  165. <view class="modal-header">
  166. <text class="modal-title">成员详情</text>
  167. <view class="modal-close" bindtap="closeDetail">✕</view>
  168. </view>
  169. <view class="modal-body" wx:if="{{detailMember}}">
  170. <view class="detail-row">
  171. <text class="dl">姓名</text>
  172. <text class="dv">{{detailMember.name}}{{detailMember.simplified_name && detailMember.simplified_name !== detailMember.name ? ' (' + detailMember.simplified_name + ')' : ''}}</text>
  173. </view>
  174. <view class="detail-row">
  175. <text class="dl">性别</text>
  176. <text class="dv">{{detailMember.sex === 1 ? '男' : '女'}}</text>
  177. </view>
  178. <view class="detail-row">
  179. <text class="dl">出生日期</text>
  180. <text class="dv">{{detailMember.birthday_date || '-'}}</text>
  181. </view>
  182. <view class="detail-row">
  183. <text class="dl">世系世代</text>
  184. <text class="dv">{{detailMember.name_word_generation || '-'}}</text>
  185. </view>
  186. <view class="detail-row">
  187. <text class="dl">堂内排行</text>
  188. <text class="dv">{{detailMember.family_rank || '-'}}</text>
  189. </view>
  190. <view class="detail-row">
  191. <text class="dl">婚姻状况</text>
  192. <text class="dv">{{helpers.getMaritalStatusText(detailMember.marital_status)}}</text>
  193. </view>
  194. <view class="detail-row">
  195. <text class="dl">是否过世</text>
  196. <text class="dv">{{detailMember.is_pass_away === 0 ? '健在' : (detailMember.is_pass_away === 1 ? '已故' : '未知')}}</text>
  197. </view>
  198. </view>
  199. <view class="modal-footer">
  200. <button class="modal-btn btn-switch" bindtap="switchCenter">以此人为中心</button>
  201. <button class="modal-btn btn-close" bindtap="closeDetail">关闭</button>
  202. </view>
  203. </view>
  204. </view>
  205. </view>