feat: 水印移到全局Shell,资产和里程页面都有水印
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
kkfluous
2026-04-02 18:12:48 +08:00
parent c2d227059c
commit 8ed2031c45
2 changed files with 16 additions and 11 deletions

View File

@@ -1,4 +1,5 @@
import { useState, useEffect, type ComponentType } from 'react'; import { useState, useEffect, useMemo, type ComponentType } from 'react';
import { useAuth } from '../auth/useAuth';
export interface ModuleConfig { export interface ModuleConfig {
id: string; id: string;
@@ -55,8 +56,22 @@ export function Shell({ modules }: { modules: ModuleConfig[] }) {
const ActiveComponent = modules.find((m) => m.id === activeModule)?.component ?? modules[0]?.component; const ActiveComponent = modules.find((m) => m.id === activeModule)?.component ?? modules[0]?.component;
const { user } = useAuth();
const watermarkText = useMemo(() => {
const name = user?.userName || '未登录';
const time = new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-');
return `${name}-${time}`;
}, [user]);
return ( return (
<div className="flex min-h-screen"> <div className="flex min-h-screen">
{/* 全局水印 */}
<div className="fixed inset-0 pointer-events-none z-[9999] overflow-hidden" style={{ opacity: 0.06 }}>
<div className="absolute inset-0" style={{
backgroundImage: `url("data:image/svg+xml,${encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' width='320' height='200'><text x='50%' y='50%' text-anchor='middle' dominant-baseline='middle' font-size='14' font-family='sans-serif' fill='%23000' transform='rotate(-25 160 100)'>${watermarkText}</text></svg>`)}")`,
backgroundRepeat: 'repeat',
}} />
</div>
{/* Web 侧边栏 (md 及以上) */} {/* Web 侧边栏 (md 及以上) */}
<nav className="hidden md:flex flex-col items-center w-16 bg-white border-r border-gray-100 fixed top-0 left-0 h-full z-50 py-6 gap-2"> <nav className="hidden md:flex flex-col items-center w-16 bg-white border-r border-gray-100 fixed top-0 left-0 h-full z-50 py-6 gap-2">
{modules.map((m) => { {modules.map((m) => {

View File

@@ -1,5 +1,4 @@
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react'; import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
import { useAuth } from '../../auth/useAuth';
import { import {
Truck, Truck,
Warehouse, Warehouse,
@@ -46,7 +45,6 @@ const TABS = [
]; ];
export default function AssetsModule() { export default function AssetsModule() {
const { user } = useAuth();
const [activeTab, setActiveTab] = useState<'overview' | 'department' | 'region' | 'customer'>('overview'); const [activeTab, setActiveTab] = useState<'overview' | 'department' | 'region' | 'customer'>('overview');
const [tabReady, setTabReady] = useState(true); const [tabReady, setTabReady] = useState(true);
const prevTabRef = useRef(activeTab); const prevTabRef = useRef(activeTab);
@@ -455,7 +453,6 @@ export default function AssetsModule() {
} }
}, [customerData, customerChartView, customerProvinceData]); }, [customerData, customerChartView, customerProvinceData]);
const watermarkText = useMemo(() => `${user?.userName || '未登录'}-${new Date().toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }).replace(/\//g, '-')}`, [lastUpdate, user]);
if (loading && !summary) { if (loading && !summary) {
return ( return (
@@ -486,13 +483,6 @@ export default function AssetsModule() {
return ( return (
<div className="min-h-screen bg-[#F8F9FB] text-gray-800 font-sans p-6 relative"> <div className="min-h-screen bg-[#F8F9FB] text-gray-800 font-sans p-6 relative">
{/* Watermark */}
<div className="fixed inset-0 pointer-events-none z-[9999] overflow-hidden" style={{ opacity: 0.06 }}>
<div className="absolute inset-0" style={{
backgroundImage: `url("data:image/svg+xml,${encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' width='320' height='200'><text x='50%' y='50%' text-anchor='middle' dominant-baseline='middle' font-size='14' font-family='sans-serif' fill='%23000' transform='rotate(-25 160 100)'>${watermarkText}</text></svg>`)}")`,
backgroundRepeat: 'repeat',
}} />
</div>
{/* Compact Header Bar */} {/* Compact Header Bar */}
<div className="sticky top-0 z-40 -mx-6 -mt-6 mb-4 bg-white/95 backdrop-blur-sm border-b border-gray-100/80"> <div className="sticky top-0 z-40 -mx-6 -mt-6 mb-4 bg-white/95 backdrop-blur-sm border-b border-gray-100/80">
{/* Title row */} {/* Title row */}