feat: 水印移到全局Shell,资产和里程页面都有水印
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
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:
@@ -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) => {
|
||||||
|
|||||||
@@ -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 */}
|
||||||
|
|||||||
Reference in New Issue
Block a user