| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- const app = getApp();
- Page({
- data: {
- searchKeyword: '',
- searchResults: [],
- center: null,
- reversedGenerations: [],
- siblings: [],
- peers: [],
- peerScrollLeft: 0,
- children: [],
- childrenScrollLeft: 0,
- loading: false,
- showDetail: false,
- detailMember: null
- },
- onLoad: function () {},
- onShow: function () {
- if (typeof this.getTabBar === 'function' && this.getTabBar()) {
- this.getTabBar().setData({ selected: 1 });
- }
- },
- onSearchInput: function (e) {
- this.setData({ searchKeyword: e.detail.value });
- },
- searchMember: function () {
- const kw = this.data.searchKeyword.trim();
- if (!kw) {
- wx.showToast({ title: '请输入姓名', icon: 'none' });
- return;
- }
- if (!app.globalData.isLoggedIn) {
- wx.showModal({
- title: '请先登录',
- showCancel: false,
- success: () => {
- wx.navigateTo({ url: '/pages/login/login' });
- }
- });
- return;
- }
- const searchUrl = `${app.globalData.baseUrl}/api/members/search`;
- console.log('[Search] URL:', searchUrl);
- console.log('[Search] keyword:', kw);
- console.log('[Search] isLoggedIn:', app.globalData.isLoggedIn);
- console.log('[Search] token:', app.globalData.token ? app.globalData.token.substring(0, 10) + '...' : 'null');
- wx.request({
- url: searchUrl,
- method: 'GET',
- data: { keyword: kw },
- header: { 'Authorization': `Bearer ${app.globalData.token}` },
- success: (res) => {
- console.log('[Search] statusCode:', res.statusCode);
- console.log('[Search] data:', JSON.stringify(res.data));
- if (res.data && res.data.success) {
- const list = res.data.data || [];
- if (list.length === 0) {
- wx.showToast({ title: '未找到相关成员', icon: 'none' });
- } else if (list.length === 1) {
- // 唯一结果,直接展示世系
- this.setData({
- searchResults: [],
- searchKeyword: list[0].name,
- loading: true,
- center: null,
- reversedGenerations: [],
- siblings: [],
- children: []
- });
- this.loadLineage(list[0].id);
- } else {
- this.setData({ searchResults: list });
- }
- } else {
- wx.showToast({ title: (res.data && res.data.message) || '搜索失败', icon: 'none' });
- }
- },
- fail: (err) => {
- console.error('[Search] 网络请求失败:', JSON.stringify(err));
- wx.showToast({ title: '网络失败:' + (err.errMsg || ''), icon: 'none', duration: 3000 });
- }
- });
- },
- selectMember: function (e) {
- const member = e.currentTarget.dataset.member;
- this.setData({
- searchResults: [],
- searchKeyword: member.name,
- loading: true,
- center: null,
- reversedGenerations: [],
- siblings: [],
- children: []
- });
- this.loadLineage(member.id);
- },
- loadLineage: function (memberId) {
- const lineageUrl = `${app.globalData.baseUrl}/api/lineage/${memberId}`;
- console.log('[Lineage] 请求URL:', lineageUrl);
- console.log('[Lineage] token:', app.globalData.token ? app.globalData.token.substring(0, 10) + '...' : 'null');
- wx.showLoading({ title: '加载中...' });
- wx.request({
- url: lineageUrl,
- method: 'GET',
- header: { 'Authorization': `Bearer ${app.globalData.token}` },
- success: (res) => {
- wx.hideLoading();
- console.log('[Lineage] statusCode:', res.statusCode);
- console.log('[Lineage] success:', res.data && res.data.success);
- console.log('[Lineage] data keys:', res.data && res.data.data ? Object.keys(res.data.data) : 'none');
- if (res.data && res.data.success) {
- const d = res.data.data;
- console.log('[Lineage] generations:', (d.generations || []).length);
- console.log('[Lineage] siblings:', (d.siblings || []).length);
- console.log('[Lineage] children:', (d.children || []).length);
- console.log('[Lineage] center:', JSON.stringify(d.center));
- const center = d.center || null;
- const siblings = d.siblings || [];
- // 计算 rpx→px 比率,用于 scroll-left
- const sysInfo = wx.getSystemInfoSync();
- const rpxRatio = sysInfo.windowWidth / 750;
- // 卡片宽200rpx + 间距16rpx = 216rpx/卡
- // padding两端各275rpx,当祖先在index=K时 scrollLeft=K*216*ratio
- const cardUnit = 216 * rpxRatio;
- // 每代:祖先 + 兄弟合并排序,计算 scrollLeft
- const rawGenerations = (d.generations || []).slice().reverse();
- const reversedGenerations = rawGenerations.map(gen => {
- const allPeers = [
- { ...gen.ancestor, isAncestor: true },
- ...(gen.siblings || []).map(s => ({ ...s, isAncestor: false }))
- ].sort((a, b) => {
- const oa = a.child_order || 1;
- const ob = b.child_order || 1;
- return oa !== ob ? oa - ob : a.id - b.id;
- });
- const ancIdx = allPeers.findIndex(p => p.isAncestor);
- return { ...gen, allPeers, scrollLeft: ancIdx * cardUnit };
- });
- // 查询人物行:center + 兄弟合并排序,计算 scrollLeft
- let peers = [];
- let peerScrollLeft = 0;
- if (center) {
- const allPeers = [
- { ...center, isCenter: true },
- ...siblings.map(s => ({ ...s, isCenter: false }))
- ].sort((a, b) => {
- const oa = a.child_order || 1;
- const ob = b.child_order || 1;
- return oa !== ob ? oa - ob : a.id - b.id;
- });
- peers = allPeers;
- const cIdx = allPeers.findIndex(p => p.isCenter);
- peerScrollLeft = cIdx * cardUnit;
- }
- // 子女行居中:将中间那个子女滚到屏幕中央
- const childrenArr = d.children || [];
- const midChildIdx = Math.floor(childrenArr.length / 2);
- const childrenScrollLeft = midChildIdx * cardUnit;
- this.setData({
- center,
- reversedGenerations,
- siblings,
- children: childrenArr,
- childrenScrollLeft,
- peers,
- peerScrollLeft,
- loading: false
- });
- } else {
- console.error('[Lineage] 失败:', JSON.stringify(res.data));
- wx.showToast({ title: (res.data && res.data.message) || '加载失败', icon: 'none' });
- this.setData({ loading: false });
- }
- },
- fail: (err) => {
- wx.hideLoading();
- console.error('[Lineage] 网络失败:', JSON.stringify(err));
- wx.showToast({ title: '世系加载失败:' + (err.errMsg || ''), icon: 'none', duration: 3000 });
- this.setData({ loading: false });
- }
- });
- },
- clearSearch: function () {
- this.setData({
- searchKeyword: '',
- searchResults: [],
- center: null,
- reversedGenerations: [],
- siblings: [],
- peers: [],
- peerScrollLeft: 0,
- children: [],
- childrenScrollLeft: 0,
- loading: false
- });
- },
- viewDetail: function (e) {
- const member = e.currentTarget.dataset.member;
- if (!member || !member.id) return;
- wx.request({
- url: `${app.globalData.baseUrl}/api/members/${member.id}`,
- method: 'GET',
- header: { 'Authorization': `Bearer ${app.globalData.token}` },
- success: (res) => {
- if (res.data && res.data.success) {
- this.setData({ showDetail: true, detailMember: res.data.data });
- }
- }
- });
- },
- switchCenter: function () {
- if (!this.data.detailMember) return;
- const m = this.data.detailMember;
- this.setData({
- showDetail: false,
- detailMember: null,
- searchKeyword: m.name,
- loading: true,
- center: null,
- reversedGenerations: [],
- siblings: [],
- children: []
- });
- this.loadLineage(m.id);
- },
- closeDetail: function () {
- this.setData({ showDetail: false, detailMember: null });
- },
- stopProp: function () {}
- });
|