抓变化

This commit is contained in:
jiang 2025-06-20 16:55:23 +08:00
parent 3ce40dd036
commit a59c925d56
5 changed files with 194 additions and 113 deletions

View File

@ -1,29 +1,29 @@
const { contextBridge, ipcRenderer } = require('electron'); const {contextBridge, ipcRenderer} = require('electron');
// 暴露安全的API给渲染进程 // 暴露安全的API给渲染进程
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {
// 文件操作 // 文件操作
selectExcelFile: () => ipcRenderer.invoke('select-excel-file'), selectExcelFile: () => ipcRenderer.invoke('select-excel-file'),
// 数据库操作 // 数据库操作
getProjects: () => ipcRenderer.invoke('get-projects'), getProjects: () => ipcRenderer.invoke('get-projects'),
getProjectsRange: () => ipcRenderer.invoke('get-projects-range'), getProjectsRange: () => ipcRenderer.invoke('get-projects-range'),
getTreeStructure: () => ipcRenderer.invoke('get-tree-structure'), getTreeStructure: () => ipcRenderer.invoke('get-tree-structure'),
filterProjects: (filters) => ipcRenderer.invoke('filter-projects', filters), filterProjects: (filters) => ipcRenderer.invoke('filter-projects', filters),
updateProject: (project) => ipcRenderer.invoke('update-project', project), updateProject: (project) => ipcRenderer.invoke('update-project', project),
deleteProject: (projectId) => ipcRenderer.invoke('delete-project', projectId), deleteProject: (projectId) => ipcRenderer.invoke('delete-project', projectId),
// Excel处理 // Excel处理
importExcel: (filePath) => ipcRenderer.invoke('import-excel', filePath), importExcel: (filePath) => ipcRenderer.invoke('import-excel', filePath),
// 数据清除 // 数据清除
clearAllData: () => ipcRenderer.invoke('clear-all-data'), clearAllData: () => ipcRenderer.invoke('clear-all-data'),
// 事件监听 // 事件监听
onImportProgress: (callback) => { onImportProgress: (callback) => {
// 移除之前的监听器,避免重复 // 移除之前的监听器,避免重复
ipcRenderer.removeAllListeners('import-progress'); ipcRenderer.removeAllListeners('import-progress');
// 添加新的监听器 // 添加新的监听器
ipcRenderer.on('import-progress', (event, data) => callback(data)); ipcRenderer.on('import-progress', (event, data) => callback(data));
} }
}); });

View File

@ -29,6 +29,8 @@ function App() {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isDarkMode] = useState(true); // 固定使用深色主题 const [isDarkMode] = useState(true); // 固定使用深色主题
const [lastImportedFilePath, setLastImportedFilePath] = useState(null); // 记录最后导入的文件路径 const [lastImportedFilePath, setLastImportedFilePath] = useState(null); // 记录最后导入的文件路径
// 根据选中的节点筛选项目数据
let select = {};
// 初始化数据 // 初始化数据
useEffect(() => { useEffect(() => {
@ -111,8 +113,6 @@ function App() {
const key = selectedKeys[0]; const key = selectedKeys[0];
setSelectedNode(key); setSelectedNode(key);
// 根据选中的节点筛选项目数据
let filters = {};
if (key === 'headquarters') { if (key === 'headquarters') {
// 总部节点,显示所有数据 // 总部节点,显示所有数据
@ -120,17 +120,17 @@ function App() {
} else if (key.startsWith('unit-')) { } else if (key.startsWith('unit-')) {
// 单位节点,筛选该单位的数据 // 单位节点,筛选该单位的数据
const unit = key.replace('unit-', ''); const unit = key.replace('unit-', '');
filters = {unit}; select = {unit};
} else if (key.startsWith('construction-')) { } else if (key.startsWith('construction-')) {
// 建设单位节点,筛选该建设单位的数据 // 建设单位节点,筛选该建设单位的数据
const parts = key.split('-'); const parts = key.split('-');
const unit = parts[1]; const unit = parts[1];
const constructionUnit = parts.slice(2).join('-'); const constructionUnit = parts.slice(2).join('-');
filters = {unit, constructionUnit}; select = {unit, constructionUnit};
} }
// 应用筛选 // 应用筛选
filterProjects(filters); filterProjects(select);
} }
}; };
@ -159,16 +159,17 @@ function App() {
} }
// 应用筛选 // 应用筛选
filterProjects(filters); filterProjects({ ...filters, ...select });
}; };
// 处理项目搜索 // 处理项目搜索
const handleSearch = (text) => { const handleSearch = (text) => {
setSearchText(text);
setSearchText(text);
console.log(select)
// 根据搜索文本筛选项目数据 // 根据搜索文本筛选项目数据
const filters = {subProjectName: text}; const filters = {subProjectName: text};
filterProjects(filters); filterProjects({ ...filters, ...select });
}; };
// 处理项目选择 // 处理项目选择
@ -261,6 +262,7 @@ function App() {
const progressMessage = document.getElementById('import-progress-message'); const progressMessage = document.getElementById('import-progress-message');
if (progressBar && progressMessage) { if (progressBar && progressMessage) {
const antProgressText = progressBar.querySelector('.ant-progress-text');
// 更新进度条 // 更新进度条
const antProgress = progressBar.querySelector('.ant-progress-bg'); const antProgress = progressBar.querySelector('.ant-progress-bg');
if (antProgress) { if (antProgress) {
@ -270,7 +272,7 @@ function App() {
// 更新文本 // 更新文本
progressMessage.textContent = data.message; progressMessage.textContent = data.message;
antProgressText.textContent = `${data.progress}%`;
// 如果导入完成,关闭对话框并重新加载数据 // 如果导入完成,关闭对话框并重新加载数据
if (data.status === 'complete') { if (data.status === 'complete') {
setTimeout(() => { setTimeout(() => {

View File

@ -1,5 +1,5 @@
import React, {useEffect} from 'react'; import React, {useEffect} from 'react';
import {Modal, Form, Input, Select, Switch, Button} from 'antd'; import {Modal, Form, Input, Select, Switch, Button, InputNumber} from 'antd';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
const {Option} = Select; const {Option} = Select;
@ -104,14 +104,26 @@ const ProjectDetailForm = ({visible, project, onCancel, onSave}) => {
<Form.Item label="下次梳理时间" name="next_review_time"> <Form.Item label="下次梳理时间" name="next_review_time">
<Input placeholder="YYYY-MM-DD"/> <Input placeholder="YYYY-MM-DD"/>
</Form.Item> </Form.Item>
<Form.Item label="参建人数" name="participants_count"> <Form.Item label="参建人数" name="participants_count"
<Input type="number"/> rules={[
{type: 'number', min: 1, message: '必须为正整数'},
]}
>
<InputNumber min={1} precision={0} style={{width: '100%'}}/>
</Form.Item> </Form.Item>
<Form.Item label="新班组进场数量" name="new_team_count"> <Form.Item label="新班组进场数量" name="new_team_count" rules={[
<Input type="number"/> {type: 'number', min: 1, message: '必须为正整数'},
]}
>
<InputNumber min={1} precision={0} style={{width: '100%'}}/>
</Form.Item> </Form.Item>
<Form.Item label="新人进场数量" name="new_person_count"> <Form.Item label="新人进场数量" name="new_person_count" rules={[
<Input type="number"/> {type: 'number', min: 1, message: '必须为正整数'},
]}
>
<InputNumber min={1} precision={0} style={{width: '100%'}}/>
</Form.Item> </Form.Item>
<Form.Item label="带班人姓名、电话" name="leader_info"> <Form.Item label="带班人姓名、电话" name="leader_info">
<Input/> <Input/>
@ -144,19 +156,50 @@ const ProjectDetailForm = ({visible, project, onCancel, onSave}) => {
<Form.Item> <Form.Item>
<div> <div>
<p style={{fontSize: '20px', fontWeight: 'bold'}}>人的变化</p> <p style={{fontSize: '20px', fontWeight: 'bold'}}>人的变化</p><Form.Item
<Form.Item label="新进班组数量" name="new_team"> label="新进班组数量"
<Input type="number"/> name="new_team"
rules={[
{ message: '请输入新进班组数量'},
{type: 'number', min: 1, message: '必须为正整数'},
]}
>
<InputNumber min={1} precision={0} style={{width: '100%'}}/>
</Form.Item>
<Form.Item
label="新进班组骨干数量"
name="new_members"
rules={[
{message: '请输入新进班组骨干数量'},
{type: 'number', min: 1, message: '必须为正整数'},
]}
>
<InputNumber min={1} precision={0} style={{width: '100%'}}/>
</Form.Item> </Form.Item>
<Form.Item label="新进班组骨干数量" name="new_members">
<Input type="number"/> <Form.Item
label="新进高空人员数量"
name="new_high_altitude"
rules={[
{message: '请输入新进高空人员数量'},
{type: 'number', min: 1, message: '必须为正整数'},
]}
>
<InputNumber min={1} precision={0} style={{width: '100%'}}/>
</Form.Item> </Form.Item>
<Form.Item label="新进高空人员数量" name="new_high_altitude">
<Input type="number"/> <Form.Item
</Form.Item> label="新进一般人员数量"
<Form.Item label="新进一般人员数量" name="new_hired_general"> name="new_hired_general"
<Input type="number"/> rules={[
{message: '请输入新进一般人员数量'},
{type: 'number', min: 1, message: '必须为正整数'},
]}
>
<InputNumber min={1} precision={0} style={{width: '100%'}}/>
</Form.Item> </Form.Item>
</div> </div>
</Form.Item> </Form.Item>

View File

@ -202,13 +202,46 @@ class ExcelService {
return defaultValue; return defaultValue;
} }
// 如果是日期类型转换为ISO格式 // 如果是日期类型转换为ISO格式
if (fieldName === '实际开工时间' || fieldName === '计划竣工时间' || fieldName === '完成时间' || fieldName === '下次梳理时间(注意与 隐患提示/工作要求 对应)') { if (
const date = new Date(value); fieldName === '实际开工时间' ||
if (!isNaN(date.getTime())) { fieldName === '计划竣工时间' ||
fieldName === '完成时间' ||
fieldName === '下次梳理时间(注意与 隐患提示/工作要求 对应)'
) {
if (value == null) return ''; // 空值处理
return date.toISOString().split('T')[0]; // 只保留日期部分 // ✅ Excel 日期序列号(一般从 25569 开始)
if (typeof value === 'number') {
if (value > 1e12 && value < 1e14) {
// ✅ 毫秒级时间戳
const date = new Date(value);
if (!isNaN(date.getTime())) return date.toISOString().split('T')[0];
} else {
// ✅ Excel 序列号转日期(从 1900-01-01 起第1天是 1
const utcDays = Math.floor(value - 25569);
const utcValue = utcDays * 86400; // 转秒
const date = new Date(utcValue * 1000);
if (!isNaN(date.getTime())) return date.toISOString().split('T')[0];
}
} }
if (typeof value === 'string') {
let parsed = new Date(value);
if (!isNaN(parsed.getTime())) return parsed.toISOString().split('T')[0];
// ✅ 支持“5-12”、“5月12日” 等格式
const matched = value.match(/^(\d{1,2})[月/-](\d{1,2})/);
if (matched) {
const year = new Date().getFullYear(); // 默认今年
const mm = matched[1].padStart(2, '0');
const dd = matched[2].padStart(2, '0');
return `${year}-${mm}-${dd}`;
}
}
return ''; // 未能解析,返回空字符串
} }
return value; return value;
}; };
@ -270,7 +303,10 @@ class ExcelService {
processedRows++; processedRows++;
if (processedRows % 10 === 0 || processedRows === totalRows) { if (processedRows % 10 === 0 || processedRows === totalRows) {
const progress = Math.floor(50 + (processedRows / totalRows) * 20); // 50%-70%的进度 const progress = Math.floor(50 + (processedRows / totalRows) * 20); // 50%-70%的进度
if (global.mainWindow) { if (global.mainWindow) {
console.log("进度+++",progress)
global.mainWindow.webContents.send('import-progress', { global.mainWindow.webContents.send('import-progress', {
status: 'saving', status: 'saving',
progress: progress, progress: progress,

View File

@ -86,7 +86,7 @@ code {
.ant-tree { .ant-tree {
background-color: transparent !important; background-color: transparent !important;
color: var(--vscode-text) !important; color: var(--vscode-text) !important;
} }mm
.ant-tree-node-content-wrapper:hover { .ant-tree-node-content-wrapper:hover {
background-color: var(--vscode-hover-item) !important; background-color: var(--vscode-hover-item) !important;