|
|
@@ -1445,46 +1445,17 @@ def members():
|
|
|
return redirect(url_for('login'))
|
|
|
|
|
|
search_name = request.args.get('name', '').strip()
|
|
|
+ search_type = request.args.get('search_type', 'name').strip() # name | name_word
|
|
|
page = request.args.get('page', 1, type=int)
|
|
|
per_page = 10
|
|
|
offset = (page - 1) * per_page
|
|
|
|
|
|
- print(f"[Members List] Fetching members page: {page}, search: '{search_name}', per_page: {per_page}")
|
|
|
+ print(f"[Members List] Fetching members page: {page}, search: '{search_name}', type: '{search_type}', per_page: {per_page}")
|
|
|
|
|
|
conn = get_db_connection()
|
|
|
try:
|
|
|
with conn.cursor() as cursor:
|
|
|
- # 1. Get total count
|
|
|
- if search_name:
|
|
|
- variants = expand_name_search_variants(search_name)
|
|
|
- where_parts = []
|
|
|
- params = []
|
|
|
- for v in variants:
|
|
|
- where_parts.append("(name LIKE %s OR simplified_name LIKE %s)")
|
|
|
- like = f"%{v}%"
|
|
|
- params.extend([like, like])
|
|
|
- where_clause = " OR ".join(where_parts) if where_parts else "name LIKE %s"
|
|
|
- if not where_parts:
|
|
|
- params = [f"%{search_name}%"]
|
|
|
- count_sql = f"SELECT COUNT(*) as count FROM family_member_info WHERE {where_clause}"
|
|
|
- print(f"[Members List] Executing count SQL: {count_sql}")
|
|
|
- print(f"[Members List] Count SQL parameters: {params}")
|
|
|
- cursor.execute(count_sql, tuple(params))
|
|
|
- else:
|
|
|
- count_sql = "SELECT COUNT(*) as count FROM family_member_info"
|
|
|
- print(f"[Members List] Executing count SQL: {count_sql}")
|
|
|
- cursor.execute(count_sql)
|
|
|
-
|
|
|
- result = cursor.fetchone()
|
|
|
- total = result['count'] if result else 0
|
|
|
- total_pages = (total + per_page - 1) // per_page
|
|
|
- print(f"[Members List] Total members: {total}, total pages: {total_pages}")
|
|
|
-
|
|
|
- # 2. Get paginated results, ordered by modified_time DESC (or create_time if modified is null/same)
|
|
|
- # Using COALESCE to ensure sort works even if modified_time is NULL
|
|
|
order_clause = "ORDER BY COALESCE(fmi.modified_time, fmi.create_time) DESC"
|
|
|
-
|
|
|
- # 父亲信息 JOIN(取亲生/普通父亲,排除入继关系)
|
|
|
father_join = """
|
|
|
LEFT JOIN family_relation_info fri
|
|
|
ON fmi.id = fri.child_mid AND fri.relation_type = 1 AND COALESCE(fri.sub_relation_type, 0) != 3
|
|
|
@@ -1492,26 +1463,47 @@ def members():
|
|
|
"""
|
|
|
father_cols = ", father.id as father_id, father.name as father_name, father.simplified_name as father_simplified_name, fri.child_order as child_order_to_father"
|
|
|
|
|
|
- if search_name:
|
|
|
+ if search_name and search_type == 'name_word':
|
|
|
+ # 字辈精确搜索
|
|
|
+ where_clause = "fmi.name_word = %s"
|
|
|
+ count_params = [search_name]
|
|
|
+ data_params = [search_name]
|
|
|
+ elif search_name:
|
|
|
+ # 姓名模糊搜索(支持繁简变体)
|
|
|
variants = expand_name_search_variants(search_name)
|
|
|
where_parts = []
|
|
|
- params = []
|
|
|
+ count_params = []
|
|
|
for v in variants:
|
|
|
where_parts.append("(fmi.name LIKE %s OR fmi.simplified_name LIKE %s)")
|
|
|
like = f"%{v}%"
|
|
|
- params.extend([like, like])
|
|
|
+ count_params.extend([like, like])
|
|
|
where_clause = " OR ".join(where_parts) if where_parts else "(fmi.name LIKE %s OR fmi.simplified_name LIKE %s)"
|
|
|
if not where_parts:
|
|
|
like = f"%{search_name}%"
|
|
|
- params = [like, like]
|
|
|
- sql = f"SELECT fmi.id, fmi.name, fmi.simplified_name, fmi.sex, fmi.name_word_generation, fmi.birthday, fmi.occupation, fmi.family_rank, fmi.branch_family_hall, fmi.residential_address, fmi.is_pass_away, fmi.create_time, fmi.modified_time{father_cols} FROM family_member_info fmi {father_join} WHERE {where_clause} {order_clause} LIMIT %s OFFSET %s"
|
|
|
- print(f"[Members List] Executing members SQL: {sql}")
|
|
|
- print(f"[Members List] Members SQL parameters: {params + [per_page, offset]}")
|
|
|
- cursor.execute(sql, tuple(params + [per_page, offset]))
|
|
|
+ count_params = [like, like]
|
|
|
+ data_params = count_params[:]
|
|
|
+ else:
|
|
|
+ where_clause = None
|
|
|
+ count_params = []
|
|
|
+ data_params = []
|
|
|
+
|
|
|
+ # 1. 计算总数
|
|
|
+ if where_clause:
|
|
|
+ count_sql = f"SELECT COUNT(*) as count FROM family_member_info fmi WHERE {where_clause}"
|
|
|
+ cursor.execute(count_sql, tuple(count_params))
|
|
|
else:
|
|
|
- sql = f"SELECT fmi.id, fmi.name, fmi.simplified_name, fmi.sex, fmi.name_word_generation, fmi.birthday, fmi.occupation, fmi.family_rank, fmi.branch_family_hall, fmi.residential_address, fmi.is_pass_away, fmi.create_time, fmi.modified_time{father_cols} FROM family_member_info fmi {father_join} {order_clause} LIMIT %s OFFSET %s"
|
|
|
- print(f"[Members List] Executing members SQL: {sql}")
|
|
|
- print(f"[Members List] Members SQL parameters: {[per_page, offset]}")
|
|
|
+ cursor.execute("SELECT COUNT(*) as count FROM family_member_info")
|
|
|
+ result = cursor.fetchone()
|
|
|
+ total = result['count'] if result else 0
|
|
|
+ total_pages = (total + per_page - 1) // per_page
|
|
|
+
|
|
|
+ # 2. 查询分页数据
|
|
|
+ select_cols = f"fmi.id, fmi.name, fmi.simplified_name, fmi.sex, fmi.name_word, fmi.name_word_generation, fmi.birthday, fmi.occupation, fmi.family_rank, fmi.branch_family_hall, fmi.residential_address, fmi.is_pass_away, fmi.create_time, fmi.modified_time{father_cols}"
|
|
|
+ if where_clause:
|
|
|
+ sql = f"SELECT {select_cols} FROM family_member_info fmi {father_join} WHERE {where_clause} {order_clause} LIMIT %s OFFSET %s"
|
|
|
+ cursor.execute(sql, tuple(data_params + [per_page, offset]))
|
|
|
+ else:
|
|
|
+ sql = f"SELECT {select_cols} FROM family_member_info fmi {father_join} {order_clause} LIMIT %s OFFSET %s"
|
|
|
cursor.execute(sql, (per_page, offset))
|
|
|
|
|
|
members = cursor.fetchall()
|
|
|
@@ -1566,7 +1558,7 @@ def members():
|
|
|
print(f"[Members List] Closing database connection")
|
|
|
conn.close()
|
|
|
|
|
|
- return render_template('members.html', members=members, search_name=search_name, page=page, total_pages=total_pages, total=total)
|
|
|
+ return render_template('members.html', members=members, search_name=search_name, search_type=search_type, page=page, total_pages=total_pages, total=total)
|
|
|
|
|
|
@app.route('/manager/batch_genealogy')
|
|
|
def batch_genealogy():
|
|
|
@@ -2600,46 +2592,49 @@ def get_members():
|
|
|
|
|
|
page = int(request.args.get('page', 1))
|
|
|
search = request.args.get('search', '')
|
|
|
+ search_type = request.args.get('search_type', 'name') # name | name_word
|
|
|
per_page = 10
|
|
|
offset = (page - 1) * per_page
|
|
|
|
|
|
conn = get_db_connection()
|
|
|
try:
|
|
|
with conn.cursor() as cursor:
|
|
|
- # Count total members
|
|
|
- if search:
|
|
|
- cursor.execute("SELECT COUNT(*) as total FROM family_member_info WHERE name LIKE %s OR simplified_name LIKE %s",
|
|
|
- (f'%{search}%', f'%{search}%'))
|
|
|
+ if search and search_type == 'name_word':
|
|
|
+ where_clause = "fmi.name_word = %s"
|
|
|
+ count_params = (search,)
|
|
|
+ data_params = (search, per_page, offset)
|
|
|
+ elif search:
|
|
|
+ where_clause = "fmi.name LIKE %s OR fmi.simplified_name LIKE %s"
|
|
|
+ count_params = (f'%{search}%', f'%{search}%')
|
|
|
+ data_params = (f'%{search}%', f'%{search}%', per_page, offset)
|
|
|
+ else:
|
|
|
+ where_clause = None
|
|
|
+ count_params = ()
|
|
|
+ data_params = (per_page, offset)
|
|
|
+
|
|
|
+ if where_clause:
|
|
|
+ cursor.execute(f"SELECT COUNT(*) as total FROM family_member_info fmi WHERE {where_clause}", count_params)
|
|
|
else:
|
|
|
cursor.execute("SELECT COUNT(*) as total FROM family_member_info")
|
|
|
total_result = cursor.fetchone()
|
|
|
total = total_result['total'] if total_result else 0
|
|
|
|
|
|
- # Get members for current page with father information
|
|
|
- if search:
|
|
|
- cursor.execute("""
|
|
|
- SELECT
|
|
|
- fmi.id, fmi.name, fmi.simplified_name, fmi.sex, fmi.name_word_generation,
|
|
|
- father.name as father_name, father.simplified_name as father_simplified_name, father.name_word_generation as father_generation
|
|
|
- FROM family_member_info fmi
|
|
|
- LEFT JOIN family_relation_info fri ON fmi.id = fri.child_mid AND fri.relation_type IN (1, 2)
|
|
|
- LEFT JOIN family_member_info father ON fri.parent_mid = father.id
|
|
|
- WHERE fmi.name LIKE %s OR fmi.simplified_name LIKE %s
|
|
|
- LIMIT %s OFFSET %s
|
|
|
- """, (f'%{search}%', f'%{search}%', per_page, offset))
|
|
|
+ base_sql = """
|
|
|
+ SELECT
|
|
|
+ fmi.id, fmi.name, fmi.simplified_name, fmi.sex,
|
|
|
+ fmi.name_word, fmi.name_word_generation,
|
|
|
+ father.name as father_name, father.simplified_name as father_simplified_name,
|
|
|
+ father.name_word_generation as father_generation
|
|
|
+ FROM family_member_info fmi
|
|
|
+ LEFT JOIN family_relation_info fri ON fmi.id = fri.child_mid AND fri.relation_type IN (1, 2)
|
|
|
+ LEFT JOIN family_member_info father ON fri.parent_mid = father.id
|
|
|
+ """
|
|
|
+ if where_clause:
|
|
|
+ cursor.execute(base_sql + f" WHERE {where_clause} LIMIT %s OFFSET %s", data_params)
|
|
|
else:
|
|
|
- cursor.execute("""
|
|
|
- SELECT
|
|
|
- fmi.id, fmi.name, fmi.simplified_name, fmi.sex, fmi.name_word_generation,
|
|
|
- father.name as father_name, father.simplified_name as father_simplified_name, father.name_word_generation as father_generation
|
|
|
- FROM family_member_info fmi
|
|
|
- LEFT JOIN family_relation_info fri ON fmi.id = fri.child_mid AND fri.relation_type IN (1, 2)
|
|
|
- LEFT JOIN family_member_info father ON fri.parent_mid = father.id
|
|
|
- LIMIT %s OFFSET %s
|
|
|
- """, (per_page, offset))
|
|
|
+ cursor.execute(base_sql + " LIMIT %s OFFSET %s", data_params)
|
|
|
members = cursor.fetchall()
|
|
|
|
|
|
- # Convert to list of dictionaries if needed
|
|
|
members_list = []
|
|
|
for member in members:
|
|
|
members_list.append({
|
|
|
@@ -2647,6 +2642,7 @@ def get_members():
|
|
|
'name': member['name'],
|
|
|
'simplified_name': member['simplified_name'],
|
|
|
'sex': member['sex'],
|
|
|
+ 'name_word': member.get('name_word'),
|
|
|
'name_word_generation': member.get('name_word_generation'),
|
|
|
'father_name': member.get('father_name'),
|
|
|
'father_simplified_name': member.get('father_simplified_name'),
|