|
|
@@ -6,6 +6,7 @@ import re
|
|
|
import threading
|
|
|
import urllib3
|
|
|
import fitz # PyMuPDF
|
|
|
+import base64
|
|
|
from flask import Flask, render_template, request, redirect, url_for, session, flash, jsonify, Response, stream_with_context
|
|
|
from werkzeug.utils import secure_filename
|
|
|
from oss_utils import upload_to_oss
|
|
|
@@ -41,6 +42,55 @@ access_token = None
|
|
|
access_token_expire_time = 0
|
|
|
access_token_lock = threading.Lock()
|
|
|
|
|
|
+# 图片扩展名列表
|
|
|
+IMAGE_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.tiff'}
|
|
|
+
|
|
|
+def add_oss_watermark(url, username=None):
|
|
|
+ """
|
|
|
+ 为图片URL添加阿里云OSS水印
|
|
|
+ :param url: 原始图片URL
|
|
|
+ :param username: 当前登录用户名,如果未提供则使用默认值
|
|
|
+ :return: 添加水印后的URL,如果不是图片则返回原始URL
|
|
|
+ """
|
|
|
+ if not url:
|
|
|
+ return url
|
|
|
+
|
|
|
+ # 检查是否已经有水印参数
|
|
|
+ if 'x-oss-process=image/watermark' in url:
|
|
|
+ return url
|
|
|
+
|
|
|
+ # 检查是否为图片格式
|
|
|
+ lower_url = url.lower()
|
|
|
+ is_image = any(lower_url.endswith(ext) for ext in IMAGE_EXTENSIONS)
|
|
|
+
|
|
|
+ if not is_image:
|
|
|
+ return url
|
|
|
+
|
|
|
+ # 生成水印内容:用户名_时间戳
|
|
|
+ if not username:
|
|
|
+ username = 'genealogy'
|
|
|
+ timestamp = int(time.time())
|
|
|
+ watermark_text = f"{username}_{timestamp}"
|
|
|
+
|
|
|
+ # 对水印文字进行base64编码(需要URL安全的base64)
|
|
|
+ try:
|
|
|
+ encoded_text = base64.b64encode(watermark_text.encode('utf-8')).decode('utf-8')
|
|
|
+ # 替换URL不安全的字符
|
|
|
+ encoded_text = encoded_text.replace('+', '-').replace('/', '_').replace('=', '')
|
|
|
+ except Exception as e:
|
|
|
+ print(f"[Watermark] Error encoding watermark text: {e}")
|
|
|
+ return url
|
|
|
+
|
|
|
+ # 构建水印参数
|
|
|
+ watermark_params = f"?x-oss-process=image/watermark,text_{encoded_text},type_d3F5LXplbmhlaQ,size_30,t_30,g_nw,x_50,y_50,rotate_30"
|
|
|
+
|
|
|
+ # 添加水印参数到URL
|
|
|
+ if '?' in url:
|
|
|
+ # 如果URL已有参数,使用&连接
|
|
|
+ return f"{url}&{watermark_params[1:]}"
|
|
|
+ else:
|
|
|
+ return f"{url}{watermark_params}"
|
|
|
+
|
|
|
def get_wechat_access_token():
|
|
|
"""获取微信小程序access_token,带缓存和线程安全"""
|
|
|
global access_token, access_token_expire_time
|
|
|
@@ -1078,6 +1128,9 @@ def delete_pdf(pdf_id):
|
|
|
def index():
|
|
|
if 'user_id' not in session:
|
|
|
return redirect(url_for('login'))
|
|
|
+
|
|
|
+ # 获取当前登录用户名
|
|
|
+ username = session.get('username', 'genealogy')
|
|
|
|
|
|
page = request.args.get('page', 1, type=int)
|
|
|
version = request.args.get('version', '').strip()
|
|
|
@@ -1118,6 +1171,11 @@ def index():
|
|
|
cursor.execute(sql, params + [per_page, offset])
|
|
|
records = cursor.fetchall()
|
|
|
|
|
|
+ # 为图片URL添加水印
|
|
|
+ for record in records:
|
|
|
+ if record.get('oss_url'):
|
|
|
+ record['oss_url'] = add_oss_watermark(record['oss_url'], username)
|
|
|
+
|
|
|
total_pages = (total + per_page - 1) // per_page
|
|
|
|
|
|
finally:
|
|
|
@@ -2292,6 +2350,9 @@ def check_relations():
|
|
|
def add_member():
|
|
|
if 'user_id' not in session:
|
|
|
return redirect(url_for('login'))
|
|
|
+
|
|
|
+ # 获取当前登录用户名
|
|
|
+ username = session.get('username', 'genealogy')
|
|
|
|
|
|
conn = get_db_connection()
|
|
|
try:
|
|
|
@@ -2366,6 +2427,11 @@ def add_member():
|
|
|
all_members = cursor.fetchall()
|
|
|
cursor.execute("SELECT * FROM genealogy_records ORDER BY page_number ASC")
|
|
|
images = cursor.fetchall()
|
|
|
+
|
|
|
+ # 为图片URL添加水印
|
|
|
+ for img in images:
|
|
|
+ if img.get('oss_url'):
|
|
|
+ img['oss_url'] = add_oss_watermark(img['oss_url'], username)
|
|
|
|
|
|
if request.headers.get('X-Requested-With') == 'XMLHttpRequest' or request.is_json:
|
|
|
return jsonify({
|
|
|
@@ -2497,6 +2563,11 @@ def add_member():
|
|
|
cursor.execute("SELECT * FROM genealogy_records ORDER BY page_number ASC")
|
|
|
images = cursor.fetchall()
|
|
|
|
|
|
+ # 为图片URL添加水印
|
|
|
+ for img in images:
|
|
|
+ if img.get('oss_url'):
|
|
|
+ img['oss_url'] = add_oss_watermark(img['oss_url'], username)
|
|
|
+
|
|
|
except Exception as e:
|
|
|
flash(f'发生错误: {e}')
|
|
|
all_members = []
|
|
|
@@ -2576,6 +2647,11 @@ def edit_member(member_id):
|
|
|
cursor.execute("SELECT * FROM genealogy_records ORDER BY page_number ASC")
|
|
|
images = cursor.fetchall()
|
|
|
|
|
|
+ # 为图片URL添加水印
|
|
|
+ for img in images:
|
|
|
+ if img.get('oss_url'):
|
|
|
+ img['oss_url'] = add_oss_watermark(img['oss_url'], username)
|
|
|
+
|
|
|
if request.headers.get('X-Requested-With') == 'XMLHttpRequest' or request.is_json:
|
|
|
return jsonify({
|
|
|
"success": False,
|
|
|
@@ -2711,6 +2787,11 @@ def edit_member(member_id):
|
|
|
|
|
|
cursor.execute("SELECT * FROM genealogy_records ORDER BY page_number ASC")
|
|
|
images = cursor.fetchall()
|
|
|
+
|
|
|
+ # 为图片URL添加水印
|
|
|
+ for img in images:
|
|
|
+ if img.get('oss_url'):
|
|
|
+ img['oss_url'] = add_oss_watermark(img['oss_url'], username)
|
|
|
finally:
|
|
|
conn.close()
|
|
|
|
|
|
@@ -2732,6 +2813,9 @@ def member_detail(member_id):
|
|
|
if 'user_id' not in session:
|
|
|
return redirect(url_for('login'))
|
|
|
|
|
|
+ # 获取当前登录用户名
|
|
|
+ username = session.get('username', 'genealogy')
|
|
|
+
|
|
|
conn = get_db_connection()
|
|
|
try:
|
|
|
with conn.cursor() as cursor:
|
|
|
@@ -2749,6 +2833,10 @@ def member_detail(member_id):
|
|
|
flash('成员不存在')
|
|
|
return redirect(url_for('members'))
|
|
|
|
|
|
+ # 为图片URL添加水印
|
|
|
+ if member.get('source_image_url'):
|
|
|
+ member['source_image_url'] = add_oss_watermark(member['source_image_url'], username)
|
|
|
+
|
|
|
member['birthday_str'] = format_timestamp(member.get('birthday'))
|
|
|
|
|
|
# 获取关系(包含子类型和第几子)
|