fix: 修复前后端编译警告 — 移除未使用变量/导入/函数

前端:
- 移除未使用导入: FileText, AlertCircle, RefreshCw, Signal, QrCode, Upload, Save, Bell, History, useMemo, Select
- 移除未使用变量/函数: scope, cfg, org, paged, salaryNum, ackColor, resultColor, maxEmployees, compareVersions, showRenewPreview, showEvidence, handleStartDateChange, ResultRow, previewEmployeeId, updateMutation
- 修复 vite.config.ts: 安装 @types/node 并配置 tsconfig.node.json
- 将未使用参数 req/s 改为 _req/_s

后端:
- 移除未使用导入: Request, Response, NextFunction, decrypt, ContractType, ensureDefaultTemplate
- 移除未使用变量/常量: scope, cfg, org, orgId(preview), monthNum, TAX_BRACKETS, months, daysBetween
- 将未使用参数 req 改为 _req
This commit is contained in:
freedakgmail
2026-07-24 08:25:31 +08:00
parent e01bad4815
commit 951a3abac5
28 changed files with 61 additions and 100 deletions
+18
View File
@@ -24,6 +24,7 @@
"zustand": "^4.5.0"
},
"devDependencies": {
"@types/node": "^26.1.1",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.0",
@@ -1309,6 +1310,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "26.1.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-26.1.1.tgz",
"integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~8.3.0"
}
},
"node_modules/@types/pako": {
"version": "2.0.4",
"resolved": "https://registry.npmmirror.com/@types/pako/-/pako-2.0.4.tgz",
@@ -3303,6 +3314,13 @@
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "8.3.0",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-8.3.0.tgz",
"integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
"dev": true,
"license": "MIT"
},
"node_modules/update-browserslist-db": {
"version": "1.2.3",
"resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
+1
View File
@@ -25,6 +25,7 @@
"zustand": "^4.5.0"
},
"devDependencies": {
"@types/node": "^26.1.1",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.0",
@@ -1,5 +1,5 @@
import { Link, useLocation } from 'react-router-dom'
import { Home, FileText, Users, Calculator, UserX, Bot, Shield } from 'lucide-react'
import { Home, Users, Calculator, UserX, Bot, Shield } from 'lucide-react'
import clsx from 'clsx'
const tabs = [
+1 -1
View File
@@ -1,5 +1,5 @@
import { Link, useLocation, useNavigate } from 'react-router-dom'
import { Building2, AlertCircle, ChevronDown } from 'lucide-react'
import { Building2, ChevronDown } from 'lucide-react'
import { useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useAuthStore } from '../../store/authStore'
+1 -2
View File
@@ -1,12 +1,11 @@
import { useState, useRef } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Plus, Search, RefreshCw, Paperclip, Trash2, X } from 'lucide-react'
import { Plus, Search, Paperclip, Trash2, X } from 'lucide-react'
import api from '../lib/api'
import Card from '../components/ui/Card'
import Button from '../components/ui/Button'
import { Input, Label, Select } from '../components/ui/Input'
import Modal from '../components/ui/Modal'
import Signal from '../components/ui/Signal'
import EmptyState from '../components/ui/EmptyState'
interface EmployeeItem {
+1 -1
View File
@@ -21,7 +21,7 @@ const TODO_ICON_CONFIG: Record<string, { icon: typeof FileText; color: string; b
ONBOARDING: { icon: UserPlus, color: 'text-cyan-600', bg: 'bg-cyan-50' },
}
function TodoIcon({ type, level }: { type: string; level: string }) {
function TodoIcon({ type }: { type: string; level: string }) {
const config = TODO_ICON_CONFIG[type] || TODO_ICON_CONFIG.MONTHLY
const Icon = config.icon
return (
+2 -17
View File
@@ -1,6 +1,6 @@
import { useState, useMemo, useRef } from 'react'
import { useState, useRef } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Calculator, AlertCircle, Info, Save, Check, Upload, Bell, Layers, Settings as SettingsIcon, Archive, Plus, Trash2, AlertTriangle, Download, FileText, History, X } from 'lucide-react'
import { Calculator, AlertCircle, Info, Check, Upload, Layers, Settings as SettingsIcon, Archive, Plus, Trash2, AlertTriangle, Download, FileText, X } from 'lucide-react'
import api from '../lib/api'
import Card from '../components/ui/Card'
import Button from '../components/ui/Button'
@@ -703,11 +703,6 @@ function TemplateManager() {
},
})
const updateMutation = useMutation({
mutationFn: ({ id, data }: { id: string; data: any }) => api.put(`/payroll2/template/${id}`, data),
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['payslip-template'] }),
})
const deleteMutation = useMutation({
mutationFn: (id: string) => api.delete(`/payroll2/template/${id}`),
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['payslip-template'] }),
@@ -1184,22 +1179,12 @@ function OvertimeCalculator() {
)
}
function ResultRow({ label, value }: { label: string; value: number }) {
return (
<div className="flex items-center justify-between text-xs">
<span className="text-gray-600">{label}</span>
<span className="font-medium">¥{fmt(value)}</span>
</div>
)
}
function PayslipManager() {
const queryClient = useQueryClient()
const [month, setMonth] = useState(new Date().toISOString().slice(0, 7))
const [page, setPage] = useState(1)
const [pageSize, setPageSize] = useState(10)
const [showTaxPreview, setShowTaxPreview] = useState(false)
const [previewEmployeeId, setPreviewEmployeeId] = useState('')
const [previewData, setPreviewData] = useState({
baseSalary: 0,
overtimePay: 0,
+1 -36
View File
@@ -1,13 +1,12 @@
import { useState, useRef } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { Users, FileText, AlertTriangle, Calendar, GraduationCap, TrendingUp, Scale, X, Plus, Paperclip, Trash2, Printer, Calculator, Shield, Info, Check, Eye, Download, UserX, UserPlus, QrCode } from 'lucide-react'
import { Users, FileText, AlertTriangle, Calendar, GraduationCap, TrendingUp, Scale, X, Plus, Paperclip, Trash2, Printer, Calculator, Shield, Info, Check, Eye, Download, UserX, UserPlus } from 'lucide-react'
import { QRCodeSVG } from 'qrcode.react'
import api from '../lib/api'
import Card from '../components/ui/Card'
import Button from '../components/ui/Button'
import { Input, Label, Select } from '../components/ui/Input'
import Modal from '../components/ui/Modal'
import Signal from '../components/ui/Signal'
import Pagination from '../components/ui/Pagination'
// 金额格式化:保留两位小数 + 千分位
@@ -41,7 +40,6 @@ export default function Roster() {
const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set())
const [showBatchRenewModal, setShowBatchRenewModal] = useState(false)
const [batchRenewYears, setBatchRenewYears] = useState(3)
const [showRenewPreview, setShowRenewPreview] = useState(false)
const [previewData, setPreviewData] = useState<any>(null)
const [filterStatus, setFilterStatus] = useState('')
const [filterContractStatus, setFilterContractStatus] = useState('')
@@ -128,7 +126,6 @@ export default function Roster() {
queryClient.invalidateQueries({ queryKey: ['roster'] })
queryClient.invalidateQueries({ queryKey: ['dashboard'] })
setShowBatchRenewModal(false)
setShowRenewPreview(false)
setSelectedIds(new Set())
setPreviewData(null)
},
@@ -138,7 +135,6 @@ export default function Roster() {
mutationFn: (contractIds: string[]) => api.post('/employees/contracts/preview-renew', { contractIds }),
onSuccess: (data: any) => {
setPreviewData(data.data)
setShowRenewPreview(true)
},
})
@@ -191,7 +187,6 @@ export default function Roster() {
const filtered = employees?.filter((e: any) =>
!search || e.name.includes(search) || e.department.includes(search)
) || []
const paged = filtered.slice((page - 1) * pageSize, page * pageSize)
if (selectedId) {
return <EmployeeProfile employeeId={selectedId} onBack={() => setSelectedId(null)} />
@@ -681,7 +676,6 @@ export default function Roster() {
function EmployeeProfile({ employeeId, onBack }: { employeeId: string; onBack: () => void }) {
const [tab, setTab] = useState<DetailTab>('basic')
const [showEvidence, setShowEvidence] = useState(false)
const { data: profile, isLoading } = useQuery<any>({
queryKey: ['roster-profile', employeeId],
@@ -1521,19 +1515,6 @@ function RehireModal({ employee, onClose, onSubmit, loading, error }: {
}
}
// 开始日期变更 → 重新计算结束日期
const handleStartDateChange = (startDate: string) => {
if (form.contractType === 'FIXED' && form.contractYears > 0 && startDate) {
const start = new Date(startDate)
const end = new Date(start)
end.setFullYear(end.getFullYear() + form.contractYears)
end.setDate(end.getDate() - 1)
setForm({ ...form, startDate, endDate: end.toISOString().slice(0, 10) })
} else {
setForm({ ...form, startDate })
}
}
const handleSubmit = () => {
const data: any = {
hireDate: new Date(form.hireDate).toISOString(),
@@ -1702,7 +1683,6 @@ function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
})
const hireMonth = form.hireDate ? form.hireDate.slice(0, 7) : ''
const salaryNum = parseFloat(form.monthlySalary) || 0
// 入职日期变更 → 同步合同开始日期 + 重算结束日期
const handleHireDateChange = (hireDate: string) => {
@@ -1788,19 +1768,6 @@ function AddEmployeeModal({ onClose, onSubmit, loading, error }: {
setForm({ ...form, endDate, contractYears: Math.max(1, Math.round(months / 12)) })
}
// 开始日期变更 → 重新计算结束日期
const handleStartDateChange = (startDate: string) => {
if (form.contractType === 'FIXED' && form.contractYears > 0 && startDate) {
const start = new Date(startDate)
const end = new Date(start)
end.setFullYear(end.getFullYear() + form.contractYears)
end.setDate(end.getDate() - 1)
setForm({ ...form, startDate, endDate: end.toISOString().slice(0, 10) })
} else {
setForm({ ...form, startDate })
}
}
const handleSubmit = () => {
const data: any = {
name: form.name, department: form.department,
@@ -2531,7 +2498,6 @@ function TrainingInfo({ employeeId, records }: { employeeId: string; records: an
})
const ackMap: Record<string, string> = { PENDING: '待签收', SIGNED: '已签收', REFUSED: '拒绝签收' }
const ackColor: Record<string, string> = { PENDING: 'bg-amber-50 text-warning', SIGNED: 'bg-green-50 text-safe', REFUSED: 'bg-red-50 text-danger' }
return (
<div className="space-y-3">
@@ -2607,7 +2573,6 @@ function PerformanceInfo({ employeeId, records }: { employeeId: string; records:
})
const resultMap: Record<string, string> = { EXCELLENT: '优秀', QUALIFIED: '合格', NEED_IMPROVE: '需改进', UNQUALIFIED: '不胜任' }
const resultColor: Record<string, string> = { EXCELLENT: 'bg-green-50 text-safe', QUALIFIED: 'bg-blue-50 text-blue-600', NEED_IMPROVE: 'bg-amber-50 text-warning', UNQUALIFIED: 'bg-red-50 text-danger' }
return (
<div className="space-y-3">
-1
View File
@@ -404,7 +404,6 @@ function ExportSettings() {
function PlanSettings({ orgData }: { orgData: any }) {
const queryClient = useQueryClient()
const plan = orgData?.data?.plan || 'FREE'
const maxEmployees = orgData?.data?.maxEmployees || 10
const { data: usageData } = useQuery<any>({
queryKey: ['usage'],
+1 -1
View File
@@ -4,7 +4,7 @@ import { Calculator, Info, Check, Settings as SettingsIcon, Plus, History, Downl
import api from '../lib/api'
import Card from '../components/ui/Card'
import Button from '../components/ui/Button'
import { Input, Label, Select } from '../components/ui/Input'
import { Input, Label } from '../components/ui/Input'
// 金额格式化:保留两位小数 + 千分位
const fmt = (n: number) => (n || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
+1 -5
View File
@@ -6,7 +6,6 @@ import api from '../lib/api'
import Card from '../components/ui/Card'
import Button from '../components/ui/Button'
import { Input, Label, Select } from '../components/ui/Input'
import Signal from '../components/ui/Signal'
// 金额格式化:保留两位小数 + 千分位
const fmt = (n: number) => (n || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
@@ -81,8 +80,6 @@ export default function Termination() {
isSimulated: boolean
createdAt: string
}>>([])
// 对比模式:选中的版本ID列表
const [compareVersions, setCompareVersions] = useState<string[]>([])
// 是否展开对比
const [showCompare, setShowCompare] = useState(false)
@@ -405,7 +402,7 @@ export default function Termination() {
{/* 进度条 */}
<div className="flex items-center gap-1">
{STEPS.map((s, i) => (
{STEPS.map((_s, i) => (
<div key={i} className="flex items-center">
<div className={`w-2.5 h-2.5 rounded-full ${i <= step ? 'bg-primary' : 'bg-gray-300'}`} />
{i < STEPS.length - 1 && <div className={`w-8 h-0.5 ${i < step ? 'bg-primary' : 'bg-gray-300'}`} />}
@@ -955,7 +952,6 @@ export default function Termination() {
size="sm"
onClick={() => {
setShowCompare(!showCompare)
if (!showCompare) setCompareVersions([])
}}
>
<List className="w-3.5 h-3.5 mr-1" />
+1 -1
View File
@@ -1,6 +1,6 @@
import { useState, useRef } from 'react'
import { useSearchParams } from 'react-router-dom'
import { ClipboardList, Check, Upload, FileText, X } from 'lucide-react'
import { ClipboardList, Check, FileText, X } from 'lucide-react'
import api from '../../lib/api'
import Card from '../../components/ui/Card'
import Button from '../../components/ui/Button'
+2 -1
View File
@@ -5,7 +5,8 @@
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true,
"strict": true
"strict": true,
"types": ["node"]
},
"include": ["vite.config.ts"]
}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"root":["./src/app.tsx","./src/main.tsx","./src/components/onboardingguide.tsx","./src/components/layout/mobiletabbar.tsx","./src/components/layout/pagecontainer.tsx","./src/components/layout/topnav.tsx","./src/components/ui/button.tsx","./src/components/ui/card.tsx","./src/components/ui/emptystate.tsx","./src/components/ui/input.tsx","./src/components/ui/modal.tsx","./src/components/ui/pagination.tsx","./src/components/ui/signal.tsx","./src/lib/api.ts","./src/pages/aiassistant.tsx","./src/pages/compensation.tsx","./src/pages/contracts.tsx","./src/pages/dashboard.tsx","./src/pages/money.tsx","./src/pages/roster.tsx","./src/pages/settings.tsx","./src/pages/socialinsurance.tsx","./src/pages/termination.tsx","./src/pages/auth/forgotpassword.tsx","./src/pages/auth/login.tsx","./src/pages/auth/register.tsx","./src/pages/portal/contractconfirm.tsx","./src/pages/portal/mycontract.tsx","./src/pages/portal/onboarding.tsx","./src/pages/portal/payslip.tsx","./src/pages/portal/portallogin.tsx","./src/store/authstore.ts","./src/types/index.ts"],"version":"5.9.3"}
+2
View File
@@ -0,0 +1,2 @@
declare const _default: import("vite").UserConfig;
export default _default;
+20
View File
@@ -0,0 +1,20 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
server: {
port: 5173,
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
},
},
},
});