diff --git a/src/views/salary-management/components/SalaryDetailModal.vue b/src/views/salary-management/components/SalaryDetailModal.vue
new file mode 100644
index 0000000..b4b910b
--- /dev/null
+++ b/src/views/salary-management/components/SalaryDetailModal.vue
@@ -0,0 +1,242 @@
+
+ emit('update:visible', val)"
+ :title="title"
+ :width="900"
+ :footer="true"
+ @cancel="handleCancel"
+ >
+
+ {{ data?.employeeName }}
+ {{ employeeTypeText }}
+ {{ data?.idCard }}
+ {{ data?.phone }}
+ {{ data?.bankCard }}
+ {{ data?.bankName }}
+ {{ data?.projectName }}
+ {{ data?.projectPeriod }}
+ {{ data?.workDays }}天
+ {{ data?.offshoreDays }}天
+
+
+ 薪酬明细
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 绩效评价
+
+
+
+ {{ record.score }}/{{ record.maxScore }}
+
+
+
+ ¥{{ (record.score / record.maxScore * record.amount).toFixed(2) }}
+
+
+
+ 补助明细
+
+
+ ¥{{ record.total.toFixed(2) }}
+
+
+
+ 审批流程
+
+
+
+
+
+
+
+
+
+
+
+
+ 关闭
+
+
+ 导出Excel
+
+
+
+
+
+
+
diff --git a/src/views/salary-management/components/SalaryFormDrawer.vue b/src/views/salary-management/components/SalaryFormDrawer.vue
new file mode 100644
index 0000000..71b998b
--- /dev/null
+++ b/src/views/salary-management/components/SalaryFormDrawer.vue
@@ -0,0 +1,468 @@
+
+ emit('update:visible', val)"
+ :title="title"
+ :width="800"
+ :footer="true"
+ @cancel="handleCancel"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+ 实习生
+ 正式员工
+ 兼职员工
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 绩效评价
+
+
+
+
+
+ {{ record.amount }}
+
+
+
+
+ 补助明细
+
+
+
+
+
+ {{ record.total }}
+
+
+
+
+ 计算结果
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 取消
+ 保存
+
+
+
+
+
+
diff --git a/src/views/salary-management/types.ts b/src/views/salary-management/types.ts
new file mode 100644
index 0000000..93df2af
--- /dev/null
+++ b/src/views/salary-management/types.ts
@@ -0,0 +1,127 @@
+// 员工类型
+export type EmployeeType = 'intern' | 'fulltime' | 'parttime'
+
+// 工资单状态
+export type SalaryStatus = 'draft' | 'pending' | 'approved' | 'rejected' | 'paid'
+
+// 补助类型
+export interface AllowanceItem {
+ type: string
+ name: string
+ amount: number
+ unit: 'day' | 'project' | 'fixed'
+ quantity: number
+ total: number
+}
+
+// 绩效评价项
+export interface PerformanceItem {
+ id: string
+ name: string
+ weight: number
+ score: number
+ maxScore: number
+ amount: number
+ description?: string
+}
+
+// 工资记录
+export interface SalaryRecord {
+ id: string
+ employeeId: string
+ employeeName: string
+ employeeType: EmployeeType
+ idCard: string
+ phone: string
+ bankCard: string
+ bankName: string
+
+ // 项目信息
+ projectName: string
+ projectPeriod: string
+ workDays: number
+ offshoreDays: number
+
+ // 薪酬结构
+ baseSalary: number
+ baseSalaryStandard: number
+ performanceBonus: number
+ allowances: number
+ performanceItems: PerformanceItem[]
+ allowanceItems: AllowanceItem[]
+
+ // 计算结果
+ totalPayable: number
+ deductions: number
+ netPay: number
+
+ // 状态
+ status: SalaryStatus
+ approvalFlow: ApprovalStep[]
+
+ // 时间
+ salaryMonth: string
+ createdAt: string
+ updatedAt: string
+}
+
+// 审批步骤
+export interface ApprovalStep {
+ step: string
+ role: string
+ approver: string
+ status: 'pending' | 'approved' | 'rejected'
+ comment?: string
+ date?: string
+}
+
+// 查询参数
+export interface SalaryQuery {
+ keyword?: string
+ employeeType?: EmployeeType
+ status?: SalaryStatus
+ dateRange?: string[]
+ projectName?: string
+}
+
+// 实习生专用配置
+export interface InternConfig {
+ baseSalaryStandard: {
+ withCertification: number
+ withoutCertification: number
+ }
+ performanceRates: {
+ construction: number
+ offshore: number
+ }
+ allowances: {
+ offshoreCert: number
+ towerWork: {
+ land: {
+ bladeInspection: number
+ lightning: number
+ }
+ sea: {
+ bladeInspection: number
+ lightning: number
+ }
+ }
+ droneWork: number
+ meal: number
+ }
+}
+
+// 工资单创建请求
+export interface SalaryCreateRequest {
+ employeeId: string
+ projectId: string
+ workDays: number
+ offshoreDays: number
+ performanceItems: Omit[]
+ allowanceItems: Omit[]
+ deductions?: {
+ type: string
+ amount: number
+ reason: string
+ }[]
+}
diff --git a/src/views/salary-management/utils/export.ts b/src/views/salary-management/utils/export.ts
new file mode 100644
index 0000000..4b5c455
--- /dev/null
+++ b/src/views/salary-management/utils/export.ts
@@ -0,0 +1,255 @@
+import * as XLSX from 'xlsx'
+import type { SalaryRecord } from '../types'
+
+// 导出工资单到Excel
+export const exportSalaryToExcel = (records: SalaryRecord[], filename: string) => {
+ // 创建工作簿
+ const workbook = XLSX.utils.book_new()
+
+ // 主表数据
+ const mainData = records.map((record) => ({
+ 员工姓名: record.employeeName,
+ 员工类型: getEmployeeTypeText(record.employeeType),
+ 身份证号: record.idCard,
+ 联系电话: record.phone,
+ 银行卡号: record.bankCard,
+ 开户银行: record.bankName,
+ 项目名称: record.projectName,
+ 项目周期: record.projectPeriod,
+ 工作天数: record.workDays,
+ 海上作业天数: record.offshoreDays,
+ 基本工资: record.baseSalary,
+ 绩效奖金: record.performanceBonus,
+ 各类补助: record.allowances,
+ 应发总额: record.totalPayable,
+ 扣款金额: record.deductions,
+ 实发金额: record.netPay,
+ 状态: getStatusText(record.status),
+ 创建时间: record.createdAt,
+ }))
+
+ // 创建主表
+ const mainSheet = XLSX.utils.json_to_sheet(mainData)
+ XLSX.utils.book_append_sheet(workbook, mainSheet, '工资汇总')
+
+ // 绩效明细表
+ const performanceData: any[] = []
+ records.forEach((record) => {
+ record.performanceItems.forEach((item) => {
+ performanceData.push({
+ 员工姓名: record.employeeName,
+ 项目名称: record.projectName,
+ 评价项: item.name,
+ 权重: item.weight,
+ 得分: item.score,
+ 满分: item.maxScore,
+ 金额: (item.score / item.maxScore * item.amount).toFixed(2),
+ })
+ })
+ })
+
+ if (performanceData.length > 0) {
+ const performanceSheet = XLSX.utils.json_to_sheet(performanceData)
+ XLSX.utils.book_append_sheet(workbook, performanceSheet, '绩效明细')
+ }
+
+ // 补助明细表
+ const allowanceData: any[] = []
+ records.forEach((record) => {
+ record.allowanceItems.forEach((item) => {
+ allowanceData.push({
+ 员工姓名: record.employeeName,
+ 项目名称: record.projectName,
+ 补助类型: item.name,
+ 标准: item.amount,
+ 单位: getUnitText(item.unit),
+ 数量: item.quantity,
+ 小计: item.total,
+ })
+ })
+ })
+
+ if (allowanceData.length > 0) {
+ const allowanceSheet = XLSX.utils.json_to_sheet(allowanceData)
+ XLSX.utils.book_append_sheet(workbook, allowanceSheet, '补助明细')
+ }
+
+ // 导出文件
+ XLSX.writeFile(workbook, filename)
+}
+
+// 导出单个工资单详情
+export const exportSingleSalaryToExcel = (record: SalaryRecord) => {
+ const workbook = XLSX.utils.book_new()
+
+ // 基本信息
+ const basicInfo = [{
+ 项目: '员工姓名',
+ 值: record.employeeName,
+ }, {
+ 项目: '员工类型',
+ 值: getEmployeeTypeText(record.employeeType),
+ }, {
+ 项目: '身份证号',
+ 值: record.idCard,
+ }, {
+ 项目: '联系电话',
+ 值: record.phone,
+ }, {
+ 项目: '银行卡号',
+ 值: record.bankCard,
+ }, {
+ 项目: '开户银行',
+ 值: record.bankName,
+ }, {
+ 项目: '项目名称',
+ 值: record.projectName,
+ }, {
+ 项目: '项目周期',
+ 值: record.projectPeriod,
+ }, {
+ 项目: '工作天数',
+ 值: record.workDays,
+ }, {
+ 项目: '海上作业天数',
+ 值: record.offshoreDays,
+ }]
+
+ const basicSheet = XLSX.utils.json_to_sheet(basicInfo)
+ XLSX.utils.book_append_sheet(workbook, basicSheet, '基本信息')
+
+ // 薪酬汇总
+ const salarySummary = [{
+ 项目: '基本工资',
+ 金额: record.baseSalary,
+ }, {
+ 项目: '绩效奖金',
+ 金额: record.performanceBonus,
+ }, {
+ 项目: '各类补助',
+ 金额: record.allowances,
+ }, {
+ 项目: '应发总额',
+ 金额: record.totalPayable,
+ }, {
+ 项目: '扣款金额',
+ 金额: record.deductions,
+ }, {
+ 项目: '实发金额',
+ 金额: record.netPay,
+ }]
+
+ const salarySheet = XLSX.utils.json_to_sheet(salarySummary)
+ XLSX.utils.book_append_sheet(workbook, salarySheet, '薪酬汇总')
+
+ // 绩效明细
+ if (record.performanceItems.length > 0) {
+ const performanceSheet = XLSX.utils.json_to_sheet(record.performanceItems.map((item) => ({
+ 评价项: item.name,
+ 权重: item.weight,
+ 得分: item.score,
+ 满分: item.maxScore,
+ 金额: (item.score / item.maxScore * item.amount).toFixed(2),
+ })))
+ XLSX.utils.book_append_sheet(workbook, performanceSheet, '绩效明细')
+ }
+
+ // 补助明细
+ if (record.allowanceItems.length > 0) {
+ const allowanceSheet = XLSX.utils.json_to_sheet(record.allowanceItems.map((item) => ({
+ 补助类型: item.name,
+ 标准: item.amount,
+ 单位: getUnitText(item.unit),
+ 数量: item.quantity,
+ 小计: item.total,
+ })))
+ XLSX.utils.book_append_sheet(workbook, allowanceSheet, '补助明细')
+ }
+
+ // 导出文件
+ const filename = `${record.employeeName}_工资单_${record.projectPeriod}.xlsx`
+ XLSX.writeFile(workbook, filename)
+}
+
+// 导出实习报酬申领表格式
+export const exportInternCompensationForm = (record: SalaryRecord) => {
+ const workbook = XLSX.utils.book_new()
+
+ // 实习生基本信息
+ const basicInfo = [
+ ['实习生基本信息', '', '', '', ''],
+ ['类别', '填写内容', '', '备注', ''],
+ ['姓名', record.employeeName, '', '', ''],
+ ['身份证号', record.idCard, '', '', ''],
+ ['联系电话', record.phone, '', '', ''],
+ ['银行卡号', record.bankCard, '', '', ''],
+ ['开户银行', record.bankName, '', '', ''],
+ ['', '', '', '', ''],
+ ['实习项目及项目实习相关信息', '', '', '', ''],
+ ['序号', '项目名称', '在项目时间', '出外业施工作业时间(天)', '备注(时间段)'],
+ ['1', record.projectName, record.workDays, record.workDays - record.offshoreDays, record.projectPeriod],
+ ['', '', '', '', ''],
+ ['薪酬、绩效、补助(一)', '', '', '', ''],
+ ['项目类别', '计算标准(元/天)或(元/台)', '计酬天数统计(日)', '应发金额', '备注'],
+ ['基本工资', record.baseSalaryStandard, record.workDays, record.baseSalary, ''],
+ ['施工绩效', 100, record.workDays - record.offshoreDays, record.performanceBonus, ''],
+ ['海上作业绩效补助', 30, record.offshoreDays, record.offshoreDays * 30, ''],
+ ['务餐补助', 45, record.workDays, record.allowances, ''],
+ ['合计应发金额', '', '', record.totalPayable, ''],
+ ]
+
+ const sheet = XLSX.utils.aoa_to_sheet(basicInfo)
+
+ // 设置列宽
+ const cols = [
+ { wch: 20 },
+ { wch: 20 },
+ { wch: 15 },
+ { wch: 25 },
+ { wch: 20 },
+ ]
+ sheet['!cols'] = cols
+
+ // 合并单元格
+ sheet['!merges'] = [
+ { s: { r: 0, c: 0 }, e: { r: 0, c: 4 } },
+ { s: { r: 8, c: 0 }, e: { r: 8, c: 4 } },
+ { s: { r: 12, c: 0 }, e: { r: 12, c: 4 } },
+ ]
+
+ XLSX.utils.book_append_sheet(workbook, sheet, '实习报酬申领表')
+
+ // 导出文件
+ const filename = `${record.employeeName}_实习报酬申领表_${record.projectPeriod}.xlsx`
+ XLSX.writeFile(workbook, filename)
+}
+
+// 辅助函数
+function getEmployeeTypeText(type: string) {
+ const typeMap = {
+ intern: '实习生',
+ fulltime: '正式员工',
+ parttime: '兼职员工',
+ }
+ return typeMap[type as keyof typeof typeMap] || type
+}
+
+function getStatusText(status: string) {
+ const statusMap = {
+ draft: '草稿',
+ pending: '待审批',
+ approved: '已批准',
+ rejected: '已拒绝',
+ paid: '已发放',
+ }
+ return statusMap[status as keyof typeof statusMap] || status
+}
+
+function getUnitText(unit: string) {
+ const unitMap = {
+ day: '天',
+ project: '项目',
+ fixed: '固定',
+ }
+ return unitMap[unit as keyof typeof unitMap] || unit
+}