海外项目综合管理系统,面向海外运营中心项目管理部,提供项目全生命周期信息的标准化管理、数据联动与可视化。
接手改代码前请先读 CHANGELOG.md(按时间倒序,最新在最上面)。 那里记录了每次改动的原因和踩过的坑——包括几处「看起来像 bug 其实是有意为之」 和「报错信息具有误导性」的情况,不看容易把修好的东西又改回去。 本文件末尾的「注意事项(易踩的坑)」一节也建议先扫一遍。
| 层 | 选型 |
|---|---|
| 后端 | Go(标准库 net/http,无 Web 框架) |
| 前端 | Vue 3 + TypeScript + Element Plus + Vite |
| 数据库 | SQLite(modernc.org/sqlite,pure-Go 免 CGO) |
| 地图 | Leaflet |
| 打包 | 单个 opims.exe(~20MB,内含前端产物) |
# 双击或命令行运行
opims.exe
# 浏览器访问
http://localhost:8080重复双击不会重复启动,仅打开浏览器(通过检测 8080 端口占用实现)。 在命令行窗口按 Enter 停止服务。
首次运行:文件根目录默认为 exe 所在目录,需在「项目文件 → 设置根目录」中指向实际的项目文件目录。该配置存入数据库,换电脑或移动文件夹后重新设置即可。
opims/
├── backend/ # Go 后端源码
│ ├── main.go # 入口:端口检测、DB 初始化、路由注册、启动浏览器
│ ├── handlers/
│ │ ├── helpers.go # Handler 结构、scanProject、列名/占位符、GPS 解析
│ │ ├── projects.go # 项目 CRUD、Excel 导入导出
│ │ ├── files.go # 文件树、合同文件识别、打开文件、根目录设置
│ │ ├── blacklist.go # 分包商黑名单
│ │ └── dashboard.go # 看板聚合、数据库备份/恢复
│ ├── database/db.go # SQLite 初始化与 schema(migrate)
│ ├── models/project.go # 数据模型(Project 82 字段宽表)
│ ├── services/
│ │ ├── excel.go # Excel 解析(按 sheet 名推断状态 + 列号映射)
│ │ ├── country.go # 国别关键词表(有序,见下方「注意事项」)
│ │ ├── country_test.go # 国别识别测试
│ │ └── rootdir.go # 线程安全保存「文件根目录」配置
│ └── frontend-dist/ # 前端构建产物(gitignore,由 npm run build 生成)
├── frontend/ # Vue 3 前端源码(唯一前端目录)
│ └── src/
│ ├── App.vue # 外壳:侧边栏导航 + 顶栏
│ ├── theme.css # 设计令牌 + Element Plus 主题覆盖
│ ├── data/countryCoords.ts # 国别→经纬度表(地图近似定位用)
│ ├── data/regions.ts # 国别→地区(大区)映射(合同额分布用)
│ ├── views/ # 页面组件
│ ├── i18n/ # 中英双语
│ └── router/ # 路由(hash 模式)
├── docs/ # 功能介绍与操作说明
└── .gitignore
| 板块 | 状态 |
|---|---|
| 首页看板 | ✅ 已实现(KPI 卡片、全球分布地图、合同额分布饼图、快捷入口) |
| 项目清单 | ✅ 已实现(筛选、排序、分页、Excel 导入导出、详情) |
| 项目文件 | ✅ 已实现 |
| 分包商黑名单 | ✅ 已实现 |
| 人员黑名单 | 📅 待开发 |
| 项目进度 | 📅 待开发 |
| 项目质量 | 📅 待开发 |
| 项目分包 | 📅 待开发 |
| 项目人员 | 📅 待开发 |
待开发模块统一指向 views/Placeholder.vue,侧边栏标记「待建」,点击给出提示。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/projects |
列表。不带 status 参数时只返回「在建+未开工」;status=all 返回全部;也支持 type/country/domestic_overseas/keyword |
| POST/PUT | /api/projects |
新建 / 更新 |
| GET/PUT/DELETE | /api/projects/{id} |
单条查询 / 更新 / 软删除(is_deleted=1) |
| POST | /api/projects/import |
Excel 导入(conflict=skip|overwrite|keep_both) |
| GET | /api/projects/export |
导出 xlsx |
| GET | /api/dashboard |
看板聚合(总数、各状态计数、有 GPS 的地图标记) |
| GET | /api/files/scan |
扫描根目录 |
| GET/POST | /api/files/root |
读取 / 设置文件根目录 |
| GET | /api/files/contracts |
某项目的合同文件列表 |
| GET | /api/files/view |
用系统默认程序打开文件 |
| GET | /api/files/{project} |
某项目的文件树 |
| GET/POST | /api/blacklist/subcontractor |
分包商黑名单列表 / 新增 |
| PUT/DELETE | /api/blacklist/subcontractor/{id} |
修改 / 删除(「已拉出」记录不可改删) |
| POST | /api/config/backup /api/config/restore |
数据库备份 / 恢复 |
整个系统以项目简称为关联键。文件夹名必须与项目简称一致,否则文件无法关联到对应项目。
01.Contract 文件夹内的文件按文件名自动分类:
| 文件名规则 | 显示标签 |
|---|---|
含 contract(不含 supplement) |
主合同 |
含 supplement |
补充合同 |
含 supplement + 末尾数字 |
补充合同一/二/三… |
| 以上均不匹配 | 合同文件 |
- 仅导入境外项目(境内/境外=境外)
- 项目简称和合同编号从
海外项目简称.xlsx按项目名称自动匹配(在文件根目录下查找) - 冲突处理:跳过 / 覆盖 / 保留两者
- Excel 解析按 sheet 名推断项目状态(含"未开工"/"停工"/"完工"/"在建"),列位置在
services/excel.go中按列号硬编码,表格列序变化会导致解析错位
导入时按 countryRules 有序匹配项目名称+地址中的关键词。
- 长国名必须排在其包含的短国名之前,否则会被抢先匹配
(
印度尼西亚必须在印度前;白俄罗斯必须在俄罗斯前) - 项目专有缩写(ADNOC/DBN/PLF)排在所有国名之后,避免抢先命中
- 不要把工艺缩写(如
LNG)当地名 —— 它会错误命中任何含 LNG 的项目 - 改完请运行
go test ./services/验证(country_test.go已覆盖上述场景)
- 环形饼图(纯 SVG 手绘,无第三方图表库依赖,便于离线与后续鸿蒙移植)
- 维度可切换:按地区(默认,口径见
frontend/src/data/regions.ts)/ 按国别 - 状态筛选:全部(单选)+ 在建/未开工/完工(可多选,取并集)
- 按地区时点击扇区或图例可下钻查看国别明细,下钻沿用当前状态筛选
- 分组超过 7 个时尾部合并为「其他 N 项」;不要通过生成新色相来容纳更多分组——新色相在色盲下无法与既有色区分
- 图例必须保留名称/金额/占比文字:分类色中有 3 个对比度低于 3:1,文字是必需的兜底
新增国别时需同时维护三处:backend/services/country.go(识别关键词)、frontend/src/data/countryCoords.ts(坐标)、frontend/src/data/regions.ts(所属地区)。
- 有 GPS 坐标的项目按真实坐标显示(实线标记)
- 无 GPS 但国别可识别的项目,落到
frontend/src/data/countryCoords.ts中该国代表坐标,虚线标记表示近似,同国多项目按黄金角散开 - 完全无可定位项目时显示空状态提示
- 状态用颜色 + 形状双重编码(圆点/空心圈/方块/小圆点),因为红绿在红绿色盲下无法靠色相区分;tooltip 始终带状态文字
- 备份:
opims_backup_YYYYMMDD_HHmm.db - 恢复:选择备份文件 → 确认覆盖 → 替换当前数据库
# 后端
cd backend
go run .
go vet ./...
go test ./...
# 前端(开发模式,代理 /api 到 8080)
cd frontend
npm install
npm run dev
# 构建(前端产物 → backend/frontend-dist/,再编进 exe 同目录)
cd frontend && npm run build
cd ../backend && go build -o opims.exe .- 前端只有一个目录
frontend/。历史上曾短暂存在frontend-v2/,两者构建到同一个frontend-dist/会互相覆盖,已合并删除。不要再新建平行的前端目录。 - 国别是导入时写入数据库的。修改
country.go的关键词表后,已入库的旧数据不会自动更新,需要重新导入 Excel 才会生效。 /api/projects默认只返回「在建+未开工」。需要全量时必须显式传status=all,否则统计会少数据。Project是 82 字段宽表。新增字段需同步改动:database/db.go的 schema、models/project.go、handlers/helpers.go的projectsInsertCols/projectsInsertVals/placeholders(82)这个数字、以及services/excel.go的各parseXXX列映射。极易漏改,改完务必实际跑一遍导入和新建。- Excel 列映射是硬编码列号。上游表格列序调整会导致数据错位,且不会报错。
- 备份前会执行
PRAGMA wal_checkpoint(TRUNCATE)以避免 WAL 中未落盘的数据丢失。
内部使用。